package org.jboss.cache.aop;
import org.jboss.cache.Fqn;
import org.jboss.cache.Node;
import org.jboss.logging.Logger;
import org.jboss.util.NestedRuntimeException;
import java.util.*;
public class CachedListInterceptor
implements List, CachedCollectionInterceptor
{
protected static final Logger log = Logger.getLogger(CachedListInterceptor.class);
protected static final Map managedMethods =
CollectionInterceptorUtil.getManagedMethods(List.class);
protected TreeCacheAop cache;
protected Fqn fqn;
protected Map methodMap;
public CachedListInterceptor(TreeCacheAop cache, Fqn fqn, Class clazz)
{
this.cache = cache;
this.fqn = fqn;
methodMap = CollectionInterceptorUtil.getMethodMap(clazz);
}
public String getName()
{
return "CachedListInterceptor";
}
public Object invoke(org.jboss.aop.joinpoint.Invocation invocation) throws Throwable
{
return CollectionInterceptorUtil.invoke(invocation,
this,
methodMap,
managedMethods);
}
protected Node getNode()
{
try {
return cache.get(fqn);
} catch (Exception e) {
throw new NestedRuntimeException(e);
}
}
public Object get(int index)
{
checkIndex(index);
try {
return cache.getObject(new Fqn(fqn, new Integer(index)));
} catch (Exception e) {
throw new NestedRuntimeException(e);
}
}
private void checkIndex(int i) {
if(size() == 0) return; if( i < 0 || i >= size() ) {
throw new IndexOutOfBoundsException("Index out of bound at CachedListInterceptor(). Index is " +i
+ " but size is " +size());
}
}
private void checkArgument(Object o) {
if(o == null)
throw new NullPointerException("Object is null");
}
public int size()
{
Node node = getNode();
if(node == null) {
return 0;
}
Map children = node.getChildren();
return children == null ? 0 : children.size();
}
public void clear()
{
for(int i=size()-1; i >= 0; i--) {
remove(i);
}
}
public boolean isEmpty()
{
return size() == 0 ? true : false;
}
public Object[] toArray()
{
Object[] objs = new Object[size()];
for(int i=0; i < size(); i++) {
objs[i] = get(i);
}
return objs;
}
public Object set(int index, Object element)
{
try {
if(index != 0)
checkIndex(index-1); Object oldValue = get(index);
return cache.putObject(new Fqn(fqn, new Integer(index)), element);
} catch (Exception e) {
throw new NestedRuntimeException(e);
}
}
public Object[] toArray(Object a[])
{
throw new AopOperationNotSupportedException("CachedListInterceptor: List.toArray(a) operation not supported");
}
public void add(int index, Object element)
{
try {
if(index != 0)
checkIndex(index-1); for (int i = size(); i > index; i--) {
Object obj = cache.removeObject(new Fqn(fqn, new Integer(i - 1)));
cache.putObject(new Fqn(fqn, new Integer(i)), obj);
}
cache.putObject(new Fqn(fqn, new Integer(index)), element);
} catch (Exception e) {
throw new NestedRuntimeException(e);
}
}
public int indexOf(Object o)
{
checkArgument(o);
for(int i=0; i < size(); i++) {
if(o.equals(get(i))) return i;
}
return -1;
}
public int lastIndexOf(Object o)
{
checkArgument(o);
int index = -1;
for(int i=0; i < size(); i++) {
if(o.equals(get(i))) index = i;
}
return index;
}
public boolean add(Object o)
{
add(size(), o);
return true;
}
public boolean contains(Object o)
{
if (indexOf(o) != -1) return true;
return false;
}
public Object remove(int index)
{
try {
checkIndex(index);
Object result = cache.removeObject(new Fqn(fqn, new Integer(index)));
int size = size();
for (int i = index; i < size; i++) {
Object obj = cache.removeObject(new Fqn(fqn, new Integer(i + 1)));
cache.putObject(new Fqn(fqn, new Integer(i)), obj);
}
return result;
} catch (Exception e) {
throw new NestedRuntimeException(e);
}
}
public boolean remove(Object o)
{
int i = indexOf(o);
if(i == -1)
return false;
remove(i);
return true;
}
public boolean addAll(int index, Collection c)
{
throw new AopOperationNotSupportedException("CachedListInterceptor: List.addAll() operation not supported");
}
public boolean addAll(Collection c)
{
Iterator i = c.iterator();
while(i.hasNext()) {
Object o = i.next();
add(o);
}
return true;
}
public boolean containsAll(Collection c)
{
throw new AopOperationNotSupportedException("CachedListInterceptor: List.containsAll() operation not supported");
}
public boolean removeAll(Collection c)
{
Iterator i = c.iterator();
while(i.hasNext()) {
Object o = i.next();
remove(o);
}
return true;
}
public int hashCode()
{
int result = 0;
for (int i =0; i < size(); i++) {
result += get(i).hashCode();
}
return result;
}
public boolean equals(Object object)
{
if (object == this)
return true;
if (!(object instanceof List))
return false;
List list = (List) object;
if (size() != list.size())
return false;
for (int i=0; i < list.size(); i++) {
Object value = list.get(i);
if (value != null) {
if( !contains(value) )
return false;
} else { return false;
}
}
return true;
}
public String toString() {
StringBuffer buf = new StringBuffer();
int size = size();
for (int i =0; i < size; i++) {
Object key = get(i);
buf.append("[" +key).append("]");
if(i <= size) buf.append(", ");
}
return buf.toString();
}
public boolean retainAll(Collection c)
{
throw new AopOperationNotSupportedException("CachedListInterceptor: List.retainAll() operation not supported");
}
public Iterator iterator()
{
return new Iterator()
{
protected int current = 0;
public boolean hasNext()
{
return current < size();
}
public Object next()
{
try {
return cache.getObject(new Fqn(fqn, new Integer(current++)));
} catch (Exception e) {
throw new NestedRuntimeException(e);
}
}
public void remove()
{
try {
int size = size();
if (current < size) {
Object last = cache.removeObject(new Fqn(fqn, new Integer(size - 1)));
cache.putObject(new Fqn(fqn, new Integer(--current)), last);
} else {
cache.removeObject(new Fqn(fqn, new Integer(--current)));
}
} catch (Exception e) {
throw new NestedRuntimeException(e);
}
}
};
}
public List subList(int fromIndex, int toIndex)
{
throw new AopOperationNotSupportedException("CachedListInterceptor: List.subList() operation not supported");
}
public ListIterator listIterator()
{
return new MyListIterator(0);
}
public ListIterator listIterator(int index)
{
return new MyListIterator(index);
}
protected class MyListIterator implements ListIterator {
protected int index = 0;
public MyListIterator(int index) {
if(index < 0 || index >= size()) {
throw new AopOperationNotSupportedException("CachedListInterceptor: MyListIterator construction. " +
" Index is out of bound : " +index);
}
this.index = index;
}
public int nextIndex()
{
return index;
}
public int previousIndex()
{
return index-1;
}
public void remove()
{
throw new AopOperationNotSupportedException("CachedListInterceptor: ListIterator.remove() optional operation not supported");
}
public boolean hasNext()
{
return (index == size()-1) ? false : true;
}
public boolean hasPrevious()
{
return (index == 0) ? false : true;
}
public Object next()
{
if( index == size() )
throw new NoSuchElementException();
index++;
return get(index-1);
}
public Object previous()
{
if( index == 0 )
throw new NoSuchElementException();
index--;
return get(index);
}
public void add(Object o)
{
throw new AopOperationNotSupportedException("CachedListInterceptor: ListIterator.add() optional operation not supported");
}
public void set(Object o)
{
throw new AopOperationNotSupportedException("CachedListInterceptor: ListIterator.set() optional operation not supported");
}
}
}