1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.trinidad.component;
20
21 import java.io.Externalizable;
22
23 import java.util.AbstractMap;
24 import java.util.Collections;
25 import java.util.HashMap;
26 import java.util.Map;
27 import java.util.Set;
28 import java.io.ObjectOutput;
29 import java.io.IOException;
30 import java.io.ObjectInput;
31
32
33
34
35
36
37
38
39 final class ValueMap<K, V> extends AbstractMap<K, V> implements Externalizable
40 {
41 public ValueMap()
42 {
43
44 this(13);
45 }
46
47 public ValueMap(int initialCapacity)
48 {
49 _cache = new HashMap<K, V>(initialCapacity);
50 _valueMap = new HashMap<V, K>(initialCapacity);
51 }
52
53
54
55
56 @Override
57 public V get(Object key)
58 {
59 return _cache.get(key);
60 }
61
62
63
64
65 public K getKey(V value)
66 {
67 return _valueMap.get(value);
68 }
69
70 @Override
71 public V put(K key, V value)
72 {
73 K oldKey = _valueMap.put(value, key);
74 assert oldKey == null : "value:"+value+" is referenced by both key:"+key+
75 " and key:"+oldKey;
76
77 V old = _cache.put(key, value);
78 assert old == null : "can't put the same key twice";
79 return old;
80 }
81
82
83
84
85
86
87
88 @Override
89 public V remove(Object key)
90 {
91 V value = _cache.remove(key);
92
93 if (value != null)
94 {
95 K oldKey = _valueMap.remove(value);
96 assert oldKey != null : "missing key in value map for value "+value;
97 }
98 return value;
99 }
100
101 @Override
102 public void clear()
103 {
104 _cache.clear();
105 _valueMap.clear();
106 }
107
108 @Override
109 public int size()
110 {
111 return _cache.size();
112 }
113
114 @Override
115 public Set<Map.Entry<K, V>> entrySet()
116 {
117 return Collections.unmodifiableSet(_cache.entrySet());
118 }
119
120 private static <K,V> Map<V, K> _invertMap(Map<K, V> cache)
121 {
122 Map<V, K> valueMap = new HashMap<V, K>(cache.size());
123 for(Map.Entry<K, V> entry : cache.entrySet())
124 {
125 K old = valueMap.put(entry.getValue(), entry.getKey());
126 assert old == null : "the value:"+entry.getValue()+
127 " was bound to both key:"+old+
128 " and key:"+entry.getKey();
129 }
130
131 return valueMap;
132 }
133
134 public void writeExternal(ObjectOutput out) throws IOException
135 {
136 if (_cache.isEmpty())
137 out.writeObject(null);
138 else
139 out.writeObject(_cache);
140 }
141
142 @SuppressWarnings("unchecked")
143 public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
144 {
145 Map<K, V> cache = (Map<K, V>) in.readObject();
146 if (cache != null)
147 {
148 _cache = cache;
149 _valueMap = _invertMap(_cache);
150 }
151 }
152
153 private Map<K, V> _cache;
154 private transient Map<V, K> _valueMap;
155 }