• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.unicode.cldr.util;
2 
3 import java.util.Arrays;
4 import java.util.Collection;
5 import java.util.Collections;
6 import java.util.HashSet;
7 import java.util.LinkedHashSet;
8 import java.util.Map;
9 import java.util.Map.Entry;
10 import java.util.Set;
11 
12 import com.ibm.icu.dev.util.UnicodeMap;
13 import com.ibm.icu.text.UnicodeSet;
14 import com.ibm.icu.util.Freezable;
15 
16 public class UnicodeRelation<T> implements Freezable<UnicodeRelation<T>> {
17 
18     final UnicodeMap<Set<T>> data = new UnicodeMap<>();
19     final SetMaker<T> maker;
20 
21     public interface SetMaker<T> {
make()22         Set<T> make();
23     }
24 
25     public static SetMaker<Object> HASHSET_MAKER = new SetMaker<Object>() {
26         @Override
27         public Set<Object> make() {
28             return new HashSet<>();
29         }
30     };
31 
32     public static final SetMaker<Object> LINKED_HASHSET_MAKER = new SetMaker<Object>() {
33         @Override
34         public Set<Object> make() {
35             return new LinkedHashSet<>();
36         }
37     };
38 
UnicodeRelation(SetMaker<T> maker)39     public UnicodeRelation(SetMaker<T> maker) {
40         this.maker = maker;
41     }
42 
UnicodeRelation()43     public UnicodeRelation() {
44         this.maker = (SetMaker<T>) HASHSET_MAKER;
45     }
46 
size()47     public int size() {
48         return data.size();
49     }
50 
isEmpty()51     public boolean isEmpty() {
52         return data.isEmpty();
53     }
54 
containsKey(int key)55     public boolean containsKey(int key) {
56         return data.containsKey(key);
57     }
58 
containsKey(String key)59     public boolean containsKey(String key) {
60         return data.containsKey(key);
61     }
62 
containsValue(T value)63     public boolean containsValue(T value) {
64         for (Set<T> v : data.values()) {
65             if (v.contains(value)) {
66                 return true;
67             }
68         }
69         return false;
70     }
71 
get(int key)72     public Set<T> get(int key) {
73         return data.get(key);
74     }
75 
get(String key)76     public Set<T> get(String key) {
77         return data.get(key);
78     }
79 
getKeys(T value)80     public UnicodeSet getKeys(T value) {
81         UnicodeSet result = new UnicodeSet();
82         for (Entry<String, Set<T>> entry : data.entrySet()) {
83             if (entry.getValue().contains(value)) {
84                 result.add(entry.getKey());
85             }
86         }
87         return result;
88     }
89 
add(String key, T value)90     public UnicodeRelation<T> add(String key, T value) {
91         Set<T> newValues = addValue(data.get(key), value);
92         if (newValues != null) {
93             data.put(key, newValues);
94         }
95         return this;
96     }
97 
add(int key, T value)98     public UnicodeRelation<T> add(int key, T value) {
99         Set<T> newValues = addValue(data.get(key), value);
100         if (newValues != null) {
101             data.put(key, newValues);
102         }
103         return this;
104     }
105 
addAll(String key, Collection<T> values)106     public UnicodeRelation<T> addAll(String key, Collection<T> values) {
107         Set<T> newValues = addValues(data.get(key), values);
108         if (newValues != null) {
109             data.put(key, newValues);
110         }
111         return this;
112     }
113 
addAll(Map<String, T> m)114     public UnicodeRelation<T> addAll(Map<String, T> m) {
115         for (Entry<String, T> entry : m.entrySet()) {
116             add(entry.getKey(), entry.getValue());
117         }
118         return this;
119     }
120 
addAll(UnicodeSet keys, Collection<T> values)121     public UnicodeRelation<T> addAll(UnicodeSet keys, Collection<T> values) {
122         for (String key : keys) {
123             addAll(key, values);
124         }
125         return this;
126     }
127 
addAll(UnicodeSet keys, T... values)128     public UnicodeRelation<T> addAll(UnicodeSet keys, T... values) {
129         return addAll(keys, Arrays.asList(values));
130     }
131 
addAll(UnicodeSet keys, T value)132     public UnicodeRelation<T> addAll(UnicodeSet keys, T value) {
133         for (String key : keys) {
134             add(key, value);
135         }
136         return this;
137     }
138 
addValue(Set<T> oldValues, T value)139     private Set<T> addValue(Set<T> oldValues, T value) {
140         if (oldValues == null) {
141             return Collections.singleton(value);
142         } else if (oldValues.contains(value)) {
143             return null;
144         } else {
145             Set<T> newValues = make(oldValues);
146             newValues.add(value);
147             return Collections.unmodifiableSet(newValues);
148         }
149     }
150 
make(Collection<T> oldValues)151     private final Set<T> make(Collection<T> oldValues) {
152         Set<T> newValues = maker.make();
153         newValues.addAll(oldValues);
154         return newValues;
155     }
156 
addValues(Set<T> oldValues, Collection<T> values)157     private Set<T> addValues(Set<T> oldValues, Collection<T> values) {
158         if (oldValues == null) {
159             if (values.size() == 1) {
160                 return Collections.singleton(values.iterator().next());
161             } else {
162                 return Collections.unmodifiableSet(make(values));
163             }
164         } else if (oldValues.containsAll(values)) {
165             return null;
166         } else {
167             Set<T> newValues = make(oldValues);
168             newValues.addAll(values);
169             return Collections.unmodifiableSet(newValues);
170         }
171     }
172 
removeValues(Set<T> oldValues, Collection<T> values)173     private Set<T> removeValues(Set<T> oldValues, Collection<T> values) {
174         if (oldValues == null) {
175             return null;
176         } else if (Collections.disjoint(oldValues, values)) {
177             return null;
178         } else {
179             Set<T> newValues = make(oldValues);
180             newValues.removeAll(values);
181             return newValues.size() == 0 ? Collections.EMPTY_SET : Collections.unmodifiableSet(newValues);
182         }
183     }
184 
remove(int key)185     public UnicodeRelation<T> remove(int key) {
186         data.remove(key);
187         return this;
188     }
189 
remove(String key)190     public UnicodeRelation<T> remove(String key) {
191         data.remove(key);
192         return this;
193     }
194 
removeValue(T value)195     public UnicodeRelation<T> removeValue(T value) {
196         UnicodeSet toChange = getKeys(value);
197         for (String key : toChange) {
198             remove(key, value);
199         }
200         return this;
201     }
202 
remove(int key, T value)203     public UnicodeRelation<T> remove(int key, T value) {
204         Set<T> values = data.getValue(key);
205         if (values != null && values.contains(value)) {
206             removeExisting(key, value, values);
207         }
208         return this;
209     }
210 
remove(String key, T value)211     public UnicodeRelation<T> remove(String key, T value) {
212         Set<T> values = data.getValue(key);
213         if (values != null && values.contains(value)) {
214             removeExisting(key, value, values);
215         }
216         return this;
217     }
218 
removeAll(String key, Collection<T> values)219     public UnicodeRelation<T> removeAll(String key, Collection<T> values) {
220         Set<T> newValues = removeValues(data.get(key), values);
221         if (newValues != null) {
222             if (newValues == Collections.EMPTY_SET) {
223                 data.remove(key);
224             } else {
225                 data.put(key, newValues);
226             }
227         }
228         return this;
229     }
230 
removeAll(Map<String, T> m)231     public UnicodeRelation<T> removeAll(Map<String, T> m) {
232         for (Entry<String, T> entry : m.entrySet()) {
233             remove(entry.getKey(), entry.getValue());
234         }
235         return this;
236     }
237 
removeAll(UnicodeSet keys, Collection<T> values)238     public UnicodeRelation<T> removeAll(UnicodeSet keys, Collection<T> values) {
239         for (String key : keys) {
240             removeAll(key, values);
241         }
242         return this;
243     }
244 
removeAll(UnicodeSet keys, T... values)245     public UnicodeRelation<T> removeAll(UnicodeSet keys, T... values) {
246         return removeAll(keys, Arrays.asList(values));
247     }
248 
removeAll(UnicodeSet keys, T value)249     public UnicodeRelation<T> removeAll(UnicodeSet keys, T value) {
250         for (String key : keys) {
251             remove(key, value);
252         }
253         return this;
254     }
255 
removeExisting(int key, T value, Set<T> values)256     private void removeExisting(int key, T value, Set<T> values) {
257         if (values.size() == 1) {
258             data.remove(key);
259         } else {
260             Set<T> newValues = make(values);
261             newValues.remove(value);
262             data.put(key, Collections.unmodifiableSet(newValues));
263         }
264     }
265 
removeExisting(String key, T value, Set<T> values)266     private void removeExisting(String key, T value, Set<T> values) {
267         if (values.size() == 1) {
268             data.remove(key);
269         } else {
270             Set<T> newValues = make(values);
271             newValues.remove(value);
272             data.put(key, Collections.unmodifiableSet(newValues));
273         }
274     }
275 
clear()276     public void clear() {
277         data.clear();
278     }
279 
keySet()280     public UnicodeSet keySet() {
281         return data.keySet();
282     }
283 
values()284     public Collection<T> values() {
285         Set<T> result = maker.make();
286         for (Set<T> v : data.values()) {
287             result.addAll(v);
288         }
289         return result;
290     }
291 
keyValues()292     public Iterable<Entry<String, Set<T>>> keyValues() {
293         return data.entrySet();
294     }
295 
296     @Override
toString()297     public String toString() {
298         return data.toString();
299     }
300 
301     @Override
hashCode()302     public int hashCode() {
303         return data.hashCode();
304     }
305 
306     @Override
equals(Object obj)307     public boolean equals(Object obj) {
308         return obj instanceof UnicodeRelation && data.equals(((UnicodeRelation) obj).data);
309     }
310 
311     @Override
isFrozen()312     public boolean isFrozen() {
313         return data.isFrozen();
314     }
315 
316     @Override
freeze()317     public UnicodeRelation<T> freeze() {
318         data.freeze();
319         return this;
320     }
321 
322     @Override
cloneAsThawed()323     public UnicodeRelation<T> cloneAsThawed() {
324         throw new UnsupportedOperationException();
325     }
326 }
327