/**************************************************************************
* Copyright (c) 2001 by Punch Telematix. All rights reserved. *
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* 1. Redistributions of source code must retain the above copyright *
* notice, this list of conditions and the following disclaimer. *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in the *
* documentation and/or other materials provided with the distribution. *
* 3. Neither the name of Punch Telematix nor the names of *
* other contributors may be used to endorse or promote products *
* derived from this software without specific prior written permission.*
* *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED *
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. *
* IN NO EVENT SHALL PUNCH TELEMATIX OR OTHER CONTRIBUTORS BE LIABLE *
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF *
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR *
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, *
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE *
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN *
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
**************************************************************************/
/*
** $Id: Vector.java,v 1.2 2006/04/18 11:35:28 cvs Exp $
*/
package java.util;
import java.lang.UnsupportedOperationException;
import java.lang.reflect.Array;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
public class Vector extends AbstractList
implements Cloneable, List, java.io.Serializable, RandomAccess {
protected Object[] elementData;
protected int elementCount;
protected int capacityIncrement;
private transient int initialCapacity;
private static final long serialVersionUID = -2767605614048989439L;
private synchronized void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
}
private synchronized void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
}
// This could probably be done with an anonymous class, but for now:
private class VectorEnum implements Enumeration {
private int _i = 0;
public boolean hasMoreElements() {
return(_i<elementCount);
}
public Object nextElement() throws NoSuchElementException {
synchronized (Vector.this){
if(_i>=elementCount) {
throw new NoSuchElementException();
}
return elementData[_i++];
}
}
}
public Vector(int initCap, int capIncr) {
initialCapacity = initCap;
elementData = new Object[initCap];
capacityIncrement = capIncr;
}
public Vector(int initCap) {
initialCapacity = initCap;
elementData = new Object[initCap];
}
public Vector() {
initialCapacity = 10;
elementData = new Object[10];
}
public Vector(Collection c) {
initialCapacity = c.size();
elementData = new Object[initialCapacity];
Iterator it = c.iterator();
while (it.hasNext()) {
elementData[elementCount++] = it.next();
}
}
/**
* calls addAll from AbstractList
*
*/
public synchronized boolean addAll(Collection c) {
super.addAll(c);
return (c.size()>0);
}
public synchronized boolean addAll(int idx, Collection c) {
super.addAll(idx,c);
return (c.size()>0);
}
public synchronized Object[] toArray() {
return toArray(new Object[elementCount]);
}
public synchronized Object[] toArray(Object [] arr) {
Object [] array = arr;
if ( array.length < elementCount ) array = (Object[])Array.newInstance(arr.getClass().getComponentType(),elementCount);
if ( array.length > elementCount ) array[elementCount] = null ;
System.arraycopy(elementData,0,array,0,elementCount);
return array;
}
public synchronized String toString() {
StringBuffer buffer = new StringBuffer("[");
for(int i=0 ; i < elementCount ; i++) {
Object element = elementData[i];
buffer.append(element == this ?
"(this Collection)" : String.valueOf(element)).append(", ");
}
int length = buffer.length();
if(length > 1) {
buffer.setLength(length - 2);
}
buffer.append(']');
return buffer.toString();
}
public synchronized Object clone() {
Vector nieuw = null;
try {
nieuw = (Vector) super.clone();
}
catch(CloneNotSupportedException cnse) {}
nieuw.elementData = new Object[elementData.length];
System.arraycopy(this.elementData, 0, nieuw.elementData, 0, this.elementCount);
return nieuw;
}
public synchronized Object elementAt(int index) {
if (index < elementCount) {
return elementData[index];
}
throw new ArrayIndexOutOfBoundsException();
}
public synchronized void setElementAt(Object obj, int index)
throws ArrayIndexOutOfBoundsException {
// throw exception if 0 > index or index >= elementCount
if (index < 0 || index >= elementCount) throw new ArrayIndexOutOfBoundsException();
elementData[index] = obj;
}
public Object firstElement() throws NoSuchElementException {
synchronized(this) {
if(elementCount==0) throw new NoSuchElementException();
return elementData[0];
}
}
public Object lastElement() throws NoSuchElementException {
synchronized(this) {
if (elementCount==0) throw new NoSuchElementException();
return elementData[elementCount - 1];
}
}
public synchronized void addElement(Object obj) {
if(elementCount == elementData.length){
ensureCapacity(elementCount+1);
}
elementData[elementCount++] = obj;
modCount++;
}
public synchronized void insertElementAt(Object obj, int index)
throws ArrayIndexOutOfBoundsException
{
int elementCount = this.elementCount;
Object[] elementData = this.elementData;
if (index<0 || index>elementCount) throw new ArrayIndexOutOfBoundsException();
if(elementCount >= elementData.length){
ensureCapacity(elementCount+1);
elementData = this.elementData;
}
if (index < elementCount) {
System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
}
elementData[index] = obj;
this.elementCount++;
modCount++;
}
public synchronized boolean removeElement(Object obj) {
int i;
i = indexOf(obj,0);
if (i<0)
return false;
removeElementAt(i);
return true;
}
// When removing an element we dont automatically trim the array:
// chances are another element will be added soon.
public synchronized void removeElementAt(int index)
throws ArrayIndexOutOfBoundsException
{
if (index<0 || index>=elementCount) throw new ArrayIndexOutOfBoundsException();
if (index < elementCount - 1) {
System.arraycopy(elementData, index + 1, elementData, index, elementCount - index - 1);
}
modCount++;
elementData[--elementCount] = null;
}
// OTOH if all elements are removed we revert to the original capacity
public synchronized void removeAllElements() {
if (elementCount>0) modCount++;
while(elementCount>0) elementData[--elementCount] = null;
// trimToSize();
}
public boolean isEmpty() {
return elementCount == 0;
}
public int size() {
return elementCount;
}
public synchronized void setSize(int newSize) throws ArrayIndexOutOfBoundsException{
if (newSize < 0) throw new ArrayIndexOutOfBoundsException();
ensureCapacity(newSize);
if (newSize != elementCount) modCount++;
if ((this.capacity() >= newSize) && (elementData.length >= newSize))
{while(elementCount<newSize) elementData[elementCount++] = null;
while(elementCount>newSize) elementData[--elementCount] = null;
}
trimToSize(); //capacity doesn't need to change
}
public int capacity() {
return elementData.length;
}
public synchronized void ensureCapacity(int minCapacity) {
if (elementData.length<minCapacity) {
int newCapacity;
if (capacityIncrement>0) {
newCapacity = elementData.length + capacityIncrement;
}
else {
newCapacity = elementData.length * 2;
}
if (newCapacity<minCapacity) newCapacity = minCapacity;
Object[] newArray = new Object[newCapacity];
System.arraycopy(elementData, 0, newArray, 0, elementCount);
elementData = newArray;
}
}
public synchronized void trimToSize() {
int newCapacity;
if (elementData.length>elementCount) {
newCapacity = elementCount;
if (newCapacity<initialCapacity && initialCapacity<elementData.length) {
newCapacity = initialCapacity;
}
Object[] newArray = new Object[newCapacity];
System.arraycopy(elementData, 0, newArray, 0, elementCount);
elementData = newArray;
}
}
public synchronized void copyInto(Object anArray[]) throws ArrayIndexOutOfBoundsException {
System.arraycopy(elementData, 0, anArray, 0, elementCount);
}
public Enumeration elements() {
return new VectorEnum();
}
public synchronized boolean contains(Object elem) {
return indexOf(elem,0) >= 0;
}
public synchronized int indexOf(Object elem)
{
int i;
if (elem != null) {
for(i=0;i<elementCount;++i) {
if (elem.equals(elementData[i]))
return i;
}
}
else {
for(i=0;i<elementCount;++i) {
if (elementData[i] == null)
return i;
}
}
return -1;
}
public synchronized int indexOf(Object elem, int index)
throws ArrayIndexOutOfBoundsException
{
int i;
if (elem != null) {
for(i=index;i<elementCount;++i) {
if (elem.equals(elementData[i]))
return i;
}
}
else {
for(i=index;i<elementCount;++i) {
if (elementData[i] == null)
return i;
}
}
return -1;
}
public synchronized int lastIndexOf(Object elem)
{
int i;
if (elem != null) {
for(i=elementCount-1;i>=0;--i) {
if (elem.equals(elementData[i]))
return i;
}
}
else {
for(i=elementCount-1;i>=0;--i){
if (elementData[i] == null)
return i;
}
}
return -1;
}
public synchronized int lastIndexOf(Object elem, int index)
throws ArrayIndexOutOfBoundsException
{
int i;
if (elem != null) {
for(i=index;i>=0;--i) {
if (elem.equals(elementData[i]))
return i;
}
}
else {
for(i=index;i>=0;--i){
if (elementData[i] == null)
return i;
}
}
return -1;
}
public synchronized boolean add(Object o) {
if(elementCount == elementData.length){
ensureCapacity(elementCount+1);
}
elementData[elementCount++] = o;
modCount++; //This is used by the iterator to throw a ConcurrentModificationException
return true;
}
public synchronized void add(int index, Object o) {
insertElementAt(o, index);
}
public synchronized boolean remove(Object o) {
return removeElement(o);
}
public synchronized Object remove(int index) {
Object returnObject = elementAt(index);
removeElementAt(index);
return returnObject;
}
public synchronized Object get(int index) {
return elementAt(index);
}
/**
** Iterator is inherited from AbstractList !!!
** --> it is allowed to overwrite it!
*/
public Iterator iterator() {
return new VectorIterator();
}
protected void removeRange(int fromIndex, int toIndex) {
if ( fromIndex < 0 || toIndex > elementCount || fromIndex > toIndex) throw new ArrayIndexOutOfBoundsException();
System.arraycopy(elementData,toIndex,elementData,fromIndex,elementCount-toIndex);
int j = elementCount;
elementCount -= toIndex - fromIndex;
for (int i=elementCount; i < j ; i++) {
elementData[i]=null;
}
modCount++;
}
/*
* implemented
*
*/
public Object set(int index, Object element) {
if ( index < 0 || index >= elementCount) throw new ArrayIndexOutOfBoundsException();
Object old = elementData[index];
elementData[index] = element;
return old;
}
/**
* is implemented
* this method calls subList in AbstractList
*/
public List subList(int fromIndex, int toIndex) throws UnsupportedOperationException {
// throw new UnsupportedOperationException("subList in Class Vector is not supported");
return super.subList(fromIndex,toIndex);
}
public synchronized boolean containsAll(Collection c) {
Iterator it=c.iterator();
while (it.hasNext()) {
if ( !contains(it.next()) )
return false;
}
return true;
}
/*
* is supported ...
*/
public synchronized boolean removeAll(Collection c) throws UnsupportedOperationException {
// throw new UnsupportedOperationException("removeAll in Class Vector is not supported");
if ( c.isEmpty() ) return false; // nothing to remove
Object [] newElements = new Object[elementData.length];
int newElementCount=0;
for (int i=0 ; i < elementCount ; i++) {
if (!c.contains(elementData[i])) {
newElements[newElementCount++]=elementData[i];
}
}
if (elementCount == newElementCount) return false;
elementData = newElements;
elementCount = newElementCount;
modCount++;
return true;
}
/*
* is supported ...
*/
public synchronized boolean retainAll(Collection c) throws UnsupportedOperationException {
// throw new UnsupportedOperationException("retainAll in Class Vector is not supported");
if ( c.isEmpty() ) {
boolean returnboolean = elementCount > 0;
clear();
return returnboolean;
}
Object [] newElements = new Object[elementData.length];
int newElementCount=0;
for (int i=0 ; i < elementCount ; i++) {
if (c.contains(elementData[i])) {
newElements[newElementCount++]=elementData[i];
}
}
if (elementCount == newElementCount) return false;
elementData = newElements;
elementCount = newElementCount;
modCount++;
return true;
}
public synchronized void clear() {
for (int i=0 ; i < elementCount ; i++) {
elementData[i] = null;
}
if(elementCount>0) modCount++;
elementCount=0;
}
/**
* Object.hashCode is overwritten
* see Algorithm p 965 of the Java Class Library
* second edition, volume 1
* supplement for the java 2 Platform v1.2
*/
public synchronized int hashCode() {
int hashcode = 1;
int count = elementCount;
Object data[] = elementData;
for (int i=0; i < count; i++) {
hashcode = 31 * hashcode + (data[i] == null ? 0 : data[i].hashCode());
}
return hashcode;
}
/**
* equals overwrites Object.equals
*
*/
public synchronized boolean equals(Object o) {
if (!(o instanceof List)) return false;
List list = (List)o;
if (list.size() != elementCount)return false;
for (int i=0; i < elementCount; i++) {
if (!(elementData[i]==null ? list.get(i)==null : elementData[i].equals(list.get(i))) )
return false;
}
return true;
}
private class VectorIterator implements Iterator {
private int i = 0;
private int Status = 0;
private int localModCount = modCount;
public boolean hasNext() throws ConcurrentModificationException {
return (i < elementCount);
}
public Object next() throws ConcurrentModificationException, NoSuchElementException {
if (localModCount != modCount)
throw new ConcurrentModificationException("in the Iterator from Vector method next");
if (i < elementCount) {
Status = 1;
return elementData[i++];
}
else
throw new NoSuchElementException();
}
public void remove() throws ConcurrentModificationException, IllegalStateException {
if (localModCount != modCount)
throw new ConcurrentModificationException("in the Iterator from Vector method remove");
if (Status != 1)
throw new IllegalStateException("remove() must be called after next()");
removeElementAt(--i);
Status=0;
localModCount++;
}
}
}