Changeset 36316 in osm for applications


Ignore:
Timestamp:
2024-08-21T21:10:21+02:00 (2 months ago)
Author:
taylor.smock
Message:

Fix #23586: Add Austria signs in RoadSigns (patch by Luzandro, modified)

Modifications are as follows:

  • Update minimum JOSM version to r19044 since we now build with Java 11.
  • Lint cleanup of RoadSignsPlugin.java
Location:
applications/editors/josm/plugins/roadsigns
Files:
59 added
3 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/roadsigns/build.xml

    r35417 r36316  
    44    <property name="commit.message" value=""/>
    55    <!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
    6     <property name="plugin.main.version" value="14153"/>
     6    <property name="plugin.main.version" value="19044"/>
    77
    88    <property name="plugin.author" value="Paul Hartmann"/>
    99    <property name="plugin.class" value="org.openstreetmap.josm.plugins.roadsigns.RoadSignsPlugin"/>
    10     <property name="plugin.description" value="Plugin for tagging of objects based on a selection of road signs. The dialog can be opened by clicking a small icon in the upper right corner of the properties window. Available country presets: Belgium, Czech Republic, Germany, Poland, Slovakia, Spain."/>
     10    <property name="plugin.description" value="Plugin for tagging of objects based on a selection of road signs. The dialog can be opened by clicking a small icon in the upper right corner of the properties window. Available country presets: Austria, Belgium, Czech Republic, Germany, Poland, Slovakia, Spain."/>
    1111    <property name="plugin.icon" value="images/pref/roadsigns.png"/>
    1212    <property name="plugin.link" value="https://wiki.openstreetmap.org/wiki/JOSM/Plugins/RoadSigns"/>
  • applications/editors/josm/plugins/roadsigns/pom.xml

    r36282 r36316  
    1717    <properties>
    1818        <plugin.src.dir>src</plugin.src.dir>
    19         <plugin.main.version>14153</plugin.main.version>
     19        <plugin.main.version>19044</plugin.main.version>
    2020
    2121        <plugin.author>Paul Hartmann</plugin.author>
  • applications/editors/josm/plugins/roadsigns/src/org/openstreetmap/josm/plugins/roadsigns/RoadSignsPlugin.java

    r35935 r36316  
    22package org.openstreetmap.josm.plugins.roadsigns;
    33
     4import static org.openstreetmap.josm.tools.I18n.marktr;
    45import static org.openstreetmap.josm.tools.I18n.tr;
    56
     
    910import java.awt.event.KeyEvent;
    1011import java.io.File;
    11 import java.io.FileInputStream;
    1212import java.io.IOException;
    1313import java.io.InputStream;
    14 import java.net.MalformedURLException;
    15 import java.net.URL;
     14import java.io.UncheckedIOException;
     15import java.net.URI;
     16import java.net.URISyntaxException;
    1617import java.util.ArrayList;
    1718import java.util.Arrays;
     
    3738import org.openstreetmap.josm.tools.Logging;
    3839import org.openstreetmap.josm.tools.Shortcut;
    39 import org.openstreetmap.josm.tools.Utils;
    4040import org.xml.sax.SAXException;
    4141
     42/**
     43 * The entry point for the {@link RoadSignsPlugin}
     44 */
    4245public class RoadSignsPlugin extends Plugin {
     46    private static final String SELECTION_PREFERENCE = "plugin.roadsigns.preset.selection";
     47    private static final String SOURCES_PREFERENCE = "plugin.roadsigns.sources";
     48    private static final String LAST_SOURCES_PREFERENCE = "plugin.roadsigns.sources.last";
     49    private static final String CUSTOM = marktr("custom");
    4350    static PresetMetaData selectedPreset;
    44     public static List<Sign> signs;
    45     public static List<String> iconDirs;
    46 
    47     public static RoadSignsPlugin plugin;
    48 
    49     public static final PresetMetaData PRESET_BE = new PresetMetaData(
     51    static List<Sign> signs;
     52    static List<String> iconDirs;
     53
     54    private static RoadSignsPlugin plugin;
     55   
     56    private static final PresetMetaData PRESET_AT = new PresetMetaData(
     57            "AT", tr("Austria"), "resource://data/roadsignpresetAT.xml", "resource://images/AT/");
     58    private static final PresetMetaData PRESET_BE = new PresetMetaData(
    5059            "BE", tr("Belgium"), "resource://data/roadsignpresetBE.xml", "resource://images/BE/");
    51     public static final PresetMetaData PRESET_CZ = new PresetMetaData(
     60    private static final PresetMetaData PRESET_CZ = new PresetMetaData(
    5261            "CZ", tr("Czech Republic"), "resource://data/roadsignpresetCZ.xml", "resource://images/CZ/");
    53     public static final PresetMetaData PRESET_ES = new PresetMetaData(
     62    private static final PresetMetaData PRESET_ES = new PresetMetaData(
    5463            "ES", tr("Spain"), "resource://data/roadsignpresetES.xml", "resource://images/ES/");
    55     public static final PresetMetaData PRESET_DE = new PresetMetaData(
     64    private static final PresetMetaData PRESET_DE = new PresetMetaData(
    5665            "DE", tr("Germany"), "resource://data/roadsignpresetDE.xml", "resource://images/DE/");
    57     public static final PresetMetaData PRESET_PL = new PresetMetaData(
     66    private static final PresetMetaData PRESET_PL = new PresetMetaData(
    5867            "PL", tr("Poland"), "resource://data/roadsignpresetPL.xml", "resource://images/PL/");
    59     public static final PresetMetaData PRESET_SK = new PresetMetaData(
     68    private static final PresetMetaData PRESET_SK = new PresetMetaData(
    6069            "SK", tr("Slovakia"), "resource://data/roadsignpresetSK.xml", "resource://images/SK/");
    61     public static final Collection<PresetMetaData> DEFAULT_PRESETS = Arrays.asList(
    62             PRESET_BE, PRESET_CZ, PRESET_ES, PRESET_DE, PRESET_PL, PRESET_SK);
    63 
     70    private static final Collection<PresetMetaData> DEFAULT_PRESETS = Arrays.asList(
     71            PRESET_AT, PRESET_BE, PRESET_CZ, PRESET_ES, PRESET_DE, PRESET_PL, PRESET_SK);
     72
     73    private static void setPluginInstance(RoadSignsPlugin plugin) {
     74        RoadSignsPlugin.plugin = plugin;
     75    }
     76
     77    /**
     78     * Create a new plugin instance
     79     * @param info The info to use when creating this instance
     80     */
    6481    public RoadSignsPlugin(PluginInformation info) {
    6582        super(info);
    66         plugin = this;
     83        setPluginInstance(this);
    6784        registerAction();
    6885    }
    6986
    70     public static File pluginDir() {
     87    /**
     88     * Get the plugin directory
     89     * @return The plugin directory
     90     */
     91    static File pluginDir() {
    7192        File dir = plugin.getPluginDirs().getUserDataDirectory(false);
    72         if (!dir.exists()) {
    73             dir.mkdirs();
     93        if (!dir.exists() && !dir.mkdirs()) {
     94            throw new UncheckedIOException(new IOException("Could not create directory: " + dir.getAbsolutePath()));
    7495        }
    7596        return dir;
    7697    }
    7798
    78     private void registerAction() {
     99    private static void registerAction() {
    79100        JButton btn = new JButton(new RoadSignAction());
    80101        btn.setText(null);
     
    95116        @Override
    96117        public void actionPerformed(ActionEvent e) {
    97             String code = Config.getPref().get("plugin.roadsigns.preset.selection", null);
     118            String code = Config.getPref().get(SELECTION_PREFERENCE, null);
    98119            if (code == null) {
    99120                ExtendedDialog ed = new ExtendedDialog(MainApplication.getMainFrame(), tr("Settings"), tr("Ok"), tr("Cancel"));
     
    106127                    settings.apply();
    107128                } catch (IOException ex) {
     129                    Logging.trace(ex);
    108130                    return;
    109131                }
     
    112134                loadSignPreset();
    113135            } catch (IOException ex) {
     136                Logging.trace(ex);
    114137                return;
    115138            }
     
    120143    }
    121144
     145    /**
     146     * A struct class for storing metadata
     147     */
    122148    public static class PresetMetaData {
     149        /** The country code */
    123150        @StructEntry public String code;
     151        /** The display name */
    124152        @StructEntry public String display_name;
     153        /** The path to the preset */
    125154        @StructEntry public String preset_path;
     155        /** The path to the icons */
    126156        @StructEntry public String icon_path;
    127157
     
    129159        }
    130160
    131         public PresetMetaData(String country_code, String display_name, String preset_path, String icons_path) {
    132             this.code = country_code;
    133             this.display_name = display_name;
    134             this.preset_path = preset_path;
    135             this.icon_path = icons_path;
     161        /**
     162         * Create a new record with the specified data
     163         * @param countryCode The country code to use
     164         * @param displayName The display name
     165         * @param presetPath The path to the preset
     166         * @param iconsPath The path to the icons
     167         */
     168        public PresetMetaData(String countryCode, String displayName, String presetPath, String iconsPath) {
     169            this.code = countryCode;
     170            this.display_name = displayName;
     171            this.preset_path = presetPath;
     172            this.icon_path = iconsPath;
    136173        }
    137174
     
    143180
    144181    public static void setSelectedPreset(PresetMetaData preset) throws IOException {
    145         Config.getPref().put("plugin.roadsigns.preset.selection", preset.code);
     182        Config.getPref().put(SELECTION_PREFERENCE, preset.code);
    146183        loadSignPreset();
    147184    }
    148185
    149186    public static List<PresetMetaData> getAvailablePresetsMetaData() {
    150 
    151         List<PresetMetaData> presetsData = StructUtils.getListOfStructs(
    152                 Config.getPref(), "plugin.roadsigns.presets", DEFAULT_PRESETS, PresetMetaData.class);
    153 
    154         String customFile = Config.getPref().get("plugin.roadsigns.sources", null);
     187        List<PresetMetaData> presetsData = Objects.requireNonNull(StructUtils.getListOfStructs(
     188                Config.getPref(), "plugin.roadsigns.presets", DEFAULT_PRESETS, PresetMetaData.class));
     189
     190        String customFile = Config.getPref().get(SOURCES_PREFERENCE, null);
    155191        if (customFile == null) {
    156192            // for legacy reasons, try both string and collection preference type
    157             List<String> customFiles = Config.getPref().getList("plugin.roadsigns.sources", null);
     193            List<String> customFiles = Config.getPref().getList(SOURCES_PREFERENCE, null);
    158194            if (customFiles != null && !customFiles.isEmpty()) {
    159195                customFile = customFiles.iterator().next();
     
    162198
    163199        if (customFile != null) {
    164             // first check, if custom file preference has changed. If yes,
    165             // change the current preset selection to custom directly
    166             String lastCustomFile = Config.getPref().get("plugin.roadsigns.sources.last", null);
    167             if (!Objects.equals(customFile, lastCustomFile)) {
    168                 Config.getPref().put("plugin.roadsigns.sources.last", customFile);
    169                 Config.getPref().put("plugin.roadsigns.preset.selection", "custom");
    170             }
    171 
    172             String customIconDirsStr = Config.getPref().get("plugin.roadsigns.icon.sources", null);
    173             List<String> customIconDirs = null;
    174             if (customIconDirsStr != null) {
    175                 customIconDirs = new ArrayList<>(Arrays.asList(customIconDirsStr.split(",")));
    176             } else {
    177                 customIconDirs = Config.getPref().getList("plugin.roadsigns.icon.sources", null);
    178             }
    179             if (customIconDirs != null) {
    180                 customIconDirs = new ArrayList<>(customIconDirs);
    181             } else {
    182                 customIconDirs = new ArrayList<>();
    183             }
    184             // add icon directory relative to preset file
    185             if (!customFile.startsWith("resource:")) {
    186                 String parentDir = null;
    187                 try {
    188                     URL url = new URL(customFile);
    189                     parentDir = url.getPath();
    190                 } catch (MalformedURLException ex) {
    191                     File f = new File(customFile);
    192                     parentDir = f.getParent();
    193                 }
    194                 if (parentDir != null && !parentDir.isEmpty()) {
    195                     customIconDirs.add(parentDir);
    196                 }
    197             }
    198             if (Config.getPref().getBoolean("plugin.roadsigns.use_default_icon_source", true)) {
    199                 customIconDirs.add("resource://images/");
    200             }
    201             presetsData.add(new PresetMetaData("custom", tr("custom"), customFile,
    202                     String.join(",", customIconDirs)));
     200            presetsData.add(readCustomFile(customFile));
    203201        } else {
    204             Config.getPref().put("plugin.roadsigns.sources.last", null);
     202            Config.getPref().put(LAST_SOURCES_PREFERENCE, null);
    205203        }
    206204
    207205        return presetsData;
     206    }
     207
     208    /**
     209     * Read the custom preset file
     210     * @param customFile The file to read
     211     * @return The metadata for that custom file
     212     */
     213    private static PresetMetaData readCustomFile(String customFile) {
     214        // first check, if custom file preference has changed. If yes,
     215        // change the current preset selection to custom directly
     216        String lastCustomFile = Config.getPref().get(LAST_SOURCES_PREFERENCE, null);
     217        if (!Objects.equals(customFile, lastCustomFile)) {
     218            Config.getPref().put(LAST_SOURCES_PREFERENCE, customFile);
     219            Config.getPref().put(SELECTION_PREFERENCE, CUSTOM);
     220        }
     221
     222        String customIconDirsStr = Config.getPref().get("plugin.roadsigns.icon.sources", null);
     223        List<String> customIconDirs = null;
     224        if (customIconDirsStr != null) {
     225            customIconDirs = new ArrayList<>(Arrays.asList(customIconDirsStr.split(",")));
     226        } else {
     227            customIconDirs = Config.getPref().getList("plugin.roadsigns.icon.sources", null);
     228        }
     229        if (customIconDirs != null) {
     230            customIconDirs = new ArrayList<>(customIconDirs);
     231        } else {
     232            customIconDirs = new ArrayList<>();
     233        }
     234        // add icon directory relative to preset file
     235        if (!customFile.startsWith("resource:")) {
     236            String parentDir;
     237            try {
     238                parentDir = new URI(customFile).getPath();
     239            } catch (URISyntaxException ex) {
     240                Logging.trace(ex);
     241                File f = new File(customFile);
     242                parentDir = f.getParent();
     243            }
     244            if (parentDir != null && !parentDir.isEmpty()) {
     245                customIconDirs.add(parentDir);
     246            }
     247        }
     248        if (Config.getPref().getBoolean("plugin.roadsigns.use_default_icon_source", true)) {
     249            customIconDirs.add("resource://images/");
     250        }
     251        return new PresetMetaData(CUSTOM, tr(CUSTOM), customFile,
     252                String.join(",", customIconDirs));
    208253    }
    209254
    210255    protected static void loadSignPreset() throws IOException {
    211256        List<PresetMetaData> presetsData = getAvailablePresetsMetaData();
    212         String code = Config.getPref().get("plugin.roadsigns.preset.selection", null);
     257        String code = Config.getPref().get(SELECTION_PREFERENCE, null);
    213258
    214259        for (PresetMetaData data : presetsData) {
     
    228273        String source = selectedPreset.preset_path;
    229274
    230         try {
    231             InputStream in = getInputStream(source);
     275        try (CachedFile cachedFile = new CachedFile(source);
     276            InputStream in = cachedFile.getInputStream()) {
    232277            RoadSignsReader reader = new RoadSignsReader(in);
    233278            signs = reader.parse();
    234 
    235279        } catch (IOException ex) {
    236280            Logging.error(ex);
     
    253297        }
    254298    }
    255 
    256     /**
    257      * Returns an inputstream from urls, files and classloaders, depending on the name.
    258      */
    259     @SuppressWarnings("resource")
    260     public static InputStream getInputStream(String source) throws IOException {
    261         InputStream in = null;
    262         if (source.startsWith("http://") || source.startsWith("https://") || source.startsWith("ftp://")) {
    263             in = new CachedFile(source).getInputStream();
    264         } else if (source.startsWith("file:")) {
    265             in = new URL(source).openStream();
    266         } else if (source.startsWith("resource://")) {
    267             in = RoadSignsPlugin.class.getResourceAsStream(source.substring("resource:/".length()));
    268         } else {
    269             in = new FileInputStream(source);
    270         }
    271         return in;
    272     }
    273299}
Note: See TracChangeset for help on using the changeset viewer.