Ignore:
Timestamp:
2018-03-03T19:45:55+01:00 (6 years ago)
Author:
Don-vip
Message:

fix #16039, see #8039, see #10456 - fix upload regression when using individual primitive upload strategy

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/io/OsmApi.java

    r13207 r13488  
    1717import java.nio.charset.StandardCharsets;
    1818import java.util.Collection;
    19 import java.util.Collections;
    2019import java.util.HashMap;
    2120import java.util.List;
    2221import java.util.Map;
     22import java.util.function.Consumer;
     23import java.util.function.Function;
    2324
    2425import javax.xml.parsers.ParserConfigurationException;
     
    361362    }
    362363
    363     /**
    364      * Creates an OSM primitive on the server. The OsmPrimitive object passed in
    365      * is modified by giving it the server-assigned id.
    366      *
    367      * @param osm the primitive
    368      * @param monitor the progress monitor
    369      * @throws OsmTransferException if something goes wrong
    370      */
    371     public void createPrimitive(IPrimitive osm, ProgressMonitor monitor) throws OsmTransferException {
     364    private void individualPrimitiveModification(String method, String verb, IPrimitive osm, ProgressMonitor monitor,
     365            Consumer<String> consumer, Function<String, String> errHandler) throws OsmTransferException {
    372366        String ret = "";
    373367        try {
    374368            ensureValidChangeset();
    375369            initialize(monitor);
    376             ret = sendRequest("PUT", OsmPrimitiveType.from(osm).getAPIName()+"/create", toXml(osm, true), monitor);
     370            // Perform request
     371            ret = sendRequest(method, OsmPrimitiveType.from(osm).getAPIName() + '/' + verb, toXml(osm, true), monitor);
     372            // Unlock dataset if needed
     373            boolean locked = false;
     374            if (osm instanceof OsmPrimitive) {
     375                locked = ((OsmPrimitive) osm).getDataSet().isLocked();
     376                if (locked) {
     377                    ((OsmPrimitive) osm).getDataSet().unlock();
     378                }
     379            }
     380            try {
     381                // Update local primitive
     382                consumer.accept(ret);
     383            } finally {
     384                // Lock dataset back if needed
     385                if (locked) {
     386                    ((OsmPrimitive) osm).getDataSet().lock();
     387                }
     388            }
     389        } catch (NumberFormatException e) {
     390            throw new OsmTransferException(errHandler.apply(ret), e);
     391        }
     392    }
     393
     394    /**
     395     * Creates an OSM primitive on the server. The OsmPrimitive object passed in
     396     * is modified by giving it the server-assigned id.
     397     *
     398     * @param osm the primitive
     399     * @param monitor the progress monitor
     400     * @throws OsmTransferException if something goes wrong
     401     */
     402    public void createPrimitive(IPrimitive osm, ProgressMonitor monitor) throws OsmTransferException {
     403        individualPrimitiveModification("PUT", "create", osm, monitor, ret -> {
    377404            osm.setOsmId(Long.parseLong(ret.trim()), 1);
    378405            osm.setChangesetId(getChangeset().getId());
    379         } catch (NumberFormatException e) {
    380             throw new OsmTransferException(tr("Unexpected format of ID replied by the server. Got ''{0}''.", ret), e);
    381         }
     406        }, ret -> tr("Unexpected format of ID replied by the server. Got ''{0}''.", ret));
    382407    }
    383408
     
    390415     */
    391416    public void modifyPrimitive(IPrimitive osm, ProgressMonitor monitor) throws OsmTransferException {
    392         String ret = null;
    393         try {
    394             ensureValidChangeset();
    395             initialize(monitor);
    396             // normal mode (0.6 and up) returns new object version.
    397             ret = sendRequest("PUT", OsmPrimitiveType.from(osm).getAPIName()+'/' + osm.getId(), toXml(osm, true), monitor);
     417        individualPrimitiveModification("PUT", Long.toString(osm.getId()), osm, monitor, ret -> {
     418            // API returns new object version
    398419            osm.setOsmId(osm.getId(), Integer.parseInt(ret.trim()));
    399420            osm.setChangesetId(getChangeset().getId());
    400421            osm.setVisible(true);
    401         } catch (NumberFormatException e) {
    402             throw new OsmTransferException(tr("Unexpected format of new version of modified primitive ''{0}''. Got ''{1}''.",
    403                     osm.getId(), ret), e);
    404         }
     422        }, ret -> tr("Unexpected format of new version of modified primitive ''{0}''. Got ''{1}''.", osm.getId(), ret));
    405423    }
    406424
    407425    /**
    408426     * Deletes an OSM primitive on the server.
     427     *
    409428     * @param osm the primitive
    410429     * @param monitor the progress monitor
     
    412431     */
    413432    public void deletePrimitive(OsmPrimitive osm, ProgressMonitor monitor) throws OsmTransferException {
    414         ensureValidChangeset();
    415         initialize(monitor);
    416         // can't use a the individual DELETE method in the 0.6 API. Java doesn't allow
    417         // submitting a DELETE request with content, the 0.6 API requires it, however. Falling back
    418         // to diff upload.
    419         //
    420         uploadDiff(Collections.singleton(osm), monitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
     433        individualPrimitiveModification("DELETE", Long.toString(osm.getId()), osm, monitor, ret -> {
     434            // API returns new object version
     435            osm.setOsmId(osm.getId(), Integer.parseInt(ret.trim()));
     436            osm.setChangesetId(getChangeset().getId());
     437            osm.setVisible(false);
     438        }, ret -> tr("Unexpected format of new version of deleted primitive ''{0}''. Got ''{1}''.", osm.getId(), ret));
    421439    }
    422440
    423441    /**
    424442     * Creates a new changeset based on the keys in <code>changeset</code>. If this
    425      * method succeeds, changeset.getId() replies the id the server assigned to the new
    426      * changeset
     443     * method succeeds, changeset.getId() replies the id the server assigned to the new changeset
    427444     *
    428445     * The changeset must not be null, but its key/value-pairs may be empty.
Note: See TracChangeset for help on using the changeset viewer.