001    // License: GPL. See LICENSE file for details.
002    package org.openstreetmap.josm.data.validation.tests;
003    
004    import static org.openstreetmap.josm.tools.I18n.tr;
005    
006    import java.util.ArrayList;
007    import java.util.HashMap;
008    import java.util.HashSet;
009    import java.util.List;
010    import java.util.Map;
011    
012    import org.openstreetmap.josm.data.osm.Node;
013    import org.openstreetmap.josm.data.validation.Severity;
014    import org.openstreetmap.josm.data.validation.Test;
015    import org.openstreetmap.josm.data.validation.TestError;
016    import org.openstreetmap.josm.gui.progress.ProgressMonitor;
017    
018    public class NodesWithSameName extends Test {
019        protected static final int SAME_NAME = 801;
020    
021        private Map<String, List<Node>> namesToNodes;
022    
023        public NodesWithSameName() {
024            super(tr("Nodes with same name"),
025                    tr("This test finds nodes that have the same name (might be duplicates)."));
026        }
027    
028        @Override public void startTest(ProgressMonitor monitor) {
029            super.startTest(monitor);
030            namesToNodes = new HashMap<String, List<Node>>();
031        }
032    
033        @Override public void visit(Node n) {
034            if (!n.isUsable()) return;
035    
036            String name = n.get("name");
037            String sign = n.get("traffic_sign");
038            String highway = n.get("highway");
039            if (name == null
040                    || (sign != null && sign.equals("city_limit"))
041                    || (highway != null && highway.equals("bus_stop")))
042                return;
043    
044            List<Node> nodes = namesToNodes.get(name);
045            if (nodes == null) {
046                namesToNodes.put(name, nodes = new ArrayList<Node>());
047            }
048    
049            nodes.add(n);
050        }
051    
052        @Override public void endTest() {
053            for (List<Node> nodes : namesToNodes.values()) {
054                if (nodes.size() > 1) {
055                    // Report the same-name nodes, unless each has a unique ref=*.
056                    HashSet<String> refs = new HashSet<String>();
057    
058                    for (Node n : nodes) {
059                        String ref = n.get("ref");
060                        if (ref == null || !refs.add(ref)) {
061                            errors.add(new TestError(this, Severity.OTHER,
062                                    tr("Nodes with same name"), SAME_NAME, nodes));
063                            break;
064                        }
065                    }
066                }
067            }
068            super.endTest();
069            namesToNodes = null;
070        }
071    }