Changeset 3674 in josm


Ignore:
Timestamp:
2010-11-25T18:06:50+01:00 (9 years ago)
Author:
bastiK
Message:

Replace Bag by MultiMap.
Both collections are quite similar, but there is a technical difference: Bag is backed by an ArrayList and MultiMap by a LinkedHashSet. So with a Bag you could map a key multiple times to a certain value. I haven't found any usage where this behaviour is required or intended.
Also there could be a certain performance drawback with LinkedHashSet compared to ArrayList. However in the typical validator use case the value collection represents duplicate or crossing ways, so the number of elements is usually 1 or 2 and mostly smaller than the initial capacity (LHS=16, AL=10). (But I could have overlooked some use cases.)

Location:
trunk/src/org/openstreetmap/josm
Files:
1 deleted
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/validation/TestError.java

    r3671 r3674  
    3434    private String description_en;
    3535    /** The affected primitives */
    36     private List<? extends OsmPrimitive> primitives;
     36    private Collection<? extends OsmPrimitive> primitives;
    3737    /** The primitives to be highlighted */
    38     private List<?> highlighted;
     38    private Collection<?> highlighted;
    3939    /** The tester that raised this error */
    4040    private Test tester;
     
    5454     */
    5555    public TestError(Test tester, Severity severity, String message, String description, String description_en,
    56             int code, List<? extends OsmPrimitive> primitives, List<?> highlighted) {
     56            int code, Collection<? extends OsmPrimitive> primitives, Collection<?> highlighted) {
    5757        this.tester = tester;
    5858        this.severity = severity;
     
    6565    }
    6666
    67     public TestError(Test tester, Severity severity, String message, int code, List<? extends OsmPrimitive> primitives,
    68             List<?> highlighted) {
     67    public TestError(Test tester, Severity severity, String message, int code, Collection<? extends OsmPrimitive> primitives,
     68            Collection<?> highlighted) {
    6969        this(tester, severity, message, null, null, code, primitives, highlighted);
    7070    }
    7171
    7272    public TestError(Test tester, Severity severity, String message, String description, String description_en,
    73             int code, List<? extends OsmPrimitive> primitives) {
     73            int code, Collection<? extends OsmPrimitive> primitives) {
    7474        this(tester, severity, message, description, description_en, code, primitives, primitives);
    7575    }
    7676
    77     public TestError(Test tester, Severity severity, String message, int code, List<? extends OsmPrimitive> primitives) {
     77    public TestError(Test tester, Severity severity, String message, int code, Collection<? extends OsmPrimitive> primitives) {
    7878        this(tester, severity, message, null, null, code, primitives, primitives);
    7979    }
     
    117117     * @return the list of primitives affected by this error
    118118     */
    119     public List<? extends OsmPrimitive> getPrimitives() {
     119    public Collection<? extends OsmPrimitive> getPrimitives() {
    120120        return primitives;
    121121    }
  • trunk/src/org/openstreetmap/josm/data/validation/tests/DuplicateNode.java

    r3671 r3674  
    1515import java.util.List;
    1616import java.util.Map;
     17import java.util.Set;
    1718
    1819import javax.swing.JLabel;
     
    3334import org.openstreetmap.josm.data.validation.Test;
    3435import org.openstreetmap.josm.data.validation.TestError;
    35 import org.openstreetmap.josm.data.validation.util.Bag;
    3636import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil;
    3737import org.openstreetmap.josm.gui.progress.ProgressMonitor;
     38import org.openstreetmap.josm.tools.MultiMap;
    3839
    3940/**
     
    138139        List<TestError> errors = new ArrayList<TestError>();
    139140
    140         Bag<Map<String,String>, OsmPrimitive> bag = new Bag<Map<String,String>, OsmPrimitive>();
     141        MultiMap<Map<String,String>, OsmPrimitive> mm = new MultiMap<Map<String,String>, OsmPrimitive>();
    141142        for (Node n: nodes) {
    142             bag.add(n.getKeys(), n);
     143            mm.put(n.getKeys(), n);
    143144        }
    144145
     
    150151        // the same tag set
    151152        //
    152         for (Iterator<Map<String,String>> it = bag.keySet().iterator(); it.hasNext();) {
     153        for (Iterator<Map<String,String>> it = mm.keySet().iterator(); it.hasNext();) {
    153154            Map<String,String> tagSet = it.next();
    154             if (bag.get(tagSet).size() > 1) {
     155            if (mm.get(tagSet).size() > 1) {
    155156
    156157                for (String type: types) {
     
    158159                }
    159160
    160                 for (OsmPrimitive p : bag.get(tagSet)) {
     161                for (OsmPrimitive p : mm.get(tagSet)) {
    161162                    if (p.getType()==OsmPrimitiveType.NODE) {
    162163                        Node n = (Node) p;
     
    198199                            msg,
    199200                            DUPLICATE_NODE_MIXED,
    200                             bag.get(tagSet)
     201                            mm.get(tagSet)
    201202                    ));
    202203                } else if (typeMap.get("highway")) {
     
    209210                            msg,
    210211                            DUPLICATE_NODE_HIGHWAY,
    211                             bag.get(tagSet)
     212                            mm.get(tagSet)
    212213                    ));
    213214                } else if (typeMap.get("railway")) {
     
    220221                            msg,
    221222                            DUPLICATE_NODE_RAILWAY,
    222                             bag.get(tagSet)
     223                            mm.get(tagSet)
    223224                    ));
    224225                } else if (typeMap.get("waterway")) {
     
    231232                            msg,
    232233                            DUPLICATE_NODE_WATERWAY,
    233                             bag.get(tagSet)
     234                            mm.get(tagSet)
    234235                    ));
    235236                } else if (typeMap.get("boundary")) {
     
    242243                            msg,
    243244                            DUPLICATE_NODE_BOUNDARY,
    244                             bag.get(tagSet)
     245                            mm.get(tagSet)
    245246                    ));
    246247                } else if (typeMap.get("power")) {
     
    253254                            msg,
    254255                            DUPLICATE_NODE_POWER,
    255                             bag.get(tagSet)
     256                            mm.get(tagSet)
    256257                    ));
    257258                } else if (typeMap.get("natural")) {
     
    264265                            msg,
    265266                            DUPLICATE_NODE_NATURAL,
    266                             bag.get(tagSet)
     267                            mm.get(tagSet)
    267268                    ));
    268269                } else if (typeMap.get("building")) {
     
    275276                            msg,
    276277                            DUPLICATE_NODE_BUILDING,
    277                             bag.get(tagSet)
     278                            mm.get(tagSet)
    278279                    ));
    279280                } else if (typeMap.get("landuse")) {
     
    286287                            msg,
    287288                            DUPLICATE_NODE_LANDUSE,
    288                             bag.get(tagSet)
     289                            mm.get(tagSet)
    289290                    ));
    290291                } else {
     
    297298                            msg,
    298299                            DUPLICATE_NODE_OTHER,
    299                             bag.get(tagSet)
     300                            mm.get(tagSet)
    300301                    ));
    301302
     
    308309        // differing tag sets
    309310        //
    310         if (!bag.isEmpty()) {
     311        if (!mm.isEmpty()) {
    311312            List<OsmPrimitive> duplicates = new ArrayList<OsmPrimitive>();
    312             for (List<OsmPrimitive> l: bag.values()) {
     313            for (Set<OsmPrimitive> l: mm.values()) {
    313314                duplicates.addAll(l);
    314315            }
  • trunk/src/org/openstreetmap/josm/data/validation/tests/DuplicateWay.java

    r3671 r3674  
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
     6import java.util.ArrayList;
    67import java.util.Collection;
    78import java.util.HashSet;
     
    910import java.util.List;
    1011import java.util.Map;
    11 import java.util.Vector;
     12import java.util.Set;
    1213
    1314import org.openstreetmap.josm.command.ChangeCommand;
     
    2425import org.openstreetmap.josm.data.validation.Test;
    2526import org.openstreetmap.josm.data.validation.TestError;
    26 import org.openstreetmap.josm.data.validation.util.Bag;
    2727import org.openstreetmap.josm.gui.progress.ProgressMonitor;
     28import org.openstreetmap.josm.tools.MultiMap;
    2829
    2930/**
     
    3637        public List<LatLon> coor;
    3738        public Map<String, String> keys;
    38         public WayPair(List<LatLon> _coor,Map<String, String> _keys) {
     39        public WayPair(List<LatLon> _coor, Map<String, String> _keys) {
    3940            coor=_coor;
    4041            keys=_keys;
     
    4344        @Override
    4445        public int hashCode() {
    45             return coor.hashCode()+keys.hashCode();
     46            return coor.hashCode() + keys.hashCode();
    4647        }
    4748
     
    5859
    5960    /** Bag of all ways */
    60     Bag<WayPair, OsmPrimitive> ways;
     61    MultiMap<WayPair, OsmPrimitive> ways;
    6162
    6263    /**
     
    7273    public void startTest(ProgressMonitor monitor) {
    7374        super.startTest(monitor);
    74         ways = new Bag<WayPair, OsmPrimitive>(1000);
     75        ways = new MultiMap<WayPair, OsmPrimitive>(1000);
    7576    }
    7677
     
    7879    public void endTest() {
    7980        super.endTest();
    80         for (List<OsmPrimitive> duplicated : ways.values()) {
     81        for (Set<OsmPrimitive> duplicated : ways.values()) {
    8182            if (duplicated.size() > 1) {
    8283                TestError testError = new TestError(this, Severity.ERROR, tr("Duplicated ways"), DUPLICATE_WAY, duplicated);
     
    9192        if (!w.isUsable())
    9293            return;
    93         List<Node> wNodes=w.getNodes();
    94         Vector<LatLon> wLat=new Vector<LatLon>(wNodes.size());
     94        List<Node> wNodes = w.getNodes();
     95        List<LatLon> wLat = new ArrayList<LatLon>(wNodes.size());
    9596        for (int i=0;i<wNodes.size();i++) {
    9697             wLat.add(wNodes.get(i).getCoor());
    9798        }
    98         Map<String, String> wkeys=w.getKeys();
     99        Map<String, String> wkeys = w.getKeys();
    99100        wkeys.remove("created_by");
    100         WayPair wKey=new WayPair(wLat,wkeys);
    101         ways.add(wKey, w);
     101        WayPair wKey = new WayPair(wLat, wkeys);
     102        ways.put(wKey, w);
    102103    }
    103104
  • trunk/src/org/openstreetmap/josm/data/validation/tests/OverlappingWays.java

    r3671 r3674  
    55
    66import java.util.ArrayList;
     7import java.util.Collection;
    78import java.util.HashMap;
     9import java.util.LinkedHashSet;
    810import java.util.List;
    911import java.util.Map;
     
    1719import org.openstreetmap.josm.data.validation.Test;
    1820import org.openstreetmap.josm.data.validation.TestError;
    19 import org.openstreetmap.josm.data.validation.util.Bag;
    2021import org.openstreetmap.josm.gui.progress.ProgressMonitor;
     22import org.openstreetmap.josm.tools.MultiMap;
    2123import org.openstreetmap.josm.tools.Pair;
    2224
     
    2931   
    3032    /** Bag of all way segments */
    31     Bag<Pair<Node,Node>, WaySegment> nodePairs;
     33    MultiMap<Pair<Node,Node>, WaySegment> nodePairs;
    3234
    3335    protected static int OVERLAPPING_HIGHWAY = 101;
     
    4951    public void startTest(ProgressMonitor monitor)  {
    5052        super.startTest(monitor);
    51         nodePairs = new Bag<Pair<Node,Node>, WaySegment>(1000);
     53        nodePairs = new MultiMap<Pair<Node,Node>, WaySegment>(1000);
    5254    }
    5355
    5456    @Override
    5557    public void endTest() {
    56         Map<List<Way>, List<WaySegment>> ways_seen = new HashMap<List<Way>, List<WaySegment>>(500);
     58        Map<List<Way>, LinkedHashSet<WaySegment>> ways_seen = new HashMap<List<Way>, LinkedHashSet<WaySegment>>(500);
    5759
    58         for (List<WaySegment> duplicated : nodePairs.values()) {
     60        for (LinkedHashSet<WaySegment> duplicated : nodePairs.values()) {
    5961            int ways = duplicated.size();
    6062
     
    6264                List<OsmPrimitive> prims = new ArrayList<OsmPrimitive>();
    6365                List<Way> current_ways = new ArrayList<Way>();
    64                 List<WaySegment> highlight;
     66                Collection<WaySegment> highlight;
    6567                int highway = 0;
    6668                int railway = 0;
     
    148150                continue;
    149151            }
    150             nodePairs.add(Pair.sort(new Pair<Node,Node>(lastN, n)),
     152            nodePairs.put(Pair.sort(new Pair<Node,Node>(lastN, n)),
    151153                new WaySegment(w, i));
    152154            lastN = n;
  • trunk/src/org/openstreetmap/josm/data/validation/tests/SimilarNamedWays.java

    r3671 r3674  
    1515import org.openstreetmap.josm.data.validation.Test;
    1616import org.openstreetmap.josm.data.validation.TestError;
    17 import org.openstreetmap.josm.data.validation.util.Bag;
    1817import org.openstreetmap.josm.data.validation.util.ValUtil;
    1918import org.openstreetmap.josm.gui.progress.ProgressMonitor;
     19import org.openstreetmap.josm.tools.MultiMap;
     20import org.openstreetmap.josm.tools.Utils;
    2021
    2122/**
     
    3233    Map<Point2D,List<Way>> cellWays;
    3334    /** The already detected errors */
    34     Bag<Way, Way> errorWays;
     35    MultiMap<Way, Way> errorWays;
    3536
    3637    /**
     
    4647        super.startTest(monitor);
    4748        cellWays = new HashMap<Point2D,List<Way>>(1000);
    48         errorWays = new Bag<Way, Way>();
     49        errorWays = new MultiMap<Way, Way>();
    4950    }
    5051
     
    8384                    primitives.add(w2);
    8485                    errors.add(new TestError(this, Severity.WARNING, tr("Similarly named ways"), SIMILAR_NAMED, primitives));
    85                     errorWays.add(w, w2);
     86                    errorWays.put(w, w2);
    8687                }
    8788            }
     
    142143
    143144                // Step 6
    144                 d[i][j] = min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost);
     145                d[i][j] = Utils.min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost);
    145146            }
    146147        }
     
    149150        return d[n][m];
    150151    }
    151 
    152     /** // FIXME: move to utils
    153      * Get minimum of three values
    154      * @param a First value
    155      * @param b Second value
    156      * @param c Third value
    157      * @return The minimum of the three values
    158      */
    159     private static int min(int a, int b, int c) {
    160         int mi = a;
    161         if (b < mi) {
    162             mi = b;
    163         } if (c < mi) {
    164             mi = c;
    165         }
    166         return mi;
    167     }
    168152}
  • trunk/src/org/openstreetmap/josm/data/validation/tests/TagChecker.java

    r3673 r3674  
    2424import java.util.Map;
    2525import java.util.Map.Entry;
     26import java.util.Set;
    2627import java.util.regex.Matcher;
    2728import java.util.regex.Pattern;
     
    5051import org.openstreetmap.josm.data.validation.Test;
    5152import org.openstreetmap.josm.data.validation.TestError;
    52 import org.openstreetmap.josm.data.validation.util.Bag;
    5353import org.openstreetmap.josm.data.validation.util.Entities;
    5454import org.openstreetmap.josm.data.validation.util.ValUtil;
     
    5959import org.openstreetmap.josm.io.MirroredInputStream;
    6060import org.openstreetmap.josm.tools.GBC;
     61import org.openstreetmap.josm.tools.MultiMap;
    6162
    6263/**
     
    7576    protected static Map<String, String> spellCheckKeyData;
    7677    /** The spell check preset values */
    77     protected static Bag<String, String> presetsValueData;
     78    protected static MultiMap<String, String> presetsValueData;
    7879    /** The TagChecker data */
    7980    protected static List<CheckerData> checkerData = new ArrayList<CheckerData>();
     
    294295        Collection<TaggingPreset> presets = TaggingPresetPreference.taggingPresets;
    295296        if (presets != null) {
    296             presetsValueData = new Bag<String, String>();
     297            presetsValueData = new MultiMap<String, String>();
    297298            for (String a : OsmPrimitive.getUninterestingKeys()) {
    298                 presetsValueData.add(a);
     299                presetsValueData.putVoid(a);
    299300            }
    300301            // TODO directionKeys are no longer in OsmPrimitive (search pattern is used instead)
     
    304305            for (String a : Main.pref.getCollection(ValidatorPreference.PREFIX + ".knownkeys",
    305306                    Arrays.asList(new String[]{"is_in", "int_ref", "fixme", "population"}))) {
    306                 presetsValueData.add(a);
     307                presetsValueData.putVoid(a);
    307308            }
    308309            for (TaggingPreset p : presets) {
     
    312313                        if (combo.values != null) {
    313314                            for(String value : combo.values.split(",")) {
    314                                 presetsValueData.add(combo.key, value);
     315                                presetsValueData.put(combo.key, value);
    315316                            }
    316317                        }
    317318                    } else if (i instanceof TaggingPreset.Key) {
    318319                        TaggingPreset.Key k = (TaggingPreset.Key) i;
    319                         presetsValueData.add(k.key, k.value);
     320                        presetsValueData.put(k.key, k.value);
    320321                    } else if (i instanceof TaggingPreset.Text) {
    321322                        TaggingPreset.Text k = (TaggingPreset.Text) i;
    322                         presetsValueData.add(k.key);
     323                        presetsValueData.putVoid(k.key);
    323324                    } else if (i instanceof TaggingPreset.Check) {
    324325                        TaggingPreset.Check k = (TaggingPreset.Check) i;
    325                         presetsValueData.add(k.key, "yes");
    326                         presetsValueData.add(k.key, "no");
     326                        presetsValueData.put(k.key, "yes");
     327                        presetsValueData.put(k.key, "no");
    327328                    }
    328329                }
     
    366367    private void checkPrimitive(OsmPrimitive p) {
    367368        // Just a collection to know if a primitive has been already marked with error
    368         Bag<OsmPrimitive, String> withErrors = new Bag<OsmPrimitive, String>();
     369        MultiMap<OsmPrimitive, String> withErrors = new MultiMap<OsmPrimitive, String>();
    369370
    370371        if (checkComplex) {
     
    400401                    errors.add( new TestError(this, Severity.ERROR, tr("Illegal tag/value combinations"),
    401402                            tr("Illegal tag/value combinations"), tr("Illegal tag/value combinations"), 1272, p) );
    402                     withErrors.add(p, "TC");
     403                    withErrors.put(p, "TC");
    403404                }
    404405            }
     
    409410                    errors.add( new TestError(this, d.getSeverity(), tr("Illegal tag/value combinations"),
    410411                            d.getDescription(), d.getDescriptionOrig(), d.getCode(), p) );
    411                     withErrors.add(p, "TC");
     412                    withErrors.put(p, "TC");
    412413                }
    413414            }
     
    422423                errors.add( new TestError(this, Severity.WARNING, tr("Tag value contains character with code less than 0x20"),
    423424                        tr(s, key), MessageFormat.format(s, key), LOW_CHAR_VALUE, p) );
    424                 withErrors.add(p, "ICV");
     425                withErrors.put(p, "ICV");
    425426            }
    426427            if (checkKeys && (containsLow(key)) && !withErrors.contains(p, "ICK")) {
    427428                errors.add( new TestError(this, Severity.WARNING, tr("Tag key contains character with code less than 0x20"),
    428429                        tr(s, key), MessageFormat.format(s, key), LOW_CHAR_KEY, p) );
    429                 withErrors.add(p, "ICK");
     430                withErrors.put(p, "ICK");
    430431            }
    431432            if (checkValues && (value!=null && value.length() > 255) && !withErrors.contains(p, "LV")) {
    432433                errors.add( new TestError(this, Severity.ERROR, tr("Tag value longer than allowed"),
    433434                        tr(s, key), MessageFormat.format(s, key), LONG_VALUE, p) );
    434                 withErrors.add(p, "LV");
     435                withErrors.put(p, "LV");
    435436            }
    436437            if (checkKeys && (key!=null && key.length() > 255) && !withErrors.contains(p, "LK")) {
    437438                errors.add( new TestError(this, Severity.ERROR, tr("Tag key longer than allowed"),
    438439                        tr(s, key), MessageFormat.format(s, key), LONG_KEY, p) );
    439                 withErrors.add(p, "LK");
     440                withErrors.put(p, "LK");
    440441            }
    441442            if (checkValues && (value==null || value.trim().length() == 0) && !withErrors.contains(p, "EV")) {
    442443                errors.add( new TestError(this, Severity.WARNING, tr("Tags with empty values"),
    443444                        tr(s, key), MessageFormat.format(s, key), EMPTY_VALUES, p) );
    444                 withErrors.add(p, "EV");
     445                withErrors.put(p, "EV");
    445446            }
    446447            if (checkKeys && spellCheckKeyData.containsKey(key) && !withErrors.contains(p, "IPK")) {
    447448                errors.add( new TestError(this, Severity.WARNING, tr("Invalid property key"),
    448449                        tr(s, key), MessageFormat.format(s, key), INVALID_KEY, p) );
    449                 withErrors.add(p, "IPK");
     450                withErrors.put(p, "IPK");
    450451            }
    451452            if (checkKeys && key.indexOf(" ") >= 0 && !withErrors.contains(p, "IPK")) {
    452453                errors.add( new TestError(this, Severity.WARNING, tr("Invalid white space in property key"),
    453454                        tr(s, key), MessageFormat.format(s, key), INVALID_KEY_SPACE, p) );
    454                 withErrors.add(p, "IPK");
     455                withErrors.put(p, "IPK");
    455456            }
    456457            if (checkValues && value != null && (value.startsWith(" ") || value.endsWith(" ")) && !withErrors.contains(p, "SPACE")) {
    457458                errors.add( new TestError(this, Severity.OTHER, tr("Property values start or end with white space"),
    458459                        tr(s, key), MessageFormat.format(s, key), INVALID_SPACE, p) );
    459                 withErrors.add(p, "SPACE");
     460                withErrors.put(p, "SPACE");
    460461            }
    461462            if (checkValues && value != null && !value.equals(entities.unescape(value)) && !withErrors.contains(p, "HTML")) {
    462463                errors.add( new TestError(this, Severity.OTHER, tr("Property values contain HTML entity"),
    463464                        tr(s, key), MessageFormat.format(s, key), INVALID_HTML, p) );
    464                 withErrors.add(p, "HTML");
     465                withErrors.put(p, "HTML");
    465466            }
    466467            if (checkValues && value != null && value.length() > 0 && presetsValueData != null) {
    467                 List<String> values = presetsValueData.get(key);
     468                Set<String> values = presetsValueData.get(key);
    468469                if (values == null) {
    469470                    boolean ignore = false;
     
    487488                        errors.add( new TestError(this, Severity.OTHER, tr("Presets do not contain property key"),
    488489                                tr(i, key), MessageFormat.format(i, key), INVALID_VALUE, p) );
    489                         withErrors.add(p, "UPK");
     490                        withErrors.put(p, "UPK");
    490491                    }
    491492                } else if (values.size() > 0 && !values.contains(prop.getValue())) {
     
    507508                        errors.add( new TestError(this, Severity.OTHER, tr("Presets do not contain property value"),
    508509                                tr(i, prop.getValue(), key), MessageFormat.format(i, prop.getValue(), key), INVALID_VALUE, p) );
    509                         withErrors.add(p, "UPV");
     510                        withErrors.put(p, "UPV");
    510511                    }
    511512                }
     
    518519                    errors.add(new TestError(this, Severity.OTHER,
    519520                            tr("FIXMES"), FIXME, p));
    520                     withErrors.add(p, "FIXME");
     521                    withErrors.put(p, "FIXME");
    521522                }
    522523            }
     
    755756        List<Command> commands = new ArrayList<Command>(50);
    756757
    757         int i = -1;
    758         List<? extends OsmPrimitive> primitives = testError.getPrimitives();
     758        Collection<? extends OsmPrimitive> primitives = testError.getPrimitives();
    759759        for (OsmPrimitive p : primitives) {
    760             i++;
    761760            Map<String, String> tags = p.getKeys();
    762761            if (tags == null || tags.isEmpty()) {
     
    768767                String value = prop.getValue();
    769768                if (value == null || value.trim().length() == 0) {
    770                     commands.add(new ChangePropertyCommand(Collections.singleton(primitives.get(i)), key, null));
     769                    commands.add(new ChangePropertyCommand(Collections.singleton(p), key, null));
    771770                } else if (value.startsWith(" ") || value.endsWith(" ")) {
    772                     commands.add(new ChangePropertyCommand(Collections.singleton(primitives.get(i)), key, value.trim()));
     771                    commands.add(new ChangePropertyCommand(Collections.singleton(p), key, value.trim()));
    773772                } else if (key.startsWith(" ") || key.endsWith(" ")) {
    774                     commands.add(new ChangePropertyKeyCommand(Collections.singleton(primitives.get(i)), key, key.trim()));
     773                    commands.add(new ChangePropertyKeyCommand(Collections.singleton(p), key, key.trim()));
    775774                } else {
    776775                    String evalue = entities.unescape(value);
    777776                    if (!evalue.equals(value)) {
    778                         commands.add(new ChangePropertyCommand(Collections.singleton(primitives.get(i)), key, evalue));
     777                        commands.add(new ChangePropertyCommand(Collections.singleton(p), key, evalue));
    779778                    } else {
    780779                        String replacementKey = spellCheckKeyData.get(key);
    781780                        if (replacementKey != null) {
    782                             commands.add(new ChangePropertyKeyCommand(Collections.singleton(primitives.get(i)),
     781                            commands.add(new ChangePropertyKeyCommand(Collections.singleton(p),
    783782                                    key, replacementKey));
    784783                        }
  • trunk/src/org/openstreetmap/josm/data/validation/tests/UnclosedWays.java

    r3671 r3674  
    1717import org.openstreetmap.josm.data.validation.Test;
    1818import org.openstreetmap.josm.data.validation.TestError;
    19 import org.openstreetmap.josm.data.validation.util.Bag;
    2019import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    2120
     
    2625 */
    2726public class UnclosedWays extends Test {
    28     /** The already detected errors */
    29     protected Bag<Way, Way> errorWays;
    3027
    3128    /**
     
    3936    public void startTest(ProgressMonitor monitor) {
    4037        super.startTest(monitor);
    41         errorWays = new Bag<Way, Way>();
    4238    }
    4339
    4440    @Override
    4541    public void endTest() {
    46         errorWays = null;
    4742        super.endTest();
    4843    }
     
    133128            errors.add(new TestError(this, Severity.WARNING, tr("Unclosed way"),
    134129                            type, etype, mode, primitives, highlight));
    135             errorWays.add(w, w);
    136130        }
    137131    }
  • trunk/src/org/openstreetmap/josm/data/validation/tests/WronglyOrderedWays.java

    r3673 r3674  
    1212import org.openstreetmap.josm.data.validation.Test;
    1313import org.openstreetmap.josm.data.validation.TestError;
    14 import org.openstreetmap.josm.data.validation.util.Bag;
    1514import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    1615
     
    2625    protected static int WRONGLY_ORDERED_LAND  = 1003;
    2726
    28     /** The already detected errors */
    29     protected Bag<Way, Way> errorWays;
    30 
    3127    /**
    3228     * Constructor
     
    4036    public void startTest(ProgressMonitor monitor) {
    4137        super.startTest(monitor);
    42         errorWays = new Bag<Way, Way>();
    4338    }
    4439
    4540    @Override
    4641    public void endTest() {
    47         errorWays = null;
    4842        super.endTest();
    4943    }
     
    9690                primitives.add(w);
    9791                errors.add( new TestError(this, Severity.OTHER, errortype, type, primitives) );
    98                 errorWays.add(w,w);
    9992            }
    10093        }
  • trunk/src/org/openstreetmap/josm/gui/dialogs/validator/ValidatorTreePanel.java

    r3671 r3674  
    88import java.util.HashMap;
    99import java.util.HashSet;
     10import java.util.LinkedHashSet;
    1011import java.util.List;
    1112import java.util.Map;
     
    2324import org.openstreetmap.josm.data.validation.Severity;
    2425import org.openstreetmap.josm.data.validation.TestError;
    25 import org.openstreetmap.josm.data.validation.util.Bag;
    2626import org.openstreetmap.josm.data.validation.util.MultipleNameVisitor;
     27import org.openstreetmap.josm.tools.MultiMap;
    2728
    2829/**
     
    138139        }
    139140
    140         Map<Severity, Bag<String, TestError>> errorTree = new HashMap<Severity, Bag<String, TestError>>();
    141         Map<Severity, HashMap<String, Bag<String, TestError>>> errorTreeDeep = new HashMap<Severity, HashMap<String, Bag<String, TestError>>>();
     141        Map<Severity, MultiMap<String, TestError>> errorTree = new HashMap<Severity, MultiMap<String, TestError>>();
     142        Map<Severity, HashMap<String, MultiMap<String, TestError>>> errorTreeDeep = new HashMap<Severity, HashMap<String, MultiMap<String, TestError>>>();
    142143        for (Severity s : Severity.values()) {
    143             errorTree.put(s, new Bag<String, TestError>(20));
    144             errorTreeDeep.put(s, new HashMap<String, Bag<String, TestError>>());
     144            errorTree.put(s, new MultiMap<String, TestError>(20));
     145            errorTreeDeep.put(s, new HashMap<String, MultiMap<String, TestError>>());
    145146        }
    146147
     
    165166            }
    166167            if (d != null) {
    167                 Bag<String, TestError> b = errorTreeDeep.get(s).get(m);
     168                MultiMap<String, TestError> b = errorTreeDeep.get(s).get(m);
    168169                if (b == null) {
    169                     b = new Bag<String, TestError>(20);
     170                    b = new MultiMap<String, TestError>(20);
    170171                    errorTreeDeep.get(s).put(m, b);
    171172                }
    172                 b.add(d, e);
     173                b.put(d, e);
    173174            } else {
    174                 errorTree.get(s).add(m, e);
     175                errorTree.get(s).put(m, e);
    175176            }
    176177        }
     
    178179        List<TreePath> expandedPaths = new ArrayList<TreePath>();
    179180        for (Severity s : Severity.values()) {
    180             Bag<String, TestError> severityErrors = errorTree.get(s);
    181             Map<String, Bag<String, TestError>> severityErrorsDeep = errorTreeDeep.get(s);
     181            MultiMap<String, TestError> severityErrors = errorTree.get(s);
     182            Map<String, MultiMap<String, TestError>> severityErrorsDeep = errorTreeDeep.get(s);
    182183            if (severityErrors.isEmpty() && severityErrorsDeep.isEmpty()) {
    183184                continue;
     
    192193            }
    193194
    194             for (Entry<String, List<TestError>> msgErrors : severityErrors.entrySet()) {
     195            for (Entry<String, LinkedHashSet<TestError>> msgErrors : severityErrors.entrySet()) {
    195196                // Message node
    196                 List<TestError> errs = msgErrors.getValue();
     197                Set<TestError> errs = msgErrors.getValue();
    197198                String msg = msgErrors.getKey() + " (" + errs.size() + ")";
    198199                DefaultMutableTreeNode messageNode = new DefaultMutableTreeNode(msg);
     
    209210                }
    210211            }
    211             for (Entry<String, Bag<String, TestError>> bag : severityErrorsDeep.entrySet()) {
     212            for (Entry<String, MultiMap<String, TestError>> bag : severityErrorsDeep.entrySet()) {
    212213                // Group node
    213                 Bag<String, TestError> errorlist = bag.getValue();
     214                MultiMap<String, TestError> errorlist = bag.getValue();
    214215                DefaultMutableTreeNode groupNode = null;
    215216                if (errorlist.size() > 1) {
     
    222223                }
    223224
    224                 for (Entry<String, List<TestError>> msgErrors : errorlist.entrySet()) {
     225                for (Entry<String, LinkedHashSet<TestError>> msgErrors : errorlist.entrySet()) {
    225226                    // Message node
    226                     List<TestError> errs = msgErrors.getValue();
     227                    Set<TestError> errs = msgErrors.getValue();
    227228                    String msg;
    228229                    if (groupNode != null) {
  • trunk/src/org/openstreetmap/josm/gui/layer/ValidatorLayer.java

    r3671 r3674  
    1919import org.openstreetmap.josm.data.validation.Severity;
    2020import org.openstreetmap.josm.data.validation.TestError;
    21 import org.openstreetmap.josm.data.validation.util.Bag;
    2221import org.openstreetmap.josm.gui.MapView;
    2322import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
     
    2524import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
    2625import org.openstreetmap.josm.tools.ImageProvider;
     26import org.openstreetmap.josm.tools.MultiMap;
    2727
    2828/**
     
    7878    @Override
    7979    public String getToolTipText() {
    80         Bag<Severity, TestError> errorTree = new Bag<Severity, TestError>();
     80        MultiMap<Severity, TestError> errorTree = new MultiMap<Severity, TestError>();
    8181        List<TestError> errors = Main.map.validatorDialog.tree.getErrors();
    8282        for (TestError e : errors) {
    83             errorTree.add(e.getSeverity(), e);
     83            errorTree.put(e.getSeverity(), e);
    8484        }
    8585
  • trunk/src/org/openstreetmap/josm/tools/MultiMap.java

    r3637 r3674  
    22package org.openstreetmap.josm.tools;
    33
     4import java.util.Collection;
    45import java.util.HashMap;
    56import java.util.LinkedHashSet;
    67import java.util.Map;
     8import java.util.Map.Entry;
    79import java.util.Set;
    810
    911/**
    10  * Maps keys to ordered sets of values.
     12 * MultiMap - maps keys to multiple values
     13 *
     14 * Corresponds to Google guava LinkedHashMultimap and Apache Collections MultiValueMap
     15 * but it is an independent (simplistic) implementation.
     16 *
    1117 */
    12 public class MultiMap<A, B>  {
     18public class MultiMap<A, B> {
    1319
    14     private final Map<A, LinkedHashSet<B>> map = new HashMap<A, LinkedHashSet<B>>();
     20    private final Map<A, LinkedHashSet<B>> map;
     21
     22    public MultiMap() {
     23        map = new HashMap<A, LinkedHashSet<B>>();
     24    }
     25
     26    public MultiMap(int capacity) {
     27        map = new HashMap<A, LinkedHashSet<B>>(capacity);
     28    }
     29
    1530    /**
    1631     * Map a key to a value. Can be called multiple times with the same key, but different value.
     
    2641
    2742    /**
    28      * Put a key that maps to nothing.
     43     * Put a key that maps to nothing. (Only if it is not already in the map)
     44     * Afterwards containsKey(key) will return true and get(key) will return
     45     * an empty Set instead of null.
    2946     */
    3047    public void putVoid(A key) {
     
    3552
    3653    /**
    37      * Returns a list of values for the given key
    38      * or an empty list, if it maps to nothing.
     54     * Get the keySet
     55     */
     56    public Set<A> keySet() {
     57        return map.keySet();
     58    }
     59
     60    /**
     61     * Return the Set associated with the given key. Result is null if
     62     * nothing has been mapped to this key. Modifications of the returned list
     63     * changes the underling map, but you should better not do that.
     64     */
     65    public Set<B> get(A key) {
     66        return map.get(key);
     67    }
     68
     69    /**
     70     * Like get, but returns an empty Set if nothing has been mapped to the key.
    3971     */
    4072    public LinkedHashSet<B> getValues(A key) {
     
    4476    }
    4577
    46     public Set<A> keySet() {
    47         return map.keySet();
     78    public boolean isEmpty() {
     79        return map.isEmpty();
    4880    }
    4981
    50     public Set<B> get(A key) {
    51         return map.get(key);
     82    public boolean containsKey(A key) {
     83        return map.containsKey(key);
     84    }
     85
     86    /**
     87     * Returns true if the multimap contains a value for a key
     88     * @param key The key
     89     * @param value The value
     90     * @return true if the key contains the value
     91     */
     92    public boolean contains(A key, B value) {
     93        Set<B> values = get(key);
     94        return (values == null) ? false : values.contains(value);
     95    }
     96
     97    public void clear() {
     98        map.clear();
     99    }
     100
     101    public Set<Entry<A, LinkedHashSet<B>>> entrySet() {
     102        return map.entrySet();
     103    }
     104
     105    /**
     106     * number of keys
     107     */
     108    public int size() {
     109        return map.size();
     110    }
     111
     112    /**
     113     * returns a collection of all value sets
     114     */
     115    public Collection<LinkedHashSet<B>> values() {
     116        return map.values();
    52117    }
    53118}
  • trunk/src/org/openstreetmap/josm/tools/Utils.java

    r3504 r3674  
    1111        return false;
    1212    }
     13
     14    /**
     15     * Get minimum of 3 values
     16     */
     17    public static int min(int a, int b, int c) {
     18        if (b < c) {
     19            if (a < b)
     20                return a;
     21            return b;
     22        } else {
     23            if (a < c) {
     24                return a;
     25            }
     26            return c;
     27        }
     28    }
    1329}
Note: See TracChangeset for help on using the changeset viewer.