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 }