1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.dishevelled.venn.model;
25
26 import java.util.HashSet;
27 import java.util.Set;
28
29 import java.util.HashMap;
30 import java.util.Map;
31
32 import com.google.common.collect.Sets;
33
34 import org.dishevelled.bitset.ImmutableBitSet;
35
36 import org.dishevelled.observable.ObservableSet;
37
38 import org.dishevelled.observable.impl.ObservableSetImpl;
39
40 import org.dishevelled.venn.QuaternaryVennModel;
41
42 import static org.dishevelled.venn.model.VennModelUtils.toImmutableBitSet;
43
44
45
46
47
48
49
50
51 public final class QuaternaryVennModelImpl<E>
52 implements QuaternaryVennModel<E>
53 {
54
55 private final ObservableSet<E> first;
56
57
58 private final ObservableSet<E> second;
59
60
61 private final ObservableSet<E> third;
62
63
64 private final ObservableSet<E> fourth;
65
66
67 private final Set<E> firstOnly;
68
69
70 private final Set<E> secondOnly;
71
72
73 private final Set<E> thirdOnly;
74
75
76 private final Set<E> fourthOnly;
77
78
79 private final Set<E> firstSecond;
80
81
82 private final Set<E> firstThird;
83
84
85 private final Set<E> firstFourth;
86
87
88 private final Set<E> secondThird;
89
90
91 private final Set<E> secondFourth;
92
93
94 private final Set<E> thirdFourth;
95
96
97 private final Set<E> firstSecondThird;
98
99
100 private final Set<E> firstSecondFourth;
101
102
103 private final Set<E> firstThirdFourth;
104
105
106 private final Set<E> secondThirdFourth;
107
108
109 private final Set<E> intersection;
110
111
112 private final Set<E> union;
113
114
115 private final ObservableSet<E> selection;
116
117
118 private final Map<ImmutableBitSet, Set<E>> exclusives;
119
120
121
122
123
124 public QuaternaryVennModelImpl()
125 {
126 this(new HashSet<E>(), new HashSet<E>(), new HashSet<E>(), new HashSet<E>());
127 }
128
129
130
131
132
133
134
135
136
137 public QuaternaryVennModelImpl(final Set<? extends E> first,
138 final Set<? extends E> second,
139 final Set<? extends E> third,
140 final Set<? extends E> fourth)
141 {
142 if (first == null)
143 {
144 throw new IllegalArgumentException("first must not be null");
145 }
146 if (second == null)
147 {
148 throw new IllegalArgumentException("second must not be null");
149 }
150 if (third == null)
151 {
152 throw new IllegalArgumentException("third must not be null");
153 }
154 if (fourth == null)
155 {
156 throw new IllegalArgumentException("fourth must not be null");
157 }
158
159
160 this.first = new ObservableSetImpl(first);
161 this.second = new ObservableSetImpl(second);
162 this.third = new ObservableSetImpl(third);
163 this.fourth = new ObservableSetImpl(fourth);
164
165
166 ObservableSet<E> f = this.first;
167 ObservableSet<E> s = this.second;
168 ObservableSet<E> t = this.third;
169 ObservableSet<E> r = this.fourth;
170 firstOnly = Sets.difference(Sets.difference(Sets.difference(f, s), t), r);
171 secondOnly = Sets.difference(Sets.difference(Sets.difference(s, f), t), r);
172 thirdOnly = Sets.difference(Sets.difference(Sets.difference(t, f), s), r);
173 fourthOnly = Sets.difference(Sets.difference(Sets.difference(r, f), s), t);
174 firstSecond = Sets.difference(Sets.difference(Sets.intersection(f, s), t), r);
175 firstThird = Sets.difference(Sets.difference(Sets.intersection(f, t), s), r);
176 firstFourth = Sets.difference(Sets.difference(Sets.intersection(f, r), s), t);
177 secondThird = Sets.difference(Sets.difference(Sets.intersection(s, t), f), r);
178 secondFourth = Sets.difference(Sets.difference(Sets.intersection(s, r), f), t);
179 thirdFourth = Sets.difference(Sets.difference(Sets.intersection(t, r), f), s);
180 firstSecondThird = Sets.difference(Sets.intersection(f, Sets.intersection(s, t)), r);
181 firstSecondFourth = Sets.difference(Sets.intersection(f, Sets.intersection(s, r)), t);
182 firstThirdFourth = Sets.difference(Sets.intersection(f, Sets.intersection(t, r)), s);
183 secondThirdFourth = Sets.difference(Sets.intersection(s, Sets.intersection(t, r)), f);
184 intersection = Sets.intersection(f, Sets.intersection(s, Sets.intersection(t, r)));
185 union = Sets.union(f, Sets.union(s, Sets.union(t, r)));
186 selection = new SelectionView<E>(union, f, s, t, r);
187
188 exclusives = new HashMap<ImmutableBitSet, Set<E>>(15);
189
190 exclusives.put(toImmutableBitSet(0), firstOnly);
191 exclusives.put(toImmutableBitSet(1), secondOnly);
192 exclusives.put(toImmutableBitSet(2), thirdOnly);
193 exclusives.put(toImmutableBitSet(3), fourthOnly);
194
195 exclusives.put(toImmutableBitSet(0, 1), firstSecond);
196 exclusives.put(toImmutableBitSet(0, 2), firstThird);
197 exclusives.put(toImmutableBitSet(0, 3), firstFourth);
198 exclusives.put(toImmutableBitSet(1, 2), secondThird);
199 exclusives.put(toImmutableBitSet(1, 3), secondFourth);
200 exclusives.put(toImmutableBitSet(2, 3), thirdFourth);
201
202 exclusives.put(toImmutableBitSet(0, 1, 2), firstSecondThird);
203 exclusives.put(toImmutableBitSet(0, 1, 3), firstSecondFourth);
204 exclusives.put(toImmutableBitSet(0, 2, 3), firstThirdFourth);
205 exclusives.put(toImmutableBitSet(1, 2, 3), secondThirdFourth);
206
207 exclusives.put(toImmutableBitSet(0, 1, 2, 3), intersection);
208 }
209
210
211
212 public int size()
213 {
214 return 4;
215 }
216
217
218 public ObservableSet<E> first()
219 {
220 return first;
221 }
222
223
224 public ObservableSet<E> second()
225 {
226 return second;
227 }
228
229
230 public ObservableSet<E> third()
231 {
232 return third;
233 }
234
235
236 public ObservableSet<E> fourth()
237 {
238 return fourth;
239 }
240
241
242 public Set<E> get(final int index)
243 {
244 if (index < 0 || index > 3)
245 {
246 throw new IndexOutOfBoundsException("index out of bounds");
247 }
248 switch (index)
249 {
250 case 0:
251 return first;
252 case 1:
253 return second;
254 case 2:
255 return third;
256 case 3:
257 return fourth;
258 default:
259 break;
260 }
261 throw new IllegalStateException("invalid index " + index);
262 }
263
264
265 public Set<E> firstOnly()
266 {
267 return firstOnly;
268 }
269
270
271 public Set<E> secondOnly()
272 {
273 return secondOnly;
274 }
275
276
277 public Set<E> thirdOnly()
278 {
279 return thirdOnly;
280 }
281
282
283 public Set<E> fourthOnly()
284 {
285 return fourthOnly;
286 }
287
288
289 public Set<E> firstSecond()
290 {
291 return firstSecond;
292 }
293
294
295 public Set<E> firstThird()
296 {
297 return firstThird;
298 }
299
300
301 public Set<E> firstFourth()
302 {
303 return firstFourth;
304 }
305
306
307 public Set<E> secondThird()
308 {
309 return secondThird;
310 }
311
312
313 public Set<E> secondFourth()
314 {
315 return secondFourth;
316 }
317
318
319 public Set<E> thirdFourth()
320 {
321 return thirdFourth;
322 }
323
324
325 public Set<E> firstSecondThird()
326 {
327 return firstSecondThird;
328 }
329
330
331 public Set<E> firstSecondFourth()
332 {
333 return firstSecondFourth;
334 }
335
336
337 public Set<E> firstThirdFourth()
338 {
339 return firstThirdFourth;
340 }
341
342
343 public Set<E> secondThirdFourth()
344 {
345 return secondThirdFourth;
346 }
347
348
349 public Set<E> intersection()
350 {
351 return intersection;
352 }
353
354
355 public Set<E> exclusiveTo(final int index, final int... additional)
356 {
357 int maxIndex = size() - 1;
358 if (index < 0 || index > maxIndex)
359 {
360 throw new IndexOutOfBoundsException("index out of bounds");
361 }
362 if (additional != null && additional.length > 0)
363 {
364 if (additional.length > maxIndex)
365 {
366 throw new IndexOutOfBoundsException("too many indices provided");
367 }
368 for (int i = 0, size = additional.length; i < size; i++)
369 {
370 if (additional[i] < 0 || additional[i] > maxIndex)
371 {
372 throw new IndexOutOfBoundsException("additional index [" + i + "] out of bounds");
373 }
374 }
375 }
376 return exclusives.get(toImmutableBitSet(index, additional));
377 }
378
379
380 public Set<E> union()
381 {
382 return union;
383 }
384
385
386 public ObservableSet<E> selection()
387 {
388 return selection;
389 }
390 }