/* This file is part of the db4o object database http://www.db4o.com Copyright (C) 2004 - 2011 Versant Corporation http://www.versant.com db4o is free software; you can redistribute it and/or modify it under the terms of version 3 of the GNU General Public License as published by the Free Software Foundation. db4o is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. */ package com.db4o.collections; import java.lang.reflect.*; import java.util.*; /** * @exclude * @sharpen.ignore */ @decaf.Ignore(unlessCompatible=decaf.Platform.JDK15) public abstract class AbstractList4<E> implements Iterable<E>, Collection<E>, List<E> { protected transient int modCount; public AbstractList4() { super(); } public boolean add(E e) { add(size(), e); return true; } public void add(int index, E element) { throw new UnsupportedOperationException(); } /** * @sharpen.ignore */ public boolean addAll(Collection<? extends E> collection) { if(collection.isEmpty()) { return false; } Iterator<? extends E> cIter = collection.iterator(); while(cIter.hasNext()) { add(cIter.next()); } return true; } /** * @sharpen.ignore */ public boolean addAll(int index, Collection<? extends E> collection) { if(collection.isEmpty()) { return false; } Iterator<? extends E> cIter = collection.iterator(); int pos = index; while(cIter.hasNext()) { add(pos++, cIter.next()); } return true; } public void clear() { removeRange(0, size()); } public boolean contains(Object o) { return indexOf(o) != -1; } /** * @sharpen.ignore */ public boolean containsAll(Collection<?> c) { Iterator<?> iter = c.iterator(); while(iter.hasNext()) { if(!contains(iter.next())) { return false; } } return true; } /** * @sharpen.ignore */ public boolean equals(Object other) { if (other == this) { return true; } if (!(other instanceof List)) { return false; } List<?> otherList = (List<?>) other; if (otherList.size() != size()) { return false; } Iterator<E> iter = iterator(); Iterator<?> otherIter = otherList.iterator(); while (iter.hasNext()) { E e1 = iter.next(); Object e2 = otherIter.next(); if (!(e1 == null ? e2 == null : e1.equals(e2))) { return false; } } return true; } public abstract E get(int index); /** * @see List#hashCode() * * @sharpen.ignore */ public int hashCode() { int hashCode = 1; Iterator<E> i = iterator(); while (i.hasNext()) { E obj = i.next(); hashCode = 31 * hashCode + (obj == null ? 0 : obj.hashCode()); } return hashCode; } /** * @sharpen.ignore */ public boolean isEmpty() { return size() == 0; } public Iterator<E> iterator() { return new ArrayList4Iterator(-1); } /** * @sharpen.ignore */ public int indexOf(Object o) { ListIterator<E> iter = listIterator(); while(iter.hasNext()) { if(equals(o, iter.next())) { return iter.previousIndex(); } } return -1; } /** * @sharpen.ignore */ public int lastIndexOf(Object o) { ListIterator<E> iter = listIterator(size()); while(iter.hasPrevious()) { if(equals(o, iter.previous())) { return iter.nextIndex(); } } return -1; } /** * @sharpen.ignore */ private boolean equals(Object e1, E e2) { return (e1 == null ? e2 == null : e1.equals(e2)); } /** * @sharpen.ignore */ public ListIterator<E> listIterator() { return listIterator(0); } /** * @sharpen.ignore */ public ListIterator<E> listIterator(int index) { checkIndex(index, 0, size()); return new ArrayList4IndexIterator(index); } public E remove(int index) { throw new UnsupportedOperationException(); } /** * @sharpen.ignore */ public boolean remove(Object o) { int index = indexOf(o); if (index == -1) { return false; } remove(index); return true; } /** * @sharpen.ignore */ public boolean removeAll(Collection <?> c) { boolean changed = false; Iterator<?> it = iterator(); while (it.hasNext()) { if (c.contains(it.next())) { it.remove(); changed = true; } } return changed; } /** * @sharpen.ignore */ protected void removeRange(int fromIndex, int toIndex) { if ((fromIndex < 0 || fromIndex >= size() || toIndex > size() || toIndex < fromIndex)) { throw new IndexOutOfBoundsException(); } if (fromIndex == toIndex) { return; } ListIterator<E> iter = listIterator(fromIndex); for(int i= fromIndex; i < toIndex; ++i) { iter.next(); iter.remove(); } } /** * @sharpen.ignore */ public boolean retainAll(Collection <?> c) { boolean changed = false; Iterator<?> it = iterator(); while (it.hasNext()) { if (!c.contains(it.next())) { it.remove(); changed = true; } } return changed; } /** * @sharpen.ignore */ public E set(int index, E element) { throw new UnsupportedOperationException(); } /** * @sharpen.internal * @sharpen.property */ public abstract int size(); /** * @sharpen.ignore */ public List<E> subList(int fromIndex, int toIndex) { return new SubArrayList4 <E> (this, fromIndex, toIndex); } /** * @sharpen.ignore */ public Object[] toArray() { int size = size(); Object[] data = new Object[size]; Iterator<E> iter = iterator(); int i = 0; while(iter.hasNext()) { data[i++] = iter.next(); } return data; } /** * @sharpen.ignore */ @SuppressWarnings("unchecked") public <T> T[] toArray(T[] a) { int size = size(); if(a.length < size) { a = (T[]) Array.newInstance(a.getClass().getComponentType(), size); } Iterator<E> iter = iterator(); int i = 0; while(iter.hasNext()) { a[i++] = (T) iter.next(); } return a; } /** * @see Collection#toString() */ public String toString() { StringBuilder buffer = new StringBuilder(); buffer.append('['); Iterator<E> iter = iterator(); while (iter.hasNext()) { E element = iter.next(); if (element != this) { buffer.append(element); } else { buffer.append("(this Collection)"); //$NON-NLS-1$ } if(iter.hasNext()) { buffer.append(", "); //$NON-NLS-1$ } } buffer.append(']'); return buffer.toString(); } void checkIndex(int index, int from, int to) { if (index < from || index > to) { throw new IndexOutOfBoundsException(); } } /** * @sharpen.ignore */ class ArrayList4Iterator implements Iterator<E> { protected int currentIndex; private int _iteratorModCount; protected boolean canOperate; public ArrayList4Iterator (int pos) { currentIndex = pos; syncModCount(); } public boolean hasNext() { return currentIndex + 1 < size(); } public E next() { checkConcurrentModification(); try { E element = get(currentIndex + 1); ++currentIndex; setCanOperateFlag(true); return element; } catch (IndexOutOfBoundsException e) { checkConcurrentModification(); throw new NoSuchElementException(); } } public void remove() { checkCanOperate(); checkConcurrentModification(); AbstractList4.this.remove(currentIndex); --currentIndex; syncModCount(); setCanOperateFlag(false); } protected void syncModCount() { _iteratorModCount = modCount; } protected void checkCanOperate() { if(!canOperate) { throw new IllegalStateException(); } } protected void setCanOperateFlag(boolean enabled) { canOperate = enabled; } protected void checkConcurrentModification() { if(_iteratorModCount != modCount) { throw new ConcurrentModificationException(); } } } /** * @sharpen.ignore */ class ArrayList4IndexIterator extends ArrayList4Iterator implements ListIterator<E> { public ArrayList4IndexIterator(int index) { super(index - 1); } public void add(E element) { checkCanOperate(); checkConcurrentModification(); try { AbstractList4.this.add(currentIndex, element); ++currentIndex; syncModCount(); setCanOperateFlag(false); } catch (IndexOutOfBoundsException e) { throw new ConcurrentModificationException(); } } public boolean hasPrevious() { return currentIndex != -1; } public int nextIndex() { return currentIndex + 1; } public E previous() { checkConcurrentModification(); try { E element = get(currentIndex); --currentIndex; setCanOperateFlag(true); return element; } catch (IndexOutOfBoundsException e) { checkConcurrentModification(); throw new NoSuchElementException(); } } public int previousIndex() { return currentIndex; } public void set(E element) { checkCanOperate(); checkConcurrentModification(); try { AbstractList4.this.set(currentIndex, element); setCanOperateFlag(false); } catch (IndexOutOfBoundsException e) { throw new ConcurrentModificationException(); } } } }