Ticket #23290: 23290.patch

File 23290.patch, 72.8 KB (added by taylor.smock, 12 months ago)
  • resources/data/defaultpresets.xml

    Subject: [PATCH] Fix #23290: Add support for regions attribute
    ---
    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/resources/data/defaultpresets.xml b/resources/data/defaultpresets.xml
    a b  
    14651465                    <list_entry value="unmarked" icon="presets/vehicle/crossing_unmarked.svg" />
    14661466                    <list_entry value="no" />
    14671467                </combo>
    1468                 <combo key="crossing_ref" text="Crossing type name (UK)" values="zebra,pelican,toucan,puffin,pegasus,tiger" />
     1468                <combo key="crossing_ref" text="Crossing type name (UK)" values="zebra,pelican,toucan,puffin,pegasus,tiger" regions="GB" />
    14691469                <combo key="kerb" text="Kerb" values="flush,lowered,no,raised,rolled,yes" values_context="kerb" />
    14701470                <combo key="supervised" text="Crossing attendant" delimiter="|" values="yes|no|06:00-20:00|Mo-Fr 09:00-18:00,Sa 08:00-14:00|May-Sep 09:30-12:30,14:15-19:30" values_i18n="false" values_sort="false" />
    14711471                <check key="crossing:island" text="With island" />
     
    15161516                <list_entry value="unmarked" icon="presets/vehicle/crossing_unmarked.svg" />
    15171517            </combo>
    15181518            <reference ref="crossing_markings" />
    1519             <combo key="crossing_ref" text="Crossing type name (UK)" values="zebra,pelican,toucan,puffin,pegasus,tiger" values_searchable="true" />
     1519            <combo key="crossing_ref" text="Crossing type name (UK)" values="zebra,pelican,toucan,puffin,pegasus,tiger" values_searchable="true" regions="GB" />
    15201520            <combo key="kerb" text="Kerb" values="flush,lowered,no,raised,rolled,yes" values_context="kerb" />
    15211521            <combo key="supervised" text="Crossing attendant" delimiter="|" values="yes|no|06:00-20:00|Mo-Fr 09:00-18:00,Sa 08:00-14:00|May-Sep 09:30-12:30,14:15-19:30" values_i18n="false" values_sort="false" />
    15221522            <combo key="tactile_paving" text="Tactile Paving" values="yes,no,incorrect" />
     
    72647264                <list_entry value="war_memorial" short_description="A building, monument, statue or other edifice celebrating a victory or commemorating those who died or were injured in a war." />
    72657265                <list_entry value="sculpture" short_description="A non figurative sculpture which does not match any of the other categories." />
    72667266                <list_entry value="cross" short_description="A cross-shaped memorial." />
    7267                 <list_entry value="blue_plaque" short_description="A blue plaque commemorating a historical link to that location. (UK)" />
     7267                <list_entry value="blue_plaque" short_description="A blue plaque commemorating a historical link to that location. (UK)" regions="GB" />
    72687268                <list_entry value="obelisk" short_description="An obelisk." />
    72697269                <list_entry value="ghost_bike" short_description="A bicycle painted white permanently placed as memorial for a victim of a road accident (usually cyclists)." />
    7270                 <list_entry value="stolperstein" short_description="10cm × 10cm brass plaque commemorating victims of Nazi persecution. (EU,RU)" />
     7270                <list_entry value="stolperstein" short_description="10cm × 10cm brass plaque commemorating victims of Nazi persecution. (EU,RU)" regions="EU,RU" />
    72717271                <list_entry value="bench" short_description="A bench placed in memory of someone or something; usually has a plaque, and sometimes a statue sitting on (part of) it." />
    72727272            </combo>
    72737273            <optional>
     
    82178217            <check key="payment:girocard" text="Girocard" match="keyvalue" />
    82188218            <check key="payment:laser" text="Laser" match="keyvalue" />
    82198219            <check key="payment:maestro" text="Maestro" match="keyvalue" />
    8220             <check key="payment:postfinance_card" text="PostFinance Card (ch)" match="keyvalue" />
     8220            <check key="payment:postfinance_card" text="PostFinance Card (ch)" match="keyvalue" region="CH" />
    82218221            <check key="payment:visa_debit" text="Visa Debit" match="keyvalue" />
    82228222            <check key="payment:visa_electron" text="Visa Electron" match="keyvalue" />
    82238223        </checkgroup>
     
    82368236        <space />
    82378237        <combo key="payment:electronic_purses" text="Electronic purses and Charge cards" values="yes,no" match="keyvalue" />
    82388238        <checkgroup columns="4">
    8239             <check key="payment:ep_avant" text="Avant (fi)" match="keyvalue" />
    8240             <check key="payment:ep_geldkarte" text="Geldkarte (de)" match="keyvalue" />
    8241             <check key="payment:ep_mep" text="Mep (pt)" match="keyvalue" />
    8242             <check key="payment:ep_minicash" text="Minicash (lu)" match="keyvalue" />
    8243             <check key="payment:ep_minipay" text="Minipay (it)" match="keyvalue" />
    8244             <check key="payment:ep_monedero4b" text="Mondero 4b (es)" match="keyvalue" />
     8239            <check key="payment:ep_avant" text="Avant (fi)" match="keyvalue" regions="FI" />
     8240            <check key="payment:ep_geldkarte" text="Geldkarte (de)" match="keyvalue" regions="DE" />
     8241            <check key="payment:ep_mep" text="Mep (pt)" match="keyvalue" regions="PT" />
     8242            <check key="payment:ep_minicash" text="Minicash (lu)" match="keyvalue" regions="LU" />
     8243            <check key="payment:ep_minipay" text="Minipay (it)" match="keyvalue" regions="IT" />
     8244            <check key="payment:ep_monedero4b" text="Mondero 4b (es)" match="keyvalue" regions="ES" />
    82458245        </checkgroup>
    82468246        <space />
    82478247        <combo key="payment:cryptocurrencies" text="Cryptocurrencies" values="yes,no" match="keyvalue" />
     
    99249924            <optional>
    99259925                <text key="destination" text="Name of river/lake/sea/ocean it runs into" />
    99269926                <text key="ref" text="Reference" />
    9927                 <text key="ref:sandre" text="Reference Sandre (FR)" />
    9928                 <text key="ref:fgkz" text="Reference FGKZ (DE)" />
    9929                 <text key="ref:regine" text="Reference REGINE (NO)" />
    9930                 <text key="ref:gnis" text="Reference GNIS (USA)" />
    9931                 <text key="ref:gnbc" text="Reference GNBC (CA)" />
     9927                <text key="ref:sandre" text="Reference Sandre (FR)" regions="FR" />
     9928                <text key="ref:fgkz" text="Reference FGKZ (DE)" regions="DE" />
     9929                <text key="ref:regine" text="Reference REGINE (NO)" regions="NO" />
     9930                <text key="ref:gnis" text="Reference GNIS (USA)" regions="US" />
     9931                <text key="ref:gnbc" text="Reference GNBC (CA)" regions="CA" />
    99329932                <reference ref="wikipedia_wikidata" />
    99339933            </optional>
    99349934            <roles>
  • resources/data/tagging-preset.xsd

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/resources/data/tagging-preset.xsd b/resources/data/tagging-preset.xsd
    a b  
    106106        <complexContent>
    107107            <extension base="tns:group-parent">
    108108                <attributeGroup ref="tns:attributes.name" />
     109                <attributeGroup ref="tns:attributes.regions"/>
    109110            </extension>
    110111        </complexContent>
    111112    </complexType>
     
    121122    <complexType name="item">
    122123        <annotation>
    123124            <documentation>
    124                 Every item is one annotation set to select from. name is required, type and preset_name_label are recommended, icon and name_template are optional attributes.
     125                Every item is one annotation set to select from. name is required, type and preset_name_label are recommended and icon, name_template, regions and exclude_regions are optional attributes.
    125126            </documentation>
    126127        </annotation>
    127128        <sequence>
     
    134135        </sequence>
    135136        <attributeGroup ref="tns:attributes.name" />
    136137        <attributeGroup ref="tns:attributes.icon" />
     138        <attributeGroup ref="tns:attributes.regions"/>
    137139        <attribute name="type" type="string">
    138140            <annotation>
    139141                <documentation><![CDATA[
     
    364366    <complexType name="list_entry">
    365367        <annotation>
    366368            <documentation><![CDATA[
    367                 Used in <combo/> and <multiselect/>. More information see short_descriptions below. The attributes are value, display_value, short_description, icon and icon_size.
     369                Used in <combo/> and <multiselect/>. More information see short_descriptions below. The attributes are value, display_value, short_description, icon, icon_size, regions, and exclude_regions.
    368370            ]]></documentation>
    369371        </annotation>
    370372        <attribute name="value" type="string" use="required" />
     
    378380            </annotation>
    379381        </attribute>
    380382        <attributeGroup ref="tns:attributes.icon" />
     383        <attributeGroup ref="tns:attributes.regions"/>
    381384        <anyAttribute processContents="skip" />
    382385    </complexType>
    383386
     
    489492        </attribute>
    490493        <attribute name="match" type="tns:match" />
    491494        <attributeGroup ref="tns:attributes.icon" />
     495        <attributeGroup ref="tns:attributes.regions"/>
    492496
    493497        <attribute name="name" use="prohibited" />
    494498        <attribute name="type" use="prohibited" />
     
    558562    <complexType name="role">
    559563        <annotation>
    560564            <documentation>
    561                 To specify possible roles of members in relations. The key attribute is required, text, requisite, count, type and member_expression are optional.
     565                To specify possible roles of members in relations. The key attribute is required, text, requisite, count, type, member_expression, regions, and exclude_regions are optional.
    562566            </documentation>
    563567        </annotation>
    564568        <attribute name="key" type="string">
     
    574578        <attribute name="count" type="integer" />
    575579        <attribute name="member_expression" type="string" />
    576580        <attribute name="regexp" type="boolean" />
     581        <attributeGroup ref="tns:attributes.regions"/>
    577582        <anyAttribute processContents="skip" />
    578583    </complexType>
    579584
     
    728733            </annotation>
    729734        </attribute>
    730735    </attributeGroup>
     736
     737    <attributeGroup name="attributes.regions">
     738        <attribute name="regions" type="string">
     739            <annotation>
     740                <documentation>
     741                    Comma separated list of countries this preset group or item is applicable for. If not specified, the preset is applicable for all countries.
     742                </documentation>
     743            </annotation>
     744        </attribute>
     745        <attribute name="exclude_regions" type="boolean">
     746            <annotation>
     747                <documentation>
     748                    If true, invert the meaning of regions.
     749                </documentation>
     750            </annotation>
     751        </attribute>
     752    </attributeGroup>
    731753
    732754</schema>
  • src/org/openstreetmap/josm/data/validation/tests/TagChecker.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/src/org/openstreetmap/josm/data/validation/tests/TagChecker.java b/src/org/openstreetmap/josm/data/validation/tests/TagChecker.java
    a b  
    3737import org.openstreetmap.josm.command.ChangePropertyKeyCommand;
    3838import org.openstreetmap.josm.command.Command;
    3939import org.openstreetmap.josm.command.SequenceCommand;
     40import org.openstreetmap.josm.data.coor.LatLon;
    4041import org.openstreetmap.josm.data.osm.AbstractPrimitive;
    4142import org.openstreetmap.josm.data.osm.DataSet;
     43import org.openstreetmap.josm.data.osm.Node;
    4244import org.openstreetmap.josm.data.osm.OsmPrimitive;
    4345import org.openstreetmap.josm.data.osm.OsmUtils;
    4446import org.openstreetmap.josm.data.osm.Relation;
     
    6264import org.openstreetmap.josm.gui.tagging.presets.TaggingPresets;
    6365import org.openstreetmap.josm.gui.tagging.presets.items.Check;
    6466import org.openstreetmap.josm.gui.tagging.presets.items.CheckGroup;
     67import org.openstreetmap.josm.gui.tagging.presets.items.ComboMultiSelect;
     68import org.openstreetmap.josm.gui.tagging.presets.items.Key;
    6569import org.openstreetmap.josm.gui.tagging.presets.items.KeyedItem;
     70import org.openstreetmap.josm.gui.tagging.presets.items.PresetListEntry;
     71import org.openstreetmap.josm.gui.tagging.presets.items.RegionSpecific;
    6672import org.openstreetmap.josm.gui.widgets.EditableList;
    6773import org.openstreetmap.josm.io.CachedFile;
    6874import org.openstreetmap.josm.spi.preferences.Config;
    6975import org.openstreetmap.josm.tools.GBC;
     76import org.openstreetmap.josm.tools.JosmRuntimeException;
    7077import org.openstreetmap.josm.tools.Logging;
    7178import org.openstreetmap.josm.tools.MultiMap;
     79import org.openstreetmap.josm.tools.Territories;
    7280import org.openstreetmap.josm.tools.Utils;
    7381
    7482/**
     
    131139     * The preference key to check presets
    132140     */
    133141    public static final String PREF_CHECK_PRESETS_TYPES = PREFIX + ".checkPresetsTypes";
     142    public static final String PREF_CHECK_REGIONS = PREFIX + ".checkPresetsRegions";
    134143
    135144    /**
    136145     * The preference key for source files
     
    159168     * The preference key to search for presets - used before upload
    160169     */
    161170    public static final String PREF_CHECK_PRESETS_TYPES_BEFORE_UPLOAD = PREF_CHECK_PRESETS_TYPES + BEFORE_UPLOAD;
     171    public static final String PREF_CHECK_REGIONS_BEFORE_UPLOAD = PREF_CHECK_REGIONS + BEFORE_UPLOAD;
    162172
    163173    /**
    164174     * The preference key for the list of tag keys that are allowed to be the same on a multipolygon and an outer way
     
    175185    protected boolean checkComplex;
    176186    protected boolean checkFixmes;
    177187    protected boolean checkPresetsTypes;
     188    protected boolean checkRegions;
    178189
    179190    protected JCheckBox prefCheckKeys;
    180191    protected JCheckBox prefCheckValues;
    181192    protected JCheckBox prefCheckComplex;
    182193    protected JCheckBox prefCheckFixmes;
    183194    protected JCheckBox prefCheckPresetsTypes;
     195    protected JCheckBox prefCheckRegions;
    184196
    185197    protected JCheckBox prefCheckKeysBeforeUpload;
    186198    protected JCheckBox prefCheckValuesBeforeUpload;
    187199    protected JCheckBox prefCheckComplexBeforeUpload;
    188200    protected JCheckBox prefCheckFixmesBeforeUpload;
    189201    protected JCheckBox prefCheckPresetsTypesBeforeUpload;
     202    protected JCheckBox prefCheckRegionsBeforeUpload;
    190203
    191204    // CHECKSTYLE.OFF: SingleSpaceSeparator
    192205    protected static final int EMPTY_VALUES                     = 1200;
     
    210223    protected static final int MULTIPOLYGON_INCOMPLETE          = 1219;
    211224    protected static final int MULTIPOLYGON_MAYBE_NO_AREA       = 1220;
    212225    protected static final int MULTIPOLYGON_SAME_TAG_ON_OUTER   = 1221;
     226    protected static final int INVALID_REGION                   = 1222;
    213227    // CHECKSTYLE.ON: SingleSpaceSeparator
    214228
    215229    protected EditableList sourcesList;
     
    559573     * @param key key
    560574     * @return {@code true} if the given key is in internal presets
    561575     * @since 9023
    562      * @deprecated Use {@link TaggingPresets#isKeyInPresets(String)} instead
     576     * @deprecated since 18281 -- use {@link TaggingPresets#isKeyInPresets(String)} instead
    563577     */
    564578    @Deprecated
    565579    public static boolean isKeyInPresets(String key) {
     
    652666        }
    653667
    654668        if (p instanceof Relation && p.hasTag("type", "multipolygon")) {
    655         checkMultipolygonTags(p);
     669            checkMultipolygonTags(p);
    656670        }
    657671
    658         if (checkPresetsTypes) {
    659             TagMap tags = p.getKeys();
    660             TaggingPresetType presetType = TaggingPresetType.forPrimitive(p);
    661             EnumSet<TaggingPresetType> presetTypes = EnumSet.of(presetType);
    662 
    663             Collection<TaggingPreset> matchingPresets = presetIndex.entrySet().stream()
     672        final Collection<TaggingPreset> matchingPresets;
     673        TagMap tags;
     674        if (checkPresetsTypes || checkRegions) {
     675            tags = p.getKeys();
     676            matchingPresets = presetIndex.entrySet().stream()
    664677                    .filter(e -> TaggingPresetItem.matches(e.getValue(), tags))
    665678                    .map(Entry::getKey)
    666679                    .collect(Collectors.toCollection(LinkedHashSet::new));
    667             Collection<TaggingPreset> matchingPresetsOK = matchingPresets.stream().filter(
    668                     tp -> tp.typeMatches(presetTypes)).collect(Collectors.toList());
    669             Collection<TaggingPreset> matchingPresetsKO = matchingPresets.stream().filter(
    670                     tp -> !tp.typeMatches(presetTypes)).collect(Collectors.toList());
     680        } else {
     681            matchingPresets = null;
     682            tags = null;
     683        }
     684
     685        if (checkPresetsTypes) {
     686            checkPresetsTypes(p, matchingPresets, tags);
     687        }
     688
     689        if (checkRegions) {
     690            checkRegions(p, matchingPresets);
     691        }
     692    }
     693
     694    /**
     695     * Check that the primitive matches the preset types for the preset
     696     * @param p The primitive to check
     697     * @param matchingPresets The presets to go through
     698     * @param tags Tags from the primitive to check
     699     */
     700    private void checkPresetsTypes(OsmPrimitive p, Collection<TaggingPreset> matchingPresets, Map<String, String> tags) {
     701        TaggingPresetType presetType = TaggingPresetType.forPrimitive(p);
     702        EnumSet<TaggingPresetType> presetTypes = EnumSet.of(presetType);
     703
     704        Collection<TaggingPreset> matchingPresetsOK = matchingPresets.stream().filter(
     705                tp -> tp.typeMatches(presetTypes)).collect(Collectors.toList());
     706        Collection<TaggingPreset> matchingPresetsKO = matchingPresets.stream().filter(
     707                tp -> !tp.typeMatches(presetTypes)).collect(Collectors.toList());
    671708
    672             for (TaggingPreset tp : matchingPresetsKO) {
    673                 // Potential error, unless matching tags are all known by a supported preset
    674                 Map<String, String> matchingTags = tp.data.stream()
     709        for (TaggingPreset tp : matchingPresetsKO) {
     710            // Potential error, unless matching tags are all known by a supported preset
     711            Map<String, String> matchingTags = tp.data.stream()
    675712                    .filter(i -> Boolean.TRUE.equals(i.matches(tags)))
    676713                    .filter(i -> i instanceof KeyedItem).map(i -> ((KeyedItem) i).key)
    677714                    .collect(Collectors.toMap(k -> k, tags::get));
    678                 if (matchingPresetsOK.stream().noneMatch(
    679                         tp2 -> matchingTags.entrySet().stream().allMatch(
    680                                 e -> tp2.data.stream().anyMatch(
    681                                         i -> i instanceof KeyedItem && ((KeyedItem) i).key.equals(e.getKey()))))) {
    682                     errors.add(TestError.builder(this, Severity.OTHER, INVALID_PRESETS_TYPE)
    683                             .message(tr("Object type not in preset"),
    684                                     marktr("Object type {0} is not supported by tagging preset: {1}"),
    685                                     tr(presetType.getName()), tp.getLocaleName())
    686                             .primitives(p)
    687                             .build());
    688                 }
    689             }
    690         }
     715            if (matchingPresetsOK.stream().noneMatch(
     716                    tp2 -> matchingTags.entrySet().stream().allMatch(
     717                            e -> tp2.data.stream().anyMatch(
     718                                    i -> i instanceof KeyedItem && ((KeyedItem) i).key.equals(e.getKey()))))) {
     719                errors.add(TestError.builder(this, Severity.OTHER, INVALID_PRESETS_TYPE)
     720                        .message(tr("Object type not in preset"),
     721                                marktr("Object type {0} is not supported by tagging preset: {1}"),
     722                                tr(presetType.getName()), tp.getLocaleName())
     723                        .primitives(p)
     724                        .build());
     725            }
     726        }
     727    }
     728
     729    /**
     730     * Check that the preset is valid for the region the primitive is in
     731     * @param p The primitive to check
     732     * @param matchingPresets The presets to check against
     733     */
     734    private void checkRegions(OsmPrimitive p, Collection<TaggingPreset> matchingPresets) {
     735        LatLon center;
     736        if (p instanceof Node) {
     737            center = ((Node) p).getCoor();
     738        } else {
     739            center = p.getBBox().getCenter();
     740        }
     741        for (TaggingPreset preset : matchingPresets) {
     742            if (preset.regions() != null) {
     743                boolean isInRegion = false; //true if the object is in an applicable region
     744                for (String region : preset.regions()) {
     745                    if (Territories.isIso3166Code(region, center)) { //check if center of the object is in a region
     746                        isInRegion = true;
     747                    }
     748                }
     749                if (isInRegion == preset.exclude_regions()) {
     750                    errors.add(TestError.builder(this, Severity.WARNING, INVALID_REGION)
     751                            .message(tr("Invalid region for this preset"),
     752                                    marktr("Preset {0} should not be applied in this region"),
     753                                    preset.getLocaleName())
     754                            .primitives(p)
     755                            .build());
     756                }
     757            }
     758            // Check the tags
     759            tagCheck(preset, p, center, preset.data);
     760        }
     761    }
     762
     763    /**
     764     * Perform the checks against a given preset value
     765     * @param preset The originating preset (used for error creation)
     766     * @param p The originating primitive (used for error creation)
     767     * @param center The center of the primitive or other location of the primitive to check
     768     * @param tagInformation The sub items for the preset
     769     */
     770    private void tagCheck(TaggingPreset preset, OsmPrimitive p, LatLon center, List<? extends TaggingPresetItem> tagInformation) {
     771        for (TaggingPresetItem item : tagInformation) {
     772            if (item instanceof CheckGroup) {
     773                tagCheckReal(preset, p, center, ((CheckGroup) item).checks);
     774            } else if (item instanceof ComboMultiSelect) {
     775                tagCheckReal(preset, p, center, ((ComboMultiSelect) item).presetListEntries());
     776            }
     777            if (item instanceof RegionSpecific && ((RegionSpecific) item).regions() != null) {
     778                tagCheckReal(preset, p, center, (RegionSpecific) item);
     779            }
     780        }
     781    }
     782
     783    /**
     784     * Perform the checks against a given preset value
     785     * @param preset The originating preset (used for error creation)
     786     * @param p The originating primitive (used for error creation)
     787     * @param center The center of the primitive or other location of the primitive to check
     788     * @param data The data for the region specific information
     789     */
     790    private void tagCheckReal(TaggingPreset preset, OsmPrimitive p, LatLon center, List<? extends RegionSpecific> data) {
     791        for (RegionSpecific regionSpecific : data) {
     792            if (regionSpecific.regions() != null) {
     793                tagCheckReal(preset, p, center, regionSpecific);
     794            }
     795        }
     796    }
     797
     798    /**
     799     * Perform the checks against a given preset value
     800     * @param preset The originating preset (used for error creation)
     801     * @param p The originating primitive (used for error creation)
     802     * @param center The center of the primitive or other location of the primitive to check
     803     * @param data The data for the region specific information
     804     */
     805    private void tagCheckReal(TaggingPreset preset, OsmPrimitive p, LatLon center, RegionSpecific data) {
     806        // First, check if we aren't in the region for the tag
     807        if (latLonInRegions(center, data.regions()) == data.exclude_regions()) {
     808            final String key;
     809            final String value;
     810            if (data instanceof PresetListEntry) {
     811                key = ((PresetListEntry) data).cms.key;
     812                value = ((PresetListEntry) data).value;
     813            } else if (data instanceof KeyedItem) {
     814                key = ((KeyedItem) data).key;
     815                if (data instanceof Key) {
     816                    value = ((Key) data).value;
     817                } else {
     818                    value = null;
     819                }
     820            } else {
     821                throw new JosmRuntimeException("Unknown implementor for RegionSpecific");
     822            }
     823            if (p.hasTag(key) && (value == null || value.equals(p.get(key)))) {
     824                final TestError.Builder builder = TestError.builder(this, Severity.WARNING, INVALID_REGION)
     825                        .primitives(p);
     826                if (value == null) {
     827                    builder.message(tr("Invalid region for this preset"),
     828                            marktr("Preset {0} should not have the key {1}"),
     829                            preset.getLocaleName(), key);
     830                } else {
     831                    builder.message(tr("Invalid region for this preset"),
     832                            marktr("Preset {0} should not have the tag {1}={2}"),
     833                            preset.getLocaleName(), key, value);
     834                }
     835                errors.add(builder.build());
     836            }
     837        }
     838    }
     839
     840    /**
     841     * Check if the specified latlon is inside any of the specified regions
     842     * @param latLon The {@link LatLon} to check
     843     * @param regions The regions to see if the {@link LatLon} is in
     844     * @return {@code true} if the coordinate is inside any of the regions
     845     */
     846    private static boolean latLonInRegions(LatLon latLon, Collection<String> regions) {
     847        if (regions != null) {
     848            for (String region : regions) {
     849                if (Territories.isIso3166Code(region, latLon)) {
     850                    return true;
     851                }
     852            }
     853        }
     854        return false;
    691855    }
    692856
    693857    private static final Collection<String> NO_AREA_KEYS = Arrays.asList("name", "area", "ref", "access", "operator");
     
    11001264        if (isBeforeUpload) {
    11011265            checkPresetsTypes = checkPresetsTypes && Config.getPref().getBoolean(PREF_CHECK_PRESETS_TYPES_BEFORE_UPLOAD, true);
    11021266        }
     1267
     1268        checkRegions = includeOtherSeverity && Config.getPref().getBoolean(PREF_CHECK_REGIONS, true);
     1269        if (isBeforeUpload) {
     1270            checkRegions = checkRegions && Config.getPref().getBoolean(PREF_CHECK_REGIONS_BEFORE_UPLOAD, true);
     1271        }
    11031272        deprecatedChecker = OsmValidator.getTest(MapCSSTagChecker.class);
    11041273        ignoreForOuterMPSameTagCheck.addAll(Config.getPref().getList(PREF_KEYS_IGNORE_OUTER_MP_SAME_TAG, Collections.emptyList()));
    11051274    }
     
    11121281
    11131282    @Override
    11141283    public void visit(Collection<OsmPrimitive> selection) {
    1115         if (checkKeys || checkValues || checkComplex || checkFixmes || checkPresetsTypes) {
     1284        if (checkKeys || checkValues || checkComplex || checkFixmes || checkPresetsTypes || checkRegions) {
    11161285            super.visit(selection);
    11171286        }
    11181287    }
     
    11771346        prefCheckPresetsTypesBeforeUpload = new JCheckBox();
    11781347        prefCheckPresetsTypesBeforeUpload.setSelected(Config.getPref().getBoolean(PREF_CHECK_PRESETS_TYPES_BEFORE_UPLOAD, true));
    11791348        testPanel.add(prefCheckPresetsTypesBeforeUpload, a);
     1349
     1350        prefCheckRegions = new JCheckBox(tr("Check for regions."), Config.getPref().getBoolean(PREF_CHECK_REGIONS, true));
     1351        prefCheckRegions.setToolTipText(tr("Validate that objects are in the correct region."));
     1352        testPanel.add(prefCheckRegions, GBC.std().insets(20, 0, 0, 0));
     1353
     1354        prefCheckRegionsBeforeUpload = new JCheckBox();
     1355        prefCheckRegionsBeforeUpload.setSelected(Config.getPref().getBoolean(PREF_CHECK_REGIONS_BEFORE_UPLOAD, true));
     1356        testPanel.add(prefCheckRegionsBeforeUpload, a);
    11801357    }
    11811358
    11821359    /**
     
    11991376        Config.getPref().putBoolean(PREF_CHECK_KEYS, prefCheckKeys.isSelected());
    12001377        Config.getPref().putBoolean(PREF_CHECK_FIXMES, prefCheckFixmes.isSelected());
    12011378        Config.getPref().putBoolean(PREF_CHECK_PRESETS_TYPES, prefCheckPresetsTypes.isSelected());
     1379        Config.getPref().putBoolean(PREF_CHECK_REGIONS, prefCheckRegions.isSelected());
    12021380        Config.getPref().putBoolean(PREF_CHECK_VALUES_BEFORE_UPLOAD, prefCheckValuesBeforeUpload.isSelected());
    12031381        Config.getPref().putBoolean(PREF_CHECK_COMPLEX_BEFORE_UPLOAD, prefCheckComplexBeforeUpload.isSelected());
    12041382        Config.getPref().putBoolean(PREF_CHECK_KEYS_BEFORE_UPLOAD, prefCheckKeysBeforeUpload.isSelected());
    12051383        Config.getPref().putBoolean(PREF_CHECK_FIXMES_BEFORE_UPLOAD, prefCheckFixmesBeforeUpload.isSelected());
    12061384        Config.getPref().putBoolean(PREF_CHECK_PRESETS_TYPES_BEFORE_UPLOAD, prefCheckPresetsTypesBeforeUpload.isSelected());
     1385        Config.getPref().putBoolean(PREF_CHECK_REGIONS_BEFORE_UPLOAD, prefCheckRegionsBeforeUpload.isSelected());
    12071386        return Config.getPref().putList(PREF_SOURCES, sourcesList.getItems());
    12081387    }
    12091388
  • src/org/openstreetmap/josm/gui/tagging/presets/items/ComboMultiSelect.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/src/org/openstreetmap/josm/gui/tagging/presets/items/ComboMultiSelect.java b/src/org/openstreetmap/josm/gui/tagging/presets/items/ComboMultiSelect.java
    a b  
    1010import java.util.ArrayList;
    1111import java.util.Arrays;
    1212import java.util.Collection;
     13import java.util.Collections;
    1314import java.util.List;
    1415import java.util.Map;
    1516import java.util.TreeMap;
     
    402403        return use_last_as_default == 2;
    403404    }
    404405
     406    /**
     407     * Get the entries for this {@link ComboMultiSelect} object
     408     * @return The {@link PresetListEntry} values for this object
     409     */
     410    public List<PresetListEntry> presetListEntries() {
     411        return Collections.unmodifiableList(this.presetListEntries);
     412    }
     413
    405414    /**
    406415     * Adds a preset list entry.
    407416     * @param e list entry to add
  • src/org/openstreetmap/josm/gui/tagging/presets/items/KeyedItem.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/src/org/openstreetmap/josm/gui/tagging/presets/items/KeyedItem.java b/src/org/openstreetmap/josm/gui/tagging/presets/items/KeyedItem.java
    a b  
    77import java.util.EnumSet;
    88import java.util.HashMap;
    99import java.util.Map;
    10 import java.util.SortedMap;
    1110import java.util.NoSuchElementException;
     11import java.util.SortedMap;
    1212import java.util.TreeMap;
    1313
    1414import javax.swing.JPopupMenu;
     
    2424/**
    2525 * Preset item associated to an OSM key.
    2626 */
    27 public abstract class KeyedItem extends TextItem {
     27public abstract class KeyedItem extends TextItem implements RegionSpecific {
    2828
    2929    /** The constant value {@code "<different>"}. */
    3030    protected static final String DIFFERENT = "<different>";
     
    5252     */
    5353    public String match = getDefaultMatch().getValue(); // NOSONAR
    5454
     55    /**
     56     * List of regions the preset is applicable for.
     57     */
     58    private Collection<String> regions;
     59    /**
     60     * If true, invert the meaning of regions.
     61     */
     62    private boolean excludeRegions;
     63
    5564    /**
    5665     * Enum denoting how a match (see {@link TaggingPresetItem#matches}) is performed.
    5766     */
     
    260269        return popupMenu;
    261270    }
    262271
     272    @Override
     273    public final Collection<String> regions() {
     274        return this.regions;
     275    }
     276
     277    @Override
     278    public final void realSetRegions(Collection<String> regions) {
     279        this.regions = regions;
     280    }
     281
     282    @Override
     283    public final boolean exclude_regions() {
     284        return this.excludeRegions;
     285    }
     286
     287    @Override
     288    public final void setExclude_regions(boolean excludeRegions) {
     289        this.excludeRegions = excludeRegions;
     290    }
     291
    263292    @Override
    264293    public String toString() {
    265294        return "KeyedItem [key=" + key + ", text=" + text
  • src/org/openstreetmap/josm/gui/tagging/presets/items/PresetListEntry.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/src/org/openstreetmap/josm/gui/tagging/presets/items/PresetListEntry.java b/src/org/openstreetmap/josm/gui/tagging/presets/items/PresetListEntry.java
    a b  
    55import static org.openstreetmap.josm.tools.I18n.tr;
    66import static org.openstreetmap.josm.tools.I18n.trc;
    77
     8import java.util.Collection;
    89import java.util.Objects;
    910
    1011import javax.swing.ImageIcon;
     
    2021 * Used for controls that offer a list of items to choose from like {@link Combo} and
    2122 * {@link MultiSelect}.
    2223 */
    23 public class PresetListEntry implements Comparable<PresetListEntry> {
     24public class PresetListEntry implements Comparable<PresetListEntry>, RegionSpecific {
    2425    /** Used to display an entry matching several different values. */
    2526    protected static final PresetListEntry ENTRY_DIFFERENT = new PresetListEntry(KeyedItem.DIFFERENT, null);
    2627    /** Used to display an empty entry used to clear values. */
     
    4748    /** The localized version of {@link #short_description}. */
    4849    public String locale_short_description; // NOSONAR
    4950
     51    /**
     52     * List of regions the entry is applicable for.
     53     */
     54    private Collection<String> regions;
     55
     56    /**
     57     * If true, invert the meaning of regions.
     58     */
     59    private boolean excludeRegions;
     60
    5061    private String cachedDisplayValue;
    5162    private String cachedShortDescription;
    5263    private ImageIcon cachedIcon;
    5364
    5465    /**
    5566     * Constructs a new {@code PresetListEntry}, uninitialized.
    56      *
     67     * <p>
    5768     * Public default constructor is needed by {@link org.openstreetmap.josm.tools.XmlObjectParser.Parser#startElement}
    5869     */
    5970    public PresetListEntry() {
     
    7384
    7485    /**
    7586     * Returns the contents displayed in the dropdown list.
    76      *
     87     * <p>
    7788     * This is the contents that would be displayed in the current view plus a short description to
    7889     * aid the user. The whole content is wrapped to {@code width}.
    7990     *
     
    163174        return tr("Clears the key ''{0}''.", key);
    164175    }
    165176
     177    @Override
     178    public Collection<String> regions() {
     179        return this.regions;
     180    }
     181
     182    @Override
     183    public void realSetRegions(Collection<String> regions) {
     184        this.regions = regions;
     185    }
     186
     187    @Override
     188    public boolean exclude_regions() {
     189        return this.excludeRegions;
     190    }
     191
     192    @Override
     193    public void setExclude_regions(boolean excludeRegions) {
     194        this.excludeRegions = excludeRegions;
     195    }
     196
    166197    // toString is mainly used to initialize the Editor
    167198    @Override
    168199    public String toString() {
  • new file src/org/openstreetmap/josm/gui/tagging/presets/items/RegionSpecific.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/src/org/openstreetmap/josm/gui/tagging/presets/items/RegionSpecific.java b/src/org/openstreetmap/josm/gui/tagging/presets/items/RegionSpecific.java
    new file mode 100644
    - +  
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.gui.tagging.presets.items;
     3
     4import static org.openstreetmap.josm.tools.I18n.tr;
     5
     6import java.util.Arrays;
     7import java.util.Collection;
     8import java.util.Collections;
     9import java.util.Set;
     10import java.util.stream.Collectors;
     11
     12import org.openstreetmap.josm.tools.Territories;
     13import org.openstreetmap.josm.tools.Utils;
     14import org.xml.sax.SAXException;
     15
     16/**
     17 * Indicates that this object may be specific to a region
     18 * @since xxx
     19 */
     20public interface RegionSpecific {
     21    /**
     22     * Get the regions for the item
     23     * @return The regions that the item is valid for
     24     * @apiNote This is not {@code getRegions} just in case we decide to make the {@link RegionSpecific} record classes.
     25     * @since xxx
     26     */
     27    Collection<String> regions();
     28
     29    /**
     30     * Set the regions for the preset
     31     * @param regions The region list (comma delimited)
     32     * @throws SAXException if an unknown ISO 3166-2 is found
     33     * @since xxx
     34     */
     35    default void setRegions(String regions) throws SAXException {
     36        Set<String> regionSet = Collections.unmodifiableSet(Arrays.stream(regions.split(","))
     37                .map(Utils::intern).collect(Collectors.toSet()));
     38        for (String region : regionSet) {
     39            if (!Territories.getKnownIso3166Codes().contains(region)) {
     40                throw new SAXException(tr("Unknown ISO-3166 Code: {0}", region));
     41            }
     42        }
     43        this.realSetRegions(regionSet);
     44    }
     45
     46    /**
     47     * Set the regions for the preset
     48     * @param regions The region collection
     49     * @since xxx
     50     */
     51    void realSetRegions(Collection<String> regions);
     52
     53    /**
     54     * Get the exclude_regions for the preset
     55     * @apiNote This is not {@code getExclude_regions} just in case we decide to make {@link RegionSpecific} a record class.
     56     * @since xxx
     57     */
     58    boolean exclude_regions();
     59
     60    /**
     61     * Set if the preset should not be used in the given region
     62     * @param excludeRegions if true the function of regions is inverted
     63     * @since xxx
     64     */
     65    void setExclude_regions(boolean excludeRegions);
     66}
  • src/org/openstreetmap/josm/gui/tagging/presets/TaggingPreset.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/src/org/openstreetmap/josm/gui/tagging/presets/TaggingPreset.java b/src/org/openstreetmap/josm/gui/tagging/presets/TaggingPreset.java
    a b  
    6767import org.openstreetmap.josm.gui.tagging.presets.items.PresetLink;
    6868import org.openstreetmap.josm.gui.tagging.presets.items.Roles;
    6969import org.openstreetmap.josm.gui.tagging.presets.items.Space;
     70import org.openstreetmap.josm.gui.tagging.presets.items.RegionSpecific;
    7071import org.openstreetmap.josm.gui.util.GuiHelper;
    7172import org.openstreetmap.josm.tools.GBC;
    7273import org.openstreetmap.josm.tools.ImageProvider;
     
    8889 * It is also able to construct dialogs out of preset definitions.
    8990 * @since 294
    9091 */
    91 public class TaggingPreset extends AbstractAction implements ActiveLayerChangeListener, AdaptableAction, Predicate<IPrimitive> {
     92public class TaggingPreset extends AbstractAction implements ActiveLayerChangeListener, AdaptableAction, Predicate<IPrimitive>,
     93        RegionSpecific {
    9294
    9395    /** The user pressed the "Apply" button */
    9496    public static final int DIALOG_ANSWER_APPLY = 1;
     
    142144     */
    143145    public transient Set<TaggingPresetType> types;
    144146    /**
     147     * List of regions the preset is applicable for.
     148     */
     149    private Collection<String> regions;
     150    /**
     151     * If true, invert the meaning of regions.
     152     */
     153    private boolean excludeRegions;
     154    /**
    145155     * The list of preset items
    146156     */
    147157    public final transient List<TaggingPresetItem> data = new ArrayList<>(2);
     
    349359        }
    350360    }
    351361
     362    @Override
     363    public final Collection<String> regions() {
     364        return this.regions != null || this.group == null ? this.regions : this.group.regions();
     365    }
     366
     367    @Override
     368    public final void realSetRegions(Collection<String> regions) {
     369        this.regions = regions;
     370    }
     371
     372    @Override
     373    public final boolean exclude_regions() {
     374        return this.excludeRegions;
     375    }
     376
     377    @Override
     378    public final void setExclude_regions(boolean excludeRegions) {
     379        this.excludeRegions = excludeRegions;
     380    }
     381
    352382    private static class PresetPanel extends JPanel {
    353383        private boolean hasElements;
    354384
  • src/org/openstreetmap/josm/gui/tagging/presets/TaggingPresetValidation.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/src/org/openstreetmap/josm/gui/tagging/presets/TaggingPresetValidation.java b/src/org/openstreetmap/josm/gui/tagging/presets/TaggingPresetValidation.java
    a b  
    2424import org.openstreetmap.josm.data.validation.TestError;
    2525import org.openstreetmap.josm.data.validation.tests.MapCSSTagChecker;
    2626import org.openstreetmap.josm.data.validation.tests.OpeningHourTest;
     27import org.openstreetmap.josm.data.validation.tests.TagChecker;
    2728import org.openstreetmap.josm.gui.MainApplication;
     29import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
    2830import org.openstreetmap.josm.gui.util.GuiHelper;
    2931import org.openstreetmap.josm.tools.Logging;
    3032import org.openstreetmap.josm.tools.SubclassFilteredCollection;
     
    5557        try {
    5658            MapCSSTagChecker mapCSSTagChecker = OsmValidator.getTest(MapCSSTagChecker.class);
    5759            OpeningHourTest openingHourTest = OsmValidator.getTest(OpeningHourTest.class);
    58             OsmValidator.initializeTests(Arrays.asList(mapCSSTagChecker, openingHourTest));
     60            TagChecker tagChecker = OsmValidator.getTest(TagChecker.class);
     61            tagChecker.startTest(NullProgressMonitor.INSTANCE); //since initializeTest works if test is enabled
     62            OsmValidator.initializeTests(Arrays.asList(mapCSSTagChecker, openingHourTest, tagChecker));
     63
    5964
    6065            List<TestError> errors = new ArrayList<>();
    6166            openingHourTest.addErrorsForPrimitive(primitive, errors);
    6267            errors.addAll(mapCSSTagChecker.getErrorsForPrimitive(primitive, ValidatorPrefHelper.PREF_OTHER.get()));
     68            tagChecker.check(primitive);
     69            errors.addAll(tagChecker.getErrors());
    6370
    6471            boolean visible = !errors.isEmpty();
    6572            String toolTipText = "<html>" + Utils.joinAsHtmlUnorderedList(Utils.transform(errors, e ->
  • test/unit/org/openstreetmap/josm/data/validation/tests/TagCheckerTest.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/test/unit/org/openstreetmap/josm/data/validation/tests/TagCheckerTest.java b/test/unit/org/openstreetmap/josm/data/validation/tests/TagCheckerTest.java
    a b  
    228228        assertFalse(errors.get(0).isFixable());
    229229    }
    230230
     231    @Test
     232    void testRegionKey() throws IOException {
     233        final List<TestError> errors = test(OsmUtils.createPrimitive("node highway=crossing crossing_ref=zebra"));
     234        assertEquals(1, errors.size());
     235        assertEquals("Invalid region for this preset", errors.get(0).getMessage());
     236        assertEquals("Preset Pedestrian Crossing should not have the key crossing_ref", errors.get(0).getDescription());
     237        assertEquals(Severity.WARNING, errors.get(0).getSeverity());
     238        assertFalse(errors.get(0).isFixable());
     239
     240    }
     241
     242    @Test
     243    void testRegionTag() throws IOException {
     244        final List<TestError> errors = test(OsmUtils.createPrimitive("relation type=waterway ref:gnis=123456"));
     245        assertEquals(1, errors.size());
     246        assertEquals("Invalid region for this preset", errors.get(0).getMessage());
     247        assertEquals("Preset Waterway should not have the key ref:gnis", errors.get(0).getDescription());
     248        assertEquals(Severity.WARNING, errors.get(0).getSeverity());
     249        assertFalse(errors.get(0).isFixable());
     250    }
     251
    231252    /**
    232253     * Key in presets but not in ignored.cfg. Caused a NPE with r14727.
    233254     * @throws IOException if any I/O error occurs
  • test/unit/org/openstreetmap/josm/gui/tagging/presets/items/CheckGroupTest.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/test/unit/org/openstreetmap/josm/gui/tagging/presets/items/CheckGroupTest.java b/test/unit/org/openstreetmap/josm/gui/tagging/presets/items/CheckGroupTest.java
    a b  
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.gui.tagging.presets.items;
    33
    4 import static org.junit.jupiter.api.Assertions.assertEquals;
    5 import static org.junit.jupiter.api.Assertions.assertFalse;
    6 import static org.junit.jupiter.api.Assertions.assertTrue;
    7 
    8 import javax.swing.JPanel;
    9 
    10 import org.junit.jupiter.api.Test;
    11 import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItemGuiSupport;
     4import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItem;
     5import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItemTest;
    126
    137/**
    148 * Unit tests of {@link CheckGroup} class.
    159 */
    16 class CheckGroupTest {
    17     /**
    18      * Unit test for {@link CheckGroup#addToPanel}.
    19      */
    20     @Test
    21     void testAddToPanel() {
    22         CheckGroup cg = new CheckGroup();
    23         JPanel p = new JPanel();
    24         assertEquals(0, p.getComponentCount());
    25         assertFalse(cg.addToPanel(p, TaggingPresetItemGuiSupport.create(false)));
    26         assertTrue(p.getComponentCount() > 0);
     10class CheckGroupTest implements TaggingPresetItemTest {
     11    @Override
     12    public TaggingPresetItem getInstance() {
     13        return new CheckGroup();
    2714    }
    2815}
  • test/unit/org/openstreetmap/josm/gui/tagging/presets/items/CheckTest.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/test/unit/org/openstreetmap/josm/gui/tagging/presets/items/CheckTest.java b/test/unit/org/openstreetmap/josm/gui/tagging/presets/items/CheckTest.java
    a b  
    88
    99import org.junit.jupiter.api.Test;
    1010import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItemGuiSupport;
     11import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItemTest;
    1112import org.openstreetmap.josm.testutils.annotations.Main;
    1213
    1314/**
    1415 * Unit tests of {@link Check} class.
    1516 */
    1617@Main
    17 class CheckTest {
     18class CheckTest implements RegionSpecificTest, TaggingPresetItemTest {
     19    @Override
     20    public Check getInstance() {
     21        final Check check = new Check();
     22        check.key = "crossing:island";
     23        return check;
     24    }
     25
    1826    /**
    1927     * Unit test for {@link Check#addToPanel}.
    2028     */
     29    @Override
    2130    @Test
    22     void testAddToPanel() {
     31    public void testAddToPanel() {
    2332        JPanel p = new JPanel();
    2433        assertEquals(0, p.getComponentCount());
    25         assertTrue(new Check().addToPanel(p, TaggingPresetItemGuiSupport.create(false)));
     34        assertTrue(getInstance().addToPanel(p, TaggingPresetItemGuiSupport.create(false)));
    2635        assertTrue(p.getComponentCount() > 0);
    2736    }
    2837}
  • test/unit/org/openstreetmap/josm/gui/tagging/presets/items/ComboTest.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/test/unit/org/openstreetmap/josm/gui/tagging/presets/items/ComboTest.java b/test/unit/org/openstreetmap/josm/gui/tagging/presets/items/ComboTest.java
    a b  
    1212import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1313import org.openstreetmap.josm.data.osm.OsmUtils;
    1414import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItemGuiSupport;
     15import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItemTest;
    1516import org.openstreetmap.josm.testutils.annotations.BasicPreferences;
    1617import org.openstreetmap.josm.testutils.annotations.I18n;
    1718import org.openstreetmap.josm.testutils.annotations.Main;
     
    2223@BasicPreferences
    2324@I18n("de")
    2425@Main
    25 class ComboTest {
     26class ComboTest implements TaggingPresetItemTest {
     27    @Override
     28    public Combo getInstance() {
     29        return new Combo();
     30    }
     31
    2632    /**
    27      * Unit test for {@link Combo#addToPanel}.
     33     * Unit test for {@link Check#addToPanel}.
    2834     */
     35    @Override
    2936    @Test
    30     void testAddToPanel() {
     37    public void testAddToPanel() {
    3138        JPanel p = new JPanel();
    3239        assertEquals(0, p.getComponentCount());
    33         assertTrue(new Combo().addToPanel(p, TaggingPresetItemGuiSupport.create(false)));
     40        assertTrue(getInstance().addToPanel(p, TaggingPresetItemGuiSupport.create(false)));
    3441        assertTrue(p.getComponentCount() > 0);
    3542    }
    3643
     
    3946     */
    4047    @Test
    4148    void testUseLastAsDefault() {
    42         Combo combo = new Combo();
     49        final Combo combo = getInstance();
    4350        combo.key = "addr:country";
    4451        combo.values_from = "java.util.Locale#getISOCountries";
    4552        OsmPrimitive way = OsmUtils.createPrimitive("way");
     
    118125
    119126    @Test
    120127    void testColor() {
    121         Combo combo = new Combo();
     128        final Combo combo = getInstance();
    122129        combo.key = "colour";
    123130        combo.values = "red;green;blue;black";
    124131        combo.values_context = "color";
  • test/unit/org/openstreetmap/josm/gui/tagging/presets/items/ItemSeparatorTest.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/test/unit/org/openstreetmap/josm/gui/tagging/presets/items/ItemSeparatorTest.java b/test/unit/org/openstreetmap/josm/gui/tagging/presets/items/ItemSeparatorTest.java
    a b  
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.gui.tagging.presets.items;
    33
    4 import static org.junit.jupiter.api.Assertions.assertEquals;
    5 import static org.junit.jupiter.api.Assertions.assertFalse;
    6 import static org.junit.jupiter.api.Assertions.assertTrue;
    7 
    8 import javax.swing.JPanel;
    9 
    10 import org.junit.jupiter.api.Test;
    11 import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItemGuiSupport;
     4import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItemTest;
    125
    136/**
    147 * Unit tests of {@link ItemSeparator} class.
    158 */
    16 class ItemSeparatorTest {
    17     /**
    18      * Unit test for {@link ItemSeparator#addToPanel}.
    19      */
    20     @Test
    21     void testAddToPanel() {
    22         JPanel p = new JPanel();
    23         assertEquals(0, p.getComponentCount());
    24         assertFalse(new ItemSeparator().addToPanel(p, TaggingPresetItemGuiSupport.create(false)));
    25         assertTrue(p.getComponentCount() > 0);
     9class ItemSeparatorTest implements TaggingPresetItemTest {
     10    @Override
     11    public ItemSeparator getInstance() {
     12        return new ItemSeparator();
    2613    }
    2714}
  • test/unit/org/openstreetmap/josm/gui/tagging/presets/items/KeyTest.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/test/unit/org/openstreetmap/josm/gui/tagging/presets/items/KeyTest.java b/test/unit/org/openstreetmap/josm/gui/tagging/presets/items/KeyTest.java
    a b  
    88
    99import org.junit.jupiter.api.Test;
    1010import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItemGuiSupport;
     11import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItemTest;
    1112
    1213/**
    1314 * Unit tests of {@link Key} class.
    1415 */
    15 class KeyTest {
     16class KeyTest implements RegionSpecificTest, TaggingPresetItemTest {
     17    @Override
     18    public Key getInstance() {
     19        final Key key = new Key();
     20        key.key = "highway";
     21        key.value = "residential";
     22        return key;
     23    }
     24
    1625    /**
    1726     * Unit test for {@link Key#addToPanel}.
    1827     */
    1928    @Test
    20     void testAddToPanel() {
     29    @Override
     30    public void testAddToPanel() {
    2131        JPanel p = new JPanel();
    2232        assertEquals(0, p.getComponentCount());
    2333        assertFalse(new Key().addToPanel(p, TaggingPresetItemGuiSupport.create(false)));
  • test/unit/org/openstreetmap/josm/gui/tagging/presets/items/LabelTest.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/test/unit/org/openstreetmap/josm/gui/tagging/presets/items/LabelTest.java b/test/unit/org/openstreetmap/josm/gui/tagging/presets/items/LabelTest.java
    a b  
    88
    99import org.junit.jupiter.api.Test;
    1010import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItemGuiSupport;
     11import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItemTest;
    1112
    1213/**
    1314 * Unit tests of {@link Label} class.
    1415 */
    15 class LabelTest {
     16class LabelTest implements TaggingPresetItemTest {
     17    @Override
     18    public Label getInstance() {
     19        return new Label();
     20    }
     21
    1622    /**
    17      * Unit test for {@link Label#addToPanel}.
     23     * Unit test for {@link Check#addToPanel}.
    1824     */
     25    @Override
    1926    @Test
    20     void testAddToPanel() {
     27    public void testAddToPanel() {
    2128        JPanel p = new JPanel();
    2229        assertEquals(0, p.getComponentCount());
    23         assertTrue(new Label().addToPanel(p, TaggingPresetItemGuiSupport.create(false)));
     30        assertTrue(getInstance().addToPanel(p, TaggingPresetItemGuiSupport.create(false)));
    2431        assertTrue(p.getComponentCount() > 0);
    2532    }
    2633}
  • test/unit/org/openstreetmap/josm/gui/tagging/presets/items/LinkTest.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/test/unit/org/openstreetmap/josm/gui/tagging/presets/items/LinkTest.java b/test/unit/org/openstreetmap/josm/gui/tagging/presets/items/LinkTest.java
    a b  
    99
    1010import org.junit.jupiter.api.Test;
    1111import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItemGuiSupport;
     12import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItemTest;
    1213import org.openstreetmap.josm.spi.preferences.Config;
    1314
    1415/**
    1516 * Unit tests of {@link Link} class.
    1617 */
    17 class LinkTest {
     18class LinkTest implements TaggingPresetItemTest {
     19    @Override
     20    public Link getInstance() {
     21        return new Link();
     22    }
     23
    1824    /**
    1925     * Unit test for {@link Link#addToPanel}.
    2026     */
     27    @Override
    2128    @Test
    22     void testAddToPanel() {
    23         Link l = new Link();
     29    public void testAddToPanel() {
     30        Link l = getInstance();
    2431        JPanel p = new JPanel();
    2532        assertEquals(0, p.getComponentCount());
    2633        assertFalse(l.addToPanel(p, TaggingPresetItemGuiSupport.create(false)));
  • test/unit/org/openstreetmap/josm/gui/tagging/presets/items/MultiSelectTest.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/test/unit/org/openstreetmap/josm/gui/tagging/presets/items/MultiSelectTest.java b/test/unit/org/openstreetmap/josm/gui/tagging/presets/items/MultiSelectTest.java
    a b  
    88
    99import org.junit.jupiter.api.Test;
    1010import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItemGuiSupport;
     11import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItemTest;
    1112import org.openstreetmap.josm.testutils.annotations.Main;
    1213
    1314/**
    1415 * Unit tests of {@link MultiSelect} class.
    1516 */
    1617@Main
    17 class MultiSelectTest {
     18class MultiSelectTest implements TaggingPresetItemTest {
     19    @Override
     20    public MultiSelect getInstance() {
     21        return new MultiSelect();
     22    }
     23
    1824    /**
    19      * Unit test for {@link MultiSelect#addToPanel}.
     25     * Unit test for {@link Check#addToPanel}.
    2026     */
     27    @Override
    2128    @Test
    22     void testAddToPanel() {
     29    public void testAddToPanel() {
    2330        JPanel p = new JPanel();
    2431        assertEquals(0, p.getComponentCount());
    25         assertTrue(new MultiSelect().addToPanel(p, TaggingPresetItemGuiSupport.create(false)));
     32        assertTrue(getInstance().addToPanel(p, TaggingPresetItemGuiSupport.create(false)));
    2633        assertTrue(p.getComponentCount() > 0);
    2734    }
    2835}
  • test/unit/org/openstreetmap/josm/gui/tagging/presets/items/OptionalTest.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/test/unit/org/openstreetmap/josm/gui/tagging/presets/items/OptionalTest.java b/test/unit/org/openstreetmap/josm/gui/tagging/presets/items/OptionalTest.java
    a b  
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.gui.tagging.presets.items;
    33
    4 import static org.junit.jupiter.api.Assertions.assertEquals;
    5 import static org.junit.jupiter.api.Assertions.assertFalse;
    6 import static org.junit.jupiter.api.Assertions.assertTrue;
    7 
    8 import javax.swing.JPanel;
    9 
    10 import org.junit.jupiter.api.Test;
    11 import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItemGuiSupport;
     4import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItemTest;
    125
    136/**
    147 * Unit tests of {@link Optional} class.
    158 */
    16 class OptionalTest {
    17     /**
    18      * Unit test for {@link Optional#addToPanel}.
    19      */
    20     @Test
    21     void testAddToPanel() {
    22         JPanel p = new JPanel();
    23         assertEquals(0, p.getComponentCount());
    24         assertFalse(new Optional().addToPanel(p, TaggingPresetItemGuiSupport.create(false)));
    25         assertTrue(p.getComponentCount() > 0);
     9class OptionalTest implements TaggingPresetItemTest {
     10    @Override
     11    public Optional getInstance() {
     12        return new Optional();
    2613    }
    2714}
  • test/unit/org/openstreetmap/josm/gui/tagging/presets/items/PresetLinkTest.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/test/unit/org/openstreetmap/josm/gui/tagging/presets/items/PresetLinkTest.java b/test/unit/org/openstreetmap/josm/gui/tagging/presets/items/PresetLinkTest.java
    a b  
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.gui.tagging.presets.items;
    33
    4 import static org.junit.jupiter.api.Assertions.assertEquals;
    5 import static org.junit.jupiter.api.Assertions.assertFalse;
    6 import static org.junit.jupiter.api.Assertions.assertTrue;
    7 
    8 import javax.swing.JPanel;
    9 
    10 import org.junit.jupiter.api.Test;
    11 import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItemGuiSupport;
     4import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItemTest;
    125import org.openstreetmap.josm.testutils.annotations.TaggingPresets;
    136
    147/**
    158 * Unit tests of {@link PresetLink} class.
    169 */
    1710@TaggingPresets
    18 class PresetLinkTest {
    19     /**
    20      * Unit test for {@link PresetLink#addToPanel}.
    21      */
    22     @Test
    23     void testAddToPanel() {
    24         PresetLink l = new PresetLink();
    25         l.preset_name = "River";
    26         JPanel p = new JPanel();
    27         assertEquals(0, p.getComponentCount());
    28         assertFalse(l.addToPanel(p, TaggingPresetItemGuiSupport.create(false)));
    29         assertTrue(p.getComponentCount() > 0);
     11class PresetLinkTest implements TaggingPresetItemTest {
     12    @Override
     13    public PresetLink getInstance() {
     14        PresetLink presetLink = new PresetLink();
     15        presetLink.preset_name = "River";
     16        return presetLink;
    3017    }
    3118}
  • new file test/unit/org/openstreetmap/josm/gui/tagging/presets/items/RegionSpecificTest.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/test/unit/org/openstreetmap/josm/gui/tagging/presets/items/RegionSpecificTest.java b/test/unit/org/openstreetmap/josm/gui/tagging/presets/items/RegionSpecificTest.java
    new file mode 100644
    - +  
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.gui.tagging.presets.items;
     3
     4import static org.junit.jupiter.api.Assertions.assertAll;
     5import static org.junit.jupiter.api.Assertions.assertEquals;
     6import static org.junit.jupiter.api.Assertions.assertFalse;
     7import static org.junit.jupiter.api.Assertions.assertNotEquals;
     8import static org.junit.jupiter.api.Assertions.assertThrows;
     9
     10import org.junit.jupiter.api.Test;
     11import org.openstreetmap.josm.testutils.annotations.Territories;
     12import org.xml.sax.SAXException;
     13
     14/**
     15 * Test class for {@link RegionSpecific}
     16 */
     17@Territories
     18interface RegionSpecificTest {
     19    /**
     20     * Get the test instance
     21     * @return The instance to test
     22     */
     23    RegionSpecific getInstance();
     24
     25    @Test
     26    default void testSetRegions() throws SAXException {
     27        final RegionSpecific regionSpecific = getInstance();
     28        if ("java.lang.Record".equals(regionSpecific.getClass().getSuperclass().getCanonicalName())) {
     29            assertThrows(UnsupportedOperationException.class, () -> regionSpecific.setRegions("US"));
     30        } else {
     31            assertFalse(regionSpecific.regions() != null && regionSpecific.regions().contains("US"),
     32                    "Using US as the test region for setting regions");
     33            regionSpecific.setRegions("US");
     34            assertAll(() -> assertEquals(1, regionSpecific.regions().size()),
     35                    () -> assertEquals("US", regionSpecific.regions().iterator().next()));
     36        }
     37    }
     38
     39    @Test
     40    default void testSetExcludeRegions() {
     41        final RegionSpecific regionSpecific = getInstance();
     42        if ("java.lang.Record".equals(regionSpecific.getClass().getSuperclass().getCanonicalName())) {
     43            assertThrows(UnsupportedOperationException.class, () -> regionSpecific.setExclude_regions(true));
     44        } else {
     45            final boolean oldExclude = regionSpecific.exclude_regions();
     46            regionSpecific.setExclude_regions(!oldExclude);
     47            assertNotEquals(oldExclude, regionSpecific.exclude_regions());
     48        }
     49    }
     50}
  • test/unit/org/openstreetmap/josm/gui/tagging/presets/items/RolesTest.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/test/unit/org/openstreetmap/josm/gui/tagging/presets/items/RolesTest.java b/test/unit/org/openstreetmap/josm/gui/tagging/presets/items/RolesTest.java
    a b  
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.gui.tagging.presets.items;
    33
    4 import static org.junit.jupiter.api.Assertions.assertEquals;
    5 import static org.junit.jupiter.api.Assertions.assertFalse;
    6 import static org.junit.jupiter.api.Assertions.assertTrue;
    7 
    8 import javax.swing.JPanel;
    9 
    10 import org.junit.jupiter.api.Test;
    11 import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItemGuiSupport;
     4import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItem;
     5import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItemTest;
    126
    137/**
    148 * Unit tests of {@link Roles} class.
    159 */
    16 class RolesTest {
    17     /**
    18      * Unit test for {@link Roles#addToPanel}.
    19      */
    20     @Test
    21     void testAddToPanel() {
    22         JPanel p = new JPanel();
    23         assertEquals(0, p.getComponentCount());
    24         assertFalse(new Roles().addToPanel(p, TaggingPresetItemGuiSupport.create(false)));
    25         assertTrue(p.getComponentCount() > 0);
     10class RolesTest implements TaggingPresetItemTest {
     11    @Override
     12    public TaggingPresetItem getInstance() {
     13        return new Roles();
    2614    }
    2715}
  • test/unit/org/openstreetmap/josm/gui/tagging/presets/items/SpaceTest.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/test/unit/org/openstreetmap/josm/gui/tagging/presets/items/SpaceTest.java b/test/unit/org/openstreetmap/josm/gui/tagging/presets/items/SpaceTest.java
    a b  
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.gui.tagging.presets.items;
    33
    4 import static org.junit.jupiter.api.Assertions.assertEquals;
    5 import static org.junit.jupiter.api.Assertions.assertFalse;
    6 import static org.junit.jupiter.api.Assertions.assertTrue;
    7 
    8 import javax.swing.JPanel;
    9 
    10 import org.junit.jupiter.api.Test;
    11 import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItemGuiSupport;
     4import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItemTest;
    125
    136/**
    147 * Unit tests of {@link Space} class.
    158 */
    16 class SpaceTest {
    17     /**
    18      * Unit test for {@link Space#addToPanel}.
    19      */
    20     @Test
    21     void testAddToPanel() {
    22         JPanel p = new JPanel();
    23         assertEquals(0, p.getComponentCount());
    24         assertFalse(new Space().addToPanel(p, TaggingPresetItemGuiSupport.create(false)));
    25         assertTrue(p.getComponentCount() > 0);
     9class SpaceTest implements TaggingPresetItemTest {
     10    @Override
     11    public Space getInstance() {
     12        return new Space();
    2613    }
    2714}
  • test/unit/org/openstreetmap/josm/gui/tagging/presets/items/TextTest.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/test/unit/org/openstreetmap/josm/gui/tagging/presets/items/TextTest.java b/test/unit/org/openstreetmap/josm/gui/tagging/presets/items/TextTest.java
    a b  
    88
    99import org.junit.jupiter.api.Test;
    1010import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItemGuiSupport;
     11import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItemTest;
    1112import org.openstreetmap.josm.testutils.annotations.Main;
    1213
    1314/**
    1415 * Unit tests of {@link Text} class.
    1516 */
    1617@Main
    17 class TextTest {
     18class TextTest implements TaggingPresetItemTest {
     19    @Override
     20    public Text getInstance() {
     21        return new Text();
     22    }
     23
    1824    /**
    19      * Unit test for {@link Text#addToPanel}.
     25     * Unit test for {@link Check#addToPanel}.
    2026     */
     27    @Override
    2128    @Test
    22     void testAddToPanel() {
     29    public void testAddToPanel() {
    2330        JPanel p = new JPanel();
    2431        assertEquals(0, p.getComponentCount());
    25         assertTrue(new Text().addToPanel(p, TaggingPresetItemGuiSupport.create(false)));
     32        assertTrue(getInstance().addToPanel(p, TaggingPresetItemGuiSupport.create(false)));
    2633        assertTrue(p.getComponentCount() > 0);
    2734    }
    2835}
  • new file test/unit/org/openstreetmap/josm/gui/tagging/presets/TaggingPresetItemTest.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/test/unit/org/openstreetmap/josm/gui/tagging/presets/TaggingPresetItemTest.java b/test/unit/org/openstreetmap/josm/gui/tagging/presets/TaggingPresetItemTest.java
    new file mode 100644
    - +  
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.gui.tagging.presets;
     3
     4import static org.junit.jupiter.api.Assertions.assertEquals;
     5import static org.junit.jupiter.api.Assertions.assertFalse;
     6import static org.junit.jupiter.api.Assertions.assertNotEquals;
     7
     8import javax.swing.JPanel;
     9
     10import org.junit.jupiter.api.Test;
     11
     12/**
     13 * Test class for {@link TaggingPresetItem}
     14 */
     15public interface TaggingPresetItemTest {
     16    /**
     17     * Get the instance to test
     18     *
     19     * @return The item to test
     20     */
     21    TaggingPresetItem getInstance();
     22
     23    /**
     24     * Test method for {@link TaggingPresetItem#addToPanel(JPanel, TaggingPresetItemGuiSupport)}
     25     */
     26    @Test
     27    default void testAddToPanel() {
     28        TaggingPresetItem item = getInstance();
     29        JPanel p = new JPanel();
     30        assertEquals(0, p.getComponentCount());
     31        assertFalse(item.addToPanel(p, TaggingPresetItemGuiSupport.create(false)));
     32        assertNotEquals(0, p.getComponentCount());
     33    }
     34}
  • test/unit/org/openstreetmap/josm/testutils/annotations/TaggingPresets.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/test/unit/org/openstreetmap/josm/testutils/annotations/TaggingPresets.java b/test/unit/org/openstreetmap/josm/testutils/annotations/TaggingPresets.java
    a b  
    88import java.lang.annotation.Target;
    99import java.util.Collection;
    1010
     11import org.junit.jupiter.api.extension.BeforeAllCallback;
    1112import org.junit.jupiter.api.extension.BeforeEachCallback;
    1213import org.junit.jupiter.api.extension.ExtendWith;
    1314import org.junit.jupiter.api.extension.ExtensionContext;
     
    2425@Retention(RetentionPolicy.RUNTIME)
    2526@Target({ ElementType.METHOD, ElementType.TYPE })
    2627@BasicPreferences
     28@Territories
    2729@ExtendWith(TaggingPresets.TaggingPresetsExtension.class)
    2830public @interface TaggingPresets {
    2931
    30     class TaggingPresetsExtension implements BeforeEachCallback {
     32    class TaggingPresetsExtension implements BeforeEachCallback, BeforeAllCallback {
    3133        private static int expectedHashcode = 0;
    3234
     35        @Override
     36        public void beforeAll(ExtensionContext extensionContext) throws Exception {
     37            setup();
     38        }
     39
    3340        @Override
    3441        public void beforeEach(ExtensionContext extensionContext) {
    3542            setup();
    3643        }
    3744
    3845        /**
    39          * Setup the tagging presets
     46         * Set up the tagging presets
    4047         */
    4148        public static synchronized void setup() {
    4249            final Collection<TaggingPreset> oldPresets = org.openstreetmap.josm.gui.tagging.presets.TaggingPresets.getTaggingPresets();