Changeset 2569 in josm for trunk


Ignore:
Timestamp:
2009-12-04T15:53:55+01:00 (15 years ago)
Author:
Gubaer
Message:

fixed #3684: Add "chunked" upload mode
Removed support for API "0.5" when uploading (there are still 0.5-files around, but I'm not aware of any 0.5-servers)

Location:
trunk
Files:
4 added
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/UploadAction.java

    r2512 r2569  
    3636import org.openstreetmap.josm.gui.HelpAwareOptionPane.ButtonSpec;
    3737import org.openstreetmap.josm.gui.io.UploadDialog;
     38import org.openstreetmap.josm.gui.io.UploadStrategySpecification;
    3839import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    3940import org.openstreetmap.josm.gui.progress.ProgressMonitor;
     
    168169            return;
    169170        Main.worker.execute(
    170                 createUploadTask(
     171                new UploadPrimitivesTask(
     172                        UploadDialog.getUploadDialog().getUploadStrategySpecification(),
    171173                        layer,
    172174                        apiData.getPrimitives(),
     
    552554    }
    553555
    554     public UploadPrimitivesTask createUploadTask(OsmDataLayer layer, Collection<OsmPrimitive> toUpload, Changeset changeset, boolean closeChangesetAfterUpload) {
    555         return new UploadPrimitivesTask(layer, toUpload, changeset, closeChangesetAfterUpload);
    556     }
    557 
    558556    /**
    559557     * The task for uploading a collection of primitives
     
    569567        private boolean closeChangesetAfterUpload;
    570568        private HashSet<OsmPrimitive> processedPrimitives;
     569        private UploadStrategySpecification strategy;
    571570
    572571        /**
    573          *
     572         * Creates the task
     573         * @param strategy the upload strategy
    574574         * @param layer  the OSM data layer for which data is uploaded
    575575         * @param toUpload the collection of primitives to upload
     
    577577         * @param closeChangesetAfterUpload true, if the changeset is to be closed after uploading
    578578         */
    579         private UploadPrimitivesTask(OsmDataLayer layer, Collection <OsmPrimitive> toUpload, Changeset changeset, boolean closeChangesetAfterUpload) {
     579        private UploadPrimitivesTask(UploadStrategySpecification strategy, OsmDataLayer layer, Collection <OsmPrimitive> toUpload, Changeset changeset, boolean closeChangesetAfterUpload) {
    580580            super(tr("Uploading data for layer ''{0}''", layer.getName()),false /* don't ignore exceptions */);
    581581            this.toUpload = toUpload;
    582582            this.layer = layer;
    583583            this.changeset = changeset;
     584            this.strategy = strategy;
    584585            this.closeChangesetAfterUpload = closeChangesetAfterUpload;
    585586            this.processedPrimitives = new HashSet<OsmPrimitive>();
     
    628629                    try {
    629630                        getProgressMonitor().subTask(tr("Uploading {0} objects ...", toUpload.size()));
    630                         writer.uploadOsm(layer.data.getVersion(), toUpload, changeset, getProgressMonitor().createSubTaskMonitor(1, false));
     631                        writer.uploadOsm(strategy, toUpload, changeset, getProgressMonitor().createSubTaskMonitor(1, false));
    631632                        processedPrimitives.addAll(writer.getProcessedPrimitives());
    632633                        // if we get here we've successfully uploaded the data. Exit the loop.
  • trunk/src/org/openstreetmap/josm/actions/upload/ApiPreconditionCheckerHook.java

    r2512 r2569  
    7373                        // value
    7474                        System.out.println(
    75                                 tr("Warning: automatically truncating value of tag ''{0}'' on deleted primitive {1}",
     75                                tr("Warning: automatically truncating value of tag ''{0}'' on deleted object {1}",
    7676                                        e.getKey(),
    7777                                        Long.toString(osmPrimitive.getId())
     
    8282                    }
    8383                    JOptionPane.showMessageDialog(Main.parent,
    84                             tr("Length of value for tag ''{0}'' on primitive {1} exceeds the max. allowed length {2}. Values length is {3}.",
     84                            tr("Length of value for tag ''{0}'' on object {1} exceeds the max. allowed length {2}. Values length is {3}.",
    8585                                    e.getKey(), Long.toString(osmPrimitive.getId()), 255, e.getValue().length()
    8686                            ),
  • trunk/src/org/openstreetmap/josm/command/RelationMemberConflictResolverCommand.java

    r2512 r2569  
    6868        super.executeCommand();
    6969
    70         // replace the list of nodes of 'my' way by the list of merged
    71         // nodes
     70        // replace the list of members of 'my' relation by the list of merged
     71        // members
    7272        //
    7373        my.setMembers(mergedMembers);
     
    8787    public void undoCommand() {
    8888        if (! Main.map.mapView.hasLayer(layer)) {
    89             logger.warning(tr("Can't undo command ''{0}'' because layer ''{1}'' is not present any more",
     89            logger.warning(tr("Can''t undo command ''{0}'' because layer ''{1}'' is not present any more",
    9090                    this.toString(),
    9191                    layer.toString()
  • trunk/src/org/openstreetmap/josm/gui/conflict/pair/ListMergeModel.java

    r2512 r2569  
    1515import java.util.HashMap;
    1616import java.util.Observable;
    17 import java.util.logging.Logger;
    1817
    1918import javax.swing.AbstractListModel;
     
    120119        return entries.get(MERGED_ENTRIES);
    121120    }
     121
    122122    protected ArrayList<T> getMyEntries() {
    123123        return entries.get(MY_ENTRIES);
    124124    }
     125
    125126    protected ArrayList<T> getTheirEntries() {
    126127        return entries.get(THEIR_ENTRIES);
  • trunk/src/org/openstreetmap/josm/gui/conflict/pair/relation/RelationMemberListMergeModel.java

    r2512 r2569  
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
     6import java.util.ArrayList;
    67import java.util.logging.Logger;
    78
     
    1617 * The model for merging two lists of relation members
    1718 *
    18  *
    1919 */
    2020public class RelationMemberListMergeModel extends ListMergeModel<RelationMember>{
     
    2424    @Override
    2525    public boolean isEqualEntry(RelationMember e1, RelationMember e2) {
    26         boolean ret = e1.getRole().equals(e2.getRole());
    27         if (!e1.getMember().isNew() ) {
    28             ret = ret && (e1.getMember().getId() == e2.getMember().getId());
    29         } else {
    30             ret = ret && (e1 == e2);
    31         }
    32         return ret;
     26        return e1.equals(e2);
    3327    }
    3428
     
    119113        if (! isFrozen())
    120114            throw new IllegalArgumentException(tr("Merged nodes not frozen yet. Can't build resolution command"));
    121         return new RelationMemberConflictResolverCommand(my, their, getMergedEntries());
     115        ArrayList<RelationMember> entries = getMergedEntries();
     116        return new RelationMemberConflictResolverCommand(my, their, entries);
    122117    }
    123118}
  • trunk/src/org/openstreetmap/josm/gui/io/SaveLayersDialog.java

    r2512 r2569  
    298298        public void cancel() {
    299299            switch(model.getMode()) {
    300                 case EDITING_DATA: cancelWhenInEditingModel(); break;
    301                 case UPLOADING_AND_SAVING: cancelSafeAndUploadTask(); break;
     300            case EDITING_DATA: cancelWhenInEditingModel(); break;
     301            case UPLOADING_AND_SAVING: cancelSafeAndUploadTask(); break;
    302302            }
    303303        }
     
    333333                Mode mode = (Mode)evt.getNewValue();
    334334                switch(mode) {
    335                     case EDITING_DATA: setEnabled(true); break;
    336                     case UPLOADING_AND_SAVING: setEnabled(false); break;
     335                case EDITING_DATA: setEnabled(true); break;
     336                case UPLOADING_AND_SAVING: setEnabled(false); break;
    337337                }
    338338            }
     
    367367                SaveLayersModel.Mode mode = (SaveLayersModel.Mode)evt.getNewValue();
    368368                switch(mode) {
    369                     case EDITING_DATA: setEnabled(true); break;
    370                     case UPLOADING_AND_SAVING: setEnabled(false); break;
     369                case EDITING_DATA: setEnabled(true); break;
     370                case UPLOADING_AND_SAVING: setEnabled(false); break;
    371371                }
    372372            }
     
    408408
    409409                currentTask = new UploadLayerTask(
     410                        UploadDialog.getUploadDialog().getUploadStrategySpecification(),
    410411                        layerInfo.getLayer(),
    411412                        monitor,
  • trunk/src/org/openstreetmap/josm/gui/io/UploadDialog.java

    r2512 r2569  
    22package org.openstreetmap.josm.gui.io;
    33
     4import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
    45import static org.openstreetmap.josm.tools.I18n.tr;
    56import static org.openstreetmap.josm.tools.I18n.trn;
     
    5051import org.openstreetmap.josm.data.osm.Changeset;
    5152import org.openstreetmap.josm.data.osm.OsmPrimitive;
     53import org.openstreetmap.josm.gui.HelpAwareOptionPane;
    5254import org.openstreetmap.josm.gui.OsmPrimitivRenderer;
    5355import org.openstreetmap.josm.gui.SideButton;
     
    5860import org.openstreetmap.josm.gui.tagging.TagModel;
    5961import org.openstreetmap.josm.gui.widgets.HistoryComboBox;
    60 import org.openstreetmap.josm.io.OsmApi;
    6162import org.openstreetmap.josm.tools.GBC;
    6263import org.openstreetmap.josm.tools.ImageProvider;
     
    192193                JComponent.WHEN_IN_FOCUSED_WINDOW
    193194        );
    194         pnl.add(new SideButton(new ContextSensitiveHelpAction("/Dialogs/UploadDialog")));
    195         HelpUtil.setHelpContext(getRootPane(),"/Dialogs/UploadDialog");
     195        pnl.add(new SideButton(new ContextSensitiveHelpAction(ht("/Dialogs/UploadDialog"))));
     196        HelpUtil.setHelpContext(getRootPane(),ht("/Dialogs/UploadDialog"));
    196197        return pnl;
    197198    }
     
    293294            pnlLists.add(spDelete, gcList);
    294295        }
     296        pnlChangesetSelection.setNumUploadedObjects(add.size() + update.size() + delete.size());
    295297    }
    296298
     
    320322        cs.put("comment", getUploadComment());
    321323        return cs;
     324    }
     325
     326    /**
     327     * Replies the {@see UploadStrategySpecification} the user entered in the dialog.
     328     *
     329     * @return the {@see UploadStrategySpecification} the user entered in the dialog.
     330     */
     331    public UploadStrategySpecification getUploadStrategySpecification() {
     332        return pnlChangesetSelection.getUploadStrategySpecification();
    322333    }
    323334
     
    487498
    488499        protected void warnIllegalUploadComment() {
    489             JOptionPane.showMessageDialog(
     500            HelpAwareOptionPane.showOptionDialog(
    490501                    UploadDialog.this,
    491502                    tr("Please enter a comment for this upload changeset (min. 3 characters)"),
    492503                    tr("Illegal upload comment"),
    493                     JOptionPane.ERROR_MESSAGE
     504                    JOptionPane.ERROR_MESSAGE,
     505                    ht("/Dialog/UploadDialog#IllegalUploadComment")
    494506
    495507            );
    496508        }
     509
     510        protected void warnIllegalChunkSize() {
     511            HelpAwareOptionPane.showOptionDialog(
     512                    UploadDialog.this,
     513                    tr("Please enter a valid chunk size first"),
     514                    tr("Illegal chunk size"),
     515                    JOptionPane.ERROR_MESSAGE,
     516                    ht("/Dialog/UploadDialog#IllegalChunkSize")
     517            );
     518        }
     519
     520
    497521        public void actionPerformed(ActionEvent e) {
    498522            if (getUploadComment().trim().length() < 3) {
     
    502526                return;
    503527            }
     528            UploadStrategySpecification strategy = getUploadStrategySpecification();
     529            if (strategy.getStrategy().equals(UploadStrategy.CHUNKED_DATASET_STRATEGY)) {
     530                if (strategy.getChunkSize() == UploadStrategySpecification.UNSPECIFIED_CHUNK_SIZE) {
     531                    warnIllegalChunkSize();
     532                    southTabbedPane.setSelectedIndex(0);
     533                    pnlChangesetSelection.initEditingOfChunkSize();
     534                    return;
     535                }
     536            }
    504537            setCanceled(false);
    505538            setVisible(false);
    506 
    507539        }
    508540    }
     
    607639        private OpenChangesetModel model;
    608640        private HistoryComboBox cmt;
    609         private JCheckBox cbUseAtomicUpload;
     641        private UploadStrategySelectionPanel pnlUploadStrategy;
    610642
    611643        /**
     
    615647         * @return the panel
    616648         */
    617         protected JPanel buildAtomicUploadControlPanel() {
    618             JPanel pnl = new JPanel();
    619             pnl.setLayout(new GridBagLayout());
    620             GridBagConstraints gc = new GridBagConstraints();
    621             gc.fill = GridBagConstraints.HORIZONTAL;
    622             gc.weightx = 1.0;
    623             gc.anchor = GridBagConstraints.FIRST_LINE_START;
    624             pnl.add(cbUseAtomicUpload = new JCheckBox(tr("Upload all changes in one request")), gc);
    625             cbUseAtomicUpload.setToolTipText(tr("Enable to upload all changes in one request, disable to use one request per changed primitive"));
    626             boolean useAtomicUpload = Main.pref.getBoolean("osm-server.atomic-upload", true);
    627             cbUseAtomicUpload.setSelected(useAtomicUpload);
    628             cbUseAtomicUpload.setEnabled(OsmApi.getOsmApi().hasSupportForDiffUploads());
    629             return pnl;
     649        protected JPanel buildUploadStrategySelectionPanel() {
     650            pnlUploadStrategy = new UploadStrategySelectionPanel();
     651            pnlUploadStrategy.initFromPreferences();
     652            return pnlUploadStrategy;
    630653        }
    631654
     
    678701            gc.weightx = 1.0;
    679702            gc.anchor = GridBagConstraints.FIRST_LINE_START;
    680             add(buildAtomicUploadControlPanel(), gc);
     703            add(buildUploadStrategySelectionPanel(), gc);
    681704
    682705            // -- changeset command
     
    764787            cmt.addCurrentItemToHistory();
    765788            Main.pref.putCollection(HISTORY_KEY, cmt.getHistory());
    766             Main.pref.put("osm-server.atomic-upload", cbUseAtomicUpload.isSelected());
     789            pnlUploadStrategy.saveToPreferences();
    767790        }
    768791
     
    819842        }
    820843
     844        public void initEditingOfChunkSize() {
     845            pnlUploadStrategy.initEditingOfChunkSize();
     846        }
     847
    821848        protected void refreshGUI() {
    822849            rbExisting.setEnabled(model.getSize() > 0);
     
    848875                return new Changeset();
    849876            return cs;
     877        }
     878
     879        /**
     880         * Replies the {@see UploadStrategySpecification} the user entered in the dialog.
     881         *
     882         * @return the {@see UploadStrategySpecification} the user entered in the dialog.
     883         */
     884        public UploadStrategySpecification getUploadStrategySpecification() {
     885            return pnlUploadStrategy.getUploadStrategySpecification();
    850886        }
    851887
     
    932968        public boolean isCloseAfterUpload() {
    933969            return cbCloseAfterUpload.isSelected();
     970        }
     971
     972        public void setNumUploadedObjects(int numUploadedObjects) {
     973            pnlUploadStrategy.setNumUploadedObjects(numUploadedObjects);
    934974        }
    935975
  • trunk/src/org/openstreetmap/josm/gui/io/UploadLayerTask.java

    r2512 r2569  
    4444    private Collection<OsmPrimitive> toUpload;
    4545    private HashSet<OsmPrimitive> processedPrimitives;
     46    private UploadStrategySpecification strategy;
    4647
    4748    /**
    48      *
     49     * Creates the upload task
     50     *
     51     * @param strategy the upload strategy specification
    4952     * @param layer the layer. Must not be null.
    5053     * @param monitor  a progress monitor. If monitor is null, uses {@see NullProgressMonitor#INSTANCE}
     
    5255     * @param closeChangesetAfterUpload true, if the changeset should be closed after the upload
    5356     * @throws IllegalArgumentException thrown, if layer is null
     57     * @throws IllegalArgumentException thrown if strategy is null
    5458     */
    55     public UploadLayerTask(OsmDataLayer layer, ProgressMonitor monitor, Changeset changeset, boolean closeChangesetAfterUpload) {
     59    public UploadLayerTask(UploadStrategySpecification strategy, OsmDataLayer layer, ProgressMonitor monitor, Changeset changeset, boolean closeChangesetAfterUpload) {
    5660        if (layer == null)
    57             throw new IllegalArgumentException(tr("Parameter ''{0}'' must not be null.", layer));
     61            throw new IllegalArgumentException(tr("Parameter ''{0}'' must not be null.", "layer"));
     62        if (strategy == null)
     63            throw new IllegalArgumentException(tr("Parameter ''{0}'' must not be null.", "strategy"));
    5864        if (monitor == null) {
    5965            monitor = NullProgressMonitor.INSTANCE;
     
    6268        this.monitor = monitor;
    6369        this.changeset = changeset;
     70        this.strategy = strategy;
    6471        this.closeChangesetAfterUpload = closeChangesetAfterUpload;
    6572        processedPrimitives = new HashSet<OsmPrimitive>();
     
    103110    @Override
    104111    public void run() {
    105         monitor.subTask(tr("Preparing primitives to upload ..."));
     112        monitor.indeterminateSubTask(tr("Preparing primitives to upload ..."));
    106113        APIDataSet ds = new APIDataSet(layer.data);
    107114        try {
     
    120127                    ProgressMonitor m = monitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false);
    121128                    if (isCancelled()) return;
    122                     writer.uploadOsm(layer.data.getVersion(), toUpload, changeset, m);
     129                    writer.uploadOsm(strategy, toUpload, changeset, m);
    123130                    processedPrimitives.addAll(writer.getProcessedPrimitives());
    124131                    break;
  • trunk/src/org/openstreetmap/josm/io/ChangesetClosedException.java

    r2512 r2569  
    1212import java.util.regex.Pattern;
    1313
     14/**
     15 * A ChangesetClosedException is thrown if the server replies with a HTTP
     16 * return code 409 (Conflict) with the error header {@see #ERROR_HEADER_PATTERN}.
     17 *
     18 * Depending on the context the exception is thrown in we have to react differently.
     19 * <ul>
     20 *   <li>if it is thrown when we try to update a changeset, the changeset was most
     21 *   likely closed before, either explicitly by the user or because of a timeout</li>
     22 *   <li>if it is thrown when we try to upload data to the changeset, the changeset
     23 *   was most likely closed because we reached the servers capability limit for the size
     24 *   of a changeset.</li>
     25 *  </ul>
     26 */
    1427public class ChangesetClosedException extends OsmTransferException {
     28    /** the error header pattern for in case of HTTP response 409 indicating
     29     * that a changeset was closed
     30     */
     31    final static public String ERROR_HEADER_PATTERN = "The changeset (\\d+) was closed at (.*)";
     32
     33    static enum Source {
     34        /**
     35         * The exception was thrown when a changeset was updated. This most likely means
     36         * that the changeset was closed before.
     37         */
     38        UPDATE_CHANGESET,
     39        /**
     40         * The exception was thrown when data was uploaded to the changeset. This most
     41         * likely means that the servers capability limits for a changeset have been
     42         * exceeded.
     43         */
     44        UPLOAD_DATA,
     45        /**
     46         * Unspecified source
     47         */
     48        UNSPECIFIED
     49    }
     50
     51    /**
     52     * Replies true if <code>errorHeader</code> matches with {@see #ERROR_HEADER_PATTERN}
     53     *
     54     * @param errorHeader the error header
     55     * @return true if <code>errorHeader</code> matches with {@see #ERROR_HEADER_PATTERN}
     56     */
     57    static public boolean errorHeaderMatchesPattern(String errorHeader) {
     58        if (errorHeader == null)
     59            return false;
     60        Pattern p = Pattern.compile(ERROR_HEADER_PATTERN);
     61        Matcher m = p.matcher(errorHeader);
     62        return m.matches();
     63    }
    1564
    1665    /** the changeset id */
     
    1867    /** the date on which the changeset was closed */
    1968    private Date closedOn;
     69    /** the source */
     70    private Source source;
    2071
    2172    protected void parseErrorHeader(String errorHeader) {
    22         String pattern = "The changeset (\\d+) was closed at (.*)";
    23         Pattern p = Pattern.compile(pattern);
     73        Pattern p = Pattern.compile(ERROR_HEADER_PATTERN);
    2474        Matcher m = p.matcher(errorHeader);
    2575        if (m.matches()) {
     
    3989    }
    4090
     91    /**
     92     * Creates the exception with the given <code>errorHeader</code>
     93     *
     94     * @param errorHeader the error header
     95     */
    4196    public ChangesetClosedException(String errorHeader) {
    4297        super(errorHeader);
    4398        parseErrorHeader(errorHeader);
     99        this.source = Source.UNSPECIFIED;
    44100    }
    45101
     102    /**
     103     * Creates the exception with the given error header and the given
     104     * source.
     105     *
     106     * @param errorHeader the error header
     107     * @param source the source for the exception
     108     */
     109    public ChangesetClosedException(String errorHeader, Source source) {
     110        super(errorHeader);
     111        parseErrorHeader(errorHeader);
     112        this.source = source == null ? Source.UNSPECIFIED : source;
     113    }
     114
     115    /**
     116     * Replies the id of the changeset which was closed
     117     *
     118     * @return the id of the changeset which was closed
     119     */
    46120    public long getChangesetId() {
    47121        return changesetId;
    48122    }
    49123
     124    /**
     125     * Replies the date the changeset was closed
     126     *
     127     * @return the date the changeset was closed. May be null if the date isn't known.
     128     */
    50129    public Date getClosedOn() {
    51130        return closedOn;
    52131    }
     132
     133    /**
     134     * Replies the source where the exception was thrown
     135     *
     136     * @return the source
     137     */
     138    public Source getSource() {
     139        return source;
     140    }
    53141}
  • trunk/src/org/openstreetmap/josm/io/OsmApi.java

    r2512 r2569  
    145145
    146146    /**
    147      * Returns true if the negotiated version supports diff uploads.
    148      * @return true if the negotiated version supports diff uploads
    149      */
    150     public boolean hasSupportForDiffUploads() {
    151         return ((version != null) && (version.compareTo("0.6")>=0));
    152     }
    153 
    154     /**
    155147     * Initializes this component by negotiating a protocol version with the server.
    156148     *
     
    168160            if (capabilities.supportsVersion("0.6")) {
    169161                version = "0.6";
    170             } else if (capabilities.supportsVersion("0.5")) {
    171                 version = "0.5";
    172162            } else {
    173163                System.err.println(tr("This version of JOSM is incompatible with the configured server."));
    174                 System.err.println(tr("It supports protocol versions 0.5 and 0.6, while the server says it supports {0} to {1}.",
     164                System.err.println(tr("It supports protocol version 0.6, while the server says it supports {0} to {1}.",
    175165                        capabilities.get("version", "minimum"), capabilities.get("version", "maximum")));
    176166                initialized = false;
     
    256246
    257247    /**
    258      * Modifies an OSM primitive on the server. For protocols greater than 0.5,
    259      * the OsmPrimitive object passed in is modified by giving it the server-assigned
    260      * version.
    261      *
    262      * @param osm the primitive. Must not be null
     248     * Modifies an OSM primitive on the server.
     249     *
     250     * @param osm the primitive. Must not be null.
     251     * @param monitor the progress monitor
    263252     * @throws OsmTransferException if something goes wrong
    264253     */
     
    268257            ensureValidChangeset();
    269258            initialize(monitor);
    270             if (version.equals("0.5")) {
    271                 // legacy mode does not return the new object version.
    272                 sendRequest("PUT", OsmPrimitiveType.from(osm).getAPIName()+"/" + osm.getId(), toXml(osm, true),monitor);
    273             } else {
    274                 // normal mode (0.6 and up) returns new object version.
    275                 ret = sendRequest("PUT", OsmPrimitiveType.from(osm).getAPIName()+"/" + osm.getId(), toXml(osm, true), monitor);
    276                 osm.setOsmId(osm.getId(), Integer.parseInt(ret.trim()));
    277             }
     259            // normal mode (0.6 and up) returns new object version.
     260            ret = sendRequest("PUT", OsmPrimitiveType.from(osm).getAPIName()+"/" + osm.getId(), toXml(osm, true), monitor);
     261            osm.setOsmId(osm.getId(), Integer.parseInt(ret.trim()));
    278262        } catch(NumberFormatException e) {
    279263            throw new OsmTransferException(tr("Unexpected format of new version of modified primitive ''{0}''. Got ''{1}''.", osm.getId(), ret));
     
    359343            );
    360344        } catch(OsmApiException e) {
    361             if (e.getResponseCode() == HttpURLConnection.HTTP_CONFLICT)
    362                 throw new ChangesetClosedException(e.getErrorHeader());
     345            if (e.getResponseCode() == HttpURLConnection.HTTP_CONFLICT && ChangesetClosedException.errorHeaderMatchesPattern(e.getErrorHeader()))
     346                throw new ChangesetClosedException(e.getErrorHeader(), ChangesetClosedException.Source.UPDATE_CHANGESET);
    363347            throw e;
    364348        } finally {
     
    569553                case HttpURLConnection.HTTP_GONE:
    570554                    throw new OsmApiPrimitiveGoneException(errorHeader, errorBody);
     555                case HttpURLConnection.HTTP_CONFLICT:
     556                    if (ChangesetClosedException.errorHeaderMatchesPattern(errorHeader))
     557                        throw new ChangesetClosedException(errorBody, ChangesetClosedException.Source.UPLOAD_DATA);
     558                    else
     559                        throw new OsmApiException(retCode, errorHeader, errorBody);
    571560                default:
    572561                    throw new OsmApiException(retCode, errorHeader, errorBody);
     
    642631        this.changeset = changeset;
    643632    }
    644 
    645633}
  • trunk/src/org/openstreetmap/josm/io/OsmServerWriter.java

    r2512 r2569  
    55import static org.openstreetmap.josm.tools.I18n.tr;
    66
     7import java.util.ArrayList;
    78import java.util.Collection;
     9import java.util.Iterator;
    810import java.util.LinkedList;
     11import java.util.List;
    912import java.util.logging.Logger;
    1013
    11 import org.openstreetmap.josm.Main;
    1214import org.openstreetmap.josm.data.osm.Changeset;
    1315import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1416import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
     17import org.openstreetmap.josm.gui.io.UploadStrategySpecification;
    1518import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
    1619import org.openstreetmap.josm.gui.progress.ProgressMonitor;
     
    3639
    3740    private OsmApi api = OsmApi.getOsmApi();
     41    private boolean canceled = false;
    3842
    3943    private static final int MSECS_PER_SECOND = 1000;
     
    4246
    4347    long uploadStartTime;
     48
    4449
    4550    public String timeLeft(int progress, int list_size) {
     
    125130
    126131    /**
     132     * Upload all changes in one diff upload
     133     *
     134     * @param primitives the collection of primitives to upload
     135     * @param progressMonitor  the progress monitor
     136     * @param chunkSize the size of the individual upload chunks. > 0 required.
     137     * @throws IllegalArgumentException thrown if chunkSize <= 0
     138     * @throws OsmTransferException thrown if an exception occurs
     139     */
     140    protected void uploadChangesInChunks(Collection<OsmPrimitive> primitives, ProgressMonitor progressMonitor, int chunkSize) throws OsmTransferException, IllegalArgumentException {
     141        if (chunkSize <=0)
     142            throw new IllegalArgumentException(tr("Value >0 expected for parameter ''{0}'', got {1}", "chunkSize", chunkSize));
     143        try {
     144            progressMonitor.beginTask(tr("Starting to upload in chunks..."));
     145            List<OsmPrimitive> chunk = new ArrayList<OsmPrimitive>(chunkSize);
     146            Iterator<OsmPrimitive> it = primitives.iterator();
     147            int numChunks = (int)Math.ceil((double)primitives.size() / (double)chunkSize);
     148            int i= 0;
     149            while(it.hasNext()) {
     150                i++;
     151                progressMonitor.setCustomText(tr("({0}/{1}) Uploading {2} objects...", i,numChunks,chunkSize));
     152                if (canceled) return;
     153                int j = 0;
     154                chunk.clear();
     155                while(it.hasNext() && j < chunkSize) {
     156                    if (canceled) return;
     157                    j++;
     158                    chunk.add(it.next());
     159                }
     160                processed.addAll(api.uploadDiff(chunk, progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false)));
     161            }
     162        } catch(OsmTransferException e) {
     163            throw e;
     164        } catch(Exception e) {
     165            throw new OsmTransferException(e);
     166        } finally {
     167            progressMonitor.finishTask();
     168        }
     169    }
     170
     171    /**
    127172     * Send the dataset to the server.
    128173     *
    129      * @param apiVersion version of the data set
     174     * @param strategy the upload strategy. Must not be null.
    130175     * @param primitives list of objects to send
    131176     * @param changeset the changeset the data is uploaded to. Must not be null.
    132177     * @param monitor the progress monitor. If null, assumes {@see NullProgressMonitor#INSTANCE}
    133178     * @throws IllegalArgumentException thrown if changeset is null
     179     * @throws IllegalArgumentException thrown if strategy is null
    134180     * @throws OsmTransferException thrown if something goes wrong
    135181     */
    136     public void uploadOsm(String apiVersion, Collection<OsmPrimitive> primitives, Changeset changeset, ProgressMonitor monitor) throws OsmTransferException {
     182    public void uploadOsm(UploadStrategySpecification strategy, Collection<OsmPrimitive> primitives, Changeset changeset, ProgressMonitor monitor) throws OsmTransferException {
    137183        if (changeset == null)
    138184            throw new IllegalArgumentException(tr("Parameter ''{0}'' must not be null", "changeset"));
     
    143189            api.initialize(monitor);
    144190            // check whether we can use diff upload
    145             //
    146             boolean canUseDiffUpload = api.hasSupportForDiffUploads();
    147             if (apiVersion == null) {
    148                 System.out.println(tr("WARNING: no API version defined for data to upload. Falling back to version 0.6"));
    149                 apiVersion = "0.6";
    150             }
    151             boolean useDiffUpload = Main.pref.getBoolean("osm-server.atomic-upload", apiVersion.compareTo("0.6")>=0);
    152             if (useDiffUpload && ! canUseDiffUpload) {
    153                 System.out.println(tr("WARNING: preference ''{0}'' or API version ''{1}'' of dataset requires to use diff uploads, but API is not able to handle them. Ignoring diff upload.", "osm-server.atomic-upload", apiVersion));
    154                 useDiffUpload = false;
    155             }
    156191            if (changeset.getId() == 0) {
    157192                api.openChangeset(changeset,monitor.createSubTaskMonitor(0, false));
     
    160195            }
    161196            api.setChangeset(changeset);
    162             if (useDiffUpload) {
     197            switch(strategy.getStrategy()) {
     198            case SINGLE_REQUEST_STRATEGY:
    163199                uploadChangesAsDiffUpload(primitives,monitor.createSubTaskMonitor(0,false));
    164             } else {
     200                break;
     201            case INDIVIDUAL_OBJECTS_STRATEGY:
    165202                uploadChangesIndividually(primitives,monitor.createSubTaskMonitor(0,false));
     203                break;
     204            case CHUNKED_DATASET_STRATEGY:
     205                uploadChangesInChunks(primitives,monitor.createSubTaskMonitor(0,false), strategy.getChunkSize());
     206                break;
    166207            }
    167208        } catch(OsmTransferException e) {
     
    186227
    187228    public void cancel() {
     229        this.canceled = true;
    188230        if (api != null) {
    189231            api.cancel();
  • trunk/test/functional/org/openstreetmap/josm/io/MultiFetchServerObjectReaderTest.java

    r2498 r2569  
    3232import org.openstreetmap.josm.data.osm.Way;
    3333import org.openstreetmap.josm.data.projection.Mercator;
     34import org.openstreetmap.josm.gui.io.UploadStrategySpecification;
    3435import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
    3536
     
    124125        OsmServerWriter writer = new OsmServerWriter();
    125126        Changeset cs = new Changeset();
    126         writer.uploadOsm("0.6", primitives,cs,NullProgressMonitor.INSTANCE);
     127        writer.uploadOsm(UploadStrategySpecification.createSingleRequestUploadStrategy(), primitives,cs,NullProgressMonitor.INSTANCE);
    127128        OsmApi.getOsmApi().closeChangeset(cs, NullProgressMonitor.INSTANCE);
    128129    }
  • trunk/test/functional/org/openstreetmap/josm/io/OsmServerBackreferenceReaderTest.java

    r2498 r2569  
    3333import org.openstreetmap.josm.data.osm.Way;
    3434import org.openstreetmap.josm.data.projection.Mercator;
     35import org.openstreetmap.josm.gui.io.UploadStrategySpecification;
    3536import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
    3637
     
    128129        OsmServerWriter writer = new OsmServerWriter();
    129130        Changeset cs  = new Changeset();
    130         writer.uploadOsm("0.6", primitives, cs, NullProgressMonitor.INSTANCE);
     131        writer.uploadOsm(UploadStrategySpecification.createSingleRequestUploadStrategy(), primitives, cs, NullProgressMonitor.INSTANCE);
    131132        OsmApi.getOsmApi().closeChangeset(cs, NullProgressMonitor.INSTANCE);
    132133    }
Note: See TracChangeset for help on using the changeset viewer.