package org.archstudio.sysutils;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.concurrent.CopyOnWriteArrayList;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
public class FilterableCopyOnWriteArrayList<E> implements List<E> {
public static final <E> FilterableCopyOnWriteArrayList<E> create() {
return new FilterableCopyOnWriteArrayList<E>();
}
CopyOnWriteArrayList<E> list = new CopyOnWriteArrayList<E>();
int listModCount = 0;
LoadingCache<Class<?>, List<?>> filteredListsCache = CacheBuilder.newBuilder().build(
new CacheLoader<Class<?>, List<?>>() {
@Override
public List<?> load(Class<?> ofType) throws Exception {
return new CopyOnWriteArrayList<Object>(Lists.newArrayList(Iterables.filter(list, ofType)));
}
});
int filteredListModCount = -1;
@Override
public int size() {
return list.size();
}
@Override
public boolean isEmpty() {
return list.isEmpty();
}
@Override
public boolean contains(Object o) {
return list.contains(o);
}
@Override
public int indexOf(Object o) {
return list.indexOf(o);
}
public int indexOf(E e, int index) {
return list.indexOf(e, index);
}
@Override
public int lastIndexOf(Object o) {
return list.lastIndexOf(o);
}
public int lastIndexOf(E e, int index) {
return list.lastIndexOf(e, index);
}
@Override
public Object clone() {
return list.clone();
}
@Override
public Object[] toArray() {
return list.toArray();
}
@Override
public <T> T[] toArray(T[] a) {
return list.toArray(a);
}
@Override
public E get(int index) {
return list.get(index);
}
@Override
public E set(int index, E element) {
try {
return list.set(index, element);
}
finally {
listModCount++;
}
}
@Override
public boolean add(E e) {
try {
return list.add(e);
}
finally {
listModCount++;
}
}
@Override
public void add(int index, E element) {
try {
list.add(index, element);
}
finally {
listModCount++;
}
}
@Override
public E remove(int index) {
try {
return list.remove(index);
}
finally {
listModCount++;
}
}
@Override
public boolean remove(Object o) {
try {
return list.remove(o);
}
finally {
listModCount++;
}
}
public boolean addIfAbsent(E e) {
try {
return list.addIfAbsent(e);
}
finally {
listModCount++;
}
}
@Override
public boolean containsAll(Collection<?> c) {
return list.containsAll(c);
}
@Override
public boolean removeAll(Collection<?> c) {
try {
return list.removeAll(c);
}
finally {
listModCount++;
}
}
@Override
public boolean retainAll(Collection<?> c) {
try {
return list.retainAll(c);
}
finally {
listModCount++;
}
}
public int addAllAbsent(Collection<? extends E> c) {
try {
return list.addAllAbsent(c);
}
finally {
listModCount++;
}
}
@Override
public void clear() {
try {
list.clear();
}
finally {
listModCount++;
}
}
@Override
public boolean addAll(Collection<? extends E> c) {
try {
return list.addAll(c);
}
finally {
listModCount++;
}
}
@Override
public boolean addAll(int index, Collection<? extends E> c) {
try {
return list.addAll(index, c);
}
finally {
listModCount++;
}
}
@Override
public String toString() {
return list.toString();
}
@Override
public boolean equals(Object o) {
return list.equals(o);
}
@Override
public int hashCode() {
return list.hashCode();
}
@Override
public Iterator<E> iterator() {
return list.iterator();
}
@Override
public ListIterator<E> listIterator() {
return list.listIterator();
}
@Override
public ListIterator<E> listIterator(int index) {
return list.listIterator(index);
}
@Override
public List<E> subList(int fromIndex, int toIndex) {
throw new UnsupportedOperationException();
}
@SuppressWarnings("unchecked")
public <T> Iterable<T> filter(Class<T> ofType) {
if (filteredListModCount != listModCount) {
filteredListModCount = listModCount;
filteredListsCache.invalidateAll();
}
return (Iterable<T>) filteredListsCache.getUnchecked(ofType);
}
}