1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.kuali.rice.kns.util.spring;
18
19 import java.io.Serializable;
20 import java.lang.reflect.Modifier;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.Iterator;
24 import java.util.List;
25 import java.util.ListIterator;
26
27 import org.springframework.util.Assert;
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 public class AutoPopulatingList extends Object implements List, Serializable {
45
46
47
48
49 private final List backingList;
50
51
52
53
54
55 private final ElementFactory elementFactory;
56
57
58
59
60
61
62
63
64 public AutoPopulatingList(Class elementClass) {
65 this(new ArrayList(), elementClass);
66 }
67
68 public AutoPopulatingList() {
69 this(new ArrayList(), String.class);
70 }
71
72
73
74
75
76
77 public AutoPopulatingList(List backingList, Class elementClass) {
78 this(backingList, new ReflectiveElementFactory(elementClass));
79 }
80
81
82
83
84
85 public AutoPopulatingList(ElementFactory elementFactory) {
86 this(new ArrayList(), elementFactory);
87 }
88
89
90
91
92
93 public AutoPopulatingList(List backingList, ElementFactory elementFactory) {
94 Assert.notNull(backingList, "Backing List must not be null");
95 Assert.notNull(elementFactory, "Element factory must not be null");
96 this.backingList = backingList;
97 this.elementFactory = elementFactory;
98 }
99
100
101 public void add(int index, Object element) {
102 this.backingList.add(index, element);
103 }
104
105 public boolean add(Object o) {
106 return this.backingList.add(o);
107 }
108
109 public boolean addAll(Collection c) {
110 return this.backingList.addAll(c);
111 }
112
113 public boolean addAll(int index, Collection c) {
114 return this.backingList.addAll(index, c);
115 }
116
117 public void clear() {
118 this.backingList.clear();
119 }
120
121 public boolean contains(Object o) {
122 return this.backingList.contains(o);
123 }
124
125 public boolean containsAll(Collection c) {
126 return this.backingList.containsAll(c);
127 }
128
129 public boolean equals(Object o) {
130 return this.backingList.equals(o);
131 }
132
133
134
135
136
137 public Object get(int index) {
138 int backingListSize = this.backingList.size();
139
140 Object element = null;
141 if (index < backingListSize) {
142 element = this.backingList.get(index);
143 if (element == null) {
144 element = this.elementFactory.createElement(index);
145 this.backingList.set(index, element);
146 }
147 }
148 else {
149 for (int x = backingListSize; x < index; x++) {
150 this.backingList.add(null);
151 }
152 element = this.elementFactory.createElement(index);
153 this.backingList.add(element);
154 }
155 return element;
156 }
157
158 public int hashCode() {
159 return this.backingList.hashCode();
160 }
161
162 public int indexOf(Object o) {
163 return this.backingList.indexOf(o);
164 }
165
166 public boolean isEmpty() {
167 return this.backingList.isEmpty();
168 }
169
170 public Iterator iterator() {
171 return this.backingList.iterator();
172 }
173
174 public int lastIndexOf(Object o) {
175 return this.backingList.lastIndexOf(o);
176 }
177
178 public ListIterator listIterator() {
179 return this.backingList.listIterator();
180 }
181
182 public ListIterator listIterator(int index) {
183 return this.backingList.listIterator(index);
184 }
185
186 public Object remove(int index) {
187 return this.backingList.remove(index);
188 }
189
190 public boolean remove(Object o) {
191 return this.backingList.remove(o);
192 }
193
194 public boolean removeAll(Collection c) {
195 return this.backingList.removeAll(c);
196 }
197
198 public boolean retainAll(Collection c) {
199 return this.backingList.retainAll(c);
200 }
201
202 public Object set(int index, Object element) {
203 get( index );
204 return this.backingList.set(index, element);
205 }
206
207 public int size() {
208 return this.backingList.size();
209 }
210
211 public List subList(int fromIndex, int toIndex) {
212 return this.backingList.subList(fromIndex, toIndex);
213 }
214
215 public Object[] toArray() {
216 return this.backingList.toArray();
217 }
218
219 public Object[] toArray(Object[] a) {
220 return this.backingList.toArray(a);
221 }
222
223
224
225
226
227
228 public interface ElementFactory {
229
230
231
232
233
234
235
236 Object createElement(int index) throws ElementInstantiationException;
237 }
238
239
240
241
242
243 public static class ElementInstantiationException extends RuntimeException {
244
245 public ElementInstantiationException(String msg) {
246 super(msg);
247 }
248 }
249
250
251
252
253
254
255
256 private static class ReflectiveElementFactory implements ElementFactory, Serializable {
257
258 private final Class elementClass;
259
260 public ReflectiveElementFactory(Class elementClass) {
261 Assert.notNull(elementClass, "Element clas must not be null");
262 Assert.isTrue(!elementClass.isInterface(), "Element class must not be an interface type");
263 Assert.isTrue(!Modifier.isAbstract(elementClass.getModifiers()), "Element class cannot be an abstract class");
264 this.elementClass = elementClass;
265 }
266
267 public Object createElement(int index) {
268 try {
269 return this.elementClass.newInstance();
270 }
271 catch (InstantiationException ex) {
272 throw new ElementInstantiationException("Unable to instantiate element class [" +
273 this.elementClass.getName() + "]. Root cause is " + ex);
274 }
275 catch (IllegalAccessException ex) {
276 throw new ElementInstantiationException("Cannot access element class [" +
277 this.elementClass.getName() + "]. Root cause is " + ex);
278 }
279 }
280 }
281
282 }