Changeset 3934 in josm


Ignore:
Timestamp:
2011-02-26T00:35:10+01:00 (8 years ago)
Author:
framm
Message:

Changed the way in which JOSM handles imagery layer blacklisting. Instead
of a hard-coded list of Google URLs, we now parse the server's
/api/capabilities response which is expected to look like this:

<osm version="0.6" generator="OpenStreetMap server">

<api>

<version minimum="0.6" maximum="0.6"/>
<area maximum="0.25"/>
<tracepoints per_page="5000"/>
<waynodes maximum="2000"/>
<changesets maximum_elements="50000"/>
<timeout seconds="300"/>

</api>
<policy>

<imagery>

<blacklist regex=".*\.google\.com/.*"/>
<blacklist regex=".*209\.85\.2\d\d.*"/>
<blacklist regex=".*209\.85\.1[3-9]\d.*"/>
<blacklist regex=".*209\.85\.12[89].*"/>

</imagery>

</policy>

</osm>

JOSM will now try to establish an API connection when started, so that
it knows about blacklisted layers. It will also re-read the list when
the URL is changed in the preferences, and if any prohibited layers are
active they will be removed.

For an interim period, JOSM still uses the four regular expressions
listed above whenever the server API URL is *.openstreetmap.org and
the API does not send any blacklist entries. It is expected that the
API will soon return proper blacklist entries.

Things that could be improved:

  1. Establish a general listener system where components can register

their interest in a change of the configured OSM server. Currently
we have to plug through to the gui layer (Main.main.mapView) from
the base comms layer (OsmApi) which is ugly.

  1. Establish a new class of blacklist which works by IP number and not

just regular expression, so that you can say "any host name that resolves
to this IP is blacklisted".

  1. Track all layers that were used in editing a data set, and refuse

uploading if the upload URL bans any of these layers.

Location:
trunk/src/org/openstreetmap/josm
Files:
5 edited

Legend:

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

    r3924 r3934  
    7171import org.openstreetmap.josm.gui.preferences.TaggingPresetPreference;
    7272import org.openstreetmap.josm.gui.preferences.ToolbarPreferences;
     73import org.openstreetmap.josm.io.OsmApi;
    7374import org.openstreetmap.josm.plugins.PluginHandler;
    7475import org.openstreetmap.josm.tools.I18n;
     
    211212        isOpenjdk = System.getProperty("java.vm.name").toUpperCase().indexOf("OPENJDK") != -1;
    212213        platform.startupHook();
     214
     215        // We try to establish an API connection early, so that any API
     216        // capabilities are already known to the editor instance. However
     217        // if it goes wrong that's not critical at this stage.
     218        try {
     219            OsmApi.getOsmApi().initialize(null);
     220        } catch (Exception x) {
     221            // ignore any exception here.
     222        }
     223
    213224        contentPanePrivate.add(panel, BorderLayout.CENTER);
    214225        panel.add(gettingStarted, BorderLayout.CENTER);
     
    234245        toolbar.control.updateUI();
    235246        contentPanePrivate.updateUI();
     247
    236248    }
    237249
  • trunk/src/org/openstreetmap/josm/data/imagery/ImageryInfo.java

    r3878 r3934  
    44import java.util.ArrayList;
    55import java.util.Collection;
     6
     7import org.openstreetmap.josm.io.OsmApi;
    68
    79/**
     
    2729        }
    2830    }
    29 
    30     private final static String[] BLACKLIST_REGEXES = {
    31         // These entries are for Google tile servers (names and IPV4 numbers)
    32         ".*\\.google\\.com/.*",
    33         ".*209\\.85\\.2\\d\\d.*",
    34         ".*209\\.85\\.1[3-9]\\d.*",
    35         ".*209\\.85\\.12[89].*"
    36     };
    3731
    3832    String name;
     
    4337    double pixelPerDegree = 0.0;
    4438    int maxZoom = 0;
    45     private boolean blacklisted = false;
    4639
    4740    public ImageryInfo(String name) {
     
    173166    public void setUrl(String url) {
    174167
    175         // determine if URL is on blacklist and flag accordingly.
    176         blacklisted = false;
    177         for (String blacklistRegex : BLACKLIST_REGEXES) {
    178             if (url.matches(blacklistRegex)) {
    179                 blacklisted = true;
    180                 System.err.println("layer '" + name + "' uses blacklisted URL");
    181                 break;
    182             }
    183         }
    184 
    185168        for (ImageryType type : ImageryType.values()) {
    186169            if (url.startsWith(type.getUrlString() + ":")) {
     
    252235    }
    253236
     237    /**
     238     * Returns true if this layer's URL is matched by one of the regular
     239     * expressions kept by the current OsmApi instance.
     240     */
    254241    public boolean isBlacklisted() {
    255         return blacklisted;
     242        return OsmApi.getOsmApi().getCapabilities().isOnImageryBlacklist(this.url);
    256243    }
    257244}
  • trunk/src/org/openstreetmap/josm/gui/preferences/server/OsmApiUrlInputPanel.java

    r3083 r3934  
    3232import org.openstreetmap.josm.gui.widgets.AbstractTextComponentValidator;
    3333import org.openstreetmap.josm.gui.widgets.SelectAllOnFocusGainedDecorator;
     34import org.openstreetmap.josm.io.OsmApi;
    3435import org.openstreetmap.josm.tools.ImageProvider;
    3536
     
    136137     */
    137138    public void saveToPreferences() {
     139        String old_url = Main.pref.get("osm-server.url", null);
    138140        if (cbUseDefaultServerUrl.isSelected()) {
    139141            Main.pref.put("osm-server.url", null);
     
    143145            Main.pref.put("osm-server.url", tfOsmServerUrl.getText().trim());
    144146        }
    145 
     147        String new_url = Main.pref.get("osm-server.url", null);
     148
     149        // When API URL changes, re-initialize API connection so we may adjust
     150        // server-dependent settings.
     151        if ((old_url == null && new_url != null) || (old_url != null && !old_url.equals(new_url))) {
     152            try {
     153                OsmApi.getOsmApi().initialize(null);
     154            } catch (Exception x) {
     155                // ignore;
     156            }
     157        }
    146158    }
    147159
  • trunk/src/org/openstreetmap/josm/io/Capabilities.java

    r3083 r3934  
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
     6import java.util.ArrayList;
     7import java.util.Collections;
    68import java.util.HashMap;
     9import java.util.List;
    710
    811/**
    912 * Represents the server capabilities
    1013 *
     14 * Example capabilites document:
     15 *
     16 * <osm version="0.6" generator="OpenStreetMap server">
     17 *   <api>
     18 *     <version minimum="0.6" maximum="0.6"/>
     19 *     <area maximum="0.25"/>
     20 *     <tracepoints per_page="5000"/>
     21 *     <waynodes maximum="2000"/>
     22 *     <changesets maximum_elements="50000"/>
     23 *     <timeout seconds="300"/>
     24 *   </api>
     25 *   <policy>
     26 *     <imagery>
     27 *       <blacklist regex=".*\.google\.com/.*"/>
     28 *       <blacklist regex=".*209\.85\.2\d\d.*"/>
     29 *       <blacklist regex=".*209\.85\.1[3-9]\d.*"/>
     30 *       <blacklist regex=".*209\.85\.12[89].*"/>
     31 *     </imagery>
     32 *   </policy>
     33 * </osm>
     34 *
     35 * This class is used in conjunction with a very primitive parser
     36 * and simply stuffs the each tag and its attributes into a hash
     37 * of hashes, with the exception of the "blacklist" tag which gets
     38 * a list of its own. The DOM hierarchy is disregarded.
    1139 */
    1240public class Capabilities {
    13     private  HashMap<String, HashMap<String,String>> capabilities;
     41
     42    private HashMap<String, HashMap<String,String>> capabilities;
     43    private ArrayList<String> imageryBlacklist;
    1444
    1545    public Capabilities() {
    16         capabilities = new HashMap<String, HashMap<String,String>>();
     46        clear();
    1747    }
    1848
     
    3262
    3363    /**
    34      * replies the value of configuration item in the capabilities as
     64     * returns the value of configuration item in the capabilities as
    3565     * double value
    3666     *
     
    5383
    5484    public void put(String element, String attribute, String value) {
    55         if (capabilities == null) {
    56             capabilities = new HashMap<String, HashMap<String,String>>();
     85        if (element.equals("blacklist")) {
     86            if (attribute.equals("regex")) {
     87                imageryBlacklist.add(value);
     88            }
     89        } else {
     90            if (! capabilities.containsKey(element))  {
     91                HashMap<String,String> h = new HashMap<String, String>();
     92                capabilities.put(element, h);
     93            }
     94            HashMap<String, String> e = capabilities.get(element);
     95            e.put(attribute, value);
    5796        }
    58         if (! capabilities.containsKey(element))  {
    59             HashMap<String,String> h = new HashMap<String, String>();
    60             capabilities.put(element, h);
    61         }
    62         HashMap<String, String> e = capabilities.get(element);
    63         e.put(attribute, value);
    6497    }
    6598
    6699    public void clear() {
    67100        capabilities = new HashMap<String, HashMap<String,String>>();
     101        imageryBlacklist = new ArrayList<String>();
    68102    }
    69103
     
    74108
    75109    /**
    76      * Replies the max number of objects in a changeset. -1 if either the capabilities
     110     * Returns the max number of objects in a changeset. -1 if either the capabilities
    77111     * don't include this parameter or if the parameter value is illegal (not a number,
    78112     * a negative number)
     
    95129        }
    96130    }
     131
     132    /**
     133     * checks if the given URL is blacklisted by one of the of the
     134     * regular expressions.
     135     */
     136
     137    public boolean isOnImageryBlacklist(String url)
     138    {
     139        for (String blacklistRegex : imageryBlacklist) {
     140            if (url.matches(blacklistRegex)) {
     141                return true;
     142            }
     143        }
     144        return false;
     145    }
     146
     147    /**
     148     * returns the full list of blacklist regular expressions.
     149     */
     150    public List<String> getImageryBlacklist()
     151    {
     152        return Collections.unmodifiableList(imageryBlacklist);
     153    }
    97154}
  • trunk/src/org/openstreetmap/josm/io/OsmApi.java

    r3566 r3934  
    3232import org.openstreetmap.josm.data.osm.OsmPrimitive;
    3333import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
     34import org.openstreetmap.josm.gui.layer.Layer;
     35import org.openstreetmap.josm.gui.layer.ImageryLayer;
    3436import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
    3537import org.openstreetmap.josm.gui.progress.ProgressMonitor;
     
    157159        cancel = false;
    158160        try {
    159             String s = sendRequest("GET", "capabilities", null,monitor, false);
     161            String s = sendRequest("GET", "capabilities", null, monitor, false);
    160162            InputSource inputSource = new InputSource(new StringReader(s));
    161163            SAXParserFactory.newInstance().newSAXParser().parse(inputSource, new CapabilitiesParser());
     
    173175            osmWriter.setVersion(version);
    174176            initialized = true;
     177
     178            /* This is an interim solution for openstreetmap.org not currently
     179             * transmitting their imagery blacklist in the capabilities call.
     180             * remove this as soon as openstreetmap.org adds blacklists. */
     181            if (this.serverUrl.matches(".*openstreetmap.org/api.*") && capabilities.getImageryBlacklist().isEmpty())
     182            {
     183                capabilities.put("blacklist", "regex", ".*\\.google\\.com/.*");
     184                capabilities.put("blacklist", "regex", ".*209\\.85\\.2\\d\\d.*");
     185                capabilities.put("blacklist", "regex", ".*209\\.85\\.1[3-9]\\d.*");
     186                capabilities.put("blacklist", "regex", ".*209\\.85\\.12[89].*");
     187            }
     188
     189            /* This checks if there are any layers currently displayed that
     190             * are now on the blacklist, and removes them. This is a rare
     191             * situaton - probably only occurs if the user changes the API URL
     192             * in the preferences menu. Otherwise they would not have been able
     193             * to load the layers in the first place becuase they would have
     194             * been disabled! */
     195            if (Main.main.isDisplayingMapView()) {
     196                for (Layer l : Main.map.mapView.getLayersOfType(ImageryLayer.class)) {
     197                    if (((ImageryLayer) l).getInfo().isBlacklisted()) {
     198                        System.out.println(tr("Removed layer {0} because it is not allowed by the configured API.", l.getName()));
     199                        Main.main.removeLayer(l);
     200                    }
     201                }
     202            }
     203
    175204        } catch(IOException e) {
    176205            initialized = false;
Note: See TracChangeset for help on using the changeset viewer.