1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.collections.bidimap;
18
19 import java.io.IOException;
20 import java.io.ObjectInputStream;
21 import java.io.ObjectOutputStream;
22 import java.io.Serializable;
23 import java.util.ArrayList;
24 import java.util.Comparator;
25 import java.util.Iterator;
26 import java.util.ListIterator;
27 import java.util.Map;
28 import java.util.SortedMap;
29 import java.util.TreeMap;
30
31 import org.apache.commons.collections.BidiMap;
32 import org.apache.commons.collections.OrderedBidiMap;
33 import org.apache.commons.collections.OrderedMap;
34 import org.apache.commons.collections.OrderedMapIterator;
35 import org.apache.commons.collections.ResettableIterator;
36 import org.apache.commons.collections.SortedBidiMap;
37 import org.apache.commons.collections.map.AbstractSortedMapDecorator;
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 public class DualTreeBidiMap<K, V> extends AbstractDualBidiMap<K, V>
56 implements SortedBidiMap<K, V>, Serializable {
57
58
59 private static final long serialVersionUID = 721969328361809L;
60
61
62 protected final Comparator<? super K> comparator;
63
64
65 protected final Comparator<? super V> valueComparator;
66
67
68
69
70 public DualTreeBidiMap() {
71 super(new TreeMap<K, V>(), new TreeMap<V, K>());
72 this.comparator = null;
73 this.valueComparator = null;
74 }
75
76
77
78
79
80
81
82 public DualTreeBidiMap(final Map<K, V> map) {
83 super(new TreeMap<K, V>(), new TreeMap<V, K>());
84 putAll(map);
85 this.comparator = null;
86 this.valueComparator = null;
87 }
88
89
90
91
92
93
94
95 public DualTreeBidiMap(final Comparator<? super K> keyComparator, final Comparator<? super V> valueComparator) {
96 super(new TreeMap<K, V>(keyComparator), new TreeMap<V, K>(valueComparator));
97 this.comparator = keyComparator;
98 this.valueComparator = valueComparator;
99 }
100
101
102
103
104
105
106
107
108 protected DualTreeBidiMap(final Map<K, V> normalMap, final Map<V, K> reverseMap,
109 final BidiMap<V, K> inverseBidiMap) {
110 super(normalMap, reverseMap, inverseBidiMap);
111 this.comparator = ((SortedMap<K, V>) normalMap).comparator();
112 this.valueComparator = ((SortedMap<V, K>) reverseMap).comparator();
113 }
114
115
116
117
118
119
120
121
122
123 @Override
124 protected DualTreeBidiMap<V, K> createBidiMap(final Map<V, K> normalMap, final Map<K, V> reverseMap,
125 final BidiMap<K, V> inverseMap) {
126 return new DualTreeBidiMap<V, K>(normalMap, reverseMap, inverseMap);
127 }
128
129
130
131 public Comparator<? super K> comparator() {
132 return ((SortedMap<K, V>) normalMap).comparator();
133 }
134
135 public Comparator<? super V> valueComparator() {
136 return ((SortedMap<V, K>) reverseMap).comparator();
137
138 }
139
140 public K firstKey() {
141 return ((SortedMap<K, V>) normalMap).firstKey();
142 }
143
144 public K lastKey() {
145 return ((SortedMap<K, V>) normalMap).lastKey();
146 }
147
148 public K nextKey(final K key) {
149 if (isEmpty()) {
150 return null;
151 }
152 if (normalMap instanceof OrderedMap) {
153 return ((OrderedMap<K, ?>) normalMap).nextKey(key);
154 }
155 final SortedMap<K, V> sm = (SortedMap<K, V>) normalMap;
156 final Iterator<K> it = sm.tailMap(key).keySet().iterator();
157 it.next();
158 if (it.hasNext()) {
159 return it.next();
160 }
161 return null;
162 }
163
164 public K previousKey(final K key) {
165 if (isEmpty()) {
166 return null;
167 }
168 if (normalMap instanceof OrderedMap) {
169 return ((OrderedMap<K, V>) normalMap).previousKey(key);
170 }
171 final SortedMap<K, V> sm = (SortedMap<K, V>) normalMap;
172 final SortedMap<K, V> hm = sm.headMap(key);
173 if (hm.isEmpty()) {
174 return null;
175 }
176 return hm.lastKey();
177 }
178
179
180
181
182
183
184
185
186
187
188 @Override
189 public OrderedMapIterator<K, V> mapIterator() {
190 return new BidiOrderedMapIterator<K, V>(this);
191 }
192
193 public SortedBidiMap<V, K> inverseSortedBidiMap() {
194 return inverseBidiMap();
195 }
196
197 public OrderedBidiMap<V, K> inverseOrderedBidiMap() {
198 return inverseBidiMap();
199 }
200
201
202
203 public SortedMap<K, V> headMap(final K toKey) {
204 final SortedMap<K, V> sub = ((SortedMap<K, V>) normalMap).headMap(toKey);
205 return new ViewMap<K, V>(this, sub);
206 }
207
208 public SortedMap<K, V> tailMap(final K fromKey) {
209 final SortedMap<K, V> sub = ((SortedMap<K, V>) normalMap).tailMap(fromKey);
210 return new ViewMap<K, V>(this, sub);
211 }
212
213 public SortedMap<K, V> subMap(final K fromKey, final K toKey) {
214 final SortedMap<K, V> sub = ((SortedMap<K, V>) normalMap).subMap(fromKey, toKey);
215 return new ViewMap<K, V>(this, sub);
216 }
217
218 @Override
219 public SortedBidiMap<V, K> inverseBidiMap() {
220 return (SortedBidiMap<V, K>) super.inverseBidiMap();
221 }
222
223
224
225
226
227 protected static class ViewMap<K, V> extends AbstractSortedMapDecorator<K, V> {
228
229 final DualTreeBidiMap<K, V> bidi;
230
231
232
233
234
235
236 protected ViewMap(final DualTreeBidiMap<K, V> bidi, final SortedMap<K, V> sm) {
237
238
239
240 super(new DualTreeBidiMap<K, V>(sm, bidi.reverseMap, bidi.inverseBidiMap));
241 this.bidi = decorated();
242 }
243
244 @Override
245 public boolean containsValue(final Object value) {
246
247 return decorated().normalMap.containsValue(value);
248 }
249
250 @Override
251 public void clear() {
252
253 for (final Iterator<K> it = keySet().iterator(); it.hasNext();) {
254 it.next();
255 it.remove();
256 }
257 }
258
259 @Override
260 public SortedMap<K, V> headMap(final K toKey) {
261 return new ViewMap<K, V>(decorated(), super.headMap(toKey));
262 }
263
264 @Override
265 public SortedMap<K, V> tailMap(final K fromKey) {
266 return new ViewMap<K, V>(decorated(), super.tailMap(fromKey));
267 }
268
269 @Override
270 public SortedMap<K, V> subMap(final K fromKey, final K toKey) {
271 return new ViewMap<K, V>(decorated(), super.subMap(fromKey, toKey));
272 }
273
274 @Override
275 protected DualTreeBidiMap<K, V> decorated() {
276 return (DualTreeBidiMap<K, V>) super.decorated();
277 }
278
279 @Override
280 public K previousKey(final K key) {
281 return decorated().previousKey(key);
282 }
283
284 @Override
285 public K nextKey(final K key) {
286 return decorated().nextKey(key);
287 }
288 }
289
290
291
292
293
294 protected static class BidiOrderedMapIterator<K, V> implements OrderedMapIterator<K, V>, ResettableIterator<K> {
295
296
297 protected final AbstractDualBidiMap<K, V> parent;
298
299
300 protected ListIterator<Map.Entry<K, V>> iterator;
301
302
303 private Map.Entry<K, V> last = null;
304
305
306
307
308
309 protected BidiOrderedMapIterator(final AbstractDualBidiMap<K, V> parent) {
310 super();
311 this.parent = parent;
312 iterator = new ArrayList<Map.Entry<K, V>>(parent.entrySet()).listIterator();
313 }
314
315 public boolean hasNext() {
316 return iterator.hasNext();
317 }
318
319 public K next() {
320 last = iterator.next();
321 return last.getKey();
322 }
323
324 public boolean hasPrevious() {
325 return iterator.hasPrevious();
326 }
327
328 public K previous() {
329 last = iterator.previous();
330 return last.getKey();
331 }
332
333 public void remove() {
334 iterator.remove();
335 parent.remove(last.getKey());
336 last = null;
337 }
338
339 public K getKey() {
340 if (last == null) {
341 throw new IllegalStateException(
342 "Iterator getKey() can only be called after next() and before remove()");
343 }
344 return last.getKey();
345 }
346
347 public V getValue() {
348 if (last == null) {
349 throw new IllegalStateException(
350 "Iterator getValue() can only be called after next() and before remove()");
351 }
352 return last.getValue();
353 }
354
355 public V setValue(final V value) {
356 if (last == null) {
357 throw new IllegalStateException(
358 "Iterator setValue() can only be called after next() and before remove()");
359 }
360 if (parent.reverseMap.containsKey(value) &&
361 parent.reverseMap.get(value) != last.getKey()) {
362 throw new IllegalArgumentException(
363 "Cannot use setValue() when the object being set is already in the map");
364 }
365 return parent.put(last.getKey(), value);
366 }
367
368 public void reset() {
369 iterator = new ArrayList<Map.Entry<K, V>>(parent.entrySet()).listIterator();
370 last = null;
371 }
372
373 @Override
374 public String toString() {
375 if (last != null) {
376 return "MapIterator[" + getKey() + "=" + getValue() + "]";
377 }
378 return "MapIterator[]";
379 }
380 }
381
382
383
384 private void writeObject(final ObjectOutputStream out) throws IOException {
385 out.defaultWriteObject();
386 out.writeObject(normalMap);
387 }
388
389 private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
390 in.defaultReadObject();
391 normalMap = new TreeMap<K, V>(comparator);
392 reverseMap = new TreeMap<V, K>(valueComparator);
393 @SuppressWarnings("unchecked")
394 final
395 Map<K, V> map = (Map<K, V>) in.readObject();
396 putAll(map);
397 }
398
399 }