KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > emf > common > util > DelegatingEList


1 /**
2  * <copyright>
3  *
4  * Copyright (c) 2002-2004 IBM Corporation and others.
5  * All rights reserved. This program and the accompanying materials
6  * are made available under the terms of the Eclipse Public License v1.0
7  * which accompanies this distribution, and is available at
8  * http://www.eclipse.org/legal/epl-v10.html
9  *
10  * Contributors:
11  * IBM - Initial API and implementation
12  *
13  * </copyright>
14  *
15  * $Id: DelegatingEList.java,v 1.4 2005/06/08 06:19:08 nickb Exp $
16  */

17 package org.eclipse.emf.common.util;
18
19
20 import java.io.Serializable JavaDoc;
21 import java.util.AbstractList JavaDoc;
22 import java.util.Collection JavaDoc;
23 import java.util.ConcurrentModificationException JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.List JavaDoc;
26 import java.util.ListIterator JavaDoc;
27 import java.util.NoSuchElementException JavaDoc;
28
29
30 /**
31  * A highly extensible delegating list implementation.
32  */

33 public abstract class DelegatingEList extends AbstractList JavaDoc implements EList, Cloneable JavaDoc, Serializable JavaDoc
34 {
35   /**
36    * Creates an empty instance.
37    */

38   public DelegatingEList()
39   {
40   }
41
42   /**
43    * Creates an instance that is a copy of the collection.
44    * @param collection the initial contents of the list.
45    */

46   public DelegatingEList(Collection JavaDoc collection)
47   {
48     addAll(collection);
49   }
50
51   /**
52    * Returns whether <code>equals</code> rather than <code>==</code> should be used to compare members.
53    * The default is to return <code>true</code> but clients can optimize performance by returning <code>false</code>.
54    * The performance difference is highly significant.
55    * @return whether <code>equals</code> rather than <code>==</code> should be used.
56    */

57   protected boolean useEquals()
58   {
59     return true;
60   }
61
62   /**
63    * Returns whether two objects are equal using the {@link #useEquals appropriate} comparison mechanism.
64    * @return whether two objects are equal.
65    */

66   protected boolean equalObjects(Object JavaDoc firstObject, Object JavaDoc secondObject)
67   {
68     return
69       useEquals() && firstObject != null ?
70         firstObject.equals(secondObject) :
71         firstObject == secondObject;
72   }
73
74   /**
75    * Returns whether <code>null</code> is a valid object for the list.
76    * The default is to return <code>true</code>, but clients can override this to exclude <code>null</code>.
77    * @return whether <code>null</code> is a valid object for the list.
78    */

79   protected boolean canContainNull()
80   {
81     return true;
82   }
83
84   /**
85    * Returns whether objects are constrained to appear at most once in the list.
86    * The default is to return <code>false</code>, but clients can override this to ensure uniqueness of contents.
87    * The performance impact is signifcant: operations such as <code>add</code> are O(n) as a result requiring uniqueness.
88    * @return whether objects are constrained to appear at most once in the list.
89    */

90   protected boolean isUnique()
91   {
92     return false;
93   }
94
95   /**
96    * Validates a new content object and returns the validated object.
97    * This implementation checks for null, if {@link #canContainNull necessary} and returns the argument object.
98    * Clients may throw additional types of runtime exceptions
99    * in order to handle constraint violations.
100    * @param index the position of the new content.
101    * @param object the new content.
102    * @return the validated content.
103    * @exception IllegalArgumentException if a constraint prevents the object from being added.
104    */

105   protected Object JavaDoc validate(int index, Object JavaDoc object)
106   {
107     if (!canContainNull() && object == null)
108     {
109       throw new IllegalArgumentException JavaDoc("The 'no null' constraint is violated");
110     }
111
112     return object;
113   }
114
115   /**
116    * Resolves the object at the index and returns the result.
117    * This implementation simply returns the <code>object</code>;
118    * clients can use this to transform objects as they are fetched.
119    * @param index the position of the content.
120    * @param object the content.
121    * @return the resolved object.
122    */

123   protected Object JavaDoc resolve(int index, Object JavaDoc object)
124   {
125     return object;
126   }
127
128   /**
129    * Called to indicate that the backing store list has been set.
130    * This implementation does nothing;
131    * clients can use this to monitor settings to the backing store list.
132    * @param index the position that was set.
133    * @param newObject the new object at the position.
134    * @param oldObject the old object at the position.
135    */

136   protected void didSet(int index, Object JavaDoc newObject, Object JavaDoc oldObject)
137   {
138   }
139
140   /**
141    * Called to indicate that an object has been added to the backing store list.
142    * This implementation does nothing;
143    * clients can use this to monitor additions to the backing store list.
144    * @param index the position object the new object.
145    * @param newObject the new object at the position.
146    */

147   protected void didAdd(int index, Object JavaDoc newObject)
148   {
149   }
150
151   /**
152    * Called to indicate that an object has been removed from the backing store list.
153    * This implementation does nothing;
154    * clients can use this to monitor removals from the backing store list.
155    * @param index the position of the old object.
156    * @param oldObject the old object at the position.
157    */

158   protected void didRemove(int index, Object JavaDoc oldObject)
159   {
160   }
161
162   /**
163    * Called to indicate that the backing store list has been cleared.
164    * This implementation calls {@link #didRemove didRemove} for each object;
165    * clients can use this to monitor clearing of the backing store list.
166    * @param size the original size of the list.
167    * @param oldObjects the old backing store list being discarded.
168    * @see #didRemove
169    */

170   protected void didClear(int size, Object JavaDoc [] oldObjects)
171   {
172     if (oldObjects != null)
173     {
174       for (int i = 0; i < size; ++i)
175       {
176         didRemove(i, oldObjects[i]);
177       }
178     }
179   }
180
181   /**
182    * Called to indicate that an object has been moved in the backing store list.
183    * This implementation does nothing;
184    * clients can use this to monitor movement in the backing store list.
185    * @param index the position of the moved object.
186    * @param movedObject the moved object at the position.
187    * @param oldIndex the position the object was at before the move.
188    */

189   protected void didMove(int index, Object JavaDoc movedObject, int oldIndex)
190   {
191   }
192
193   /**
194    * Called to indicate that the backing store list has been changed.
195    * This implementation does nothing;
196    * clients can use this to monitor change in the backing store list.
197    */

198   protected void didChange()
199   {
200   }
201
202   /**
203    * Returns the list that acts as the backing store.
204    * @return the list that acts as the backing store.
205    */

206   protected abstract List JavaDoc delegateList();
207
208   /**
209    * Returns the number of objects in the list.
210    * @return the number of objects in the list.
211    */

212   public int size()
213   {
214     return delegateSize();
215   }
216
217   /**
218    * Returns the number of objects in the backing store list.
219    * @return the number of objects in the backing store list.
220    */

221   protected int delegateSize()
222   {
223     return delegateList().size();
224   }
225
226   /**
227    * Returns whether the list has zero size.
228    * @return whether the list has zero size.
229    */

230   public boolean isEmpty()
231   {
232     return delegateIsEmpty();
233   }
234
235   /**
236    * Returns whether the backing store list has zero size.
237    * @return whether the backing store list has zero size.
238    */

239   protected boolean delegateIsEmpty()
240   {
241     return delegateList().isEmpty();
242   }
243
244   /**
245    * Returns whether the list contains the object.
246    * @param object the object in question.
247    * @return whether the list contains the object.
248    */

249   public boolean contains(Object JavaDoc object)
250   {
251     return delegateContains(object);
252   }
253
254   /**
255    * Returns whether the backing store list contains the object.
256    * @param object the object in question.
257    * @return whether the backing store list contains the object.
258    */

259   protected boolean delegateContains(Object JavaDoc object)
260   {
261     return delegateList().contains(object);
262   }
263
264   /**
265    * Returns whether the list contains each object in the collection.
266    * @return whether the list contains each object in the collection.
267    * @see #contains
268    * @see #useEquals
269    */

270   public boolean containsAll(Collection JavaDoc collection)
271   {
272     return delegateContainsAll(collection);
273   }
274
275   /**
276    * Returns whether the backing store list contains each object in the collection.
277    * @return whether the backing store list contains each object in the collection.
278    * @see #contains
279    * @see #useEquals
280    */

281   protected boolean delegateContainsAll(Collection JavaDoc collection)
282   {
283     return delegateList().containsAll(collection);
284   }
285
286   /**
287    * Returns the position of the first occurrence of the object in the list.
288    * @param object the object in question.
289    * @return the position of the first occurrence of the object in the list.
290    */

291   public int indexOf(Object JavaDoc object)
292   {
293     return delegateIndexOf(object);
294   }
295
296   /**
297    * Returns the position of the first occurrence of the object in the backing store list.
298    * @param object the object in question.
299    * @return the position of the first occurrence of the object in the backing store list.
300    */

301   protected int delegateIndexOf(Object JavaDoc object)
302   {
303     return delegateList().indexOf(object);
304   }
305
306   /**
307    * Returns the position of the last occurrence of the object in the list.
308    * @param object the object in question.
309    * @return the position of the last occurrence of the object in the list.
310    */

311   public int lastIndexOf(Object JavaDoc object)
312   {
313     return delegateLastIndexOf(object);
314   }
315
316   /**
317    * Returns the position of the last occurrence of the object in the backing store list.
318    * @param object the object in question.
319    * @return the position of the last occurrence of the object in the backing store list.
320    */

321   protected int delegateLastIndexOf(Object JavaDoc object)
322   {
323     return delegateList().lastIndexOf(object);
324   }
325
326   /**
327    * Returns an array containing all the objects in sequence.
328    * @return an array containing all the objects in sequence.
329    */

330   public Object JavaDoc[] toArray()
331   {
332     return delegateToArray();
333   }
334
335   /**
336    * Returns an array containing all the objects in the backing store list in sequence.
337    * @return an array containing all the objects in the backing store list in sequence.
338    */

339   protected Object JavaDoc[] delegateToArray()
340   {
341     return delegateList().toArray();
342   }
343
344   /**
345    * Returns an array containing all the objects in sequence.
346    * @param array the array that will be filled and returned, if it's big enough;
347    * otherwise, a suitably large array of the same type will be allocated and used instead.
348    * @return an array containing all the objects in sequence.
349    */

350   public Object JavaDoc[] toArray(Object JavaDoc array[])
351   {
352     return delegateToArray(array);
353   }
354
355   /**
356    * Returns an array containing all the objects in the backing store list in sequence.
357    * @param array the array that will be filled and returned, if it's big enough;
358    * otherwise, a suitably large array of the same type will be allocated and used instead.
359    * @return an array containing all the objects in sequence.
360    */

361   protected Object JavaDoc[] delegateToArray(Object JavaDoc array[])
362   {
363     return delegateList().toArray(array);
364   }
365
366   /**
367    * Returns the object at the index.
368    * This implementation delegates to {@link #resolve resolve}
369    * so that clients may transform the fetched object.
370    * @param index the position in question.
371    * @return the object at the index.
372    * @exception IndexOutOfBoundsException if the index isn't within the size range.
373    * @see #resolve
374    * @see #basicGet
375    */

376   public Object JavaDoc get(int index)
377   {
378     return resolve(index, delegateGet(index));
379   }
380
381   /**
382    * Returns the object at the index in the backing store list.
383    * @param index the position in question.
384    * @return the object at the index.
385    * @exception IndexOutOfBoundsException if the index isn't within the size range.
386    */

387   protected Object JavaDoc delegateGet(int index)
388   {
389     return delegateList().get(index);
390   }
391
392   /**
393    * Returns the object at the index without {@link #resolve resolving} it.
394    * @param index the position in question.
395    * @return the object at the index.
396    * @exception IndexOutOfBoundsException if the index isn't within the size range.
397    * @see #resolve
398    * @see #get
399    */

400   protected Object JavaDoc basicGet(int index)
401   {
402     return delegateGet(index);
403   }
404
405   /**
406    * Sets the object at the index
407    * and returns the old object at the index.
408    * This implementation delegates to {@link #setUnique setUnique}
409    * after range checking and after {@link #isUnique uniqueness} checking.
410    * @param index the position in question.
411    * @param object the object to set.
412    * @return the old object at the index.
413    * @exception IndexOutOfBoundsException if the index isn't within the size range.
414    * @exception IllegalArgumentException if there is a constraint violation, e.g., non-uniqueness.
415    * @see #setUnique
416    */

417   public Object JavaDoc set(int index, Object JavaDoc object)
418   {
419     if (isUnique())
420     {
421       int currentIndex = indexOf(object);
422       if (currentIndex >= 0 && currentIndex != index)
423       {
424         throw new IllegalArgumentException JavaDoc("The 'no duplicates' constraint is violated");
425       }
426     }
427
428     return setUnique(index, object);
429   }
430
431   /**
432    * Sets the object at the index
433    * and returns the old object at the index;
434    * it does no ranging checking or uniqueness checking.
435    * This implementation delegates to {@link #didSet didSet} and {@link #didChange didChange}.
436    * @param index the position in question.
437    * @param object the object to set.
438    * @return the old object at the index.
439    * @see #set
440    */

441   public Object JavaDoc setUnique(int index, Object JavaDoc object)
442   {
443     Object JavaDoc oldObject = delegateSet(index, validate(index, object));
444     didSet(index, object, oldObject);
445     didChange();
446     return oldObject;
447   }
448
449   /**
450    * Sets the object at the index in the backing store list
451    * and returns the old object at the index.
452    * @param object the object to set.
453    * @return the old object at the index.
454    */

455   protected Object JavaDoc delegateSet(int index, Object JavaDoc object)
456   {
457     return delegateList().set(index, object);
458   }
459
460   /**
461    * Adds the object at the end of the list
462    * and returns whether the object was added;
463    * if {@link #isUnique uniqueness} is required,
464    * duplicates will be ignored and <code>false</code> will be returned.
465    * This implementation delegates to {@link #addUnique(Object) addUnique(Object)}
466    * after uniqueness checking.
467    * @param object the object to be added.
468    * @return whether the object was added.
469    * @see #addUnique(Object)
470    */

471   public boolean add(Object JavaDoc object)
472   {
473     if (isUnique() && contains(object))
474     {
475       return false;
476     }
477     else
478     {
479       addUnique(object);
480       return true;
481     }
482   }
483
484   /**
485    * Adds the object at the end of the list;
486    * it does no uniqueness checking.
487    * This implementation delegates to {@link #didAdd didAdd} and {@link #didChange didChange}.
488    * after uniqueness checking.
489    * @param object the object to be added.
490    * @see #add(Object)
491    */

492   public void addUnique(Object JavaDoc object)
493   {
494     ++modCount;
495
496     int size = size();
497     delegateAdd(validate(size, object));
498     didAdd(size, object);
499     didChange();
500   }
501
502   /**
503    * Adds the object at the end of the backing store list.
504    * @param object the object to be added.
505    */

506   protected void delegateAdd(Object JavaDoc object)
507   {
508     delegateList().add(object);
509   }
510
511   /**
512    * Adds the object at the given index in the list.
513    * If {@link #isUnique uniqueness} is required,
514    * duplicates will be ignored.
515    * This implementation delegates to {@link #addUnique(int, Object) addUnique(int, Object)}
516    * after uniqueness checking.
517    * @param object the object to be added.
518    * @exception IllegalArgumentException if {@link #isUnique uniqueness} is required,
519    * and the object is a duplicate.
520    * @see #addUnique(int, Object)
521    */

522   public void add(int index, Object JavaDoc object)
523   {
524     if (isUnique() && contains(object))
525     {
526       throw new IllegalArgumentException JavaDoc("The 'no duplicates' constraint is violated");
527     }
528
529     addUnique(index, object);
530   }
531
532   /**
533    * Adds the object at the given index in the list;
534    * it does no ranging checking or uniqueness checking.
535    * This implementation delegates to {@link #didAdd didAdd} and {@link #didChange didChange}.
536    * @param object the object to be added.
537    * @see #add(int, Object)
538    */

539   public void addUnique(int index, Object JavaDoc object)
540   {
541     ++modCount;
542
543     delegateAdd(index, validate(index, object));
544     didAdd(index, object);
545     didChange();
546   }
547
548   /**
549    * Adds the object at the given index in the backing store list.
550    * @param object the object to be added.
551    */

552   protected void delegateAdd(int index, Object JavaDoc object)
553   {
554     delegateList().add(index, object);
555   }
556
557   /**
558    * Adds each object of the collection to the end of the list.
559    * If {@link #isUnique uniqueness} is required,
560    * duplicates will be {@link #getNonDuplicates removed} from the collection,
561    * which could even result in an empty collection.
562    * This implementation delegates to {@link #addAllUnique(Collection) addAllUnique(Collection)}
563    * after uniqueness checking.
564    * @param collection the collection of objects to be added.
565    * @see #addAllUnique(Collection)
566    */

567   public boolean addAll(Collection JavaDoc collection)
568   {
569     if (isUnique())
570     {
571       collection = getNonDuplicates(collection);
572     }
573     return addAllUnique(collection);
574   }
575
576   /**
577    * Adds each object of the collection to the end of the list;
578    * it does no uniqueness checking.
579    * This implementation delegates to {@link #didAdd didAdd} and {@link #didChange didChange}.
580    * @param collection the collection of objects to be added.
581    * @see #addAll(Collection)
582    */

583   public boolean addAllUnique(Collection JavaDoc collection)
584   {
585     ++modCount;
586
587     if (collection.isEmpty())
588     {
589       return false;
590     }
591     else
592     {
593       int i = size();
594       for (Iterator JavaDoc objects = collection.iterator(); objects.hasNext(); ++i)
595       {
596         Object JavaDoc object = objects.next();
597         delegateAdd(validate(i, object));
598         didAdd(i, object);
599         didChange();
600       }
601   
602       return true;
603     }
604   }
605
606   /**
607    * Adds each object of the collection at each successive index in the list
608    * and returns whether any objects were added.
609    * If {@link #isUnique uniqueness} is required,
610    * duplicates will be {@link #getNonDuplicates removed} from the collection,
611    * which could even result in an empty collection.
612    * This implementation delegates to {@link #addAllUnique(int, Collection) addAllUnique(int, Collection)}
613    * after uniqueness checking.
614    * @param index the index at which to add.
615    * @param collection the collection of objects to be added.
616    * @return whether any objects were added.
617    * @see #addAllUnique(int, Collection)
618    */

619   public boolean addAll(int index, Collection JavaDoc collection)
620   {
621     if (isUnique())
622     {
623       collection = getNonDuplicates(collection);
624     }
625     return addAllUnique(index, collection);
626   }
627
628   /**
629    * Adds each object of the collection at each successive index in the list
630    * and returns whether any objects were added;
631    * it does no ranging checking or uniqueness checking.
632    * This implementation delegates to {@link #didAdd didAdd} and {@link #didChange didChange}.
633    * @param index the index at which to add.
634    * @param collection the collection of objects to be added.
635    * @return whether any objects were added.
636    * @see #addAll(int, Collection)
637    */

638   public boolean addAllUnique(int index, Collection JavaDoc collection)
639   {
640     ++modCount;
641
642     if (collection.isEmpty())
643     {
644       return false;
645     }
646     else
647     {
648       for (Iterator JavaDoc objects = collection.iterator(); objects.hasNext(); ++index)
649       {
650         Object JavaDoc object = objects.next();
651         delegateAdd(index, validate(index, object));
652         didAdd(index, object);
653         didChange();
654       }
655
656       return true;
657     }
658   }
659
660   /**
661    * Removes the object from the list and returns whether the object was actually contained by the list.
662    * This implementation uses {@link #indexOf indexOf} to find the object
663    * and delegates to {@link #remove(int) remove(int)}
664    * in the case that it finds the object.
665    * @param object the object to be removed.
666    * @return whether the object was actually contained by the list.
667    */

668   public boolean remove(Object JavaDoc object)
669   {
670     int index = indexOf(object);
671     if (index >= 0)
672     {
673       remove(index);
674       return true;
675     }
676     else
677     {
678       return false;
679     }
680   }
681
682   /**
683    * Removes each object of the collection from the list and returns whether any object was actually contained by the list.
684    * @param collection the collection of objects to be removed.
685    * @return whether any object was actually contained by the list.
686    */

687   public boolean removeAll(Collection JavaDoc collection)
688   {
689     boolean modified = false;
690     for (ListIterator JavaDoc i = delegateListIterator(); i.hasNext(); )
691     {
692       if (collection.contains(i.next()))
693       {
694         remove(i.previousIndex());
695         modified = true;
696       }
697     }
698
699     return modified;
700   }
701
702   /**
703    * Removes the object at the index from the list and returns it.
704    * This implementation delegates to {@link #didRemove didRemove} and {@link #didChange didChange}.
705    * @param index the position of the object to remove.
706    * @return the removed object.
707    * @exception IndexOutOfBoundsException if the index isn't within the size range.
708    */

709   public Object JavaDoc remove(int index)
710   {
711     ++modCount;
712
713     Object JavaDoc oldObject = delegateRemove(index);
714     didRemove(index, oldObject);
715     didChange();
716
717     return oldObject;
718   }
719
720   /**
721    * Removes the object at the index from the backing store list and returns it.
722    * @return the removed object.
723    * @exception IndexOutOfBoundsException if the index isn't within the size range.
724    */

725   protected Object JavaDoc delegateRemove(int index)
726   {
727     return delegateList().remove(index);
728   }
729
730   /**
731    * Removes from the list each object not contained by the collection
732    * and returns whether any object was actually removed.
733    * This delegates to {@link #remove(int) remove(int)}
734    * in the case that it finds an object that isn't retained.
735    * @param collection the collection of objects to be retained.
736    * @return whether any object was actually removed.
737    */

738   public boolean retainAll(Collection JavaDoc collection)
739   {
740     boolean modified = false;
741     for (ListIterator JavaDoc i = delegateListIterator(); i.hasNext(); )
742     {
743       if (!collection.contains(i.next()))
744       {
745         remove(i.previousIndex());
746         modified = true;
747       }
748     }
749     return modified;
750   }
751
752   /**
753    * Clears the list of all objects.
754    */

755   public void clear()
756   {
757     doClear(size(), delegateToArray());
758   }
759
760   /**
761    * Does the actual object of clearing the all the objects.
762    * @param oldSize the size of the list before it is cleared.
763    * @param oldData old values of the list before it is cleared.
764    */

765   protected void doClear(int oldSize, Object JavaDoc [] oldData)
766   {
767     ++modCount;
768
769     delegateClear();
770
771     didClear(oldSize, oldData);
772     didChange();
773   }
774
775   /**
776    * Clears the backing store list of all objects.
777    */

778   protected void delegateClear()
779   {
780     delegateList().clear();
781   }
782
783   /**
784    * Moves the object to the index of the list.
785    * This implementation uses {@link #indexOf} of find the object
786    * and delegates to {@link #move(int, int) move(int, int)}.
787    * @param index the new position for the object in the list.
788    * @param object the object to be moved.
789    * @exception IndexOutOfBoundsException if the index isn't within the size range or the object isn't contained by the list.
790    */

791   public void move(int index, Object JavaDoc object)
792   {
793     move(index, indexOf(object));
794   }
795
796   /**
797    * Moves the object at the source index of the list to the target index of the list
798    * and returns the moved object.
799    * This implementation delegates to {@link #didMove didMove} and {@link #didChange didChange}.
800    * @param targetIndex the new position for the object in the list.
801    * @param sourceIndex the old position of the object in the list.
802    * @return the moved object.
803    * @exception IndexOutOfBoundsException if either index isn't within the size range.
804    */

805   public Object JavaDoc move(int targetIndex, int sourceIndex)
806   {
807     ++modCount;
808     int size = size();
809     if (targetIndex >= size || targetIndex < 0)
810       throw new IndexOutOfBoundsException JavaDoc("targetIndex=" + targetIndex + ", size=" + size);
811
812     if (sourceIndex >= size || sourceIndex < 0)
813       throw new IndexOutOfBoundsException JavaDoc("sourceIndex=" + sourceIndex + ", size=" + size);
814
815     Object JavaDoc object = delegateGet(sourceIndex);
816     if (targetIndex != sourceIndex)
817     {
818       delegateAdd(targetIndex, delegateRemove(sourceIndex));
819       didMove(targetIndex, object, sourceIndex);
820       didChange();
821     }
822     return object;
823   }
824
825   /**
826    * Returns whether the object is a list with corresponding equal objects.
827    * This implementation uses either <code>equals</code> or <code>"=="</code> depending on {@link #useEquals useEquals}.
828    * @return whether the object is a list with corresponding equal objects.
829    * @see #useEquals
830    */

831   public boolean equals(Object JavaDoc object)
832   {
833     return delegateEquals(object);
834   }
835
836   /**
837    * Returns whether the object is a list with corresponding equal objects to those in the backing store list.
838    * @return whether the object is a list with corresponding equal objects.
839    */

840   protected boolean delegateEquals(Object JavaDoc object)
841   {
842     return delegateList().equals(object);
843   }
844
845   /**
846    * Returns a hash code computed from each object's hash code.
847    * @return a hash code.
848    */

849   public int hashCode()
850   {
851     return delegateHashCode();
852   }
853
854   /**
855    * Returns the hash code of the backing store list.
856    * @return a hash code.
857    */

858   protected int delegateHashCode()
859   {
860     return delegateList().hashCode();
861   }
862
863   /**
864    * Returns a string of the form <code>"[object1, object2]"</code>.
865    * @return a string of the form <code>"[object1, object2]"</code>.
866    */

867   public String JavaDoc toString()
868   {
869     return delegateToString();
870   }
871
872   /**
873    * Returns a the string form of the backing store list.
874    * @return a the string form of the backing store list.
875    */

876   protected String JavaDoc delegateToString()
877   {
878     return delegateList().toString();
879   }
880
881   /**
882    * Returns an iterator.
883    * This implementation allocates a {@link DelegatingEList.EIterator}.
884    * @return an iterator.
885    * @see DelegatingEList.EIterator
886    */

887   public Iterator JavaDoc iterator()
888   {
889     return new EIterator();
890   }
891
892   /**
893    * Returns an iterator over the backing store list.
894    * @return an iterator.
895    */

896   protected Iterator JavaDoc delegateIterator()
897   {
898     return delegateList().iterator();
899   }
900
901   /**
902    * An extensible iterator implementation.
903    */

904   protected class EIterator implements Iterator JavaDoc
905   {
906     /**
907      * The current position of the iterator.
908      */

909     protected int cursor = 0;
910
911     /**
912      * The previous position of the iterator.
913      */

914     protected int lastCursor = -1;
915
916     /**
917      * The modification count of the containing list.
918      */

919     protected int expectedModCount = modCount;
920
921     /**
922      * Returns whether there are more objects.
923      * @return whether there are more objects.
924      */

925     public boolean hasNext()
926     {
927       return cursor != size();
928     }
929
930     /**
931      * Returns the next object and advances the iterator.
932      * This implementation delegates to {@link DelegatingEList#get get}.
933      * @return the next object.
934      * @exception NoSuchElementException if the iterator is done.
935      */

936     public Object JavaDoc next()
937     {
938       try
939       {
940         Object JavaDoc next = DelegatingEList.this.get(cursor);
941         checkModCount();
942         lastCursor = cursor++;
943         return next;
944       }
945       catch (IndexOutOfBoundsException JavaDoc exception)
946       {
947         checkModCount();
948         throw new NoSuchElementException JavaDoc();
949       }
950     }
951
952     /**
953      * Removes the last object returned by {@link #next()} from the list,
954      * it's an optional operation.
955      * This implementation can also function in a list iterator
956      * to act upon on the object returned by calling <code>previous</code>.
957      * @exception IllegalStateException
958      * if <code>next</code> has not yet been called,
959      * or <code>remove</code> has already been called after the last call to <code>next</code>.
960      */

961     public void remove()
962     {
963       if (lastCursor == -1)
964       {
965         throw new IllegalStateException JavaDoc();
966       }
967       checkModCount();
968
969       try
970       {
971         DelegatingEList.this.remove(lastCursor);
972         expectedModCount = modCount;
973         if (lastCursor < cursor)
974         {
975           --cursor;
976         }
977         lastCursor = -1;
978       }
979       catch (IndexOutOfBoundsException JavaDoc exception)
980       {
981         throw new ConcurrentModificationException JavaDoc();
982       }
983     }
984
985     /**
986      * Checks that the modification count is as expected.
987      * @exception ConcurrentModificationException if the modification count is not as expected.
988      */

989     protected void checkModCount()
990     {
991       if (modCount != expectedModCount)
992       {
993         throw new ConcurrentModificationException JavaDoc();
994       }
995     }
996   }
997
998   /**
999    * Returns a read-only iterator that does not {@link #resolve resolve} objects.
1000   * This implementation allocates a {@link NonResolvingEIterator}.
1001   * @return a read-only iterator that does not resolve objects.
1002   */

1003  protected Iterator JavaDoc basicIterator()
1004  {
1005    return new NonResolvingEIterator();
1006  }
1007
1008  /**
1009   * An extended read-only iterator that does not {@link #resolve resolve} objects.
1010   */

1011  protected class NonResolvingEIterator extends EIterator
1012  {
1013    /**
1014     * Returns the next object and advances the iterator.
1015     * This implementation accesses the backing list directly.
1016     * @return the next object.
1017     * @exception NoSuchElementException if the iterator is done.
1018     */

1019    public Object JavaDoc next()
1020    {
1021      try
1022      {
1023        Object JavaDoc next = delegateGet(cursor);
1024        checkModCount();
1025        lastCursor = cursor++;
1026        return next;
1027      }
1028      catch (IndexOutOfBoundsException JavaDoc exception)
1029      {
1030        checkModCount();
1031        throw new NoSuchElementException JavaDoc();
1032      }
1033    }
1034
1035    /**
1036     * Throws and exception.
1037     * @exception UnsupportedOperationException always because it's not supported.
1038     */

1039    public void remove()
1040    {
1041      throw new UnsupportedOperationException JavaDoc();
1042    }
1043  }
1044
1045  /**
1046   * Returns a list iterator.
1047   * This implementation allocates a {@link DelegatingEList.EListIterator}.
1048   * @return a list iterator.
1049   * @see DelegatingEList.EListIterator
1050   */

1051  public ListIterator JavaDoc listIterator()
1052  {
1053    return new EListIterator();
1054  }
1055
1056  /**
1057   * Returns a list iterator over the backing store list.
1058   * @return a list iterator.
1059   */

1060  protected ListIterator JavaDoc delegateListIterator()
1061  {
1062    return delegateList().listIterator();
1063  }
1064
1065  /**
1066   * Returns a list iterator advanced to the given index.
1067   * This implementation allocates a {@link DelegatingEList.EListIterator}.
1068   * @param index the starting index.
1069   * @return a list iterator advanced to the index.
1070   * @see DelegatingEList.EListIterator
1071   * @exception IndexOutOfBoundsException if the index isn't within the size range.
1072   */

1073  public ListIterator JavaDoc listIterator(int index)
1074  {
1075    int size = size();
1076    if (index < 0 || index > size())
1077      throw new IndexOutOfBoundsException JavaDoc("index=" + index + ", size=" + size);
1078
1079    return new EListIterator(index);
1080  }
1081
1082  /**
1083   * An extensible list iterator implementation.
1084   */

1085  protected class EListIterator extends EIterator implements ListIterator JavaDoc
1086  {
1087    /**
1088     * Creates an instance.
1089     */

1090    public EListIterator()
1091    {
1092    }
1093
1094    /**
1095     * Creates an instance advanced to the index.
1096     * @param index the starting index.
1097     */

1098    public EListIterator(int index)
1099    {
1100      cursor = index;
1101    }
1102
1103    /**
1104     * Returns whether there are more objects for {@link #previous}.
1105     * Returns whether there are more objects.
1106     */

1107    public boolean hasPrevious()
1108    {
1109      return cursor != 0;
1110    }
1111
1112    /**
1113     * Returns the previous object and advances the iterator.
1114     * This implementation delegates to {@link DelegatingEList#get get}.
1115     * @return the previous object.
1116     * @exception NoSuchElementException if the iterator is done.
1117     */

1118    public Object JavaDoc previous()
1119    {
1120      try
1121      {
1122        Object JavaDoc previous = DelegatingEList.this.get(--cursor);
1123        checkModCount();
1124        lastCursor = cursor;
1125        return previous;
1126      }
1127      catch (IndexOutOfBoundsException JavaDoc exception)
1128      {
1129        checkModCount();
1130        throw new NoSuchElementException JavaDoc();
1131      }
1132    }
1133
1134    /**
1135     * Returns the index of the object that would be returned by calling {@link #next next}.
1136     * @return the index of the object that would be returned by calling <code>next</code>.
1137     */

1138    public int nextIndex()
1139    {
1140      return cursor;
1141    }
1142
1143    /**
1144     * Returns the index of the object that would be returned by calling {@link #previous previous}.
1145     * @return the index of the object that would be returned by calling <code>previous</code>.
1146     */

1147    public int previousIndex()
1148    {
1149      return cursor - 1;
1150    }
1151
1152    /**
1153     * Sets the object at the index of the last call to {@link #next next} or {@link #previous previous}.
1154     * This implementation delegates to {@link DelegatingEList#set set}.
1155     * @param object the object to set.
1156     * @exception IllegalStateException
1157     * if <code>next</code> or <code>previous</code> have not yet been called,
1158     * or {@link #remove remove} or {@link #add add} have already been called
1159     * after the last call to <code>next</code> or <code>previous</code>.
1160     */

1161    public void set(Object JavaDoc object)
1162    {
1163      if (lastCursor == -1)
1164      {
1165        throw new IllegalStateException JavaDoc();
1166      }
1167      checkModCount();
1168
1169      try
1170      {
1171        DelegatingEList.this.set(lastCursor, object);
1172      }
1173      catch (IndexOutOfBoundsException JavaDoc exception)
1174      {
1175        throw new ConcurrentModificationException JavaDoc();
1176      }
1177    }
1178
1179    /**
1180     * Adds the object at the {@link #next next} index and advances the iterator past it.
1181     * This implementation delegates to {@link DelegatingEList#add(int, Object) add(int, Object)}.
1182     * @param object the object to add.
1183     */

1184    public void add(Object JavaDoc object)
1185    {
1186      checkModCount();
1187
1188      try
1189      {
1190        DelegatingEList.this.add(cursor++, object);
1191        expectedModCount = modCount;
1192        lastCursor = -1;
1193      }
1194      catch (IndexOutOfBoundsException JavaDoc exception)
1195      {
1196        throw new ConcurrentModificationException JavaDoc();
1197      }
1198    }
1199  }
1200
1201  /**
1202   * Returns a read-only list iterator that does not {@link #resolve resolve} objects.
1203   * This implementation allocates a {@link NonResolvingEListIterator}.
1204   * @return a read-only list iterator that does not resolve objects.
1205   */

1206  protected ListIterator JavaDoc basicListIterator()
1207  {
1208    return new NonResolvingEListIterator();
1209  }
1210
1211  /**
1212   * Returns a read-only list iterator advanced to the given index that does not {@link #resolve resolve} objects.
1213   * This implementation allocates a {@link NonResolvingEListIterator}.
1214   * @param index the starting index.
1215   * @return a read-only list iterator advanced to the index.
1216   * @exception IndexOutOfBoundsException if the index isn't within the size range.
1217   */

1218  protected ListIterator JavaDoc basicListIterator(int index)
1219  {
1220    int size = size();
1221    if (index < 0 || index > size())
1222      throw new IndexOutOfBoundsException JavaDoc("index=" + index + ", size=" + size);
1223
1224    return new NonResolvingEListIterator(index);
1225  }
1226
1227  /**
1228   * An extended read-only list iterator that does not {@link #resolve resolve} objects.
1229   */

1230  protected class NonResolvingEListIterator extends EListIterator
1231  {
1232    /**
1233     * Creates an instance.
1234     */

1235    public NonResolvingEListIterator()
1236    {
1237    }
1238
1239    /**
1240     * Creates an instance advanced to the index.
1241     * @param index the starting index.
1242     */

1243    public NonResolvingEListIterator(int index)
1244    {
1245      super(index);
1246    }
1247
1248    /**
1249     * Returns the next object and advances the iterator.
1250     * This implementation accesses the backing list directly.
1251     * @return the next object.
1252     * @exception NoSuchElementException if the iterator is done.
1253     */

1254    public Object JavaDoc next()
1255    {
1256      try
1257      {
1258        Object JavaDoc next = delegateGet(cursor);
1259        checkModCount();
1260        lastCursor = cursor++;
1261        return next;
1262      }
1263      catch (IndexOutOfBoundsException JavaDoc exception)
1264      {
1265        checkModCount();
1266        throw new NoSuchElementException JavaDoc();
1267      }
1268    }
1269
1270    /**
1271     * Returns the previous object and advances the iterator.
1272     * This implementation acesses the backing list directly.
1273     * @return the previous object.
1274     * @exception NoSuchElementException if the iterator is done.
1275     */

1276    public Object JavaDoc previous()
1277    {
1278      try
1279      {
1280        Object JavaDoc previous = delegateGet(--cursor);
1281        checkModCount();
1282        lastCursor = cursor;
1283        return previous;
1284      }
1285      catch (IndexOutOfBoundsException JavaDoc exception)
1286      {
1287        checkModCount();
1288        throw new NoSuchElementException JavaDoc();
1289      }
1290    }
1291
1292    /**
1293     * Throws an exception.
1294     * @exception UnsupportedOperationException always because it's not supported.
1295     */

1296    public void remove()
1297    {
1298      throw new UnsupportedOperationException JavaDoc();
1299    }
1300
1301    /**
1302     * Throws an exception.
1303     * @exception UnsupportedOperationException always because it's not supported.
1304     */

1305    public void set(Object JavaDoc object)
1306    {
1307      throw new UnsupportedOperationException JavaDoc();
1308    }
1309
1310    /**
1311     * Throws an exception.
1312     * @exception UnsupportedOperationException always because it's not supported.
1313     */

1314    public void add(Object JavaDoc object)
1315    {
1316      throw new UnsupportedOperationException JavaDoc();
1317    }
1318  }
1319
1320  /**
1321   * An unmodifiable version of {@link DelegatingEList}.
1322   */

1323  public static class UnmodifiableEList extends DelegatingEList
1324  {
1325    protected List JavaDoc underlyingList;
1326
1327    /**
1328     * Creates an initialized instance.
1329     * @param underlyingList the backing store list.
1330     */

1331    public UnmodifiableEList(List JavaDoc underlyingList)
1332    {
1333      this.underlyingList = underlyingList;
1334    }
1335
1336    protected List JavaDoc delegateList()
1337    {
1338      return underlyingList;
1339    }
1340
1341    /**
1342     * Throws an exception.
1343     * @exception UnsupportedOperationException always because it's not supported.
1344     */

1345    public Object JavaDoc set(int index, Object JavaDoc object)
1346    {
1347      throw new UnsupportedOperationException JavaDoc();
1348    }
1349
1350    /**
1351     * Throws an exception.
1352     * @exception UnsupportedOperationException always because it's not supported.
1353     */

1354    public boolean add(Object JavaDoc object)
1355    {
1356      throw new UnsupportedOperationException JavaDoc();
1357    }
1358
1359    /**
1360     * Throws an exception.
1361     * @exception UnsupportedOperationException always because it's not supported.
1362     */

1363    public void add(int index, Object JavaDoc object)
1364    {
1365      throw new UnsupportedOperationException JavaDoc();
1366    }
1367
1368    /**
1369     * Throws an exception.
1370     * @exception UnsupportedOperationException always because it's not supported.
1371     */

1372    public boolean addAll(Collection JavaDoc collection)
1373    {
1374      throw new UnsupportedOperationException JavaDoc();
1375    }
1376
1377    /**
1378     * Throws an exception.
1379     * @exception UnsupportedOperationException always because it's not supported.
1380     */

1381    public boolean addAll(int index, Collection JavaDoc collection)
1382    {
1383      throw new UnsupportedOperationException JavaDoc();
1384    }
1385
1386    /**
1387     * Throws an exception.
1388     * @exception UnsupportedOperationException always because it's not supported.
1389     */

1390    public boolean remove(Object JavaDoc object)
1391    {
1392      throw new UnsupportedOperationException JavaDoc();
1393    }
1394
1395    /**
1396     * Throws an exception.
1397     * @exception UnsupportedOperationException always because it's not supported.
1398     */

1399    public Object JavaDoc remove(int index)
1400    {
1401      throw new UnsupportedOperationException JavaDoc();
1402    }
1403
1404    /**
1405     * Throws an exception.
1406     * @exception UnsupportedOperationException always because it's not supported.
1407     */

1408    public boolean removeAll(Collection JavaDoc collection)
1409    {
1410      throw new UnsupportedOperationException JavaDoc();
1411    }
1412
1413    /**
1414     * Throws an exception.
1415     * @exception UnsupportedOperationException always because it's not supported.
1416     */

1417    public boolean retainAll(Collection JavaDoc collection)
1418    {
1419      throw new UnsupportedOperationException JavaDoc();
1420    }
1421
1422    /**
1423     * Throws an exception.
1424     * @exception UnsupportedOperationException always because it's not supported.
1425     */

1426    public void clear()
1427    {
1428      throw new UnsupportedOperationException JavaDoc();
1429    }
1430
1431    /**
1432     * Throws an exception.
1433     * @exception UnsupportedOperationException always because it's not supported.
1434     */

1435    public void move(int index, Object JavaDoc object)
1436    {
1437      throw new UnsupportedOperationException JavaDoc();
1438    }
1439
1440    /**
1441     * Throws an exception.
1442     * @exception UnsupportedOperationException always because it's not supported.
1443     */

1444    public Object JavaDoc move(int targetIndex, int sourceIndex)
1445    {
1446      throw new UnsupportedOperationException JavaDoc();
1447    }
1448
1449    /**
1450     * Returns the {@link DelegatingEList#basicIterator basic iterator}.
1451     * @return the basic iterator.
1452     */

1453    public Iterator JavaDoc iterator()
1454    {
1455      return basicIterator();
1456    }
1457
1458    /**
1459     * Returns the {@link #basicListIterator() basic list iterator}.
1460     * @return the basic list iterator.
1461     */

1462    public ListIterator JavaDoc listIterator()
1463    {
1464      return basicListIterator();
1465    }
1466  
1467    /**
1468     * Returns the {@link #basicListIterator(int) basic list iterator} advanced to the index.
1469     * @param index the starting index.
1470     * @return the basic list iterator.
1471     */

1472    public ListIterator JavaDoc listIterator(int index)
1473    {
1474      return basicListIterator(index);
1475    }
1476  }
1477
1478  /**
1479   * Returns an <b>unsafe</b> list that provides a {@link #resolve non-resolving} view of the backing store list.
1480   * @return an <b>unsafe</b> list that provides a non-resolving view of the backign store list.
1481   */

1482  protected List JavaDoc basicList()
1483  {
1484    return delegateBasicList();
1485  }
1486
1487  /**
1488   * Returns an <b>unsafe</b> list that provides a {@link #resolve non-resolving} view of the backing store list.
1489   * @return an <b>unsafe</b> list that provides a non-resolving view of the backing store list.
1490   */

1491  protected List JavaDoc delegateBasicList()
1492  {
1493    return delegateList();
1494  }
1495
1496  /**
1497   * Returns the collection of objects in the given collection that are also contained by this list.
1498   * @param collection the other collection.
1499   * @return the collection of objects in the given collection that are also contained by this list.
1500   */

1501  protected Collection JavaDoc getDuplicates(Collection JavaDoc collection)
1502  {
1503    Collection JavaDoc result = collection;
1504    Collection JavaDoc filteredResult = null;
1505    for (Iterator JavaDoc i = collection.iterator(); i.hasNext(); )
1506    {
1507      Object JavaDoc object = i.next();
1508      if (!contains(object))
1509      {
1510        if (filteredResult == null)
1511        {
1512          result = filteredResult = new BasicEList(collection);
1513        }
1514        filteredResult.remove(object);
1515      }
1516    }
1517    return result;
1518  }
1519
1520  /**
1521   * Returns the collection of objects in the given collection that are not also contained by this list.
1522   * @param collection the other collection.
1523   * @return the collection of objects in the given collection that are not also contained by this list.
1524   */

1525  protected Collection JavaDoc getNonDuplicates(Collection JavaDoc collection)
1526  {
1527    Collection JavaDoc result = new UniqueEList(collection.size());
1528    for (Iterator JavaDoc i = collection.iterator(); i.hasNext(); )
1529    {
1530      Object JavaDoc object = i.next();
1531      if (!contains(object))
1532      {
1533        result.add(object);
1534      }
1535    }
1536    return result;
1537  }
1538}
1539
Popular Tags