/* ********************************************************************** **
** Copyright notice **
** **
** (c) 2005-2009 RSSOwl Development Team **
** http://www.rssowl.org/ **
** **
** All rights reserved **
** **
** This program and the accompanying materials are made available under **
** the terms of the Eclipse Public License v1.0 which accompanies this **
** distribution, and is available at: **
** http://www.rssowl.org/legal/epl-v10.html **
** **
** A copy is found in the file epl-v10.html and important notices to the **
** license from the team is found in the textfile LICENSE.txt distributed **
** in this package. **
** **
** This copyright notice MUST APPEAR in all copies of the file! **
** **
** Contributors: **
** RSSOwl Development Team - initial API and implementation **
** **
** ********************************************************************** */
package org.rssowl.core.internal.persist;
import org.eclipse.core.runtime.Assert;
import org.rssowl.core.persist.IEntity;
import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
/**
* An implementation of {@link List} that uses a provided
* {@link ObjectContainer} to access a list of entities in a lazy way. Entities
* get resolved lazily as they are retrieved from the list.
*
* @param <E> any type that extends {@link IEntity}.
*/
public final class LazyList<E extends IEntity> implements List<E> {
private final LongArrayList fIds;
private final ObjectContainer fObjectContainer;
public LazyList(ObjectSet<? extends E> entities, ObjectContainer objectContainer) {
Assert.isNotNull(entities, "entities"); //$NON-NLS-1$
Assert.isNotNull(objectContainer, "objectContainer"); //$NON-NLS-1$
long[] ids = entities.ext().getIDs();
fIds = new LongArrayList(ids.length);
fIds.setAll(ids);
fObjectContainer = objectContainer;
}
/*
* @see java.util.List#toArray()
*/
public Object[] toArray() {
Object[] array = new Object[size()];
int index = 0;
for (E e : this)
array[index++] = e;
return array;
}
/*
* @see java.util.List#toArray(T[])
*/
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
int size = size();
T[] array = a;
if (a.length < size)
array = (T[]) Array.newInstance(a.getClass().getComponentType(), size);
int index = 0;
for (E e : this)
array[index++] = (T) e;
return array;
}
private E getEntity(long id) {
E object = fObjectContainer.ext().getByID(id);
fObjectContainer.activate(object, Integer.MAX_VALUE);
return object;
}
/*
* @see java.util.List#get(int)
*/
public E get(int index) {
return getEntity(fIds.get(index));
}
/*
* @see java.util.List#indexOf(java.lang.Object)
*/
public int indexOf(Object o) {
if (o instanceof IEntity) {
IEntity entity = (IEntity) o;
if (entity.getId() != null)
return fIds.indexOf(entity.getId());
}
return -1;
}
/*
* @see java.util.List#lastIndexOf(java.lang.Object)
*/
public int lastIndexOf(Object o) {
if (o instanceof IEntity) {
IEntity entity = (IEntity) o;
if (entity.getId() != null)
return fIds.lastIndexOf(entity.getId());
}
return -1;
}
/*
* @see java.util.List#listIterator()
*/
public ListIterator<E> listIterator() {
return listIterator(0);
}
/*
* @see java.util.List#listIterator(int)
*/
public ListIterator<E> listIterator(int index) {
return new ListIterator<E>() {
private int cursor;
private int lastReturned = -1;
public boolean hasNext() {
return cursor < fIds.size();
}
public boolean hasPrevious() {
return cursor > 0;
}
public E next() {
E entity = getEntity(fIds.get(cursor));
lastReturned = cursor++;
return entity;
}
public int nextIndex() {
return cursor;
}
public E previous() {
E entity = getEntity(fIds.get(--cursor));
lastReturned = cursor;
return entity;
}
public int previousIndex() {
return cursor - 1;
}
public void remove() {
if (lastReturned == -1)
throw new IllegalStateException();
fIds.removeByIndex(lastReturned);
if (lastReturned < cursor)
--cursor;
lastReturned = -1;
}
public void set(E o) {
throw new UnsupportedOperationException();
}
public void add(E o) {
throw new UnsupportedOperationException();
}
};
}
/*
* @see java.util.List#remove(int)
*/
public E remove(int index) {
return getEntity(fIds.removeByIndex(index));
}
/*
* @see java.util.List#iterator()
*/
public Iterator<E> iterator() {
return listIterator();
}
/*
* @see java.util.List#clear()
*/
public void clear() {
fIds.clear();
}
/*
* @see java.util.List#contains(java.lang.Object)
*/
public boolean contains(Object o) {
if (o instanceof IEntity) {
return fIds.contains(((IEntity) o).getId());
}
return false;
}
/*
* @see java.util.List#containsAll(java.util.Collection)
*/
public boolean containsAll(Collection<?> c) {
for (Object o : c) {
if (!contains(o))
return false;
}
return true;
}
/*
* @see java.util.List#isEmpty()
*/
public boolean isEmpty() {
return fIds.isEmpty();
}
/*
* @see java.util.List#remove(java.lang.Object)
*/
public boolean remove(Object o) {
int index = indexOf(o);
if (index >= 0) {
fIds.removeByIndex(index);
return true;
}
return false;
}
/*
* @see java.util.List#removeAll(java.util.Collection)
*/
public boolean removeAll(Collection<?> c) {
boolean changed = false;
for (Object o : c)
changed |= remove(o);
return changed;
}
/*
* @see java.util.List#size()
*/
public int size() {
return fIds.size();
}
/*
* @see java.util.List#subList(int, int)
*/
public List<E> subList(int fromIndex, int toIndex) {
throw new UnsupportedOperationException();
}
/*
* @see java.util.List#retainAll(java.util.Collection)
*/
public boolean retainAll(Collection<?> c) {
throw new UnsupportedOperationException();
}
/*
* @see java.util.List#add(int, java.lang.Object)
*/
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
/*
* @see java.util.List#addAll(int, java.util.Collection)
*/
public boolean addAll(int index, Collection<? extends E> c) {
throw new UnsupportedOperationException();
}
/*
* @see java.util.List#set(int, java.lang.Object)
*/
public E set(int index, E element) {
throw new UnsupportedOperationException();
}
/*
* @see java.util.List#add(java.lang.Object)
*/
public boolean add(E e) {
throw new UnsupportedOperationException();
}
/*
* @see java.util.List#addAll(java.util.Collection)
*/
public boolean addAll(Collection<? extends E> c) {
throw new UnsupportedOperationException();
}
/*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object o) {
if (o == this)
return true;
if (o == null)
return false;
if (getClass() != o.getClass())
return false;
Collection<?> c = (Collection<?>) o;
if (c.size() != size())
return false;
return containsAll(c);
}
/*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
int h = 0;
for (E e : this) {
if (e != null)
h += e.hashCode();
}
return h;
}
}