]>
Commit | Line | Data |
---|---|---|
1b2798f6 EK |
1 | package no.uio.ifi.refaktor.prefix; |
2 | ||
3 | import java.util.HashMap; | |
4 | import java.util.Iterator; | |
5 | import java.util.LinkedList; | |
6 | import java.util.Map; | |
7 | ||
8 | /** | |
9 | * A set for collecting prefixes (see {@link Prefix}}). | |
10 | * | |
11 | * It can increment a counter in a prefix each time an equal | |
12 | * prefix is registered with the set. In addition | |
13 | * it can produce the set that is this set, minus the | |
14 | * prefixes from another set that are enclosed by the | |
15 | * prefixes in this set. | |
16 | */ | |
17 | public class PrefixSet implements Iterable<Prefix> { | |
18 | ||
19 | private final Map<Prefix, Prefix> prefixes = new HashMap<Prefix, Prefix>(); | |
20 | ||
21 | public PrefixSet() { | |
22 | } | |
23 | ||
24 | private PrefixSet(PrefixSet initialElements) { | |
25 | prefixes.putAll(initialElements.prefixes); | |
26 | } | |
27 | ||
28 | public void add(Prefix prefix) { | |
29 | assert prefix != null: "A " + this.getClass().getName() + " will not accept a null value"; | |
30 | ||
31 | if (!contains(prefix)) | |
32 | prefixes.put(prefix, prefix); | |
33 | } | |
34 | ||
35 | private void remove(Prefix prefix) { | |
36 | prefixes.remove(prefix); | |
37 | } | |
38 | ||
39 | public boolean contains(Prefix prefix) { | |
40 | boolean res = prefixes.containsKey(prefix); | |
41 | // TODO: Show prefixes in debugging output as well? | |
42 | if (res) | |
43 | assert get(prefix) != null : prefix; | |
44 | else | |
45 | assert get(prefix) == null : prefix; | |
46 | return res; | |
47 | } | |
48 | ||
49 | @Override | |
50 | public Iterator<Prefix> iterator() { | |
51 | return prefixes.values().iterator(); | |
52 | } | |
53 | ||
54 | public boolean isEmpty() { | |
55 | return prefixes.isEmpty(); | |
56 | } | |
57 | ||
58 | public LinkedList<Prefix> toList() { | |
59 | return new LinkedList<Prefix>(prefixes.values()); | |
60 | } | |
61 | ||
62 | public Prefix get(Prefix prefix) { | |
63 | return prefixes.get(prefix); | |
64 | } | |
65 | ||
66 | public void registerAllSubPrefixesOf(Prefix prefix) { | |
67 | for (Prefix p: prefix.getSubPrefixes()) | |
68 | register(p); | |
69 | } | |
70 | ||
71 | private void register(Prefix prefix) { | |
72 | Prefix prefixFromMap = get(prefix); | |
73 | if (prefixFromMap != null) { | |
74 | prefixFromMap.incrementCount(); | |
75 | } else { | |
76 | add(prefix); | |
77 | } | |
78 | } | |
79 | ||
80 | @Override | |
81 | public String toString() { | |
82 | String str = ""; | |
83 | for (Prefix p: this) { | |
84 | str += p.toString() + " (" + p.getCount() + ")\n"; | |
85 | } | |
86 | return str; | |
87 | } | |
88 | ||
89 | /** | |
90 | * Creates a set of prefixes that are the prefixes of this set, | |
91 | * minus the prefixes that are enclosing the prefixes of the | |
92 | * other set. A prefix is enclosing another if the other prefix | |
93 | * is a sub-prefix of the first prefix. | |
94 | * | |
95 | * @param other The set of prefixes that are to be checked against this one. | |
96 | * @return The set of prefixes that are not enclosing the ones in the other set. | |
97 | */ | |
98 | public PrefixSet minusEnclosedPrefixesFrom(PrefixSet other) { | |
99 | PrefixSet prefixSet = shallowCopy(); | |
100 | removeEnclosingPrefixesFromPrefixSet(prefixSet, other); | |
101 | return prefixSet; | |
102 | } | |
103 | ||
104 | private PrefixSet shallowCopy() { | |
105 | return new PrefixSet(this); | |
106 | } | |
107 | ||
108 | private void removeEnclosingPrefixesFromPrefixSet(PrefixSet prefixSet, PrefixSet other) { | |
109 | for (Prefix p: other) { | |
110 | for (Prefix prefix: this) { | |
111 | if (prefix.hasSubPrefix(p)) | |
112 | prefixSet.remove(prefix); | |
113 | } | |
114 | } | |
115 | } | |
116 | ||
117 | public void clear() { | |
118 | prefixes.clear(); | |
119 | } | |
120 | ||
121 | public int size() { | |
122 | return prefixes.size(); | |
123 | } | |
124 | } |