summaryrefslogtreecommitdiffstats
path: root/ridljar/com/sun/star/lib/uno/helper/InterfaceContainer.java
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
commit940b4d1848e8c70ab7642901a68594e8016caffc (patch)
treeeb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /ridljar/com/sun/star/lib/uno/helper/InterfaceContainer.java
parentInitial commit. (diff)
downloadlibreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.tar.xz
libreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.zip
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ridljar/com/sun/star/lib/uno/helper/InterfaceContainer.java')
-rw-r--r--ridljar/com/sun/star/lib/uno/helper/InterfaceContainer.java864
1 files changed, 864 insertions, 0 deletions
diff --git a/ridljar/com/sun/star/lib/uno/helper/InterfaceContainer.java b/ridljar/com/sun/star/lib/uno/helper/InterfaceContainer.java
new file mode 100644
index 000000000..e858ced81
--- /dev/null
+++ b/ridljar/com/sun/star/lib/uno/helper/InterfaceContainer.java
@@ -0,0 +1,864 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+package com.sun.star.lib.uno.helper;
+
+import java.util.Iterator;
+import java.util.ListIterator;
+import java.util.Collection;
+
+import com.sun.star.lang.EventObject;
+import com.sun.star.lang.XEventListener;
+import com.sun.star.uno.UnoRuntime;
+
+/**
+ * This class is a container for interfaces.
+ *
+ * It is intended to be used as storage for UNO interface of a specific type.
+ * The client has to ensure that the container contains only elements of the same
+ * type. If one needs to store different types, then one uses OMultiTypeInterfaceContainer.
+ * When the client calls disposeAndClear, the contained objects are queried for
+ * com.sun.star.lang.XEventListener and disposing is called. Afterwards
+ * the list cannot be used anymore.
+ *
+ * This list does not allow null values.
+ * All methods are thread-safe. The same holds true for
+ * iterators, issued by this class. Several iterators can exist at the same time and can also
+ * be modified (java.util.ListIterator.add, java.util.ListIterator.remove etc.). To make this work,
+ * the InterfaceContainer provides the iterators with copies of the list's data.
+ * The add and remove calls on the iterator modify the data in the iterator's list as well as
+ * in InterfaceContainer. Modification on InterfaceContainer, however, are not
+ * synchronized with existing iterators. For example
+ * <pre>
+ * InterfaceContainer cont= new InterfaceContainer();
+ * ListIterator it= cont.listIterator();
+ *
+ * cont.add( someInterface);
+ * // one cannot obtain someInterface through iterator it,
+ * // instead get a new iterator
+ * it= cont.listIterator();
+ * // it now keeps a fresh copy of cont and hence contains someInterface
+ *
+ * // Adding an interface on the iterator will cause the interface also to be added
+ * // to InterfaceContainer
+ * it.add( someOtherInterface);
+ * // someOtherInterface is now in it and cont
+ * ListIterator it2= cont.listIterator();
+ * //someOtherInterface can also be obtained by all newly created iterators, e.g. it2.
+ * </pre>
+ *
+ * The add and remove methods of an iterator work on a particular location within a list,
+ * dependent on what the value of the iterator's cursor is. After the call the value at the
+ * appropriate position has been modified. Since the iterator received a copy of InterfaceContainer's
+ * data, InterfaceContainer may have been modified (by List methods or through other iterators).
+ * Therefore both data sets may not contain the same elements anymore. Consequently, a List method
+ * that modifies data, does not modify InterfaceContainer's data at a certain index
+ * (according to the iterators cursor). Instead, new elements are added at the end of list. When
+ * Iterator.remove is called, then the first occurrence of that element in InterfaceContainer
+ * is removed.
+ * ListIterator.set is not supported.
+ *
+ * A lot of methods resemble those of the to java.util.List interface, although
+ * this class does not implement it. However, the list iterators returned, for example by
+ * the listIterator method implement the java.util.ListIterator interface.
+ * Implementing the List interface would mean to support all none - optional methods as
+ * prescribed by the interface declaration. Among those is the subList method which returns
+ * a range of values of the list's data wrapped in a List implementation. Changes to the sub
+ * list have to cause changes in the main list. This is a problem, since this class is to be
+ * used in a multi-threaded environment. The sub list could work on a copy as the iterators
+ * do, but all the functions which work on a given index could not be properly supported.
+ * Unfortunately, the List interface documentation states that all optional methods implemented
+ * by the list have to be implemented in the sub list. That would mean to do without all those
+ * critical methods, although they might work well in the "main list" (as opposed to sub list).
+ */
+public class InterfaceContainer implements Cloneable
+{
+ static final boolean DEBUG= false;
+ /**
+ * The array buffer into which the elements of the ArrayList are stored.
+ * The capacity of the ArrayList is the length of this array buffer.
+ */
+ Object elementData[];
+
+ /**
+ * The size of the ArrayList (the number of elements it contains).
+ */
+ private int size;
+
+
+ /** Creates a new instance of InterfaceContainer */
+ public InterfaceContainer()
+ {
+ this(10);
+ }
+ /**
+ * Constructs an empty list with the specified initial capacity.
+ *
+ * @param initialCapacity the initial capacity of the list.
+ * @exception IllegalArgumentException if the specified initial capacity
+ * is negative
+ */
+ public InterfaceContainer(int initialCapacity)
+ {
+ if (initialCapacity < 0)
+ throw new java.lang.IllegalArgumentException("Illegal Capacity: "+
+ initialCapacity);
+ this.elementData = new Object[initialCapacity];
+ }
+
+ private InterfaceContainer(Object[] data) {
+ elementData = data;
+ size = elementData == null ? 0 : elementData.length;
+ }
+
+ /**
+ * Trims the capacity of this <code>ArrayList</code> instance to be the
+ * list's current size. An application can use this operation to minimize
+ * the storage of an <code>ArrayList</code> instance.
+ */
+ synchronized public void trimToSize()
+ {
+ int oldCapacity = elementData.length;
+ if (size < oldCapacity)
+ {
+ Object oldData[] = elementData;
+ elementData = new Object[size];
+ System.arraycopy(oldData, 0, elementData, 0, size);
+ }
+ }
+
+ /**
+ * Increases the capacity of this <code>ArrayList</code> instance, if
+ * necessary, to ensure that it can hold at least the number of elements
+ * specified by the minimum capacity argument.
+ *
+ * @param minCapacity the desired minimum capacity.
+ */
+ synchronized public void ensureCapacity(int minCapacity)
+ {
+ int oldCapacity = elementData.length;
+ if (minCapacity > oldCapacity)
+ {
+ Object oldData[] = elementData;
+ int newCapacity = (oldCapacity * 3)/2 + 1;
+ if (newCapacity < minCapacity)
+ newCapacity = minCapacity;
+ elementData = new Object[newCapacity];
+ System.arraycopy(oldData, 0, elementData, 0, size);
+ }
+ }
+
+ /**
+ * Appends the specified element to the end of this list.
+ *
+ * @param o element to be appended to this list.
+ * @return <code>true</code> (as per the general contract of Collection.add).
+ */
+ synchronized public boolean add(Object o)
+ {
+ boolean ret= false;
+ if (elementData != null && o != null)
+ {
+ ensureCapacity(size + 1); // Increments modCount!!
+ elementData[size++] = o;
+ ret= true;
+ }
+ return ret;
+ }
+
+ /**
+ * Inserts the specified element at the specified position in this
+ * list. Shifts the element currently at that position (if any) and
+ * any subsequent elements to the right (adds one to their indices).
+ *
+ * @param index index at which the specified element is to be inserted.
+ * @param element element to be inserted.
+ * @throws IndexOutOfBoundsException if index is out of range
+ * <code>(index &lt; 0 || index &gt; size())</code>.
+ */
+ synchronized public void add(int index, Object element)
+ {
+ if (elementData != null && element != null)
+ {
+ if (index > size || index < 0)
+ throw new IndexOutOfBoundsException(
+ "Index: "+index+", Size: "+size);
+
+ ensureCapacity(size+1);
+ System.arraycopy(elementData, index, elementData, index + 1,
+ size - index);
+ elementData[index] = element;
+ size++;
+ }
+ }
+
+
+ /**
+ * Appends all of the elements in the specified Collection to the end of
+ * this list, in the order that they are returned by the
+ * specified Collection's Iterator. The behavior of this operation is
+ * undefined if the specified Collection is modified while the operation
+ * is in progress. (This implies that the behavior of this call is
+ * undefined if the specified Collection is this list, and this
+ * list is nonempty.)
+ *
+ * @param c the elements to be inserted into this list.
+ * @throws IndexOutOfBoundsException if index out of range <code>(index
+ * &lt; 0 || index &gt; size())</code>.
+ * @return true if an element was inserted.
+ */
+ synchronized public boolean addAll(Collection c)
+ {
+ int numNew = c.size();
+ ensureCapacity(size + numNew);
+
+ Iterator e = c.iterator();
+ for (int i=0; i<numNew; i++)
+ {
+ Object o= e.next();
+ if (o != null)
+ elementData[size++] = o;
+ }
+ return numNew != 0;
+ }
+ /**
+ * Inserts all of the elements in the specified Collection into this
+ * list, starting at the specified position. Shifts the element
+ * currently at that position (if any) and any subsequent elements to
+ * the right (increases their indices). The new elements will appear
+ * in the list in the order that they are returned by the
+ * specified Collection's iterator.
+ *
+ * @param index index at which to insert first element
+ * from the specified collection.
+ * @param c elements to be inserted into this list.
+ * @throws IndexOutOfBoundsException if index out of range <code>(index
+ * &lt; 0 || index &gt; size())</code>.
+ * @return true if an element was inserted.
+ */
+ synchronized public boolean addAll(int index, Collection c)
+ {
+ boolean ret= false;
+ if (elementData != null)
+ {
+ if (index > size || index < 0)
+ throw new IndexOutOfBoundsException(
+ "Index: "+index+", Size: "+size);
+ // only add the non-null elements
+ int sizeCol= c.size();
+ Object[] arColl= new Object[sizeCol];
+ Iterator icol= c.iterator();
+ int curIndex= 0;
+ for (int i=0; i < sizeCol; i++)
+ {
+ Object o= icol.next();
+ if (o != null)
+ arColl[curIndex++]= o;
+ }
+ int numNew = curIndex;
+ ensureCapacity(size + numNew); // Increments modCount!!
+
+ int numMoved = size - index;
+ if (numMoved > 0)
+ System.arraycopy(elementData, index, elementData, index + numNew,
+ numMoved);
+
+ for (int i=0; i<numNew; i++)
+ {
+ elementData[index++]= arColl[i];
+ }
+ size += numNew;
+ ret= numNew != 0;
+ }
+ return ret;
+ }
+
+ /**
+ * Removes all of the elements from this list. The list will
+ * be empty after this call returns.
+ */
+ synchronized public void clear()
+ {
+ if (elementData != null)
+ {
+ // Let gc do its work
+ for (int i = 0; i < size; i++)
+ elementData[i] = null;
+
+ size = 0;
+ }
+ }
+ /**
+ * Returns <code>true</code> if this list contains the specified element.
+ *
+ * @param elem element whose presence in this List is to be tested.
+ * @return <code>true</code> if this list contains the specified element.
+ */
+ synchronized public boolean contains(Object elem)
+ {
+ return indexOf(elem) >= 0;
+ }
+
+ synchronized public boolean containsAll(Collection collection)
+ {
+ boolean retVal= true;
+ if (elementData != null && collection != null)
+ {
+ Iterator it= collection.iterator();
+ while (it.hasNext())
+ {
+ Object obj= it.next();
+ if (!contains(obj))
+ {
+ retVal= false;
+ break;
+ }
+ }
+ }
+ return retVal;
+ }
+ /**
+ * Returns the element at the specified position in this list.
+ *
+ * @param index index of element to return.
+ * @return the element at the specified position in this list.
+ * @throws IndexOutOfBoundsException if index is out of range <code>(index
+ * &lt; 0 || index &gt;= size())</code>.
+ */
+ synchronized public Object get(int index)
+ {
+ if (elementData != null)
+ {
+ RangeCheck(index);
+ return elementData[index];
+ }
+ return null;
+ }
+
+ /**
+ * Searches for the first occurrence of the given argument, testing
+ * for equality using the <code>equals</code> method.
+ *
+ * @param elem an object.
+ * @return the index of the first occurrence of the argument in this
+ * list; returns <code>-1</code> if the object is not found.
+ * @see Object#equals(Object)
+ */
+ synchronized public int indexOf(Object elem)
+ {
+ if (elementData == null || elem == null) {
+ return -1;
+ }
+
+ int index= -1;
+
+ for (int i = 0; i < size; i++)
+ {
+ if (elem == elementData[i])
+ {
+ index= i;
+ break;
+ }
+ }
+
+ if (index == -1)
+ {
+ for (int i = 0; i < size; i++)
+ {
+ if (UnoRuntime.areSame(elem, elementData[i]))
+ {
+ index= i;
+ break;
+ }
+ }
+ }
+ return index;
+ }
+ /**
+ * Tests if this list has no elements.
+ *
+ * @return <code>true</code> if this list has no elements;
+ * <code>false</code> otherwise.
+ */
+ synchronized public boolean isEmpty()
+ {
+ return size == 0;
+ }
+
+ synchronized public Iterator iterator()
+ {
+ if (elementData != null)
+ {
+ InterfaceContainer aCopy= (InterfaceContainer) clone();
+ return new Itr(aCopy);
+ }
+ return null;
+ }
+ /**
+ * Returns the index of the last occurrence of the specified object in
+ * this list.
+ *
+ * @param elem the desired element.
+ * @return the index of the last occurrence of the specified object in
+ * this list; returns -1 if the object is not found.
+ */
+ synchronized public int lastIndexOf(Object elem)
+ {
+ if (elementData == null || elem == null) {
+ return -1;
+ }
+
+ int index= -1;
+
+ for (int i = size-1; i >= 0; i--)
+ {
+ if (elem == elementData[i])
+ {
+ index= i;
+ break;
+ }
+ }
+ if (index == -1)
+ {
+ for (int i = size-1; i >= 0; i--)
+ {
+ if (UnoRuntime.areSame(elem, elementData[i]))
+ {
+ index= i;
+ break;
+ }
+ }
+ }
+ return index;
+ }
+
+ /**
+ * Returns a shallow copy of this <code>ArrayList</code> instance. The contained
+ * references are copied but the objects not.
+ *
+ * @return a clone of this <code>List</code> instance.
+ */
+ @Override
+ synchronized public Object clone()
+ {
+ Object[] data;
+ if (elementData == null) {
+ data = null;
+ } else {
+ data = new Object[size];
+ System.arraycopy(elementData, 0, data, 0, size);
+ }
+ return new InterfaceContainer(data);
+ }
+ synchronized public ListIterator listIterator()
+ {
+ return listIterator(0);
+ }
+
+ /** The iterator keeps a copy of the list. Changes to InterfaceContainer do not
+ * affect the data of the iterator. Conversely, changes to the iterator are effect
+ * InterfaceContainer.
+ * @param index the starting offset into the list.
+ * @return a new iterator.
+ */
+ synchronized public ListIterator listIterator(int index)
+ {
+ if (elementData != null)
+ {
+ InterfaceContainer aCopy= (InterfaceContainer) clone();
+ return new LstItr(aCopy, index);
+ }
+ return null;
+ }
+ /**
+ * Removes the element at the specified position in this list.
+ * Shifts any subsequent elements to the left (subtracts one from their
+ * indices).
+ *
+ * @param index the index of the element to removed.
+ * @return the element that was removed from the list.
+ * @throws IndexOutOfBoundsException if index out of range <code>(index
+ * &lt; 0 || index &gt;= size())</code>.
+ */
+ synchronized public Object remove(int index)
+ {
+ Object ret= null;
+ if (elementData != null)
+ {
+ RangeCheck(index);
+ ret= elementData[index];
+
+ int numMoved = size - index - 1;
+ if (numMoved > 0)
+ System.arraycopy(elementData, index+1, elementData, index,
+ numMoved);
+ elementData[--size] = null; // Let gc do its work
+ }
+ return ret;
+ }
+
+
+ /** Parameter obj may... or may not. What did the original author want
+ * to tell us here?
+ * @param obj the object to be removed.
+ * @return true if obj was successfully removed from the list.
+ */
+ synchronized public boolean remove(Object obj)
+ {
+ boolean ret= false;
+ if (elementData != null && obj != null)
+ {
+ int index= indexOf(obj);
+ if (index != -1)
+ {
+ ret= true;
+ remove(index);
+ }
+ }
+ return ret;
+ }
+
+ synchronized public boolean removeAll(Collection collection)
+ {
+ boolean retVal= false;
+ if (elementData != null && collection != null)
+ {
+ Iterator it= collection.iterator();
+ while (it.hasNext())
+ {
+ Object obj= it.next();
+ boolean bMod= remove( obj);
+ if (bMod)
+ retVal= true;
+ }
+ }
+ return retVal;
+ }
+
+ synchronized public boolean retainAll(Collection collection)
+ {
+ if (elementData == null || collection == null) {
+ return false;
+ }
+
+ boolean retVal= false;
+ // iterate over data
+ Object[] arRetained= new Object[size];
+ int indexRetained= 0;
+ for(int i= 0; i < size; i++)
+ {
+ Object curElem= elementData[i];
+ // try to find the element in collection
+ Iterator itColl= collection.iterator();
+ boolean bExists= false;
+ while (itColl.hasNext())
+ {
+ if (curElem == itColl.next())
+ {
+ // current element is in collection
+ bExists= true;
+ break;
+ }
+ }
+ if (!bExists)
+ {
+ itColl= collection.iterator();
+ while (itColl.hasNext())
+ {
+ Object o= itColl.next();
+ if (o != null && UnoRuntime.areSame(o, curElem))
+ {
+ bExists= true;
+ break;
+ }
+ }
+ }
+ if (bExists)
+ arRetained[indexRetained++]= curElem;
+ }
+ retVal= size != indexRetained;
+ if (indexRetained > 0)
+ {
+ elementData= arRetained;
+ size= indexRetained;
+ }
+ return retVal;
+ }
+
+
+ /** Not supported.
+ * @param index index of element to replace.
+ * @param element element to be stored at the specified position.
+ * @return the element previously at the specified position.
+ * @throws IndexOutOfBoundsException if index out of range
+ * <code>(index &lt; 0 || index &gt;= size())</code>.
+ */
+ synchronized public Object set(int index, Object element)
+ {
+ Object ret= null;
+ if (elementData != null && element != null)
+ {
+ RangeCheck(index);
+ ret = elementData[index];
+ elementData[index] = element;
+ }
+ return ret;
+ }
+
+ /**
+ * Returns the number of elements in this list.
+ *
+ * @return the number of elements in this list.
+ */
+ synchronized public int size()
+ {
+ if (elementData != null)
+ return size;
+ return 0;
+ }
+
+
+ /**
+ * Returns an array containing all of the elements in this list
+ * in the correct order.
+ *
+ * @return an array containing all of the elements in this list
+ * in the correct order.
+ */
+ synchronized public Object[] toArray()
+ {
+ if (elementData != null)
+ {
+ Object[] result = new Object[size];
+ System.arraycopy(elementData, 0, result, 0, size);
+ return result;
+ }
+ return null;
+ }
+
+ /**
+ * Returns an array containing all of the elements in this list in the
+ * correct order. The runtime type of the returned array is that of the
+ * specified array. If the list fits in the specified array, it is
+ * returned therein. Otherwise, a new array is allocated with the runtime
+ * type of the specified array and the size of this list.<p>
+ *
+ * If the list fits in the specified array with room to spare (i.e., the
+ * array has more elements than the list), the element in the array
+ * immediately following the end of the collection is set to
+ * <code>null</code>. This is useful in determining the length of the list
+ * <i>only</i> if the caller knows that the list does not contain any
+ * <code>null</code> elements.
+ *
+ * @param a the array into which the elements of the list are to
+ * be stored, if it is big enough; otherwise, a new array of the
+ * same runtime type is allocated for this purpose.
+ * @return an array containing the elements of the list.
+ * @throws ArrayStoreException if the runtime type of a is not a supertype
+ * of the runtime type of every element in this list.
+ */
+ synchronized public Object[] toArray(Object a[])
+ {
+ if (a.length < size)
+ a = (Object[])java.lang.reflect.Array.newInstance(
+ a.getClass().getComponentType(), size);
+ if (elementData != null)
+ System.arraycopy(elementData, 0, a, 0, size);
+
+ if (a.length > size)
+ a[size] = null;
+
+ return a;
+ }
+
+ /**
+ * Check if the given index is in range. If not, throw an appropriate
+ * runtime exception.
+ */
+ private void RangeCheck(int index)
+ {
+ if (index >= size || index < 0)
+ throw new IndexOutOfBoundsException(
+ "Index: "+index+", Size: "+size);
+ }
+
+ public void disposeAndClear(EventObject evt)
+ {
+ Iterator aIt;
+ synchronized (this)
+ {
+ aIt= iterator();
+ // Release containers if new entries occur in disposing;
+ // set the member to null, the iterator delete the values
+ clear();
+ elementData= null;
+ size= 0;
+ }
+ if (aIt != null)
+ {
+ while( aIt.hasNext() )
+ {
+ try
+ {
+ Object o= aIt.next();
+ XEventListener evtListener= UnoRuntime.queryInterface(
+ XEventListener.class, o);
+ if( evtListener != null )
+ evtListener.disposing( evt );
+ }
+ catch ( RuntimeException e)
+ {
+ // be robust, if e.g. a remote bridge has disposed already.
+ // there is no way, to delegate the error to the caller :o(.
+ }
+ }
+ }
+ }
+
+
+ private class Itr implements Iterator
+ {
+ InterfaceContainer dataIt;
+ /**
+ * Index of element to be returned by subsequent call to next.
+ */
+ int cursor= 0;
+ /**
+ * Index of element returned by most recent call to next or
+ * previous. Reset to -1 if this element is deleted by a call
+ * to remove.
+ */
+ int lastRet = -1;
+
+ /** The object that has been returned by most recent call to next
+ * or previous. Reset to null if this element is deleted by a call
+ * to remove.
+ */
+ Object lastRetObj= null;
+
+ Itr(InterfaceContainer _data)
+ {
+ dataIt= _data;
+ }
+
+ synchronized public boolean hasNext()
+ {
+ return cursor !=dataIt.size();
+ }
+
+ public synchronized Object next()
+ {
+ try
+ {
+ Object next = dataIt.get(cursor);
+ lastRet = cursor++;
+ lastRetObj= next;
+ return next;
+ }
+ catch(java.lang.IndexOutOfBoundsException e)
+ {
+ java.util.NoSuchElementException ex2 = new java.util.NoSuchElementException();
+ ex2.initCause(e);
+ throw ex2;
+ }
+ }
+
+ /** Removes the interface from the list, that has been last returned by a
+ * call to next(). This is done according to the specification of the interface
+ * method. The element is also removed from InterfaceContainer but independent
+ * of the location. If the element is multiple times in InterfaceContainer then
+ * it is up to the java.util.ArrayList implementation what element is removed.
+ */
+ public synchronized void remove()
+ {
+ if (lastRet == -1)
+ throw new IllegalStateException();
+ // Remove the entry from InterfaceContainer.
+ InterfaceContainer.this.remove(lastRetObj);
+ dataIt.remove(lastRet);
+
+ if (lastRet < cursor)
+ cursor--;
+ lastRet = -1;
+ lastRetObj= null;
+ }
+ }
+
+ private class LstItr extends Itr implements ListIterator
+ {
+
+ LstItr(InterfaceContainer _data, int _index)
+ {
+ super(_data);
+ cursor= _index;
+ }
+
+ /** Inserts an element to the iterators list according to the specification
+ * of this interface method. The element is also added to InterfaceContainer
+ * but its location within the list cannot be guaranteed.
+ */
+ public synchronized void add(Object o)
+ {
+ InterfaceContainer.this.add(o);
+ dataIt.add(cursor++, o);
+ lastRet = -1;
+ lastRetObj= null;
+ }
+
+ synchronized public boolean hasPrevious()
+ {
+ return cursor != 0;
+ }
+
+ synchronized public int nextIndex()
+ {
+ return cursor;
+ }
+
+ public synchronized Object previous()
+ {
+ try
+ {
+ Object previous = dataIt.get(--cursor);
+ lastRet = cursor;
+ lastRetObj= previous;
+ return previous;
+ } catch(IndexOutOfBoundsException e)
+ {
+ java.util.NoSuchElementException ex2 = new java.util.NoSuchElementException();
+ ex2.initCause(e);
+ throw ex2;
+ }
+ }
+
+ synchronized public int previousIndex()
+ {
+ return cursor-1;
+ }
+
+ /** This is not possible since several iterators can modify InterfaceContainer
+ */
+ public synchronized void set(Object o)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+
+ } // class LstItr
+}
+