1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package net.wotonomy.web;
20
21 import java.util.Collection;
22 import java.util.Iterator;
23 import java.util.List;
24
25 import net.wotonomy.control.EOObserverCenter;
26 import net.wotonomy.control.EOObserving;
27 import net.wotonomy.foundation.NSMutableArray;
28 import net.wotonomy.foundation.NSRange;
29
30 /***
31 * A package class that extends NSMutableArray but makes use
32 * of the fact that wotonomy's implementation extends ArrayList
33 * to intercept insertions and deletion and register and
34 * unregister objects for change notifications as appropriate.
35 * Since we can't be sure of ArrayList's implementation, we're
36 * forced to override each and every add and remove method,
37 * some of which probably call each other. However,
38 * EOObserverCenter will only register us once per object.
39 */
40 class ObservableArray extends NSMutableArray
41 {
42 EOObserving observer;
43
44 ObservableArray( EOObserving anObserver )
45 {
46 observer = anObserver;
47 }
48
49 /***
50 * Removes the last object from the array.
51 */
52 public void removeLastObject ()
53 {
54 remove( count() - 1 );
55 }
56
57 /***
58 * Removes the object at the specified index.
59 */
60 public void removeObjectAtIndex (int index)
61 {
62 remove( index );
63 }
64
65 /***
66 * Adds all objects in the specified collection.
67 */
68 public void addObjectsFromArray (Collection aCollection)
69 {
70 addAll( aCollection );
71 }
72
73 /***
74 * Removes all objects from the array.
75 */
76 public void removeAllObjects ()
77 {
78 clear();
79 }
80
81 /***
82 * Removes all objects equivalent to the specified object
83 * within the range of specified indices.
84 */
85 public void removeObject (Object anObject, NSRange aRange)
86 {
87 if ( ( anObject == null ) || ( aRange == null ) ) return;
88
89 int loc = aRange.location();
90 int max = aRange.maxRange();
91 for ( int i = loc; i < max; i++ )
92 {
93 if ( anObject.equals( get( i ) ) )
94 {
95 remove( i );
96 i = i - 1;
97 max = max - 1;
98 }
99 }
100 }
101
102 /***
103 * Removes all instances of the specified object within the
104 * range of specified indices, comparing by reference.
105 */
106 public void removeIdenticalObject (Object anObject, NSRange aRange)
107 {
108 if ( ( anObject == null ) || ( aRange == null ) ) return;
109
110 int loc = aRange.location();
111 int max = aRange.maxRange();
112 for ( int i = loc; i < max; i++ )
113 {
114 if ( anObject == get( i ) )
115 {
116 remove( i );
117 i = i - 1;
118 max = max - 1;
119 }
120 }
121 }
122
123 /***
124 * Removes all objects in the specified collection from the array.
125 */
126 public void removeObjectsInArray (Collection aCollection)
127 {
128 removeAll( aCollection );
129 }
130
131 /***
132 * Removes all objects in the indices within the specified range
133 * from the array.
134 */
135 public void removeObjectsInRange (NSRange aRange)
136 {
137 if ( aRange == null ) return;
138
139 for ( int i = 0; i < aRange.length(); i++ )
140 {
141 remove( aRange.location() );
142 }
143 }
144
145 /***
146 * Replaces objects in the current range with objects from
147 * the specified range of the specified array. If currentRange
148 * is larger than otherRange, the extra objects are removed.
149 * If otherRange is larger than currentRange, the extra objects
150 * are added.
151 */
152 public void replaceObjectsInRange (NSRange currentRange,
153 List otherArray, NSRange otherRange)
154 {
155 if ( ( currentRange == null ) || ( otherArray == null ) ||
156 ( otherRange == null ) ) return;
157
158
159 if ( otherRange.maxRange() > otherArray.size() )
160 {
161
162 int loc = Math.min( otherRange.location(), otherArray.size() - 1 );
163 otherRange = new NSRange( loc, otherArray.size() - loc );
164 }
165
166 Object o;
167 List subList = subList(
168 currentRange.location(), currentRange.maxRange() );
169 int otherIndex = otherRange.location();
170
171 for ( int i = 0; i < subList.size(); i++ )
172 {
173 if ( otherIndex < otherRange.maxRange() )
174 {
175 subList.set( i, otherArray.get( otherIndex ) );
176 }
177 else
178 {
179 subList.remove( i );
180 i--;
181 }
182 otherIndex++;
183 }
184
185 for ( int i = otherIndex; i < otherRange.maxRange(); i++ )
186 {
187 add( otherArray.get( i ) );
188 }
189 }
190
191 /***
192 * Clears the current array and then populates it with the
193 * contents of the specified collection.
194 */
195 public void setArray (Collection aCollection)
196 {
197 clear();
198 addAll( aCollection );
199 }
200
201 /***
202 * Removes all objects equivalent to the specified object.
203 */
204 public void removeObject (Object anObject)
205 {
206 remove( anObject );
207 }
208
209 /***
210 * Removes all occurences of the specified object,
211 * comparing by reference.
212 */
213 public void removeIdenticalObject (Object anObject)
214 {
215 EOObserverCenter.removeObserver( observer, anObject );
216 super.removeIdenticalObject( anObject );
217 }
218
219 /***
220 * Inserts the specified object into this array at the
221 * specified index.
222 */
223 public void insertObjectAtIndex (Object anObject, int anIndex)
224 {
225 add( anIndex, anObject );
226 }
227
228 /***
229 * Replaces the object at the specified index with the
230 * specified object.
231 */
232 public void replaceObjectAtIndex (int anIndex, Object anObject)
233 {
234 set( anIndex, anObject );
235 }
236
237 /***
238 * Adds the specified object to the end of this array.
239 */
240 public void addObject (Object anObject)
241 {
242 add( anObject );
243 }
244
245
246
247 public void add(int index, Object element)
248 {
249 EOObserverCenter.addObserver( observer, element );
250 super.add( index, element );
251 }
252
253 public boolean add(Object o)
254 {
255 EOObserverCenter.addObserver( observer, o );
256 return super.add(o);
257 }
258
259 public boolean addAll(Collection coll)
260 {
261 Iterator it = coll.iterator();
262 while ( it.hasNext() )
263 {
264 EOObserverCenter.addObserver( observer, it.next() );
265 }
266 return super.addAll(coll);
267 }
268
269 public boolean addAll(int index, Collection c)
270 {
271 Iterator it = c.iterator();
272 while ( it.hasNext() )
273 {
274 EOObserverCenter.addObserver( observer, it.next() );
275 }
276 return super.addAll( index, c );
277 }
278
279 public void clear()
280 {
281 Iterator it = iterator();
282 while ( it.hasNext() )
283 {
284 EOObserverCenter.removeObserver( observer, it.next() );
285 }
286 super.clear();
287 }
288
289 public Object remove(int index)
290 {
291 EOObserverCenter.removeObserver( observer, get(index) );
292 return super.remove( index );
293 }
294
295 public boolean remove(Object o)
296 {
297 EOObserverCenter.removeObserver( observer, o );
298 return super.remove(o);
299 }
300
301 public boolean removeAll(Collection coll)
302 {
303 Iterator it = coll.iterator();
304 while ( it.hasNext() )
305 {
306 EOObserverCenter.removeObserver( observer, it.next() );
307 }
308 return super.removeAll(coll);
309 }
310
311 public boolean retainAll(Collection coll)
312 {
313 throw new UnsupportedOperationException();
314 }
315
316 public Object set(int index, Object element)
317 {
318 EOObserverCenter.removeObserver( observer, get(index) );
319 EOObserverCenter.addObserver( observer, element );
320 return super.set( index, element );
321 }
322 }
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351