Ticket #21826: josm_21826_wip.patch

File josm_21826_wip.patch, 6.9 KB (added by gaben, 3 years ago)

add support for capabilities on max relation members (checked only on upload)

  • test/data/__files/api/0.6/capabilities

     
    66    <note_area maximum="25"/>
    77    <tracepoints per_page="5000"/>
    88    <waynodes maximum="2000"/>
     9    <relationmembers maximum="32000"/>
    910    <changesets maximum_elements="10000"/>
    1011    <timeout seconds="300"/>
    1112    <status database="online" api="online" gpx="online"/>
     
    1516      <blacklist regex=".*\.google(apis)?\..*/(vt|kh)[\?/].*([xyz]=.*){3}.*"/>
    1617    </imagery>
    1718  </policy>
    18 </osm>
     19</osm>
     20 No newline at end of file
  • src/org/openstreetmap/josm/io/Capabilities.java

     
    2424 *
    2525 * Example capabilities document:
    2626 * <pre>
    27  * &lt;osm version="0.6" generator="OpenStreetMap server"&gt;
     27 * &lt;?xml version="1.0" encoding="UTF-8"?&gt;
     28 * &lt;osm version="0.6" generator="OpenStreetMap server" copyright="OpenStreetMap and contributors" attribution="http://www.openstreetmap.org/copyright" license="http://opendatacommons.org/licenses/odbl/1-0/"&gt;
    2829 *   &lt;api&gt;
    2930 *     &lt;version minimum="0.6" maximum="0.6"/&gt;
    3031 *     &lt;area maximum="0.25"/&gt;
     32 *     &lt;note_area maximum="25"/&gt;
    3133 *     &lt;tracepoints per_page="5000"/&gt;
    3234 *     &lt;waynodes maximum="2000"/&gt;
     35 *     &lt;relationmembers maximum="32000"/&gt;
    3336 *     &lt;changesets maximum_elements="10000"/&gt;
    3437 *     &lt;timeout seconds="300"/&gt;
    3538 *     &lt;status database="online" api="online" gpx="online"/&gt;
     
    3639 *   &lt;/api&gt;
    3740 *   &lt;policy&gt;
    3841 *     &lt;imagery&gt;
    39  *       &lt;blacklist regex=".*\.google\.com/.*"/&gt;
    40  *       &lt;blacklist regex=".*209\.85\.2\d\d.*"/&gt;
    41  *       &lt;blacklist regex=".*209\.85\.1[3-9]\d.*"/&gt;
    42  *       &lt;blacklist regex=".*209\.85\.12[89].*"/&gt;
     42 *       &lt;blacklist regex=".*\.google(apis)?\..*(vt|kh)[\?/].*([xyz]=.*){3}.*"/&gt;
     43 *       &lt;blacklist regex="http://xdworld\.vworld\.kr:8080/.*"/&gt;
     44 *       &lt;blacklist regex=".*\.here\.com[/:].*"/&gt;
    4345 *     &lt;/imagery&gt;
    4446 *   &lt;/policy&gt;
    4547 * &lt;/osm&gt;
    4648 * </pre>
    4749 * This class is used in conjunction with a very primitive parser
    48  * and simply stuffs the each tag and its attributes into a hash
     50 * and simply stuffs each tag and its attributes into a hash
    4951 * of hashes, with the exception of the "blacklist" tag which gets
    5052 * a list of its own. The DOM hierarchy is disregarded.
    5153 */
     
    188190    }
    189191
    190192    /**
     193     * Returns the max number of members in a relation. -1 if either the capabilities
     194     * don't include this parameter or if the parameter value is illegal (not a number,
     195     * a negative number)
     196     *
     197     * @return the max number of members in a relation
     198     * @since xxx
     199     */
     200    public long getMaxRelationMembers() {
     201        String v = get("relationmembers", "maximum");
     202        if (v != null) {
     203            try {
     204                long n = Long.parseLong(v);
     205                if (n <= 0) {
     206                    warnIllegalValue("relationmembers", "maximum", n);
     207                } else {
     208                    return n;
     209                }
     210            } catch (NumberFormatException e) {
     211                warnIllegalValue("relationmembers", "maximum", v);
     212            }
     213        }
     214        return -1;
     215    }
     216   
     217    /**
    191218     * Returns the max number of nodes in a way. -1 if either the capabilities
    192219     * don't include this parameter or if the parameter value is illegal (not a number,
    193220     * a negative number)
  • src/org/openstreetmap/josm/actions/upload/ApiPreconditionCheckerHook.java

     
    1111
    1212import org.openstreetmap.josm.data.APIDataSet;
    1313import org.openstreetmap.josm.data.osm.OsmPrimitive;
     14import org.openstreetmap.josm.data.osm.Relation;
    1415import org.openstreetmap.josm.data.osm.Tagged;
    1516import org.openstreetmap.josm.data.osm.Way;
    1617import org.openstreetmap.josm.gui.ExceptionDialogUtil;
     
    3637            if (NetworkManager.isOffline(OnlineResource.OSM_API)) {
    3738                return false;
    3839            }
     40
    3941            // FIXME: this should run asynchronously and a progress monitor
    40             // should be displayed.
     42            //  should be displayed.
    4143            api.initialize(NullProgressMonitor.INSTANCE);
     44
    4245            long maxNodes = api.getCapabilities().getMaxWayNodes();
    4346            if (maxNodes > 0) {
    4447                if (!checkMaxNodes(apiData.getPrimitivesToAdd(), maxNodes))
     
    4851                if (!checkMaxNodes(apiData.getPrimitivesToDelete(), maxNodes))
    4952                    return false;
    5053            }
     54
     55            long maxMembers = api.getCapabilities().getMaxRelationMembers();
     56            if (maxMembers > 0) {
     57                if (!checkMaxMembers(apiData.getPrimitivesToAdd(), maxNodes))
     58                    return false;
     59                if (!checkMaxMembers(apiData.getPrimitivesToUpdate(), maxNodes))
     60                    return false;
     61                if (!checkMaxMembers(apiData.getPrimitivesToDelete(), maxNodes))
     62                    return false;
     63            }
    5164        } catch (OsmTransferCanceledException e) {
    5265            Logging.trace(e);
    5366            return false;
     
    5871        return true;
    5972    }
    6073
     74    private static boolean checkMaxMembers(Collection<OsmPrimitive> primitives, long maxMembers) {
     75        for (OsmPrimitive osmPrimitive : primitives) {
     76            if (osmPrimitive instanceof Relation && ((Relation) osmPrimitive).getMembersCount() > maxMembers) {
     77                JOptionPane.showMessageDialog(
     78                        MainApplication.getMainFrame(),
     79                        tr("{0} members in relation {1} exceed the max. allowed number of members {2}",
     80                                ((Relation) osmPrimitive).getMembersCount(),
     81                                Long.toString(osmPrimitive.getId()),
     82                                maxMembers
     83                        ),
     84                        tr("API Capabilities Violation"),
     85                        JOptionPane.ERROR_MESSAGE
     86                );
     87                MainApplication.getLayerManager().getEditDataSet().setSelected(Collections.singleton(osmPrimitive));
     88                return false;
     89            }
     90        }
     91        return true;
     92    }
     93
    6194    private static boolean checkMaxNodes(Collection<OsmPrimitive> primitives, long maxNodes) {
    6295        for (OsmPrimitive osmPrimitive : primitives) {
    6396            for (Map.Entry<String, String> entry: osmPrimitive.getKeys().entrySet()) {