1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.uif.util;
17
18 import java.io.Serializable;
19 import java.util.ArrayList;
20 import java.util.Collection;
21 import java.util.Collections;
22 import java.util.Iterator;
23 import java.util.List;
24 import java.util.ListIterator;
25
26 import org.kuali.rice.krad.datadictionary.Copyable;
27 import org.kuali.rice.krad.uif.component.DelayedCopy;
28
29
30
31
32
33
34
35
36
37 public class LifecycleAwareList<T> implements List<T>, Copyable, Serializable {
38
39 private static final long serialVersionUID = -8971217230511446882L;
40
41
42
43
44
45
46 private class ListIter implements ListIterator<T> {
47
48 private final ListIterator<T> delegate;
49
50
51
52
53 private ListIter() {
54 this.delegate = LifecycleAwareList.this.delegate.listIterator();
55 }
56
57
58
59
60 private ListIter(int index) {
61 this.delegate = LifecycleAwareList.this.delegate.listIterator(index);
62 }
63
64 @Override
65 public boolean hasNext() {
66 return this.delegate.hasNext();
67 }
68
69 @Override
70 public T next() {
71 return this.delegate.next();
72 }
73
74 @Override
75 public boolean hasPrevious() {
76 return this.delegate.hasPrevious();
77 }
78
79 @Override
80 public T previous() {
81 return this.delegate.previous();
82 }
83
84 @Override
85 public int nextIndex() {
86 return this.delegate.nextIndex();
87 }
88
89 @Override
90 public int previousIndex() {
91 return this.delegate.previousIndex();
92 }
93
94 @Override
95 public void remove() {
96 lifecycleElement.checkMutable(true);
97 this.delegate.remove();
98 }
99
100 @Override
101 public void set(T e) {
102 lifecycleElement.checkMutable(true);
103 this.delegate.set(e);
104 }
105
106 @Override
107 public void add(T e) {
108 lifecycleElement.checkMutable(true);
109 this.delegate.add(e);
110 }
111
112 }
113
114
115
116
117
118
119 private class Iter implements Iterator<T> {
120
121 private final Iterator<T> delegate;
122
123
124
125
126 private Iter() {
127 this.delegate = LifecycleAwareList.this.delegate.iterator();
128 }
129
130 @Override
131 public boolean hasNext() {
132 return this.delegate.hasNext();
133 }
134
135 @Override
136 public T next() {
137 return this.delegate.next();
138 }
139
140 @Override
141 public void remove() {
142 lifecycleElement.checkMutable(true);
143 this.delegate.remove();
144 }
145 }
146
147
148
149
150 private final LifecycleElement lifecycleElement;
151
152
153
154
155 @DelayedCopy(inherit = true)
156 private List<T> delegate;
157
158
159
160
161
162
163 public LifecycleAwareList(LifecycleElement lifecycleElement) {
164 this.lifecycleElement = lifecycleElement;
165 this.delegate = Collections.emptyList();
166 }
167
168
169
170
171
172
173
174 public LifecycleAwareList(LifecycleElement lifecycleElement, List<T> delegate) {
175 this.lifecycleElement = lifecycleElement;
176
177 List<T> wrapped = delegate;
178 while (wrapped instanceof LifecycleAwareList) {
179 wrapped = ((LifecycleAwareList<T>) wrapped).delegate;
180 }
181
182 this.delegate = delegate;
183 }
184
185
186
187
188 private void ensureMutable() {
189 lifecycleElement.checkMutable(true);
190
191 if (delegate == Collections.EMPTY_LIST) {
192 delegate = new ArrayList<T>();
193 }
194 }
195
196 @Override
197 public int size() {
198 return this.delegate.size();
199 }
200
201 @Override
202 public boolean isEmpty() {
203 return this.delegate.isEmpty();
204 }
205
206 @Override
207 public boolean contains(Object o) {
208 return this.delegate.contains(o);
209 }
210
211 @Override
212 public Iterator<T> iterator() {
213 return new Iter();
214 }
215
216 @Override
217 public Object[] toArray() {
218 return this.delegate.toArray();
219 }
220
221 @Override
222 public <A> A[] toArray(A[] a) {
223 return this.delegate.toArray(a);
224 }
225
226 @Override
227 public boolean add(T e) {
228 ensureMutable();
229 return this.delegate.add(e);
230 }
231
232 @Override
233 public boolean remove(Object o) {
234 lifecycleElement.checkMutable(true);
235 return delegate != Collections.EMPTY_LIST && delegate.remove(o);
236 }
237
238 @Override
239 public boolean containsAll(Collection<?> c) {
240 return this.delegate.containsAll(c);
241 }
242
243 @Override
244 public boolean addAll(Collection<? extends T> c) {
245 ensureMutable();
246 return this.delegate.addAll(c);
247 }
248
249 @Override
250 public boolean addAll(int index, Collection<? extends T> c) {
251 ensureMutable();
252 return this.delegate.addAll(index, c);
253 }
254
255 @Override
256 public boolean removeAll(Collection<?> c) {
257 lifecycleElement.checkMutable(true);
258 return delegate != Collections.EMPTY_LIST && this.delegate.removeAll(c);
259 }
260
261 @Override
262 public boolean retainAll(Collection<?> c) {
263 lifecycleElement.checkMutable(true);
264 return delegate != Collections.EMPTY_LIST && this.delegate.retainAll(c);
265 }
266
267 @Override
268 public void clear() {
269 if (this.delegate != Collections.EMPTY_LIST) {
270 this.delegate.clear();
271 }
272 }
273
274 @Override
275 public boolean equals(Object o) {
276 return this.delegate.equals(o);
277 }
278
279 @Override
280 public int hashCode() {
281 return this.delegate.hashCode();
282 }
283
284 @Override
285 public T get(int index) {
286 return this.delegate.get(index);
287 }
288
289 @Override
290 public T set(int index, T element) {
291 lifecycleElement.checkMutable(true);
292 return this.delegate.set(index, element);
293 }
294
295 @Override
296 public void add(int index, T element) {
297 ensureMutable();
298 this.delegate.add(index, element);
299 }
300
301 @Override
302 public T remove(int index) {
303 lifecycleElement.checkMutable(true);
304 return this.delegate.remove(index);
305 }
306
307 @Override
308 public int indexOf(Object o) {
309 return this.delegate.indexOf(o);
310 }
311
312 @Override
313 public int lastIndexOf(Object o) {
314 return this.delegate.lastIndexOf(o);
315 }
316
317 @Override
318 public ListIterator<T> listIterator() {
319 ensureMutable();
320 return new ListIter();
321 }
322
323 @Override
324 public ListIterator<T> listIterator(int index) {
325 ensureMutable();
326 return new ListIter(index);
327 }
328
329 @Override
330 public List<T> subList(int fromIndex, int toIndex) {
331 return new LifecycleAwareList<T>(lifecycleElement, this.delegate.subList(fromIndex, toIndex));
332 }
333
334
335
336
337 @Override
338 public Object clone() throws CloneNotSupportedException {
339 return super.clone();
340 }
341
342 }