1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski package com.sun.star.lib.uno.helper;
25*b1cdbd2cSJim Jagielski import java.util.Iterator;
26*b1cdbd2cSJim Jagielski import java.util.ListIterator;
27*b1cdbd2cSJim Jagielski import java.util.NoSuchElementException;
28*b1cdbd2cSJim Jagielski import java.util.Collection;
29*b1cdbd2cSJim Jagielski import com.sun.star.lang.EventObject;
30*b1cdbd2cSJim Jagielski import com.sun.star.lang.XEventListener;
31*b1cdbd2cSJim Jagielski import com.sun.star.uno.UnoRuntime;
32*b1cdbd2cSJim Jagielski 
33*b1cdbd2cSJim Jagielski /**
34*b1cdbd2cSJim Jagielski  * This class is a container for interfaces.
35*b1cdbd2cSJim Jagielski  *
36*b1cdbd2cSJim Jagielski  * It is intended to be used as storage for UNO interface of a specific type.
37*b1cdbd2cSJim Jagielski  * The client has to ensure that the container contains only elements of the same
38*b1cdbd2cSJim Jagielski  * type. If one needs to store different types, then one uses OMultiTypeInterfaceContainer.
39*b1cdbd2cSJim Jagielski  * When the client calls disposeAndClear, the contained objects are queried for
40*b1cdbd2cSJim Jagielski  * com.sun.star.lang.XEventListener and disposing is called. Afterwards
41*b1cdbd2cSJim Jagielski  * the list cannot be used anymore.
42*b1cdbd2cSJim Jagielski  *
43*b1cdbd2cSJim Jagielski  * This list does not allow null values.
44*b1cdbd2cSJim Jagielski  * All methods are thread-safe. The same holds true for
45*b1cdbd2cSJim Jagielski  * iterators, issued by this class. Several iterators can exist at the same time and can also
46*b1cdbd2cSJim Jagielski  * be modified (java.util.ListIterator.add, java.util.ListIterator.remove etc.). To make this work,
47*b1cdbd2cSJim Jagielski  * the InterfaceContainer provides the iterators with copys of the list's data.
48*b1cdbd2cSJim Jagielski  * The add and remove calls on the iterator modify the data in the iterator's list as well as
49*b1cdbd2cSJim Jagielski  * in InterfaceContainer. Modification on InterfaceContainer, however, are not
50*b1cdbd2cSJim Jagielski  * synchronized with existing iterators. For example
51*b1cdbd2cSJim Jagielski  * <pre>
52*b1cdbd2cSJim Jagielski  * InterfaceContainer cont= new InterfaceContainer();
53*b1cdbd2cSJim Jagielski  * ListIterator it= cont.listIterator();
54*b1cdbd2cSJim Jagielski  *
55*b1cdbd2cSJim Jagielski  * cont.add( someInterface);
56*b1cdbd2cSJim Jagielski  * // one cannot obtain someInterface through iterator it,
57*b1cdbd2cSJim Jagielski  * // instead get a new iterator
58*b1cdbd2cSJim Jagielski  * it= cont.listIterator();
59*b1cdbd2cSJim Jagielski  * // it now keeps a fresh copy of cont and hence contains someInterface
60*b1cdbd2cSJim Jagielski  *
61*b1cdbd2cSJim Jagielski  * // Adding an interface on the iterator will cause the interface also to be added
62*b1cdbd2cSJim Jagielski  * // to InterfaceContainer
63*b1cdbd2cSJim Jagielski  * it.add( someOtherInterface);
64*b1cdbd2cSJim Jagielski  * // someOtherInterface is now in it and cont
65*b1cdbd2cSJim Jagielski  * ListIterator it2= cont.listIterator();
66*b1cdbd2cSJim Jagielski  * //someOtherInterface can also be obtained by all newly created iterators, e.g. it2.
67*b1cdbd2cSJim Jagielski  * </pre>
68*b1cdbd2cSJim Jagielski  *
69*b1cdbd2cSJim Jagielski  *  The add and remove methods of an iterator work on a particular location within a list,
70*b1cdbd2cSJim Jagielski  *  dependent on what the value of the iterator's cursor is. After the call the value at the
71*b1cdbd2cSJim Jagielski  *  appropriate position has been modified. Since the iterator received a copy of InterfaceContainer's
72*b1cdbd2cSJim Jagielski  *  data, InterfaceContainer may have been modified (by List methods or through other iterators).
73*b1cdbd2cSJim Jagielski  *  Therefore both data sets may not contain the same elements anymore. Consequently, a List method
74*b1cdbd2cSJim Jagielski  *  that modifies data, does not modify InterfaceContainer's data at a certain index
75*b1cdbd2cSJim Jagielski  *  (according to the iterators cursor). Instead, new elements are added at the end of list. When
76*b1cdbd2cSJim Jagielski  *  Iterator.remove is called, then the first occurrence of that element in InterfaceContainer
77*b1cdbd2cSJim Jagielski  *  is removed.
78*b1cdbd2cSJim Jagielski  *  ListIterator.set is not supported.
79*b1cdbd2cSJim Jagielski  *
80*b1cdbd2cSJim Jagielski  * A lot of  methods resemble those of the  to java.util.List interface, allthough
81*b1cdbd2cSJim Jagielski  * this class does not implement it. However, the list iterators returned, for example by
82*b1cdbd2cSJim Jagielski  * the listIterator method implement the java.util.ListIterator interface.
83*b1cdbd2cSJim Jagielski  * Implementing the List interface would mean to support all none - optional methods as
84*b1cdbd2cSJim Jagielski  * prescribed by the interface declaration. Among those is the subList method which returns
85*b1cdbd2cSJim Jagielski  * a range of values of the list's data wrapped in a List implementation. Changes to the sub
86*b1cdbd2cSJim Jagielski  * list have to cause changes in the main list. This is a problem, since this class is to be
87*b1cdbd2cSJim Jagielski  * used in a multi-threaded environment. The sub list could work on a copy as the iterators
88*b1cdbd2cSJim Jagielski  * do, but all the functions which work on an given index could not be properly supported.
89*b1cdbd2cSJim Jagielski  * Unfortunatly, the List interface documentation states that all optional methods implemented
90*b1cdbd2cSJim Jagielski  * by the list have to be implemented in the sub list. That would mean to do without all those
91*b1cdbd2cSJim Jagielski  * critical methods, allthough they might work well in the "main list" (as opposed to sub list).
92*b1cdbd2cSJim Jagielski  */
93*b1cdbd2cSJim Jagielski public class InterfaceContainer implements Cloneable
94*b1cdbd2cSJim Jagielski {
95*b1cdbd2cSJim Jagielski     final boolean DEBUG= false;
96*b1cdbd2cSJim Jagielski     /**
97*b1cdbd2cSJim Jagielski      * The array buffer into which the elements of the ArrayList are stored.
98*b1cdbd2cSJim Jagielski      * The capacity of the ArrayList is the length of this array buffer.
99*b1cdbd2cSJim Jagielski      */
100*b1cdbd2cSJim Jagielski     Object elementData[];
101*b1cdbd2cSJim Jagielski 
102*b1cdbd2cSJim Jagielski     /**
103*b1cdbd2cSJim Jagielski      * The size of the ArrayList (the number of elements it contains).
104*b1cdbd2cSJim Jagielski      */
105*b1cdbd2cSJim Jagielski     private int size;
106*b1cdbd2cSJim Jagielski 
107*b1cdbd2cSJim Jagielski 
108*b1cdbd2cSJim Jagielski     //private ArrayList data= new ArrayList();
109*b1cdbd2cSJim Jagielski     /** Creates a new instance of InterfaceContainer */
InterfaceContainer()110*b1cdbd2cSJim Jagielski     public InterfaceContainer()
111*b1cdbd2cSJim Jagielski     {
112*b1cdbd2cSJim Jagielski         this(10);
113*b1cdbd2cSJim Jagielski     }
114*b1cdbd2cSJim Jagielski     /**
115*b1cdbd2cSJim Jagielski      * Constructs an empty list with the specified initial capacity.
116*b1cdbd2cSJim Jagielski      *
117*b1cdbd2cSJim Jagielski      * @param   initialCapacity   the initial capacity of the list.
118*b1cdbd2cSJim Jagielski      * @exception IllegalArgumentException if the specified initial capacity
119*b1cdbd2cSJim Jagielski      *            is negative
120*b1cdbd2cSJim Jagielski      */
InterfaceContainer(int initialCapacity)121*b1cdbd2cSJim Jagielski     public InterfaceContainer(int initialCapacity)
122*b1cdbd2cSJim Jagielski     {
123*b1cdbd2cSJim Jagielski         if (initialCapacity < 0)
124*b1cdbd2cSJim Jagielski             throw new java.lang.IllegalArgumentException("Illegal Capacity: "+
125*b1cdbd2cSJim Jagielski             initialCapacity);
126*b1cdbd2cSJim Jagielski         this.elementData = new Object[initialCapacity];
127*b1cdbd2cSJim Jagielski     }
128*b1cdbd2cSJim Jagielski 
129*b1cdbd2cSJim Jagielski     /**
130*b1cdbd2cSJim Jagielski      * Trims the capacity of this <tt>ArrayList</tt> instance to be the
131*b1cdbd2cSJim Jagielski      * list's current size.  An application can use this operation to minimize
132*b1cdbd2cSJim Jagielski      * the storage of an <tt>ArrayList</tt> instance.
133*b1cdbd2cSJim Jagielski      */
trimToSize()134*b1cdbd2cSJim Jagielski     synchronized public void trimToSize()
135*b1cdbd2cSJim Jagielski     {
136*b1cdbd2cSJim Jagielski         int oldCapacity = elementData.length;
137*b1cdbd2cSJim Jagielski         if (size < oldCapacity)
138*b1cdbd2cSJim Jagielski         {
139*b1cdbd2cSJim Jagielski             Object oldData[] = elementData;
140*b1cdbd2cSJim Jagielski             elementData = new Object[size];
141*b1cdbd2cSJim Jagielski             System.arraycopy(oldData, 0, elementData, 0, size);
142*b1cdbd2cSJim Jagielski         }
143*b1cdbd2cSJim Jagielski     }
144*b1cdbd2cSJim Jagielski 
145*b1cdbd2cSJim Jagielski     /**
146*b1cdbd2cSJim Jagielski      * Increases the capacity of this <tt>ArrayList</tt> instance, if
147*b1cdbd2cSJim Jagielski      * necessary, to ensure  that it can hold at least the number of elements
148*b1cdbd2cSJim Jagielski      * specified by the minimum capacity argument.
149*b1cdbd2cSJim Jagielski      *
150*b1cdbd2cSJim Jagielski      * @param   minCapacity   the desired minimum capacity.
151*b1cdbd2cSJim Jagielski      */
ensureCapacity(int minCapacity)152*b1cdbd2cSJim Jagielski     synchronized public void ensureCapacity(int minCapacity)
153*b1cdbd2cSJim Jagielski     {
154*b1cdbd2cSJim Jagielski         int oldCapacity = elementData.length;
155*b1cdbd2cSJim Jagielski         if (minCapacity > oldCapacity)
156*b1cdbd2cSJim Jagielski         {
157*b1cdbd2cSJim Jagielski             Object oldData[] = elementData;
158*b1cdbd2cSJim Jagielski             int newCapacity = (oldCapacity * 3)/2 + 1;
159*b1cdbd2cSJim Jagielski             if (newCapacity < minCapacity)
160*b1cdbd2cSJim Jagielski                 newCapacity = minCapacity;
161*b1cdbd2cSJim Jagielski             elementData = new Object[newCapacity];
162*b1cdbd2cSJim Jagielski             System.arraycopy(oldData, 0, elementData, 0, size);
163*b1cdbd2cSJim Jagielski         }
164*b1cdbd2cSJim Jagielski     }
165*b1cdbd2cSJim Jagielski 
166*b1cdbd2cSJim Jagielski     /**
167*b1cdbd2cSJim Jagielski      * Appends the specified element to the end of this list.
168*b1cdbd2cSJim Jagielski      *
169*b1cdbd2cSJim Jagielski      * @param o element to be appended to this list.
170*b1cdbd2cSJim Jagielski      * @return <tt>true</tt> (as per the general contract of Collection.add).
171*b1cdbd2cSJim Jagielski      */
add(Object o)172*b1cdbd2cSJim Jagielski     synchronized public boolean add(Object o)
173*b1cdbd2cSJim Jagielski     {
174*b1cdbd2cSJim Jagielski         boolean ret= false;
175*b1cdbd2cSJim Jagielski         if (elementData != null && o != null)
176*b1cdbd2cSJim Jagielski         {
177*b1cdbd2cSJim Jagielski             ensureCapacity(size + 1);  // Increments modCount!!
178*b1cdbd2cSJim Jagielski             elementData[size++] = o;
179*b1cdbd2cSJim Jagielski             ret= true;
180*b1cdbd2cSJim Jagielski         }
181*b1cdbd2cSJim Jagielski         return ret;
182*b1cdbd2cSJim Jagielski     }
183*b1cdbd2cSJim Jagielski 
184*b1cdbd2cSJim Jagielski     /**
185*b1cdbd2cSJim Jagielski      * Inserts the specified element at the specified position in this
186*b1cdbd2cSJim Jagielski      * list. Shifts the element currently at that position (if any) and
187*b1cdbd2cSJim Jagielski      * any subsequent elements to the right (adds one to their indices).
188*b1cdbd2cSJim Jagielski      *
189*b1cdbd2cSJim Jagielski      * @param index index at which the specified element is to be inserted.
190*b1cdbd2cSJim Jagielski      * @param element element to be inserted.
191*b1cdbd2cSJim Jagielski      * @throws    IndexOutOfBoundsException if index is out of range
192*b1cdbd2cSJim Jagielski      *		  <tt>(index &lt; 0 || index &gt; size())</tt>.
193*b1cdbd2cSJim Jagielski      */
add(int index, Object element)194*b1cdbd2cSJim Jagielski     synchronized public void add(int index, Object element)
195*b1cdbd2cSJim Jagielski     {
196*b1cdbd2cSJim Jagielski         if (elementData != null && element != null)
197*b1cdbd2cSJim Jagielski         {
198*b1cdbd2cSJim Jagielski             if (index > size || index < 0)
199*b1cdbd2cSJim Jagielski                 throw new IndexOutOfBoundsException(
200*b1cdbd2cSJim Jagielski                 "Index: "+index+", Size: "+size);
201*b1cdbd2cSJim Jagielski 
202*b1cdbd2cSJim Jagielski             ensureCapacity(size+1);
203*b1cdbd2cSJim Jagielski             System.arraycopy(elementData, index, elementData, index + 1,
204*b1cdbd2cSJim Jagielski             size - index);
205*b1cdbd2cSJim Jagielski             elementData[index] = element;
206*b1cdbd2cSJim Jagielski             size++;
207*b1cdbd2cSJim Jagielski         }
208*b1cdbd2cSJim Jagielski     }
209*b1cdbd2cSJim Jagielski 
210*b1cdbd2cSJim Jagielski 
211*b1cdbd2cSJim Jagielski     /**
212*b1cdbd2cSJim Jagielski      * Appends all of the elements in the specified Collection to the end of
213*b1cdbd2cSJim Jagielski      * this list, in the order that they are returned by the
214*b1cdbd2cSJim Jagielski      * specified Collection's Iterator.  The behavior of this operation is
215*b1cdbd2cSJim Jagielski      * undefined if the specified Collection is modified while the operation
216*b1cdbd2cSJim Jagielski      * is in progress.  (This implies that the behavior of this call is
217*b1cdbd2cSJim Jagielski      * undefined if the specified Collection is this list, and this
218*b1cdbd2cSJim Jagielski      * list is nonempty.)
219*b1cdbd2cSJim Jagielski      *
220*b1cdbd2cSJim Jagielski      * @param c the elements to be inserted into this list.
221*b1cdbd2cSJim Jagielski      * @throws    IndexOutOfBoundsException if index out of range <tt>(index
222*b1cdbd2cSJim Jagielski      *		  &lt; 0 || index &gt; size())</tt>.
223*b1cdbd2cSJim Jagielski      */
addAll(Collection c)224*b1cdbd2cSJim Jagielski     synchronized public boolean addAll(Collection c)
225*b1cdbd2cSJim Jagielski     {
226*b1cdbd2cSJim Jagielski         int numNew = c.size();
227*b1cdbd2cSJim Jagielski         ensureCapacity(size + numNew);
228*b1cdbd2cSJim Jagielski 
229*b1cdbd2cSJim Jagielski         Iterator e = c.iterator();
230*b1cdbd2cSJim Jagielski         for (int i=0; i<numNew; i++)
231*b1cdbd2cSJim Jagielski         {
232*b1cdbd2cSJim Jagielski             Object o= e.next();
233*b1cdbd2cSJim Jagielski             if (o != null)
234*b1cdbd2cSJim Jagielski                 elementData[size++] = o;
235*b1cdbd2cSJim Jagielski         }
236*b1cdbd2cSJim Jagielski         return numNew != 0;
237*b1cdbd2cSJim Jagielski     }
238*b1cdbd2cSJim Jagielski     /**
239*b1cdbd2cSJim Jagielski      * Inserts all of the elements in the specified Collection into this
240*b1cdbd2cSJim Jagielski      * list, starting at the specified position.  Shifts the element
241*b1cdbd2cSJim Jagielski      * currently at that position (if any) and any subsequent elements to
242*b1cdbd2cSJim Jagielski      * the right (increases their indices).  The new elements will appear
243*b1cdbd2cSJim Jagielski      * in the list in the order that they are returned by the
244*b1cdbd2cSJim Jagielski      * specified Collection's iterator.
245*b1cdbd2cSJim Jagielski      *
246*b1cdbd2cSJim Jagielski      * @param index index at which to insert first element
247*b1cdbd2cSJim Jagielski      *		    from the specified collection.
248*b1cdbd2cSJim Jagielski      * @param c elements to be inserted into this list.
249*b1cdbd2cSJim Jagielski      * @throws    IndexOutOfBoundsException if index out of range <tt>(index
250*b1cdbd2cSJim Jagielski      *		  &lt; 0 || index &gt; size())</tt>.
251*b1cdbd2cSJim Jagielski      */
addAll(int index, Collection c)252*b1cdbd2cSJim Jagielski     synchronized public boolean addAll(int index, Collection c)
253*b1cdbd2cSJim Jagielski     {
254*b1cdbd2cSJim Jagielski         boolean ret= false;
255*b1cdbd2cSJim Jagielski         if (elementData != null)
256*b1cdbd2cSJim Jagielski         {
257*b1cdbd2cSJim Jagielski             if (index > size || index < 0)
258*b1cdbd2cSJim Jagielski                 throw new IndexOutOfBoundsException(
259*b1cdbd2cSJim Jagielski                 "Index: "+index+", Size: "+size);
260*b1cdbd2cSJim Jagielski             // only add  the non-null elements
261*b1cdbd2cSJim Jagielski             int sizeCol= c.size();
262*b1cdbd2cSJim Jagielski             Object[] arColl= new Object[sizeCol];
263*b1cdbd2cSJim Jagielski             Iterator icol= c.iterator();
264*b1cdbd2cSJim Jagielski             int curIndex= 0;
265*b1cdbd2cSJim Jagielski             for (int i=0; i < sizeCol; i++)
266*b1cdbd2cSJim Jagielski             {
267*b1cdbd2cSJim Jagielski                 Object o= icol.next();
268*b1cdbd2cSJim Jagielski                 if (o != null)
269*b1cdbd2cSJim Jagielski                     arColl[curIndex++]= o;
270*b1cdbd2cSJim Jagielski             }
271*b1cdbd2cSJim Jagielski             int numNew = curIndex;
272*b1cdbd2cSJim Jagielski             ensureCapacity(size + numNew);  // Increments modCount!!
273*b1cdbd2cSJim Jagielski 
274*b1cdbd2cSJim Jagielski             int numMoved = size - index;
275*b1cdbd2cSJim Jagielski             if (numMoved > 0)
276*b1cdbd2cSJim Jagielski                 System.arraycopy(elementData, index, elementData, index + numNew,
277*b1cdbd2cSJim Jagielski                 numMoved);
278*b1cdbd2cSJim Jagielski 
279*b1cdbd2cSJim Jagielski             for (int i=0; i<numNew; i++)
280*b1cdbd2cSJim Jagielski             {
281*b1cdbd2cSJim Jagielski                 elementData[index++]= arColl[i];
282*b1cdbd2cSJim Jagielski             }
283*b1cdbd2cSJim Jagielski             size += numNew;
284*b1cdbd2cSJim Jagielski             ret= numNew != 0;
285*b1cdbd2cSJim Jagielski         }
286*b1cdbd2cSJim Jagielski         return ret;
287*b1cdbd2cSJim Jagielski     }
288*b1cdbd2cSJim Jagielski 
289*b1cdbd2cSJim Jagielski     /**
290*b1cdbd2cSJim Jagielski      * Removes all of the elements from this list.  The list will
291*b1cdbd2cSJim Jagielski      * be empty after this call returns.
292*b1cdbd2cSJim Jagielski      */
clear()293*b1cdbd2cSJim Jagielski     synchronized public void clear()
294*b1cdbd2cSJim Jagielski     {
295*b1cdbd2cSJim Jagielski         if (elementData != null)
296*b1cdbd2cSJim Jagielski         {
297*b1cdbd2cSJim Jagielski             // Let gc do its work
298*b1cdbd2cSJim Jagielski             for (int i = 0; i < size; i++)
299*b1cdbd2cSJim Jagielski                 elementData[i] = null;
300*b1cdbd2cSJim Jagielski 
301*b1cdbd2cSJim Jagielski             size = 0;
302*b1cdbd2cSJim Jagielski         }
303*b1cdbd2cSJim Jagielski     }
304*b1cdbd2cSJim Jagielski     /**
305*b1cdbd2cSJim Jagielski      * Returns <tt>true</tt> if this list contains the specified element.
306*b1cdbd2cSJim Jagielski      *
307*b1cdbd2cSJim Jagielski      * @param elem element whose presence in this List is to be tested.
308*b1cdbd2cSJim Jagielski      */
contains(Object elem)309*b1cdbd2cSJim Jagielski     synchronized public boolean contains(Object elem)
310*b1cdbd2cSJim Jagielski     {
311*b1cdbd2cSJim Jagielski         return indexOf(elem) >= 0;
312*b1cdbd2cSJim Jagielski     }
313*b1cdbd2cSJim Jagielski 
containsAll(Collection collection)314*b1cdbd2cSJim Jagielski     synchronized public boolean containsAll(Collection collection)
315*b1cdbd2cSJim Jagielski     {
316*b1cdbd2cSJim Jagielski         boolean retVal= true;
317*b1cdbd2cSJim Jagielski         if (elementData != null && collection != null)
318*b1cdbd2cSJim Jagielski         {
319*b1cdbd2cSJim Jagielski             Iterator it= collection.iterator();
320*b1cdbd2cSJim Jagielski             while (it.hasNext())
321*b1cdbd2cSJim Jagielski             {
322*b1cdbd2cSJim Jagielski                 Object obj= it.next();
323*b1cdbd2cSJim Jagielski                 if (false == contains(obj))
324*b1cdbd2cSJim Jagielski                 {
325*b1cdbd2cSJim Jagielski                     retVal= false;
326*b1cdbd2cSJim Jagielski                     break;
327*b1cdbd2cSJim Jagielski                 }
328*b1cdbd2cSJim Jagielski             }
329*b1cdbd2cSJim Jagielski         }
330*b1cdbd2cSJim Jagielski         return retVal;
331*b1cdbd2cSJim Jagielski     }
332*b1cdbd2cSJim Jagielski     /**
333*b1cdbd2cSJim Jagielski      * Returns the element at the specified position in this list.
334*b1cdbd2cSJim Jagielski      *
335*b1cdbd2cSJim Jagielski      * @param  index index of element to return.
336*b1cdbd2cSJim Jagielski      * @return the element at the specified position in this list.
337*b1cdbd2cSJim Jagielski      * @throws    IndexOutOfBoundsException if index is out of range <tt>(index
338*b1cdbd2cSJim Jagielski      * 		  &lt; 0 || index &gt;= size())</tt>.
339*b1cdbd2cSJim Jagielski      */
get(int index)340*b1cdbd2cSJim Jagielski     synchronized public Object get(int index)
341*b1cdbd2cSJim Jagielski     {
342*b1cdbd2cSJim Jagielski         if (elementData != null)
343*b1cdbd2cSJim Jagielski         {
344*b1cdbd2cSJim Jagielski             RangeCheck(index);
345*b1cdbd2cSJim Jagielski             return elementData[index];
346*b1cdbd2cSJim Jagielski         }
347*b1cdbd2cSJim Jagielski         return null;
348*b1cdbd2cSJim Jagielski     }
349*b1cdbd2cSJim Jagielski 
350*b1cdbd2cSJim Jagielski     /**
351*b1cdbd2cSJim Jagielski      * Searches for the first occurence of the given argument, testing
352*b1cdbd2cSJim Jagielski      * for equality using the <tt>equals</tt> method.
353*b1cdbd2cSJim Jagielski      *
354*b1cdbd2cSJim Jagielski      * @param   elem   an object.
355*b1cdbd2cSJim Jagielski      * @return  the index of the first occurrence of the argument in this
356*b1cdbd2cSJim Jagielski      *          list; returns <tt>-1</tt> if the object is not found.
357*b1cdbd2cSJim Jagielski      * @see     Object#equals(Object)
358*b1cdbd2cSJim Jagielski      */
indexOf(Object elem)359*b1cdbd2cSJim Jagielski     synchronized public int indexOf(Object elem)
360*b1cdbd2cSJim Jagielski     {
361*b1cdbd2cSJim Jagielski         int index= -1;
362*b1cdbd2cSJim Jagielski         if (elementData != null && elem != null)
363*b1cdbd2cSJim Jagielski         {
364*b1cdbd2cSJim Jagielski             for (int i = 0; i < size; i++)
365*b1cdbd2cSJim Jagielski             {
366*b1cdbd2cSJim Jagielski                 if (elem == elementData[i])
367*b1cdbd2cSJim Jagielski                 {
368*b1cdbd2cSJim Jagielski                     index= i;
369*b1cdbd2cSJim Jagielski                     break;
370*b1cdbd2cSJim Jagielski                 }
371*b1cdbd2cSJim Jagielski             }
372*b1cdbd2cSJim Jagielski 
373*b1cdbd2cSJim Jagielski             if (index == -1)
374*b1cdbd2cSJim Jagielski             {
375*b1cdbd2cSJim Jagielski                 for (int i = 0; i < size; i++)
376*b1cdbd2cSJim Jagielski                 {
377*b1cdbd2cSJim Jagielski                     if (UnoRuntime.areSame(elem, elementData[i]))
378*b1cdbd2cSJim Jagielski                     {
379*b1cdbd2cSJim Jagielski                         index= i;
380*b1cdbd2cSJim Jagielski                         break;
381*b1cdbd2cSJim Jagielski                     }
382*b1cdbd2cSJim Jagielski                 }
383*b1cdbd2cSJim Jagielski             }
384*b1cdbd2cSJim Jagielski         }
385*b1cdbd2cSJim Jagielski         return index;
386*b1cdbd2cSJim Jagielski     }
387*b1cdbd2cSJim Jagielski     /**
388*b1cdbd2cSJim Jagielski      * Tests if this list has no elements.
389*b1cdbd2cSJim Jagielski      *
390*b1cdbd2cSJim Jagielski      * @return  <tt>true</tt> if this list has no elements;
391*b1cdbd2cSJim Jagielski      *          <tt>false</tt> otherwise.
392*b1cdbd2cSJim Jagielski      */
isEmpty()393*b1cdbd2cSJim Jagielski     synchronized public boolean isEmpty()
394*b1cdbd2cSJim Jagielski     {
395*b1cdbd2cSJim Jagielski         return size == 0;
396*b1cdbd2cSJim Jagielski     }
397*b1cdbd2cSJim Jagielski 
iterator()398*b1cdbd2cSJim Jagielski     synchronized public Iterator iterator()
399*b1cdbd2cSJim Jagielski     {
400*b1cdbd2cSJim Jagielski         if (elementData != null)
401*b1cdbd2cSJim Jagielski         {
402*b1cdbd2cSJim Jagielski             InterfaceContainer aCopy= (InterfaceContainer) clone();
403*b1cdbd2cSJim Jagielski             return new Itr(aCopy);
404*b1cdbd2cSJim Jagielski         }
405*b1cdbd2cSJim Jagielski         return null;
406*b1cdbd2cSJim Jagielski     }
407*b1cdbd2cSJim Jagielski     /**
408*b1cdbd2cSJim Jagielski      * Returns the index of the last occurrence of the specified object in
409*b1cdbd2cSJim Jagielski      * this list.
410*b1cdbd2cSJim Jagielski      *
411*b1cdbd2cSJim Jagielski      * @param   elem   the desired element.
412*b1cdbd2cSJim Jagielski      * @return  the index of the last occurrence of the specified object in
413*b1cdbd2cSJim Jagielski      *          this list; returns -1 if the object is not found.
414*b1cdbd2cSJim Jagielski      */
lastIndexOf(Object elem)415*b1cdbd2cSJim Jagielski     synchronized public int lastIndexOf(Object elem)
416*b1cdbd2cSJim Jagielski     {
417*b1cdbd2cSJim Jagielski         int index= -1;
418*b1cdbd2cSJim Jagielski         if (elementData != null && elem != null)
419*b1cdbd2cSJim Jagielski         {
420*b1cdbd2cSJim Jagielski             for (int i = size-1; i >= 0; i--)
421*b1cdbd2cSJim Jagielski             {
422*b1cdbd2cSJim Jagielski                 if (elem == elementData[i])
423*b1cdbd2cSJim Jagielski                 {
424*b1cdbd2cSJim Jagielski                     index= i;
425*b1cdbd2cSJim Jagielski                     break;
426*b1cdbd2cSJim Jagielski                 }
427*b1cdbd2cSJim Jagielski             }
428*b1cdbd2cSJim Jagielski             if (index == -1)
429*b1cdbd2cSJim Jagielski             {
430*b1cdbd2cSJim Jagielski                 for (int i = size-1; i >= 0; i--)
431*b1cdbd2cSJim Jagielski                 {
432*b1cdbd2cSJim Jagielski                     if (UnoRuntime.areSame(elem, elementData[i]))
433*b1cdbd2cSJim Jagielski                     {
434*b1cdbd2cSJim Jagielski                         index= i;
435*b1cdbd2cSJim Jagielski                         break;
436*b1cdbd2cSJim Jagielski                     }
437*b1cdbd2cSJim Jagielski                 }
438*b1cdbd2cSJim Jagielski             }
439*b1cdbd2cSJim Jagielski         }
440*b1cdbd2cSJim Jagielski         return index;
441*b1cdbd2cSJim Jagielski     }
442*b1cdbd2cSJim Jagielski 
443*b1cdbd2cSJim Jagielski     /**
444*b1cdbd2cSJim Jagielski      * Returns a shallow copy of this <tt>ArrayList</tt> instance. The contained
445*b1cdbd2cSJim Jagielski      * references are copied but the objects not.
446*b1cdbd2cSJim Jagielski      *
447*b1cdbd2cSJim Jagielski      * @return  a clone of this <tt>List</tt> instance.
448*b1cdbd2cSJim Jagielski      */
clone()449*b1cdbd2cSJim Jagielski     synchronized public Object clone()
450*b1cdbd2cSJim Jagielski     {
451*b1cdbd2cSJim Jagielski         Object ret= null;
452*b1cdbd2cSJim Jagielski         if (elementData != null)
453*b1cdbd2cSJim Jagielski         {
454*b1cdbd2cSJim Jagielski             InterfaceContainer cont= new InterfaceContainer();
455*b1cdbd2cSJim Jagielski             cont.elementData = new Object[size];
456*b1cdbd2cSJim Jagielski             cont.size= size;
457*b1cdbd2cSJim Jagielski             System.arraycopy(elementData, 0, cont.elementData, 0, size);
458*b1cdbd2cSJim Jagielski             ret= cont;
459*b1cdbd2cSJim Jagielski         }
460*b1cdbd2cSJim Jagielski         return ret;
461*b1cdbd2cSJim Jagielski     }
listIterator()462*b1cdbd2cSJim Jagielski     synchronized public ListIterator listIterator()
463*b1cdbd2cSJim Jagielski     {
464*b1cdbd2cSJim Jagielski         return listIterator(0);
465*b1cdbd2cSJim Jagielski     }
466*b1cdbd2cSJim Jagielski 
467*b1cdbd2cSJim Jagielski     /** The iterator keeps a copy of the list. Changes to InterfaceContainer do not
468*b1cdbd2cSJim Jagielski      *  affect the data of the iterator. Conversly, changes to the iterator are effect
469*b1cdbd2cSJim Jagielski      *  InterfaceContainer.
470*b1cdbd2cSJim Jagielski      *
471*b1cdbd2cSJim Jagielski      * @param index
472*b1cdbd2cSJim Jagielski      */
listIterator(int index)473*b1cdbd2cSJim Jagielski     synchronized public ListIterator listIterator(int index)
474*b1cdbd2cSJim Jagielski     {
475*b1cdbd2cSJim Jagielski         if (elementData != null)
476*b1cdbd2cSJim Jagielski         {
477*b1cdbd2cSJim Jagielski             InterfaceContainer aCopy= (InterfaceContainer) clone();
478*b1cdbd2cSJim Jagielski             return new LstItr(aCopy, index);
479*b1cdbd2cSJim Jagielski         }
480*b1cdbd2cSJim Jagielski         return null;
481*b1cdbd2cSJim Jagielski     }
482*b1cdbd2cSJim Jagielski     /**
483*b1cdbd2cSJim Jagielski      * Removes the element at the specified position in this list.
484*b1cdbd2cSJim Jagielski      * Shifts any subsequent elements to the left (subtracts one from their
485*b1cdbd2cSJim Jagielski      * indices).
486*b1cdbd2cSJim Jagielski      *
487*b1cdbd2cSJim Jagielski      * @param index the index of the element to removed.
488*b1cdbd2cSJim Jagielski      * @return the element that was removed from the list.
489*b1cdbd2cSJim Jagielski      * @throws    IndexOutOfBoundsException if index out of range <tt>(index
490*b1cdbd2cSJim Jagielski      * 		  &lt; 0 || index &gt;= size())</tt>.
491*b1cdbd2cSJim Jagielski      */
remove(int index)492*b1cdbd2cSJim Jagielski     synchronized public Object remove(int index)
493*b1cdbd2cSJim Jagielski     {
494*b1cdbd2cSJim Jagielski         Object ret= null;
495*b1cdbd2cSJim Jagielski         if (elementData != null)
496*b1cdbd2cSJim Jagielski         {
497*b1cdbd2cSJim Jagielski             RangeCheck(index);
498*b1cdbd2cSJim Jagielski             ret= elementData[index];
499*b1cdbd2cSJim Jagielski 
500*b1cdbd2cSJim Jagielski             int numMoved = size - index - 1;
501*b1cdbd2cSJim Jagielski             if (numMoved > 0)
502*b1cdbd2cSJim Jagielski                 System.arraycopy(elementData, index+1, elementData, index,
503*b1cdbd2cSJim Jagielski                 numMoved);
504*b1cdbd2cSJim Jagielski             elementData[--size] = null; // Let gc do its work
505*b1cdbd2cSJim Jagielski         }
506*b1cdbd2cSJim Jagielski         return ret;
507*b1cdbd2cSJim Jagielski     }
508*b1cdbd2cSJim Jagielski 
509*b1cdbd2cSJim Jagielski 
510*b1cdbd2cSJim Jagielski     /** Parameter obj may  */
remove(Object obj)511*b1cdbd2cSJim Jagielski     synchronized public boolean remove(Object obj)
512*b1cdbd2cSJim Jagielski     {
513*b1cdbd2cSJim Jagielski         boolean ret= false;
514*b1cdbd2cSJim Jagielski         if (elementData != null && obj != null)
515*b1cdbd2cSJim Jagielski         {
516*b1cdbd2cSJim Jagielski             int index= indexOf(obj);
517*b1cdbd2cSJim Jagielski             if (index != -1)
518*b1cdbd2cSJim Jagielski             {
519*b1cdbd2cSJim Jagielski                 ret= true;
520*b1cdbd2cSJim Jagielski                 remove(index);
521*b1cdbd2cSJim Jagielski             }
522*b1cdbd2cSJim Jagielski         }
523*b1cdbd2cSJim Jagielski         return ret;
524*b1cdbd2cSJim Jagielski     }
525*b1cdbd2cSJim Jagielski 
removeAll(Collection collection)526*b1cdbd2cSJim Jagielski     synchronized public boolean removeAll(Collection collection)
527*b1cdbd2cSJim Jagielski     {
528*b1cdbd2cSJim Jagielski         boolean retVal= false;
529*b1cdbd2cSJim Jagielski         if (elementData != null && collection != null)
530*b1cdbd2cSJim Jagielski         {
531*b1cdbd2cSJim Jagielski             Iterator it= collection.iterator();
532*b1cdbd2cSJim Jagielski             while (it.hasNext())
533*b1cdbd2cSJim Jagielski             {
534*b1cdbd2cSJim Jagielski                 Object obj= it.next();
535*b1cdbd2cSJim Jagielski                 boolean bMod= remove( obj);
536*b1cdbd2cSJim Jagielski                 if (bMod)
537*b1cdbd2cSJim Jagielski                     retVal= true;
538*b1cdbd2cSJim Jagielski             }
539*b1cdbd2cSJim Jagielski         }
540*b1cdbd2cSJim Jagielski         return retVal;
541*b1cdbd2cSJim Jagielski     }
542*b1cdbd2cSJim Jagielski 
retainAll(Collection collection)543*b1cdbd2cSJim Jagielski     synchronized public boolean retainAll(Collection collection)
544*b1cdbd2cSJim Jagielski     {
545*b1cdbd2cSJim Jagielski         boolean retVal= false;
546*b1cdbd2cSJim Jagielski         if (elementData != null && collection != null)
547*b1cdbd2cSJim Jagielski         {
548*b1cdbd2cSJim Jagielski             // iterate over data
549*b1cdbd2cSJim Jagielski             Object[] arRetained= new Object[size];
550*b1cdbd2cSJim Jagielski             int indexRetained= 0;
551*b1cdbd2cSJim Jagielski             for(int i= 0; i < size; i++)
552*b1cdbd2cSJim Jagielski             {
553*b1cdbd2cSJim Jagielski                 Object curElem= elementData[i];
554*b1cdbd2cSJim Jagielski                 // try to find the element in collection
555*b1cdbd2cSJim Jagielski                 Iterator itColl= collection.iterator();
556*b1cdbd2cSJim Jagielski                 boolean bExists= false;
557*b1cdbd2cSJim Jagielski                 while (itColl.hasNext())
558*b1cdbd2cSJim Jagielski                 {
559*b1cdbd2cSJim Jagielski                     if (curElem == itColl.next())
560*b1cdbd2cSJim Jagielski                     {
561*b1cdbd2cSJim Jagielski                         // current element is in collection
562*b1cdbd2cSJim Jagielski                         bExists= true;
563*b1cdbd2cSJim Jagielski                         break;
564*b1cdbd2cSJim Jagielski                     }
565*b1cdbd2cSJim Jagielski                 }
566*b1cdbd2cSJim Jagielski                 if (bExists == false)
567*b1cdbd2cSJim Jagielski                 {
568*b1cdbd2cSJim Jagielski                     itColl= collection.iterator();
569*b1cdbd2cSJim Jagielski                     while (itColl.hasNext())
570*b1cdbd2cSJim Jagielski                     {
571*b1cdbd2cSJim Jagielski                         Object o= itColl.next();
572*b1cdbd2cSJim Jagielski                         if (o != null)
573*b1cdbd2cSJim Jagielski                         {
574*b1cdbd2cSJim Jagielski                             if (UnoRuntime.areSame(o, curElem))
575*b1cdbd2cSJim Jagielski                             {
576*b1cdbd2cSJim Jagielski                                 bExists= true;
577*b1cdbd2cSJim Jagielski                                 break;
578*b1cdbd2cSJim Jagielski                             }
579*b1cdbd2cSJim Jagielski                         }
580*b1cdbd2cSJim Jagielski                     }
581*b1cdbd2cSJim Jagielski                 }
582*b1cdbd2cSJim Jagielski                 if (bExists == true)
583*b1cdbd2cSJim Jagielski                     arRetained[indexRetained++]= curElem;
584*b1cdbd2cSJim Jagielski             }
585*b1cdbd2cSJim Jagielski             retVal= size != indexRetained;
586*b1cdbd2cSJim Jagielski             if (indexRetained > 0)
587*b1cdbd2cSJim Jagielski             {
588*b1cdbd2cSJim Jagielski                 elementData= arRetained;
589*b1cdbd2cSJim Jagielski                 size= indexRetained;
590*b1cdbd2cSJim Jagielski             }
591*b1cdbd2cSJim Jagielski         }
592*b1cdbd2cSJim Jagielski         return retVal;
593*b1cdbd2cSJim Jagielski     }
594*b1cdbd2cSJim Jagielski 
595*b1cdbd2cSJim Jagielski 
596*b1cdbd2cSJim Jagielski     /** Not supported.
597*b1cdbd2cSJim Jagielski      * @param index index of element to replace.
598*b1cdbd2cSJim Jagielski      * @param element element to be stored at the specified position.
599*b1cdbd2cSJim Jagielski      * @return the element previously at the specified position.
600*b1cdbd2cSJim Jagielski      * @throws    IndexOutOfBoundsException if index out of range
601*b1cdbd2cSJim Jagielski      *		  <tt>(index &lt; 0 || index &gt;= size())</tt>.
602*b1cdbd2cSJim Jagielski      */
set(int index, Object element)603*b1cdbd2cSJim Jagielski     synchronized public Object set(int index, Object element)
604*b1cdbd2cSJim Jagielski     {
605*b1cdbd2cSJim Jagielski           Object ret= null;
606*b1cdbd2cSJim Jagielski           if (elementData != null && element != null)
607*b1cdbd2cSJim Jagielski           {
608*b1cdbd2cSJim Jagielski               RangeCheck(index);
609*b1cdbd2cSJim Jagielski               ret = elementData[index];
610*b1cdbd2cSJim Jagielski               elementData[index] = element;
611*b1cdbd2cSJim Jagielski           }
612*b1cdbd2cSJim Jagielski           return ret;
613*b1cdbd2cSJim Jagielski     }
614*b1cdbd2cSJim Jagielski 
615*b1cdbd2cSJim Jagielski     /**
616*b1cdbd2cSJim Jagielski      * Returns the number of elements in this list.
617*b1cdbd2cSJim Jagielski      *
618*b1cdbd2cSJim Jagielski      * @return  the number of elements in this list.
619*b1cdbd2cSJim Jagielski      */
size()620*b1cdbd2cSJim Jagielski     synchronized public int size()
621*b1cdbd2cSJim Jagielski     {
622*b1cdbd2cSJim Jagielski         if (elementData != null)
623*b1cdbd2cSJim Jagielski             return size;
624*b1cdbd2cSJim Jagielski         return 0;
625*b1cdbd2cSJim Jagielski     }
626*b1cdbd2cSJim Jagielski 
627*b1cdbd2cSJim Jagielski 
628*b1cdbd2cSJim Jagielski     /**
629*b1cdbd2cSJim Jagielski      * Returns an array containing all of the elements in this list
630*b1cdbd2cSJim Jagielski      * in the correct order.
631*b1cdbd2cSJim Jagielski      *
632*b1cdbd2cSJim Jagielski      * @return an array containing all of the elements in this list
633*b1cdbd2cSJim Jagielski      * 	       in the correct order.
634*b1cdbd2cSJim Jagielski      */
toArray()635*b1cdbd2cSJim Jagielski     synchronized public Object[] toArray()
636*b1cdbd2cSJim Jagielski     {
637*b1cdbd2cSJim Jagielski         if (elementData != null)
638*b1cdbd2cSJim Jagielski         {
639*b1cdbd2cSJim Jagielski             Object[] result = new Object[size];
640*b1cdbd2cSJim Jagielski             System.arraycopy(elementData, 0, result, 0, size);
641*b1cdbd2cSJim Jagielski             return result;
642*b1cdbd2cSJim Jagielski         }
643*b1cdbd2cSJim Jagielski         return null;
644*b1cdbd2cSJim Jagielski     }
645*b1cdbd2cSJim Jagielski 
646*b1cdbd2cSJim Jagielski     /**
647*b1cdbd2cSJim Jagielski      * Returns an array containing all of the elements in this list in the
648*b1cdbd2cSJim Jagielski      * correct order.  The runtime type of the returned array is that of the
649*b1cdbd2cSJim Jagielski      * specified array.  If the list fits in the specified array, it is
650*b1cdbd2cSJim Jagielski      * returned therein.  Otherwise, a new array is allocated with the runtime
651*b1cdbd2cSJim Jagielski      * type of the specified array and the size of this list.<p>
652*b1cdbd2cSJim Jagielski      *
653*b1cdbd2cSJim Jagielski      * If the list fits in the specified array with room to spare (i.e., the
654*b1cdbd2cSJim Jagielski      * array has more elements than the list), the element in the array
655*b1cdbd2cSJim Jagielski      * immediately following the end of the collection is set to
656*b1cdbd2cSJim Jagielski      * <tt>null</tt>.  This is useful in determining the length of the list
657*b1cdbd2cSJim Jagielski      * <i>only</i> if the caller knows that the list does not contain any
658*b1cdbd2cSJim Jagielski      * <tt>null</tt> elements.
659*b1cdbd2cSJim Jagielski      *
660*b1cdbd2cSJim Jagielski      * @param a the array into which the elements of the list are to
661*b1cdbd2cSJim Jagielski      *		be stored, if it is big enough; otherwise, a new array of the
662*b1cdbd2cSJim Jagielski      * 		same runtime type is allocated for this purpose.
663*b1cdbd2cSJim Jagielski      * @return an array containing the elements of the list.
664*b1cdbd2cSJim Jagielski      * @throws ArrayStoreException if the runtime type of a is not a supertype
665*b1cdbd2cSJim Jagielski      *         of the runtime type of every element in this list.
666*b1cdbd2cSJim Jagielski      */
toArray(Object a[])667*b1cdbd2cSJim Jagielski     synchronized public Object[] toArray(Object a[])
668*b1cdbd2cSJim Jagielski     {
669*b1cdbd2cSJim Jagielski         if (a.length < size)
670*b1cdbd2cSJim Jagielski             a = (Object[])java.lang.reflect.Array.newInstance(
671*b1cdbd2cSJim Jagielski             a.getClass().getComponentType(), size);
672*b1cdbd2cSJim Jagielski         if (elementData != null)
673*b1cdbd2cSJim Jagielski             System.arraycopy(elementData, 0, a, 0, size);
674*b1cdbd2cSJim Jagielski 
675*b1cdbd2cSJim Jagielski         if (a.length > size)
676*b1cdbd2cSJim Jagielski             a[size] = null;
677*b1cdbd2cSJim Jagielski 
678*b1cdbd2cSJim Jagielski         return a;
679*b1cdbd2cSJim Jagielski     }
680*b1cdbd2cSJim Jagielski 
681*b1cdbd2cSJim Jagielski     /**
682*b1cdbd2cSJim Jagielski      * Check if the given index is in range.  If not, throw an appropriate
683*b1cdbd2cSJim Jagielski      * runtime exception.
684*b1cdbd2cSJim Jagielski      */
RangeCheck(int index)685*b1cdbd2cSJim Jagielski     private void RangeCheck(int index)
686*b1cdbd2cSJim Jagielski     {
687*b1cdbd2cSJim Jagielski         if (index >= size || index < 0)
688*b1cdbd2cSJim Jagielski             throw new IndexOutOfBoundsException(
689*b1cdbd2cSJim Jagielski             "Index: "+index+", Size: "+size);
690*b1cdbd2cSJim Jagielski     }
691*b1cdbd2cSJim Jagielski 
disposeAndClear(EventObject evt)692*b1cdbd2cSJim Jagielski     public void disposeAndClear(EventObject evt)
693*b1cdbd2cSJim Jagielski     {
694*b1cdbd2cSJim Jagielski         Iterator aIt;
695*b1cdbd2cSJim Jagielski         synchronized (this)
696*b1cdbd2cSJim Jagielski         {
697*b1cdbd2cSJim Jagielski             aIt= iterator();
698*b1cdbd2cSJim Jagielski             // Container freigeben, falls im disposing neue Eintraege kommen
699*b1cdbd2cSJim Jagielski             // set the member to null, the iterator delete the values
700*b1cdbd2cSJim Jagielski             clear();
701*b1cdbd2cSJim Jagielski             elementData= null;
702*b1cdbd2cSJim Jagielski             size= 0;
703*b1cdbd2cSJim Jagielski         }
704*b1cdbd2cSJim Jagielski         if (aIt != null)
705*b1cdbd2cSJim Jagielski         {
706*b1cdbd2cSJim Jagielski             while( aIt.hasNext() )
707*b1cdbd2cSJim Jagielski             {
708*b1cdbd2cSJim Jagielski                 try
709*b1cdbd2cSJim Jagielski                 {
710*b1cdbd2cSJim Jagielski                     Object o= aIt.next();
711*b1cdbd2cSJim Jagielski                     XEventListener evtListener= UnoRuntime.queryInterface(
712*b1cdbd2cSJim Jagielski                     XEventListener.class, o);
713*b1cdbd2cSJim Jagielski                     if( evtListener != null )
714*b1cdbd2cSJim Jagielski                         evtListener.disposing( evt );
715*b1cdbd2cSJim Jagielski                 }
716*b1cdbd2cSJim Jagielski                 catch ( RuntimeException e)
717*b1cdbd2cSJim Jagielski                 {
718*b1cdbd2cSJim Jagielski                     // be robust, if e.g. a remote bridge has disposed already.
719*b1cdbd2cSJim Jagielski                     // there is no way, to delegate the error to the caller :o(.
720*b1cdbd2cSJim Jagielski                 }
721*b1cdbd2cSJim Jagielski             }
722*b1cdbd2cSJim Jagielski         }
723*b1cdbd2cSJim Jagielski     }
724*b1cdbd2cSJim Jagielski 
725*b1cdbd2cSJim Jagielski 
726*b1cdbd2cSJim Jagielski     private class Itr implements Iterator
727*b1cdbd2cSJim Jagielski     {
728*b1cdbd2cSJim Jagielski         InterfaceContainer dataIt;
729*b1cdbd2cSJim Jagielski         /**
730*b1cdbd2cSJim Jagielski          * Index of element to be returned by subsequent call to next.
731*b1cdbd2cSJim Jagielski          */
732*b1cdbd2cSJim Jagielski         int cursor= 0;
733*b1cdbd2cSJim Jagielski         /**
734*b1cdbd2cSJim Jagielski          * Index of element returned by most recent call to next or
735*b1cdbd2cSJim Jagielski          * previous.  Reset to -1 if this element is deleted by a call
736*b1cdbd2cSJim Jagielski          * to remove.
737*b1cdbd2cSJim Jagielski          */
738*b1cdbd2cSJim Jagielski         int lastRet = -1;
739*b1cdbd2cSJim Jagielski 
740*b1cdbd2cSJim Jagielski         /** The object that has been returned by most recent call to next
741*b1cdbd2cSJim Jagielski          *  or previous. Reset to null if this element is deleted by a call
742*b1cdbd2cSJim Jagielski          *  to remove.
743*b1cdbd2cSJim Jagielski          */
744*b1cdbd2cSJim Jagielski         Object lastRetObj= null;
745*b1cdbd2cSJim Jagielski 
Itr(InterfaceContainer _data)746*b1cdbd2cSJim Jagielski         Itr(InterfaceContainer _data)
747*b1cdbd2cSJim Jagielski         {
748*b1cdbd2cSJim Jagielski             dataIt= _data;
749*b1cdbd2cSJim Jagielski         }
750*b1cdbd2cSJim Jagielski 
hasNext()751*b1cdbd2cSJim Jagielski         synchronized public boolean hasNext()
752*b1cdbd2cSJim Jagielski         {
753*b1cdbd2cSJim Jagielski             return cursor !=dataIt.size();
754*b1cdbd2cSJim Jagielski         }
755*b1cdbd2cSJim Jagielski 
next()756*b1cdbd2cSJim Jagielski         public synchronized Object next()
757*b1cdbd2cSJim Jagielski         {
758*b1cdbd2cSJim Jagielski             try
759*b1cdbd2cSJim Jagielski             {
760*b1cdbd2cSJim Jagielski                 Object next = dataIt.get(cursor);
761*b1cdbd2cSJim Jagielski                 lastRet = cursor++;
762*b1cdbd2cSJim Jagielski                 lastRetObj= next;
763*b1cdbd2cSJim Jagielski                 return next;
764*b1cdbd2cSJim Jagielski             }
765*b1cdbd2cSJim Jagielski             catch(java.lang.IndexOutOfBoundsException e)
766*b1cdbd2cSJim Jagielski             {
767*b1cdbd2cSJim Jagielski                 throw new java.util.NoSuchElementException();
768*b1cdbd2cSJim Jagielski             }
769*b1cdbd2cSJim Jagielski         }
770*b1cdbd2cSJim Jagielski 
771*b1cdbd2cSJim Jagielski         /** Removes the interface from the list, that has been last returned by a
772*b1cdbd2cSJim Jagielski          *  call to next(). This is done according to the specification of the interface
773*b1cdbd2cSJim Jagielski          *  method. The element is also removed from InterfaceContainer but independent
774*b1cdbd2cSJim Jagielski          *  of the location. If the element is multiple times in InterfaceContainer then
775*b1cdbd2cSJim Jagielski          *  it is up to the java.util.ArrayList implementation what element is removed.
776*b1cdbd2cSJim Jagielski          */
remove()777*b1cdbd2cSJim Jagielski         public synchronized void remove()
778*b1cdbd2cSJim Jagielski         {
779*b1cdbd2cSJim Jagielski             if (lastRet == -1)
780*b1cdbd2cSJim Jagielski                 throw new IllegalStateException();
781*b1cdbd2cSJim Jagielski             // Remove the entry from InterfaceContainer.
782*b1cdbd2cSJim Jagielski             InterfaceContainer.this.remove(lastRetObj);
783*b1cdbd2cSJim Jagielski             dataIt.remove(lastRet);
784*b1cdbd2cSJim Jagielski 
785*b1cdbd2cSJim Jagielski             if (lastRet < cursor)
786*b1cdbd2cSJim Jagielski                 cursor--;
787*b1cdbd2cSJim Jagielski             lastRet = -1;
788*b1cdbd2cSJim Jagielski             lastRetObj= null;
789*b1cdbd2cSJim Jagielski         }
790*b1cdbd2cSJim Jagielski     }
791*b1cdbd2cSJim Jagielski 
792*b1cdbd2cSJim Jagielski     private class LstItr extends Itr implements ListIterator
793*b1cdbd2cSJim Jagielski     {
794*b1cdbd2cSJim Jagielski 
LstItr(InterfaceContainer _data, int _index)795*b1cdbd2cSJim Jagielski         LstItr(InterfaceContainer _data, int _index)
796*b1cdbd2cSJim Jagielski         {
797*b1cdbd2cSJim Jagielski             super(_data);
798*b1cdbd2cSJim Jagielski             cursor= _index;
799*b1cdbd2cSJim Jagielski         }
800*b1cdbd2cSJim Jagielski 
801*b1cdbd2cSJim Jagielski         /** Inserts an element to the iterators list according to the specification
802*b1cdbd2cSJim Jagielski          *  of this interface method. The element is also added to InterfaceContainer
803*b1cdbd2cSJim Jagielski          *  but its location within the list cannot be guaranteed.
804*b1cdbd2cSJim Jagielski          */
add(Object o)805*b1cdbd2cSJim Jagielski         public synchronized void add(Object o)
806*b1cdbd2cSJim Jagielski         {
807*b1cdbd2cSJim Jagielski             InterfaceContainer.this.add(o);
808*b1cdbd2cSJim Jagielski             dataIt.add(cursor++, o);
809*b1cdbd2cSJim Jagielski             lastRet = -1;
810*b1cdbd2cSJim Jagielski             lastRetObj= null;
811*b1cdbd2cSJim Jagielski         }
812*b1cdbd2cSJim Jagielski 
hasPrevious()813*b1cdbd2cSJim Jagielski         synchronized public boolean hasPrevious()
814*b1cdbd2cSJim Jagielski         {
815*b1cdbd2cSJim Jagielski             return cursor != 0;
816*b1cdbd2cSJim Jagielski         }
817*b1cdbd2cSJim Jagielski 
nextIndex()818*b1cdbd2cSJim Jagielski         synchronized public int nextIndex()
819*b1cdbd2cSJim Jagielski         {
820*b1cdbd2cSJim Jagielski             return cursor;
821*b1cdbd2cSJim Jagielski         }
822*b1cdbd2cSJim Jagielski 
previous()823*b1cdbd2cSJim Jagielski         public synchronized Object previous()
824*b1cdbd2cSJim Jagielski         {
825*b1cdbd2cSJim Jagielski             try
826*b1cdbd2cSJim Jagielski             {
827*b1cdbd2cSJim Jagielski                 Object previous = dataIt.get(--cursor);
828*b1cdbd2cSJim Jagielski                 lastRet = cursor;
829*b1cdbd2cSJim Jagielski                 lastRetObj= previous;
830*b1cdbd2cSJim Jagielski                 return previous;
831*b1cdbd2cSJim Jagielski             } catch(IndexOutOfBoundsException e)
832*b1cdbd2cSJim Jagielski             {
833*b1cdbd2cSJim Jagielski                 throw new NoSuchElementException();
834*b1cdbd2cSJim Jagielski             }
835*b1cdbd2cSJim Jagielski         }
836*b1cdbd2cSJim Jagielski 
previousIndex()837*b1cdbd2cSJim Jagielski         synchronized public int previousIndex()
838*b1cdbd2cSJim Jagielski         {
839*b1cdbd2cSJim Jagielski             return cursor-1;
840*b1cdbd2cSJim Jagielski         }
841*b1cdbd2cSJim Jagielski 
842*b1cdbd2cSJim Jagielski         /** This is not possible since several iterators can modify InterfaceContainer
843*b1cdbd2cSJim Jagielski          */
set(Object o)844*b1cdbd2cSJim Jagielski         public synchronized void set(Object o)
845*b1cdbd2cSJim Jagielski         {
846*b1cdbd2cSJim Jagielski             throw new UnsupportedOperationException();
847*b1cdbd2cSJim Jagielski         }
848*b1cdbd2cSJim Jagielski 
849*b1cdbd2cSJim Jagielski 
850*b1cdbd2cSJim Jagielski     } // class LstItr
851*b1cdbd2cSJim Jagielski }
852*b1cdbd2cSJim Jagielski 
853