001: /* Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com
002:
003: This file is part of the db4o open source object database.
004:
005: db4o is free software; you can redistribute it and/or modify it under
006: the terms of version 2 of the GNU General Public License as published
007: by the Free Software Foundation and as clarified by db4objects' GPL
008: interpretation policy, available at
009: http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
010: Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
011: Suite 350, San Mateo, CA 94403, USA.
012:
013: db4o is distributed in the hope that it will be useful, but WITHOUT ANY
014: WARRANTY; without even the implied warranty of MERCHANTABILITY or
015: FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
016: for more details.
017:
018: You should have received a copy of the GNU General Public License along
019: with this program; if not, write to the Free Software Foundation, Inc.,
020: 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
021: package com.db4o.collections;
022:
023: import java.io.*;
024: import java.lang.reflect.*;
025: import java.util.*;
026:
027: import com.db4o.activation.*;
028: import com.db4o.ta.*;
029:
030: /**
031: * db4o ArrayList implementation, which is transparent activate awared.
032: * The behaviour is similar as java.util.ArrayList.
033: *
034: * @see java.util.ArrayList
035: */
036:
037: public class ArrayList4<E> extends AbstractList4<E> implements
038: Cloneable, Serializable, RandomAccess, Activatable {
039:
040: private static final long serialVersionUID = 7971683768827646182L;
041:
042: private E[] elements;
043:
044: private int capacity;
045:
046: private int listSize;
047:
048: private transient Activator _activator;
049:
050: public void activate() {
051: if (_activator != null) {
052: _activator.activate();
053: }
054: }
055:
056: public void bind(Activator activator) {
057: if (_activator != null || activator == null) {
058: throw new IllegalStateException();
059: }
060: _activator = activator;
061: }
062:
063: public ArrayList4() {
064: this (10);
065: }
066:
067: @SuppressWarnings("unchecked")
068: public ArrayList4(Collection<? extends E> c) {
069: Object[] data = c.toArray();
070: capacity = data.length;
071: elements = (E[]) new Object[capacity];
072: listSize = data.length;
073: System.arraycopy(data, 0, elements, 0, data.length);
074: }
075:
076: @SuppressWarnings("unchecked")
077: public ArrayList4(int initialCapacity) {
078: if (initialCapacity < 0) {
079: throw new IllegalArgumentException();
080: }
081: capacity = initialCapacity;
082: elements = (E[]) new Object[initialCapacity];
083: }
084:
085: public void add(int index, E element) {
086: checkIndex(index, 0, size());
087: ensureCapacity(size() + 1);
088: System.arraycopy(elements, index, elements, index + 1, listSize
089: - index);
090: elements[index] = element;
091: increaseSize(1);
092: markModified();
093: }
094:
095: public boolean addAll(Collection<? extends E> c) {
096: return addAll(size(), c);
097: }
098:
099: public boolean addAll(int index, Collection<? extends E> c) {
100: checkIndex(index, 0, size());
101: int length = c.size();
102: if (length == 0) {
103: return false;
104: }
105: ensureCapacity(size() + length);
106: Object[] toBeAdded = c.toArray();
107: System.arraycopy(elements, index, elements, index + length,
108: size() - index);
109: System.arraycopy(toBeAdded, 0, elements, index, length);
110: increaseSize(length);
111: markModified();
112: return true;
113: }
114:
115: public void clear() {
116: int size = size();
117: Arrays.fill(elements, 0, size, null);
118: setSize(0);
119: markModified();
120: }
121:
122: @SuppressWarnings("unchecked")
123: public Object clone() {
124: activate();
125: try {
126: ArrayList4<E> clonedList = (ArrayList4<E>) super .clone();
127: clonedList.elements = elements.clone();
128: return clonedList;
129: } catch (CloneNotSupportedException e) {
130: throw new Error(e);
131: }
132: }
133:
134: public void ensureCapacity(int minCapacity) {
135: activate();
136: if (minCapacity <= capacity) {
137: return;
138: }
139: resize(minCapacity);
140: }
141:
142: public E get(int index) {
143: checkIndex(index, 0, size() - 1);
144: return elements[index];
145: }
146:
147: public int indexOf(Object o) {
148: for (int index = 0; index < size(); ++index) {
149: E element = get(index);
150: if (o == null ? element == null : o.equals(element)) {
151: return index;
152: }
153: }
154: return -1;
155: }
156:
157: public int lastIndexOf(Object o) {
158: for (int index = size() - 1; index >= 0; --index) {
159: E element = get(index);
160: if (o == null ? element == null : o.equals(element)) {
161: return index;
162: }
163: }
164: return -1;
165: }
166:
167: public E remove(int index) {
168: int size = size();
169: checkIndex(index, 0, size - 1);
170: E element = elements[index];
171: System.arraycopy(elements, index + 1, elements, index, size
172: - index - 1);
173: elements[size - 1] = null;
174: decreaseSize(1);
175: markModified();
176: return element;
177: }
178:
179: protected void removeRange(int fromIndex, int toIndex) {
180: int size = size();
181: if ((fromIndex < 0 || fromIndex >= size || toIndex > size || toIndex < fromIndex)) {
182: throw new IndexOutOfBoundsException();
183: }
184: if (fromIndex == toIndex) {
185: return;
186: }
187: int count = toIndex - fromIndex;
188: System.arraycopy(elements, toIndex, elements, fromIndex, size
189: - toIndex);
190: Arrays.fill(elements, size - count, size, null);
191: decreaseSize(count);
192: markModified();
193: }
194:
195: public E set(int index, E element) {
196: checkIndex(index, 0, size() - 1);
197: E oldValue = elements[index];
198: elements[index] = element;
199: return oldValue;
200: }
201:
202: public int size() {
203: activate();
204: return listSize;
205: }
206:
207: public Object[] toArray() {
208: int size = size();
209: Object[] data = new Object[size];
210: System.arraycopy(elements, 0, data, 0, size);
211: return data;
212: }
213:
214: @SuppressWarnings("unchecked")
215: public <T> T[] toArray(T[] a) {
216: int size = size();
217: if (a.length < size) {
218: a = (T[]) Array.newInstance(
219: a.getClass().getComponentType(), size);
220: }
221: System.arraycopy(elements, 0, a, 0, size);
222: return a;
223: }
224:
225: public void trimToSize() {
226: resize(size());
227: }
228:
229: @SuppressWarnings("unchecked")
230: private void resize(int minCapacity) {
231: markModified();
232: E[] temp = (E[]) new Object[minCapacity];
233: System.arraycopy(elements, 0, temp, 0, size());
234: elements = temp;
235: capacity = minCapacity;
236: }
237:
238: void setSize(int count) {
239: listSize = count;
240: }
241:
242: void increaseSize(int count) {
243: listSize += count;
244: }
245:
246: void decreaseSize(int count) {
247: listSize -= count;
248: }
249:
250: void markModified() {
251: ++modCount;
252: }
253:
254: }
|