diff --git a/src/main/java/org/bukkit/craftbukkit/util/WeakCollection.java b/src/main/java/org/bukkit/craftbukkit/util/WeakCollection.java new file mode 100644 index 0000000000..d63348aff1 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/util/WeakCollection.java @@ -0,0 +1,173 @@ +package org.bukkit.craftbukkit.util; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.NoSuchElementException; + +import org.apache.commons.lang.Validate; + + +public final class WeakCollection implements Collection { + static final Object NO_VALUE = new Object(); + private final Collection> collection; + + public WeakCollection() { + collection = new ArrayList>(); + } + + public boolean add(T value) { + Validate.notNull(value, "Cannot add null value"); + return collection.add(new WeakReference(value)); + } + + public boolean addAll(Collection collection) { + Collection> values = this.collection; + boolean ret = false; + for (T value : collection) { + Validate.notNull(value, "Cannot add null value"); + ret |= values.add(new WeakReference(value)); + } + return ret; + } + + public void clear() { + collection.clear(); + } + + public boolean contains(Object object) { + if (object == null) { + return false; + } + for (T compare : this) { + if (object.equals(compare)) { + return true; + } + } + return false; + } + + public boolean containsAll(Collection collection) { + return toCollection().containsAll(collection); + } + + public boolean isEmpty() { + return !iterator().hasNext(); + } + + public Iterator iterator() { + return new Iterator() { + Iterator> it = collection.iterator(); + Object value = NO_VALUE; + + @Override + public boolean hasNext() { + Object value = this.value; + if (value != null && value != NO_VALUE) { + return true; + } + + Iterator> it = this.it; + value = null; + + while (it.hasNext()) { + WeakReference ref = it.next(); + value = ref.get(); + if (value == null) { + it.remove(); + } else { + this.value = value; + return true; + } + } + return false; + } + + @Override + public T next() throws NoSuchElementException { + if (!hasNext()) { + throw new NoSuchElementException("No more elements"); + } + + @SuppressWarnings("unchecked") + T value = (T) this.value; + this.value = NO_VALUE; + return value; + } + + @Override + public void remove() throws IllegalStateException { + if (value != NO_VALUE) { + throw new IllegalStateException("No last element"); + } + + value = null; + it.remove(); + } + }; + } + + public boolean remove(Object object) { + if (object == null) { + return false; + } + + Iterator it = this.iterator(); + while (it.hasNext()) { + if (object.equals(it.next())) { + it.remove(); + return true; + } + } + return false; + } + + public boolean removeAll(Collection collection) { + Iterator it = this.iterator(); + boolean ret = false; + while (it.hasNext()) { + if (collection.contains(it.next())) { + ret = true; + it.remove(); + } + } + return ret; + } + + public boolean retainAll(Collection collection) { + Iterator it = this.iterator(); + boolean ret = false; + while (it.hasNext()) { + if (!collection.contains(it.next())) { + ret = true; + it.remove(); + } + } + return ret; + } + + public int size() { + int s = 0; + for (T value : this) { + s++; + } + return s; + } + + public Object[] toArray() { + return this.toArray(new Object[0]); + } + + public T[] toArray(T[] array) { + return toCollection().toArray(array); + } + + private Collection toCollection() { + ArrayList collection = new ArrayList(); + for (T value : this) { + collection.add(value); + } + return collection; + } +}