1 /*
2 * Scope: a generic MVC framework.
3 * Copyright (c) 2000-2002, The Scope team
4 * All rights reserved.
5 *
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * Neither the name "Scope" nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 *
35 *
36 * $Id: ArrayModel.java,v 1.7 2002/09/12 10:51:03 ludovicc Exp $
37 */
38 package org.scopemvc.model.collection;
39
40
41 import java.util.Arrays;
42 import java.util.Collection;
43 import java.util.Iterator;
44 import java.util.List;
45 import java.util.ListIterator;
46 import org.apache.commons.logging.Log;
47 import org.apache.commons.logging.LogFactory;
48 import org.scopemvc.core.ModelChangeEvent;
49 import org.scopemvc.core.ModelChangeEventSource;
50 import org.scopemvc.core.Selector;
51 import org.scopemvc.model.basic.BasicModel;
52
53 /***
54 * <P>
55 *
56 * A BasicModel wrapper for an <CODE>Object[]</CODE> that can propagate changes
57 * to contained Models up the Model hierarchy, and implements the java.util.List
58 * interface. The array itself is exposed via the "array" property, however,
59 * changes to this array must be made through the public API in order to
60 * maintain the model change propagation. </P> <P>
61 *
62 * By default ArrayModel registers itself as a listener to Models that are added
63 * to the array and deregisters when those Models are removed. This behaviour
64 * can be changed at creation so that ModelChangeEvent propagation is disabled.
65 * </P>
66 *
67 * @author <A HREF="mailto:smeyfroi@users.sourceforge.net">Steve Meyfroidt</A>
68 * @created 05 September 2002
69 * @version $Revision: 1.7 $ $Date: 2002/09/12 10:51:03 $
70 */
71 public class ArrayModel extends BasicModel implements List {
72
73 /***
74 * The selector for the array contained in this wrapper class.
75 */
76 public static final Selector ARRAY = Selector.fromString("array");
77
78 private static final String TO_STRING_SEPARATOR = ", ";
79 private static final int TO_STRING_SEPARATOR_LENGTH = TO_STRING_SEPARATOR.length();
80
81 private static final Log LOG = LogFactory.getLog(ArrayModel.class);
82
83 /***
84 * The wrapped array
85 */
86 private Object[] contents;
87
88 /***
89 * if true, propagate the changes made in the elements of the array
90 */
91 private boolean propagateModelChanges;
92
93
94 /***
95 * Constructor for the ArrayModel object
96 */
97 public ArrayModel() {
98 this(true);
99 }
100
101
102 /***
103 * Constructor for the ArrayModel object
104 *
105 * @param inArray The array to wrap
106 */
107 public ArrayModel(Object[] inArray) {
108 this(true);
109 setArray(inArray);
110 }
111
112
113 /***
114 * Constructor for the ArrayModel object
115 *
116 * @param inSize The initial size of the array
117 */
118 public ArrayModel(int inSize) {
119 this(true, inSize);
120 }
121
122
123 /***
124 * Constructor for the ArrayModel object
125 *
126 * @param inPropagateModelChanges If true, propagate the changes made in the
127 * elements of the array
128 */
129 public ArrayModel(boolean inPropagateModelChanges) {
130 propagateModelChanges = inPropagateModelChanges;
131 }
132
133
134 /***
135 * Constructor for the ArrayModel object
136 *
137 * @param inPropagateModelChanges If true, propagate the changes made in the
138 * elements of the array
139 * @param inSize The initial size of the array
140 */
141 public ArrayModel(boolean inPropagateModelChanges, int inSize) {
142 this(inPropagateModelChanges);
143 if (inSize < 0) {
144 throw new IllegalArgumentException("Can't create ArrayModel with size < 0: " + inSize);
145 }
146 setArray(new Object[inSize]);
147 }
148
149
150 /***
151 * Constructor for the ArrayModel object
152 *
153 * @param inPropagateModelChanges If true, propagate the changes made in the
154 * elements of the array
155 * @param inArray The array to wrap
156 */
157 public ArrayModel(boolean inPropagateModelChanges, Object[] inArray) {
158 this(inPropagateModelChanges);
159 setArray(inArray);
160 }
161
162
163 /***
164 * Gets the array
165 *
166 * @return The array value
167 */
168 public Object[] getArray() {
169 return contents;
170 }
171
172
173 /***
174 * Expose size as a JavaBeans property.
175 *
176 * @return size of array, 0 if null.
177 */
178 public int getSize() {
179 return size();
180 }
181
182
183 /***
184 * @param inValue TODO: Describe the Parameter
185 * @return The indexOf value
186 * @deprecated see indexOf
187 */
188 public int getIndexOf(Object inValue) {
189 if (inValue == null) {
190 return -1;
191 }
192 for (int i = 0; i < getSize(); ++i) {
193 if (inValue.equals(contents[i])) {
194 return i;
195 }
196 }
197 return -1;
198 }
199
200 /***
201 * Gets the empty
202 *
203 * @return The empty value
204 */
205 public boolean isEmpty() {
206 return (contents == null || contents.length < 1);
207 }
208
209 /***
210 * TODO: document the method
211 *
212 * @param index TODO: Describe the Parameter
213 * @return TODO: Describe the Return Value
214 */
215 public Object get(int index) {
216 return contents[index];
217 }
218
219
220 /***
221 * Set contents to the passed Object array and fire a ModelChangeEvent.
222 *
223 * @param inContents The new array value
224 */
225 public void setArray(Object[] inContents) {
226
227 if (propagateModelChanges) {
228 // Clear up old array if it contained any Models
229 if (contents != null) {
230 for (int i = 0; i < contents.length; ++i) {
231 Object o = contents[i];
232 if (o instanceof ModelChangeEventSource) {
233 ((ModelChangeEventSource) o).removeModelChangeListener(this);
234 }
235 }
236 }
237 }
238
239 contents = inContents;
240
241 if (propagateModelChanges) {
242 // Register as listener to any Models in the new array
243 if (contents != null) {
244 for (int i = 0; i < contents.length; ++i) {
245 Object o = contents[i];
246 if (o != null && o instanceof ModelChangeEventSource) {
247 ((ModelChangeEventSource) o).addModelChangeListener(this);
248 }
249 }
250 }
251 }
252
253 fireModelChange(ModelChangeEvent.VALUE_CHANGED, ARRAY);
254 }
255
256 /***
257 * TODO: document the method
258 *
259 * @param index TODO: Describe the Parameter
260 * @param element TODO: Describe the Parameter
261 * @return TODO: Describe the Return Value
262 */
263 public Object set(int index, Object element) {
264 if (LOG.isDebugEnabled()) {
265 LOG.debug("set: " + index + ", " + element);
266 }
267
268 Object oldValue = get(index);
269 contents[index] = element;
270 fireModelChange(VALUE_CHANGED, Selector.fromInt(index));
271
272 if (propagateModelChanges) {
273 if (oldValue instanceof ModelChangeEventSource) {
274 ((ModelChangeEventSource) oldValue).removeModelChangeListener(this);
275 }
276 if (element instanceof ModelChangeEventSource) {
277 ((ModelChangeEventSource) element).addModelChangeListener(this);
278 }
279 }
280
281 return oldValue;
282 }
283
284 /***
285 * TODO: document the method
286 *
287 * @return TODO: Describe the Return Value
288 */
289 public String toString() {
290
291 if (contents == null) {
292 return "";
293 }
294
295 StringBuffer result = new StringBuffer("(");
296
297 for (int i = 0; i < contents.length; ++i) {
298 result.append(contents[i] == null ? "[null]" : contents[i].toString());
299 result.append(TO_STRING_SEPARATOR);
300 }
301
302 if (contents.length > 0) {
303 result.setLength(result.length() - TO_STRING_SEPARATOR_LENGTH);
304 }
305 result.append(')');
306
307 return result.toString();
308 }
309
310
311 // -------------------------- implement List. This is mostly very lazy -- tidy up sometime. ------------------------------
312
313 /***
314 * TODO: document the method
315 *
316 * @return TODO: Describe the Return Value
317 */
318 public Iterator iterator() {
319 return Arrays.asList(contents).iterator();
320 }
321
322 /***
323 * TODO: document the method
324 *
325 * @return TODO: Describe the Return Value
326 */
327 public int size() {
328 if (contents == null) {
329 return 0;
330 }
331 return contents.length;
332 }
333
334 /***
335 * TODO: document the method
336 *
337 * @param a TODO: Describe the Parameter
338 * @return TODO: Describe the Return Value
339 */
340 public Object[] toArray(Object a[]) {
341 return Arrays.asList(contents).toArray(a);
342 }
343
344 /***
345 * TODO: document the method
346 *
347 * @param o TODO: Describe the Parameter
348 * @return TODO: Describe the Return Value
349 */
350 public boolean contains(Object o) {
351 return Arrays.asList(contents).contains(o);
352 }
353
354 /***
355 * TODO: document the method
356 *
357 * @param o TODO: Describe the Parameter
358 * @return TODO: Describe the Return Value
359 */
360 public boolean remove(Object o) {
361 throw new UnsupportedOperationException();
362 }
363
364 /***
365 * TODO: document the method
366 *
367 * @return TODO: Describe the Return Value
368 */
369 public Object[] toArray() {
370 return contents;
371 }
372
373 /***
374 * Adds an element to the All attribute of the ArrayModel object
375 *
376 * @param c The element to be added to the All attribute
377 * @return TODO: Describe the Return Value
378 */
379 public boolean addAll(Collection c) {
380 throw new UnsupportedOperationException();
381 }
382
383 /***
384 * TODO: document the method
385 *
386 * @param o TODO: Describe the Parameter
387 * @return TODO: Describe the Return Value
388 */
389 public boolean add(Object o) {
390 throw new UnsupportedOperationException();
391 }
392
393 /***
394 * TODO: document the method
395 *
396 * @param c TODO: Describe the Parameter
397 * @return TODO: Describe the Return Value
398 */
399 public boolean removeAll(Collection c) {
400 throw new UnsupportedOperationException();
401 }
402
403 /***
404 * TODO: document the method
405 *
406 * @param c TODO: Describe the Parameter
407 * @return TODO: Describe the Return Value
408 */
409 public boolean containsAll(Collection c) {
410 return Arrays.asList(contents).containsAll(c);
411 }
412
413 /***
414 * TODO: document the method
415 */
416 public void clear() {
417 throw new UnsupportedOperationException();
418 }
419
420 /***
421 * Adds an element to the All attribute of the ArrayModel object
422 *
423 * @param index The element to be added to the All attribute
424 * @param c The element to be added to the All attribute
425 * @return TODO: Describe the Return Value
426 */
427 public boolean addAll(int index, Collection c) {
428 throw new UnsupportedOperationException();
429 }
430
431 /***
432 * TODO: document the method
433 *
434 * @return TODO: Describe the Return Value
435 */
436 public int hashCode() {
437 return contents.hashCode();
438 }
439
440 /***
441 * TODO: document the method
442 *
443 * @param c TODO: Describe the Parameter
444 * @return TODO: Describe the Return Value
445 */
446 public boolean retainAll(Collection c) {
447 throw new UnsupportedOperationException();
448 }
449
450 /***
451 * TODO: document the method
452 *
453 * @param o TODO: Describe the Parameter
454 * @return TODO: Describe the Return Value
455 */
456 public boolean equals(Object o) {
457 return contents.equals(o);
458 }
459
460 /***
461 * TODO: document the method
462 *
463 * @param index TODO: Describe the Parameter
464 * @return TODO: Describe the Return Value
465 */
466 public Object remove(int index) {
467 throw new UnsupportedOperationException();
468 }
469
470 /***
471 * TODO: document the method
472 *
473 * @param o TODO: Describe the Parameter
474 * @return TODO: Describe the Return Value
475 */
476 public int lastIndexOf(Object o) {
477 return Arrays.asList(contents).lastIndexOf(o);
478 }
479
480 /***
481 * TODO: document the method
482 *
483 * @param index TODO: Describe the Parameter
484 * @param element TODO: Describe the Parameter
485 */
486 public void add(int index, Object element) {
487 throw new UnsupportedOperationException();
488 }
489
490 /***
491 * TODO: document the method
492 *
493 * @param index TODO: Describe the Parameter
494 * @return TODO: Describe the Return Value
495 */
496 public ListIterator listIterator(int index) {
497 return Arrays.asList(contents).listIterator(index);
498 }
499
500 /***
501 * TODO: document the method
502 *
503 * @param o TODO: Describe the Parameter
504 * @return TODO: Describe the Return Value
505 */
506 public int indexOf(Object o) {
507 return getIndexOf(o);
508 }
509
510 /***
511 * TODO: document the method
512 *
513 * @return TODO: Describe the Return Value
514 */
515 public ListIterator listIterator() {
516 return Arrays.asList(contents).listIterator();
517 }
518
519 /***
520 * TODO: document the method
521 *
522 * @param fromIndex TODO: Describe the Parameter
523 * @param toIndex TODO: Describe the Parameter
524 * @return TODO: Describe the Return Value
525 */
526 public List subList(int fromIndex, int toIndex) {
527 return Arrays.asList(contents).subList(fromIndex, toIndex);
528 }
529 }
This page was automatically generated by Maven