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.TernaryVennModel;
41
42 import static org.dishevelled.venn.model.VennModelUtils.toImmutableBitSet;
43
44
45
46
47
48
49
50
51 public final class TernaryVennModelImpl<E>
52 implements TernaryVennModel<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 Set<E> firstOnly;
65
66
67 private final Set<E> secondOnly;
68
69
70 private final Set<E> thirdOnly;
71
72
73 private final Set<E> firstSecond;
74
75
76 private final Set<E> firstThird;
77
78
79 private final Set<E> secondThird;
80
81
82 private final Set<E> intersection;
83
84
85 private final Set<E> union;
86
87
88 private final ObservableSet<E> selection;
89
90
91 private final Map<ImmutableBitSet, Set<E>> exclusives;
92
93
94
95
96
97 public TernaryVennModelImpl()
98 {
99 this(new HashSet<E>(), new HashSet<E>(), new HashSet<E>());
100 }
101
102
103
104
105
106
107
108
109 public TernaryVennModelImpl(final Set<? extends E> first,
110 final Set<? extends E> second,
111 final Set<? extends E> third)
112 {
113 if (first == null)
114 {
115 throw new IllegalArgumentException("first must not be null");
116 }
117 if (second == null)
118 {
119 throw new IllegalArgumentException("second must not be null");
120 }
121 if (third == null)
122 {
123 throw new IllegalArgumentException("third must not be null");
124 }
125
126
127 this.first = new ObservableSetImpl(first);
128 this.second = new ObservableSetImpl(second);
129 this.third = new ObservableSetImpl(third);
130
131
132 ObservableSet<E> f = this.first;
133 ObservableSet<E> s = this.second;
134 ObservableSet<E> t = this.third;
135 firstOnly = Sets.difference(Sets.difference(f, s), t);
136 secondOnly = Sets.difference(Sets.difference(s, f), t);
137 thirdOnly = Sets.difference(Sets.difference(t, f), s);
138 firstSecond = Sets.difference(Sets.intersection(f, s), t);
139 firstThird = Sets.difference(Sets.intersection(f, t), s);
140 secondThird = Sets.difference(Sets.intersection(s, t), f);
141 intersection = Sets.intersection(f, Sets.intersection(s, t));
142 union = Sets.union(f, Sets.union(s, t));
143 selection = new SelectionView<E>(union, f, s, t);
144
145 exclusives = new HashMap<ImmutableBitSet, Set<E>>(7);
146
147 exclusives.put(toImmutableBitSet(0), firstOnly);
148 exclusives.put(toImmutableBitSet(1), secondOnly);
149 exclusives.put(toImmutableBitSet(2), thirdOnly);
150
151 exclusives.put(toImmutableBitSet(0, 1), firstSecond);
152 exclusives.put(toImmutableBitSet(0, 2), firstThird);
153 exclusives.put(toImmutableBitSet(1, 2), secondThird);
154
155 exclusives.put(toImmutableBitSet(0, 1, 2), intersection);
156 }
157
158
159
160 public int size()
161 {
162 return 3;
163 }
164
165
166 public ObservableSet<E> first()
167 {
168 return first;
169 }
170
171
172 public ObservableSet<E> second()
173 {
174 return second;
175 }
176
177
178 public ObservableSet<E> third()
179 {
180 return third;
181 }
182
183
184 public Set<E> get(final int index)
185 {
186 if (index < 0 || index > 2)
187 {
188 throw new IndexOutOfBoundsException("index out of bounds");
189 }
190 switch (index)
191 {
192 case 0:
193 return first;
194 case 1:
195 return second;
196 case 2:
197 return third;
198 default:
199 break;
200 }
201 throw new IllegalStateException("invalid index " + index);
202 }
203
204
205 public Set<E> firstOnly()
206 {
207 return firstOnly;
208 }
209
210
211 public Set<E> secondOnly()
212 {
213 return secondOnly;
214 }
215
216
217 public Set<E> thirdOnly()
218 {
219 return thirdOnly;
220 }
221
222
223 public Set<E> firstSecond()
224 {
225 return firstSecond;
226 }
227
228
229 public Set<E> firstThird()
230 {
231 return firstThird;
232 }
233
234
235 public Set<E> secondThird()
236 {
237 return secondThird;
238 }
239
240
241 public Set<E> intersection()
242 {
243 return intersection;
244 }
245
246
247 public Set<E> exclusiveTo(final int index, final int... additional)
248 {
249 int maxIndex = size() - 1;
250 if (index < 0 || index > maxIndex)
251 {
252 throw new IndexOutOfBoundsException("index out of bounds");
253 }
254 if (additional != null && additional.length > 0)
255 {
256 if (additional.length > maxIndex)
257 {
258 throw new IndexOutOfBoundsException("too many indices provided");
259 }
260 for (int i = 0, size = additional.length; i < size; i++)
261 {
262 if (additional[i] < 0 || additional[i] > maxIndex)
263 {
264 throw new IndexOutOfBoundsException("additional index [" + i + "] out of bounds");
265 }
266 }
267 }
268 return exclusives.get(toImmutableBitSet(index, additional));
269 }
270
271
272 public Set<E> union()
273 {
274 return union;
275 }
276
277
278 public ObservableSet<E> selection()
279 {
280 return selection;
281 }
282 }