1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.opensaml.xml.util;
18
19 import java.util.AbstractList;
20 import java.util.Collection;
21 import java.util.List;
22 import java.util.Map;
23
24 import javax.xml.namespace.QName;
25
26 import net.jcip.annotations.NotThreadSafe;
27
28 import org.opensaml.xml.XMLObject;
29
30
31
32
33
34
35 @NotThreadSafe
36 public class IndexedXMLObjectChildrenList<ElementType extends XMLObject> extends XMLObjectChildrenList<ElementType> {
37
38
39 private Map<QName, List<ElementType>> objectIndex;
40
41
42
43
44
45
46 public IndexedXMLObjectChildrenList(XMLObject parent) {
47 super(parent);
48 objectIndex = new LazyMap<QName, List<ElementType>>();
49 }
50
51
52
53
54
55
56
57 public IndexedXMLObjectChildrenList(XMLObject parent, Collection<ElementType> col) {
58 super(parent);
59 objectIndex = new LazyMap<QName, List<ElementType>>();
60 addAll(col);
61 }
62
63
64
65
66
67
68
69
70 public void add(int index, ElementType element) {
71 super.add(index, element);
72 indexElement(element);
73 }
74
75
76 public void clear() {
77 super.clear();
78 objectIndex.clear();
79 }
80
81
82
83
84
85
86
87
88 public List<ElementType> get(QName typeOrName) {
89 return objectIndex.get(typeOrName);
90 }
91
92
93
94
95
96
97 protected void indexElement(ElementType element) {
98 if (element == null) {
99 return;
100 }
101
102 QName type = element.getSchemaType();
103 if (type != null) {
104 indexElement(type, element);
105 }
106
107 indexElement(element.getElementQName(), element);
108 }
109
110
111
112
113
114
115
116 protected void indexElement(QName index, ElementType element) {
117 List<ElementType> objects = objectIndex.get(index);
118 if (objects == null) {
119 objects = new LazyList<ElementType>();
120 objectIndex.put(index, objects);
121 }
122
123 objects.add(element);
124 }
125
126
127
128
129
130
131
132
133 public boolean remove(ElementType element) {
134 boolean elementRemoved = false;
135
136 elementRemoved = super.remove(element);
137 if (elementRemoved) {
138 removeElementFromIndex(element);
139 }
140
141 return elementRemoved;
142 }
143
144
145
146
147
148
149
150
151
152 public ElementType remove(int index) {
153 ElementType returnValue = super.remove(index);
154
155 removeElementFromIndex(returnValue);
156
157 return returnValue;
158 }
159
160
161
162
163
164
165 protected void removeElementFromIndex(ElementType element) {
166 if (element == null) {
167 return;
168 }
169
170 QName type = element.getSchemaType();
171 if (type != null) {
172 removeElementFromIndex(type, element);
173 }
174
175 removeElementFromIndex(element.getElementQName(), element);
176 }
177
178
179
180
181
182
183
184 protected void removeElementFromIndex(QName index, ElementType element) {
185 List<ElementType> objects = objectIndex.get(index);
186 if (objects != null) {
187 objects.remove(element);
188 }
189
190 if (objects.size() == 0) {
191 objectIndex.remove(index);
192 }
193 }
194
195
196
197
198
199
200
201
202
203 public ElementType set(int index, ElementType element) {
204 ElementType returnValue = super.set(index, element);
205
206 removeElementFromIndex(returnValue);
207
208 indexElement(element);
209 return returnValue;
210 }
211
212
213
214
215
216
217
218
219
220
221 public List<? extends ElementType> subList(QName index) {
222 if (!objectIndex.containsKey(index)) {
223 objectIndex.put(index, new LazyList<ElementType>());
224 }
225
226 return new ListView<ElementType>(this, index);
227 }
228 }
229
230
231
232
233
234
235
236
237 class ListView<ElementType extends XMLObject> extends AbstractList<ElementType> {
238
239
240 private IndexedXMLObjectChildrenList<ElementType> backingList;
241
242
243 private QName index;
244
245
246 private List<ElementType> indexList;
247
248
249
250
251
252
253
254 public ListView(IndexedXMLObjectChildrenList<ElementType> newBackingList, QName newIndex) {
255 backingList = newBackingList;
256 index = newIndex;
257 indexList = backingList.get(index);
258 }
259
260 public boolean add(ElementType o) {
261 boolean result = backingList.add(o);
262 indexList = backingList.get(index);
263 return result;
264 }
265
266
267 public void add(int newIndex, ElementType element) {
268 throw new UnsupportedOperationException();
269 }
270
271
272 public boolean addAll(Collection<? extends ElementType> c) {
273 boolean result = backingList.addAll(c);
274 indexList = backingList.get(index);
275 return result;
276 }
277
278
279 public boolean addAll(int index, Collection<? extends ElementType> c) {
280 throw new UnsupportedOperationException();
281 }
282
283
284 public void clear() {
285 backingList.clear();
286 indexList = backingList.get(index);
287 }
288
289
290
291
292
293
294
295
296 public boolean contains(Object element) {
297 return indexList.contains(element);
298 }
299
300
301 public boolean containsAll(Collection<?> c) {
302 return indexList.containsAll(c);
303 }
304
305
306 public ElementType get(int newIndex) {
307 return indexList.get(newIndex);
308 }
309
310
311 public int indexOf(Object o) {
312 return backingList.indexOf(o);
313 }
314
315
316 public boolean isEmpty() {
317 return indexList.isEmpty();
318 }
319
320
321 public int lastIndexOf(Object o) {
322 return backingList.lastIndexOf(o);
323 }
324
325
326 public ElementType remove(int newIndex) {
327 throw new UnsupportedOperationException();
328 }
329
330
331 public boolean remove(Object o) {
332 boolean result = backingList.remove(o);
333 indexList = backingList.get(index);
334 return result;
335 }
336
337
338 public boolean removeAll(Collection<?> c) {
339 boolean result = backingList.removeAll(c);
340 indexList = backingList.get(index);
341 return result;
342 }
343
344
345 public boolean retainAll(Collection<?> c) {
346 boolean result = backingList.retainAll(c);
347 indexList = backingList.get(index);
348 return result;
349 }
350
351
352 public ElementType set(int newIndex, ElementType element) {
353 throw new UnsupportedOperationException();
354 }
355
356
357 public int size() {
358 return indexList.size();
359 }
360
361
362 public Object[] toArray() {
363 return indexList.toArray();
364 }
365
366 public <T extends Object> T[] toArray(T[] a) {
367 return indexList.toArray(a);
368 }
369 }