package com.limegroup.gnutella.util; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.ListIterator; import com.limegroup.gnutella.ErrorService; interface ListCreator { public List getList(); } public class CoWList implements List { public static final ListCreator ARRAY_LIST = new ArrayCreator(); public static final ListCreator LINKED_LIST = new LinkedCreator(); private volatile List l; private final ListCreator creator; /** Object to synchronize the atomic operations on */ private final Object lock; public CoWList(List l, Object lock) { this.l = l; this.creator = new ReflectiveCreator(l.getClass()); this.lock = lock == null ? this : lock; } public CoWList(Class listType, Object lock) { this(new ReflectiveCreator(listType),lock); } public CoWList(ListCreator creator) { this(creator, null); } public CoWList(ListCreator creator, Object lock) { this.creator = creator; l = creator.getList(); this.lock = lock == null ? this : lock; } private List getListCopy() { List ret = creator.getList(); if (l != null) ret.addAll(l); return ret; } public void add(int arg0, Object arg1) { synchronized(lock) { List newList = getListCopy(); newList.add(arg0, arg1); l = newList; } } public boolean add(Object arg0) { synchronized(lock) { List newList = getListCopy(); boolean ret = newList.add(arg0); l = newList; return ret; } } public boolean addAll(Collection arg0) { synchronized(lock) { List newList = getListCopy(); boolean ret = newList.addAll(arg0); l = newList; return ret; } } public boolean addAll(int arg0, Collection arg1) { synchronized(lock) { List newList = getListCopy(); boolean ret = newList.addAll(arg0,arg1); l = newList; return ret; } } public void clear() { synchronized(lock) { List newList = getListCopy(); newList.clear(); l = newList; } } public boolean contains(Object o) { return l.contains(o); } public boolean containsAll(Collection arg0) { return l.containsAll(arg0); } public Object get(int index) { return l.get(index); } public int indexOf(Object o) { return l.indexOf(o); } public boolean isEmpty() { return l.isEmpty(); } public Iterator iterator() { return l.iterator(); } public int lastIndexOf(Object o) { return l.lastIndexOf(o); } public ListIterator listIterator() { return l.listIterator(); } public ListIterator listIterator(int index) { return l.listIterator(index); } public Object remove(int index) { synchronized(lock) { Object ret = null; List newList = getListCopy(); ret = newList.remove(index); l = newList; return ret; } } public boolean remove(Object o) { synchronized(lock) { List newList = getListCopy(); boolean ret = newList.remove(o); l = newList; return ret; } } public boolean removeAll(Collection arg0) { synchronized(lock) { List newList = getListCopy(); boolean ret = newList.removeAll(arg0); l = newList; return ret; } } public boolean retainAll(Collection arg0) { synchronized(lock) { List newList = getListCopy(); boolean ret = newList.retainAll(arg0); l = newList; return ret; } } public Object set(int arg0, Object arg1) { synchronized(lock) { List newList = getListCopy(); Object ret = newList.set(arg0,arg1); l = newList; return ret; } } public int size() { return l.size(); } public List subList(int fromIndex, int toIndex) { return l.subList(fromIndex, toIndex); } public Object[] toArray() { return l.toArray(); } public Object[] toArray(Object[] arg0) { return l.toArray(arg0); } private static class ReflectiveCreator implements ListCreator { private final Class listType; public ReflectiveCreator(Class c) { this.listType = c; } public List getList() { List ret = null; try { ret = (List) listType.newInstance(); } catch (IllegalAccessException bad) { ErrorService.error(bad); } catch (InstantiationException bad) { ErrorService.error(bad); } return ret; } } private static class ArrayCreator implements ListCreator { public List getList() { return new ArrayList(); } } private static class LinkedCreator implements ListCreator { public List getList() { return new LinkedList(); } } }