source: josm/trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitiveComparator.java@ 9600

Last change on this file since 9600 was 8308, checked in by Don-vip, 9 years ago

fix potential NPEs and Sonar issues related to serialization

  • Property svn:eol-style set to native
File size: 3.3 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.osm;
3
4import java.io.Serializable;
5import java.util.Comparator;
6import java.util.HashMap;
7import java.util.Map;
8
9import org.openstreetmap.josm.gui.DefaultNameFormatter;
10
11/**
12 * Comparator, comparing pritimives by:<ul>
13 * <li>type and ids in "quick" mode</li>
14 * <li>type and objects display names instead</li>
15 * </ul>
16 * @since 4113
17 */
18public class OsmPrimitiveComparator implements Comparator<OsmPrimitive>, Serializable {
19
20 private static final long serialVersionUID = 1L;
21
22 private final Map<OsmPrimitive, String> cache = new HashMap<>();
23 private final boolean relationsFirst;
24 private final boolean quick;
25
26 /**
27 * Constructs a new {@code OsmPrimitiveComparator}.
28 */
29 public OsmPrimitiveComparator() {
30 this(false, false);
31 }
32
33 /**
34 * Constructs a new {@code OsmPrimitiveComparator}.
35 * @param quick if {@code true}, sorts by type and ids (fast), otherwise sort by type and display names (slower)
36 * @param relationsFirst if {@code true}, always list relations first
37 */
38 public OsmPrimitiveComparator(boolean quick, boolean relationsFirst) {
39 this.quick = quick;
40 this.relationsFirst = relationsFirst;
41 }
42
43 private String cachedName(OsmPrimitive p) {
44 String name = cache.get(p);
45 if (name == null) {
46 name = p.getDisplayName(DefaultNameFormatter.getInstance());
47 cache.put(p, name);
48 }
49 return name;
50 }
51
52 private int compareName(OsmPrimitive a, OsmPrimitive b) {
53 String an = cachedName(a);
54 String bn = cachedName(b);
55 // make sure display names starting with digits are the end of the list
56 if (Character.isDigit(an.charAt(0)) && Character.isDigit(bn.charAt(0)))
57 return an.compareTo(bn);
58 else if (Character.isDigit(an.charAt(0)) && !Character.isDigit(bn.charAt(0)))
59 return 1;
60 else if (!Character.isDigit(an.charAt(0)) && Character.isDigit(bn.charAt(0)))
61 return -1;
62 return an.compareTo(bn);
63 }
64
65 private static int compareId(OsmPrimitive a, OsmPrimitive b) {
66 long idA = a.getUniqueId();
67 long idB = b.getUniqueId();
68 if (idA < idB) return -1;
69 if (idA > idB) return 1;
70 return 0;
71 }
72
73 private int compareType(OsmPrimitive a, OsmPrimitive b) {
74 if (relationsFirst) {
75 // show relations before ways, then nodes
76 if (a.getType().equals(OsmPrimitiveType.RELATION)) return -1;
77 if (a.getType().equals(OsmPrimitiveType.NODE)) return 1;
78 // a is a way
79 if (b.getType().equals(OsmPrimitiveType.RELATION)) return 1;
80 // b is a node
81 } else {
82 // show ways before relations, then nodes
83 if (a.getType().equals(OsmPrimitiveType.WAY)) return -1;
84 if (a.getType().equals(OsmPrimitiveType.NODE)) return 1;
85 // a is a relation
86 if (b.getType().equals(OsmPrimitiveType.WAY)) return 1;
87 // b is a node
88 }
89 return -1;
90 }
91
92 @Override
93 public int compare(OsmPrimitive a, OsmPrimitive b) {
94 if (a.getType().equals(b.getType()))
95 return quick ? compareId(a, b) : compareName(a, b);
96 return compareType(a, b);
97 }
98}
Note: See TracBrowser for help on using the repository browser.