Ticket #13956: 13956_v3.patch

File 13956_v3.patch, 15.0 KB (added by GerdP, 7 years ago)
  • src/org/openstreetmap/josm/data/validation/tests/TagChecker.java

     
    6868
    6969    /** Normalized keys: the key should be substituted by the value if the key was not found in presets */
    7070    private static final Map<String, String> harmonizedKeys = new HashMap<>();
    71     /** The spell check preset values */
    72     private static volatile MultiMap<String, String> presetsValueData;
     71    /** The spell check preset values which are not stored in TaggingPresets */
     72    private static volatile MultiMap<String, String> additionalPresetsValueData;
    7373    /** The TagChecker data */
    7474    private static final List<CheckerData> checkerData = new ArrayList<>();
    7575    private static final List<String> ignoreDataStartsWith = new ArrayList<>();
     
    258258
    259259        Collection<TaggingPreset> presets = TaggingPresets.getTaggingPresets();
    260260        if (!presets.isEmpty()) {
    261             presetsValueData = new MultiMap<>();
     261            additionalPresetsValueData = new MultiMap<>();
    262262            for (String a : OsmPrimitive.getUninterestingKeys()) {
    263                 presetsValueData.putVoid(a);
     263                additionalPresetsValueData.putVoid(a);
    264264            }
    265265            // TODO directionKeys are no longer in OsmPrimitive (search pattern is used instead)
    266266            for (String a : Main.pref.getCollection(ValidatorPreference.PREFIX + ".knownkeys",
    267267                    Arrays.asList(new String[]{"is_in", "int_ref", "fixme", "population"}))) {
    268                 presetsValueData.putVoid(a);
     268                additionalPresetsValueData.putVoid(a);
    269269            }
    270270            for (TaggingPreset p : presets) {
    271271                for (TaggingPresetItem i : p.data) {
     
    285285        Collection<String> values = ky.getValues();
    286286        if (ky.key != null && values != null) {
    287287            try {
    288                 presetsValueData.putAll(ky.key, values);
    289288                harmonizedKeys.put(harmonizeKey(ky.key), ky.key);
    290289            } catch (NullPointerException e) {
    291290                Main.error(e, p+": Unable to initialize "+ky+'.');
     
    308307        return false;
    309308    }
    310309
     310    private static Set<String> getPresetValues(String key) {
     311        Set<String> res = TaggingPresets.getPresetValues(key);
     312        if (res != null)
     313            return res;
     314        return additionalPresetsValueData.get(key);
     315    }
     316
    311317    /**
    312318     * Determines if the given key is in internal presets.
    313319     * @param key key
     
    315321     * @since 9023
    316322     */
    317323    public static boolean isKeyInPresets(String key) {
    318         return presetsValueData.get(key) != null;
     324        return getPresetValues(key) != null;
    319325    }
    320326
    321327    /**
     
    326332     * @since 9023
    327333     */
    328334    public static boolean isTagInPresets(String key, String value) {
    329         final Set<String> values = presetsValueData.get(key);
     335        final Set<String> values = getPresetValues(key);
    330336        return values != null && (values.isEmpty() || values.contains(value));
    331337    }
    332338
     
    465471                        .build());
    466472                withErrors.put(p, "HTML");
    467473            }
    468             if (checkValues && key != null && value != null && !value.isEmpty() && presetsValueData != null) {
     474            if (checkValues && key != null && value != null && !value.isEmpty() && additionalPresetsValueData != null) {
    469475                if (!isTagIgnored(key, value)) {
    470476                    if (!isKeyInPresets(key)) {
    471477                        String prettifiedKey = harmonizeKey(key);
     
    491497                    } else if (!isTagInPresets(key, value)) {
    492498                        // try to fix common typos and check again if value is still unknown
    493499                        String fixedValue = harmonizeValue(prop.getValue());
    494                         Map<String, String> possibleValues = getPossibleValues(presetsValueData.get(key));
     500                        Map<String, String> possibleValues = getPossibleValues(getPresetValues(key));
    495501                        if (possibleValues.containsKey(fixedValue)) {
    496502                            final String newKey = possibleValues.get(fixedValue);
    497503                            // misspelled preset value
  • src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletionManager.java

     
    1414import java.util.Set;
    1515import java.util.function.Function;
    1616
    17 import org.openstreetmap.josm.Main;
    1817import org.openstreetmap.josm.data.osm.DataSet;
    1918import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2019import org.openstreetmap.josm.data.osm.Relation;
     
    2928import org.openstreetmap.josm.data.osm.event.TagsChangedEvent;
    3029import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent;
    3130import org.openstreetmap.josm.gui.tagging.presets.TaggingPreset;
    32 import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItem;
    3331import org.openstreetmap.josm.gui.tagging.presets.TaggingPresets;
    34 import org.openstreetmap.josm.gui.tagging.presets.items.CheckGroup;
    35 import org.openstreetmap.josm.gui.tagging.presets.items.KeyedItem;
    36 import org.openstreetmap.josm.gui.tagging.presets.items.Roles;
    3732import org.openstreetmap.josm.gui.tagging.presets.items.Roles.Role;
    3833import org.openstreetmap.josm.tools.CheckParameterUtil;
    3934import org.openstreetmap.josm.tools.MultiMap;
     
    112107    protected MultiMap<String, String> tagCache;
    113108
    114109    /**
    115      * the same as tagCache but for the preset keys and values can be accessed directly
    116      */
    117     protected static final MultiMap<String, String> PRESET_TAG_CACHE = new MultiMap<>();
    118 
    119     /**
    120110     * Cache for tags that have been entered by the user.
    121111     */
    122112    protected static final Set<UserInputTag> USER_INPUT_TAG_CACHE = new LinkedHashSet<>();
     
    129119    protected Set<String> roleCache;
    130120
    131121    /**
    132      * the same as roleCache but for the preset roles can be accessed directly
    133      */
    134     protected static final Set<String> PRESET_ROLE_CACHE = new HashSet<>();
    135 
    136     /**
    137122     * Constructs a new {@code AutoCompletionManager}.
    138123     * @param ds data set
    139124     */
     
    203188    }
    204189
    205190    /**
    206      * Initialize the cache for presets. This is done only once.
    207      * @param presets Tagging presets to cache
    208      */
    209     public static void cachePresets(Collection<TaggingPreset> presets) {
    210         for (final TaggingPreset p : presets) {
    211             for (TaggingPresetItem item : p.data) {
    212                 cachePresetItem(p, item);
    213             }
    214         }
    215     }
    216 
    217     protected static void cachePresetItem(TaggingPreset p, TaggingPresetItem item) {
    218         if (item instanceof KeyedItem) {
    219             KeyedItem ki = (KeyedItem) item;
    220             if (ki.key != null && ki.getValues() != null) {
    221                 try {
    222                     PRESET_TAG_CACHE.putAll(ki.key, ki.getValues());
    223                 } catch (NullPointerException e) {
    224                     Main.error(e, p + ": Unable to cache " + ki);
    225                 }
    226             }
    227         } else if (item instanceof Roles) {
    228             Roles r = (Roles) item;
    229             for (Role i : r.roles) {
    230                 if (i.key != null) {
    231                     PRESET_ROLE_CACHE.add(i.key);
    232                 }
    233             }
    234         } else if (item instanceof CheckGroup) {
    235             for (KeyedItem check : ((CheckGroup) item).checks) {
    236                 cachePresetItem(p, check);
    237             }
    238         }
    239     }
    240 
    241     /**
    242191     * Remembers user input for the given key/value.
    243192     * @param key Tag key
    244193     * @param value Tag value
     
    259208        return new ArrayList<>(getTagCache().keySet());
    260209    }
    261210
    262     protected List<String> getPresetKeys() {
    263         return new ArrayList<>(PRESET_TAG_CACHE.keySet());
    264     }
    265 
    266211    protected Collection<String> getUserInputKeys() {
    267212        List<String> keys = new ArrayList<>();
    268213        for (UserInputTag tag : USER_INPUT_TAG_CACHE) {
     
    285230        return new ArrayList<>(getTagCache().getValues(key));
    286231    }
    287232
    288     protected static List<String> getPresetValues(String key) {
    289         return new ArrayList<>(PRESET_TAG_CACHE.getValues(key));
    290     }
    291 
    292233    protected static Collection<String> getUserInputValues(String key) {
    293234        List<String> values = new ArrayList<>();
    294235        for (UserInputTag tag : USER_INPUT_TAG_CACHE) {
     
    316257     * @param list the list to populate
    317258     */
    318259    public void populateWithMemberRoles(AutoCompletionList list) {
    319         list.add(PRESET_ROLE_CACHE, AutoCompletionItemPriority.IS_IN_STANDARD);
     260        list.add(TaggingPresets.getPresetRoles(), AutoCompletionItemPriority.IS_IN_STANDARD);
    320261        list.add(getRoleCache(), AutoCompletionItemPriority.IS_IN_DATASET);
    321262    }
    322263
     
    351292     * @param list the list to populate
    352293     */
    353294    public void populateWithKeys(AutoCompletionList list) {
    354         list.add(getPresetKeys(), AutoCompletionItemPriority.IS_IN_STANDARD);
     295        list.add(TaggingPresets.getPresetKeys(), AutoCompletionItemPriority.IS_IN_STANDARD);
    355296        list.add(new AutoCompletionListItem("source", AutoCompletionItemPriority.IS_IN_STANDARD));
    356297        list.add(getDataKeys(), AutoCompletionItemPriority.IS_IN_DATASET);
    357298        list.addUserInput(getUserInputKeys());
     
    377318     */
    378319    public void populateWithTagValues(AutoCompletionList list, List<String> keys) {
    379320        for (String key : keys) {
    380             list.add(getPresetValues(key), AutoCompletionItemPriority.IS_IN_STANDARD);
     321            list.add(TaggingPresets.getPresetValues(key), AutoCompletionItemPriority.IS_IN_STANDARD);
    381322            list.add(getDataValues(key), AutoCompletionItemPriority.IS_IN_DATASET);
    382323            list.addUserInput(getUserInputValues(key));
    383324        }
  • src/org/openstreetmap/josm/gui/tagging/presets/TaggingPresets.java

     
    33
    44import java.util.ArrayList;
    55import java.util.Collection;
     6import java.util.Collections;
    67import java.util.HashMap;
     8import java.util.HashSet;
     9import java.util.List;
    710import java.util.Map;
     11import java.util.Set;
    812
    913import javax.swing.JMenu;
    1014import javax.swing.JMenuItem;
     
    1317import org.openstreetmap.josm.Main;
    1418import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1519import org.openstreetmap.josm.gui.MenuScroller;
    16 import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionManager;
     20import org.openstreetmap.josm.gui.tagging.presets.items.CheckGroup;
     21import org.openstreetmap.josm.gui.tagging.presets.items.KeyedItem;
     22import org.openstreetmap.josm.gui.tagging.presets.items.Roles;
     23import org.openstreetmap.josm.gui.tagging.presets.items.Roles.Role;
     24import org.openstreetmap.josm.tools.MultiMap;
    1725import org.openstreetmap.josm.tools.SubclassFilteredCollection;
    1826
    1927/**
     
    2533    /** The collection of tagging presets */
    2634    private static final Collection<TaggingPreset> taggingPresets = new ArrayList<>();
    2735
     36    /** cache for key/value pairs found in the preset */
     37    private static final MultiMap<String, String> PRESET_TAG_CACHE = new MultiMap<>();
     38    /** cache for roles found in the preset */
     39    private static final Set<String> PRESET_ROLE_CACHE = new HashSet<>();
     40
    2841    /** The collection of listeners */
    2942    private static final Collection<TaggingPresetListener> listeners = new ArrayList<>();
    3043
     
    3851    public static void readFromPreferences() {
    3952        taggingPresets.clear();
    4053        taggingPresets.addAll(TaggingPresetReader.readFromPreferences(false, false));
     54        cachePresets(taggingPresets);
    4155    }
    4256
    4357    /**
     
    5367        if (taggingPresets.isEmpty()) {
    5468            Main.main.menu.presetsMenu.setVisible(false);
    5569        } else {
    56             AutoCompletionManager.cachePresets(taggingPresets);
    5770            Map<TaggingPresetMenu, JMenu> submenus = new HashMap<>();
    5871            for (final TaggingPreset p : taggingPresets) {
    5972                JMenu m = p.group != null ? submenus.get(p.group) : Main.main.menu.presetsMenu;
     
    87100    }
    88101
    89102    /**
     103     * Initialize the cache for presets. This is done only once.
     104     * @param presets Tagging presets to cache
     105     */
     106    private static void cachePresets(Collection<TaggingPreset> presets) {
     107        for (final TaggingPreset p : presets) {
     108            for (TaggingPresetItem item : p.data) {
     109                cachePresetItem(p, item);
     110            }
     111        }
     112    }
     113
     114    private static void cachePresetItem(TaggingPreset p, TaggingPresetItem item) {
     115        if (item instanceof KeyedItem) {
     116            KeyedItem ki = (KeyedItem) item;
     117            if (ki.key != null && ki.getValues() != null) {
     118                try {
     119                    PRESET_TAG_CACHE.putAll(ki.key, ki.getValues());
     120                } catch (NullPointerException e) {
     121                    Main.error(e, p + ": Unable to cache " + ki);
     122                }
     123            }
     124        } else if (item instanceof Roles) {
     125            Roles r = (Roles) item;
     126            for (Role i : r.roles) {
     127                if (i.key != null) {
     128                    PRESET_ROLE_CACHE.add(i.key);
     129                }
     130            }
     131        } else if (item instanceof CheckGroup) {
     132            for (KeyedItem check : ((CheckGroup) item).checks) {
     133                cachePresetItem(p, check);
     134            }
     135        }
     136    }
     137
     138    /**
    90139     * Replies a new collection containing all tagging presets.
    91140     * @return a new collection containing all tagging presets. Empty if presets are not initialized (never null)
    92141     */
     
    95144    }
    96145
    97146    /**
     147     * Replies a list of all roles in the tagging presets.
     148     * @return a list of all roles in the tagging presets.
     149     */
     150    public static Set<String> getPresetRoles() {
     151        return Collections.unmodifiableSet(PRESET_ROLE_CACHE);
     152    }
     153
     154    /**
     155     * Replies a list of all keys in the tagging presets.
     156     * @return a list of all keys in the tagging presets.
     157     */
     158    public static List<String> getPresetKeys() {
     159        return new ArrayList<>(PRESET_TAG_CACHE.keySet());
     160    }
     161
     162    /**
     163     * Return set of values for a key in the tagging presets
     164     * @param key the key
     165     * @return set of values for a key in the tagging presets or null if none is found
     166     */
     167    public static Set<String> getPresetValues(String key) {
     168        Set<String> values = PRESET_TAG_CACHE.get(key);
     169        if (values != null)
     170            return Collections.unmodifiableSet(values);
     171        return null;
     172    }
     173
     174    /**
    98175     * Replies a new collection of all presets matching the parameters.
    99176     *
    100177     * @param t the preset types to include