/* */ package org.apache.commons.collections;
/* */
/* */ import java.io.IOException;
/* */ import java.io.ObjectInputStream;
/* */ import java.io.ObjectOutputStream;
/* */ import java.lang.ref.Reference;
/* */ import java.lang.ref.ReferenceQueue;
/* */ import java.lang.ref.SoftReference;
/* */ import java.lang.ref.WeakReference;
/* */ import java.util.AbstractCollection;
/* */ import java.util.AbstractMap;
/* */ import java.util.AbstractSet;
/* */ import java.util.ArrayList;
/* */ import java.util.Arrays;
/* */ import java.util.Collection;
/* */ import java.util.ConcurrentModificationException;
/* */ import java.util.Iterator;
/* */ import java.util.Map.Entry;
/* */ import java.util.NoSuchElementException;
/* */ import java.util.Set;
/* */ import org.apache.commons.collections.keyvalue.DefaultMapEntry;
/* */
/* */ /** @deprecated */
/* */ public class ReferenceMap extends AbstractMap
/* */ {
/* */ private static final long serialVersionUID = -3370601314380922368L;
/* */ public static final int HARD = 0;
/* */ public static final int SOFT = 1;
/* */ public static final int WEAK = 2;
/* */ private int keyType;
/* */ private int valueType;
/* */ private float loadFactor;
/* 143 */ private boolean purgeValues = false;
/* */
/* 152 */ private transient ReferenceQueue queue = new ReferenceQueue();
/* */ private transient Entry[] table;
/* */ private transient int size;
/* */ private transient int threshold;
/* */ private volatile transient int modCount;
/* */ private transient Set keySet;
/* */ private transient Set entrySet;
/* */ private transient Collection values;
/* */
/* */ public ReferenceMap()
/* */ {
/* 203 */ this(0, 1);
/* */ }
/* */
/* */ public ReferenceMap(int keyType, int valueType, boolean purgeValues)
/* */ {
/* 218 */ this(keyType, valueType);
/* 219 */ this.purgeValues = purgeValues;
/* */ }
/* */
/* */ public ReferenceMap(int keyType, int valueType)
/* */ {
/* 232 */ this(keyType, valueType, 16, 0.75F);
/* */ }
/* */
/* */ public ReferenceMap(int keyType, int valueType, int capacity, float loadFactor, boolean purgeValues)
/* */ {
/* 255 */ this(keyType, valueType, capacity, loadFactor);
/* 256 */ this.purgeValues = purgeValues;
/* */ }
/* */
/* */ public ReferenceMap(int keyType, int valueType, int capacity, float loadFactor)
/* */ {
/* 274 */ verify("keyType", keyType);
/* 275 */ verify("valueType", valueType);
/* */
/* 277 */ if (capacity <= 0) {
/* 278 */ throw new IllegalArgumentException("capacity must be positive");
/* */ }
/* 280 */ if ((loadFactor <= 0.0F) || (loadFactor >= 1.0F)) {
/* 281 */ throw new IllegalArgumentException("Load factor must be greater than 0 and less than 1.");
/* */ }
/* */
/* 284 */ this.keyType = keyType;
/* 285 */ this.valueType = valueType;
/* */
/* 287 */ int v = 1;
/* 288 */ while (v < capacity) v *= 2;
/* */
/* 290 */ this.table = new Entry[v];
/* 291 */ this.loadFactor = loadFactor;
/* 292 */ this.threshold = (int)(v * loadFactor);
/* */ }
/* */
/* */ private static void verify(String name, int type)
/* */ {
/* 298 */ if ((type < 0) || (type > 2))
/* 299 */ throw new IllegalArgumentException(name + " must be HARD, SOFT, WEAK.");
/* */ }
/* */
/* */ private void writeObject(ObjectOutputStream out)
/* */ throws IOException
/* */ {
/* 312 */ out.defaultWriteObject();
/* 313 */ out.writeInt(this.table.length);
/* */
/* 318 */ for (Iterator iter = entrySet().iterator(); iter.hasNext(); ) {
/* 319 */ Map.Entry entry = (Map.Entry)iter.next();
/* 320 */ out.writeObject(entry.getKey());
/* 321 */ out.writeObject(entry.getValue());
/* */ }
/* 323 */ out.writeObject(null);
/* */ }
/* */
/* */ private void readObject(ObjectInputStream inp)
/* */ throws IOException, ClassNotFoundException
/* */ {
/* 335 */ inp.defaultReadObject();
/* 336 */ this.table = new Entry[inp.readInt()];
/* 337 */ this.threshold = (int)(this.table.length * this.loadFactor);
/* 338 */ this.queue = new ReferenceQueue();
/* 339 */ Object key = inp.readObject();
/* 340 */ while (key != null) {
/* 341 */ Object value = inp.readObject();
/* 342 */ put(key, value);
/* 343 */ key = inp.readObject();
/* */ }
/* */ }
/* */
/* */ private Object toReference(int type, Object referent, int hash)
/* */ {
/* 360 */ switch (type) { case 0:
/* 361 */ return referent;
/* */ case 1:
/* 362 */ return new SoftRef(hash, referent, this.queue);
/* */ case 2:
/* 363 */ return new WeakRef(hash, referent, this.queue); }
/* 364 */ throw new Error();
/* */ }
/* */
/* */ private Entry getEntry(Object key)
/* */ {
/* 377 */ if (key == null) return null;
/* 378 */ int hash = key.hashCode();
/* 379 */ int index = indexFor(hash);
/* 380 */ for (Entry entry = this.table[index]; entry != null; entry = entry.next) {
/* 381 */ if ((entry.hash == hash) && (key.equals(entry.getKey()))) {
/* 382 */ return entry;
/* */ }
/* */ }
/* 385 */ return null;
/* */ }
/* */
/* */ private int indexFor(int hash)
/* */ {
/* 395 */ hash += (hash << 15 ^ 0xFFFFFFFF);
/* 396 */ hash ^= hash >>> 10;
/* 397 */ hash += (hash << 3);
/* 398 */ hash ^= hash >>> 6;
/* 399 */ hash += (hash << 11 ^ 0xFFFFFFFF);
/* 400 */ hash ^= hash >>> 16;
/* 401 */ return hash & this.table.length - 1;
/* */ }
/* */
/* */ private void resize()
/* */ {
/* 413 */ Entry[] old = this.table;
/* 414 */ this.table = new Entry[old.length * 2];
/* */
/* 416 */ for (int i = 0; i < old.length; i++) {
/* 417 */ Entry next = old[i];
/* 418 */ while (next != null) {
/* 419 */ Entry entry = next;
/* 420 */ next = next.next;
/* 421 */ int index = indexFor(entry.hash);
/* 422 */ entry.next = this.table[index];
/* 423 */ this.table[index] = entry;
/* */ }
/* 425 */ old[i] = null;
/* */ }
/* 427 */ this.threshold = (int)(this.table.length * this.loadFactor);
/* */ }
/* */
/* */ private void purge()
/* */ {
/* 445 */ Reference ref = this.queue.poll();
/* 446 */ while (ref != null) {
/* 447 */ purge(ref);
/* 448 */ ref = this.queue.poll();
/* */ }
/* */ }
/* */
/* */ private void purge(Reference ref)
/* */ {
/* 457 */ int hash = ref.hashCode();
/* 458 */ int index = indexFor(hash);
/* 459 */ Entry previous = null;
/* 460 */ Entry entry = this.table[index];
/* 461 */ while (entry != null) {
/* 462 */ if (entry.purge(ref)) {
/* 463 */ if (previous == null) this.table[index] = entry.next; else
/* 464 */ previous.next = entry.next;
/* 465 */ this.size -= 1;
/* 466 */ return;
/* */ }
/* 468 */ previous = entry;
/* 469 */ entry = entry.next;
/* */ }
/* */ }
/* */
/* */ public int size()
/* */ {
/* 481 */ purge();
/* 482 */ return this.size;
/* */ }
/* */
/* */ public boolean isEmpty()
/* */ {
/* 492 */ purge();
/* 493 */ return this.size == 0;
/* */ }
/* */
/* */ public boolean containsKey(Object key)
/* */ {
/* 503 */ purge();
/* 504 */ Entry entry = getEntry(key);
/* 505 */ if (entry == null) return false;
/* 506 */ return entry.getValue() != null;
/* */ }
/* */
/* */ public Object get(Object key)
/* */ {
/* 517 */ purge();
/* 518 */ Entry entry = getEntry(key);
/* 519 */ if (entry == null) return null;
/* 520 */ return entry.getValue();
/* */ }
/* */
/* */ public Object put(Object key, Object value)
/* */ {
/* 536 */ if (key == null) throw new NullPointerException("null keys not allowed");
/* 537 */ if (value == null) throw new NullPointerException("null values not allowed");
/* */
/* 539 */ purge();
/* 540 */ if (this.size + 1 > this.threshold) resize();
/* */
/* 542 */ int hash = key.hashCode();
/* 543 */ int index = indexFor(hash);
/* 544 */ Entry entry = this.table[index];
/* 545 */ while (entry != null) {
/* 546 */ if ((hash == entry.hash) && (key.equals(entry.getKey()))) {
/* 547 */ Object result = entry.getValue();
/* 548 */ entry.setValue(value);
/* 549 */ return result;
/* */ }
/* 551 */ entry = entry.next;
/* */ }
/* 553 */ this.size += 1;
/* 554 */ this.modCount += 1;
/* 555 */ key = toReference(this.keyType, key, hash);
/* 556 */ value = toReference(this.valueType, value, hash);
/* 557 */ this.table[index] = new Entry(key, hash, value, this.table[index]);
/* 558 */ return null;
/* */ }
/* */
/* */ public Object remove(Object key)
/* */ {
/* 570 */ if (key == null) return null;
/* 571 */ purge();
/* 572 */ int hash = key.hashCode();
/* 573 */ int index = indexFor(hash);
/* 574 */ Entry previous = null;
/* 575 */ Entry entry = this.table[index];
/* 576 */ while (entry != null) {
/* 577 */ if ((hash == entry.hash) && (key.equals(entry.getKey()))) {
/* 578 */ if (previous == null) this.table[index] = entry.next; else
/* 579 */ previous.next = entry.next;
/* 580 */ this.size -= 1;
/* 581 */ this.modCount += 1;
/* 582 */ return entry.getValue();
/* */ }
/* 584 */ previous = entry;
/* 585 */ entry = entry.next;
/* */ }
/* 587 */ return null;
/* */ }
/* */
/* */ public void clear()
/* */ {
/* 595 */ Arrays.fill(this.table, null);
/* 596 */ this.size = 0;
/* 597 */ while (this.queue.poll() != null);
/* */ }
/* */
/* */ public Set entrySet()
/* */ {
/* 607 */ if (this.entrySet != null) {
/* 608 */ return this.entrySet;
/* */ }
/* 610 */ this.entrySet = new AbstractSet() {
/* */ public int size() {
/* 612 */ return ReferenceMap.this.size();
/* */ }
/* */
/* */ public void clear() {
/* 616 */ ReferenceMap.this.clear();
/* */ }
/* */
/* */ public boolean contains(Object o) {
/* 620 */ if (o == null) return false;
/* 621 */ if (!(o instanceof Map.Entry)) return false;
/* 622 */ Map.Entry e = (Map.Entry)o;
/* 623 */ ReferenceMap.Entry e2 = ReferenceMap.this.getEntry(e.getKey());
/* 624 */ return (e2 != null) && (e.equals(e2));
/* */ }
/* */
/* */ public boolean remove(Object o) {
/* 628 */ boolean r = contains(o);
/* 629 */ if (r) {
/* 630 */ Map.Entry e = (Map.Entry)o;
/* 631 */ ReferenceMap.this.remove(e.getKey());
/* */ }
/* 633 */ return r;
/* */ }
/* */
/* */ public Iterator iterator() {
/* 637 */ return new ReferenceMap.EntryIterator(ReferenceMap.this);
/* */ }
/* */
/* */ public Object[] toArray() {
/* 641 */ return toArray(new Object[0]);
/* */ }
/* */
/* */ public Object[] toArray(Object[] arr) {
/* 645 */ ArrayList list = new ArrayList();
/* 646 */ Iterator iterator = iterator();
/* 647 */ while (iterator.hasNext()) {
/* 648 */ ReferenceMap.Entry e = (ReferenceMap.Entry)iterator.next();
/* 649 */ list.add(new DefaultMapEntry(e.getKey(), e.getValue()));
/* */ }
/* 651 */ return list.toArray(arr);
/* */ }
/* */ };
/* 654 */ return this.entrySet;
/* */ }
/* */
/* */ public Set keySet()
/* */ {
/* 664 */ if (this.keySet != null) return this.keySet;
/* 665 */ this.keySet = new AbstractSet() {
/* */ public int size() {
/* 667 */ return ReferenceMap.this.size();
/* */ }
/* */
/* */ public Iterator iterator() {
/* 671 */ return new ReferenceMap.KeyIterator(ReferenceMap.this, null);
/* */ }
/* */
/* */ public boolean contains(Object o) {
/* 675 */ return ReferenceMap.this.containsKey(o);
/* */ }
/* */
/* */ public boolean remove(Object o)
/* */ {
/* 680 */ Object r = ReferenceMap.this.remove(o);
/* 681 */ return r != null;
/* */ }
/* */
/* */ public void clear() {
/* 685 */ ReferenceMap.this.clear();
/* */ }
/* */
/* */ public Object[] toArray() {
/* 689 */ return toArray(new Object[0]);
/* */ }
/* */
/* */ public Object[] toArray(Object[] array) {
/* 693 */ Collection c = new ArrayList(size());
/* 694 */ for (Iterator it = iterator(); it.hasNext(); ) {
/* 695 */ c.add(it.next());
/* */ }
/* 697 */ return c.toArray(array);
/* */ }
/* */ };
/* 700 */ return this.keySet;
/* */ }
/* */
/* */ public Collection values()
/* */ {
/* 710 */ if (this.values != null) return this.values;
/* 711 */ this.values = new AbstractCollection() {
/* */ public int size() {
/* 713 */ return ReferenceMap.this.size();
/* */ }
/* */
/* */ public void clear() {
/* 717 */ ReferenceMap.this.clear();
/* */ }
/* */
/* */ public Iterator iterator() {
/* 721 */ return new ReferenceMap.ValueIterator(ReferenceMap.this, null);
/* */ }
/* */
/* */ public Object[] toArray() {
/* 725 */ return toArray(new Object[0]);
/* */ }
/* */
/* */ public Object[] toArray(Object[] array) {
/* 729 */ Collection c = new ArrayList(size());
/* 730 */ for (Iterator it = iterator(); it.hasNext(); ) {
/* 731 */ c.add(it.next());
/* */ }
/* 733 */ return c.toArray(array);
/* */ }
/* */ };
/* 736 */ return this.values;
/* */ }
/* */
/* */ private static class WeakRef extends WeakReference
/* */ {
/* */ private int hash;
/* */
/* */ public WeakRef(int hash, Object r, ReferenceQueue q)
/* */ {
/* 946 */ super(q);
/* 947 */ this.hash = hash;
/* */ }
/* */
/* */ public int hashCode()
/* */ {
/* 952 */ return this.hash;
/* */ }
/* */ }
/* */
/* */ private static class SoftRef extends SoftReference
/* */ {
/* */ private int hash;
/* */
/* */ public SoftRef(int hash, Object r, ReferenceQueue q)
/* */ {
/* 930 */ super(q);
/* 931 */ this.hash = hash;
/* */ }
/* */
/* */ public int hashCode()
/* */ {
/* 936 */ return this.hash;
/* */ }
/* */ }
/* */
/* */ private class KeyIterator extends ReferenceMap.EntryIterator
/* */ {
/* */ private final ReferenceMap this$0;
/* */
/* */ private KeyIterator()
/* */ {
/* 912 */ super(); this.this$0 = this$0;
/* */ }
/* 914 */ public Object next() { return nextEntry().getKey();
/* */ }
/* */
/* */ KeyIterator(ReferenceMap.1 x1)
/* */ {
/* 912 */ this();
/* */ }
/* */ }
/* */
/* */ private class ValueIterator extends ReferenceMap.EntryIterator
/* */ {
/* */ private final ReferenceMap this$0;
/* */
/* */ private ValueIterator()
/* */ {
/* 905 */ super(); this.this$0 = this$0;
/* */ }
/* 907 */ public Object next() { return nextEntry().getValue();
/* */ }
/* */
/* */ ValueIterator(ReferenceMap.1 x1)
/* */ {
/* 905 */ this();
/* */ }
/* */ }
/* */
/* */ private class EntryIterator
/* */ implements Iterator
/* */ {
/* */ int index;
/* */ ReferenceMap.Entry entry;
/* */ ReferenceMap.Entry previous;
/* */ Object nextKey;
/* */ Object nextValue;
/* */ Object currentKey;
/* */ Object currentValue;
/* */ int expectedModCount;
/* */
/* */ public EntryIterator()
/* */ {
/* 832 */ this.index = (ReferenceMap.this.size() != 0 ? ReferenceMap.this.table.length : 0);
/* */
/* 835 */ this.expectedModCount = ReferenceMap.this.modCount;
/* */ }
/* */
/* */ public boolean hasNext()
/* */ {
/* 840 */ checkMod();
/* 841 */ while (nextNull()) {
/* 842 */ ReferenceMap.Entry e = this.entry;
/* 843 */ int i = this.index;
/* 844 */ while ((e == null) && (i > 0)) {
/* 845 */ i--;
/* 846 */ e = ReferenceMap.this.table[i];
/* */ }
/* 848 */ this.entry = e;
/* 849 */ this.index = i;
/* 850 */ if (e == null) {
/* 851 */ this.currentKey = null;
/* 852 */ this.currentValue = null;
/* 853 */ return false;
/* */ }
/* 855 */ this.nextKey = e.getKey();
/* 856 */ this.nextValue = e.getValue();
/* 857 */ if (nextNull()) this.entry = this.entry.next;
/* */ }
/* 859 */ return true;
/* */ }
/* */
/* */ private void checkMod()
/* */ {
/* 864 */ if (ReferenceMap.this.modCount != this.expectedModCount)
/* 865 */ throw new ConcurrentModificationException();
/* */ }
/* */
/* */ private boolean nextNull()
/* */ {
/* 871 */ return (this.nextKey == null) || (this.nextValue == null);
/* */ }
/* */
/* */ protected ReferenceMap.Entry nextEntry() {
/* 875 */ checkMod();
/* 876 */ if ((nextNull()) && (!hasNext())) throw new NoSuchElementException();
/* 877 */ this.previous = this.entry;
/* 878 */ this.entry = this.entry.next;
/* 879 */ this.currentKey = this.nextKey;
/* 880 */ this.currentValue = this.nextValue;
/* 881 */ this.nextKey = null;
/* 882 */ this.nextValue = null;
/* 883 */ return this.previous;
/* */ }
/* */
/* */ public Object next()
/* */ {
/* 888 */ return nextEntry();
/* */ }
/* */
/* */ public void remove()
/* */ {
/* 893 */ checkMod();
/* 894 */ if (this.previous == null) throw new IllegalStateException();
/* 895 */ ReferenceMap.this.remove(this.currentKey);
/* 896 */ this.previous = null;
/* 897 */ this.currentKey = null;
/* 898 */ this.currentValue = null;
/* 899 */ this.expectedModCount = ReferenceMap.this.modCount;
/* */ }
/* */ }
/* */
/* */ private class Entry
/* */ implements Map.Entry, KeyValue
/* */ {
/* */ Object key;
/* */ Object value;
/* */ int hash;
/* */ Entry next;
/* */
/* */ public Entry(Object key, int hash, Object value, Entry next)
/* */ {
/* 751 */ this.key = key;
/* 752 */ this.hash = hash;
/* 753 */ this.value = value;
/* 754 */ this.next = next;
/* */ }
/* */
/* */ public Object getKey()
/* */ {
/* 759 */ return ReferenceMap.this.keyType > 0 ? ((Reference)this.key).get() : this.key;
/* */ }
/* */
/* */ public Object getValue()
/* */ {
/* 764 */ return ReferenceMap.this.valueType > 0 ? ((Reference)this.value).get() : this.value;
/* */ }
/* */
/* */ public Object setValue(Object object)
/* */ {
/* 769 */ Object old = getValue();
/* 770 */ if (ReferenceMap.this.valueType > 0) ((Reference)this.value).clear();
/* 771 */ this.value = ReferenceMap.this.toReference(ReferenceMap.this.valueType, object, this.hash);
/* 772 */ return old;
/* */ }
/* */
/* */ public boolean equals(Object o)
/* */ {
/* 777 */ if (o == null) return false;
/* 778 */ if (o == this) return true;
/* 779 */ if (!(o instanceof KeyValue)) return false;
/* */
/* 781 */ Map.Entry entry = (KeyValue)o;
/* 782 */ Object key = entry.getKey();
/* 783 */ Object value = entry.getValue();
/* 784 */ if ((key == null) || (value == null)) return false;
/* 785 */ return (key.equals(getKey())) && (value.equals(getValue()));
/* */ }
/* */
/* */ public int hashCode()
/* */ {
/* 790 */ Object v = getValue();
/* 791 */ return this.hash ^ (v == null ? 0 : v.hashCode());
/* */ }
/* */
/* */ public String toString()
/* */ {
/* 796 */ return getKey() + "=" + getValue();
/* */ }
/* */
/* */ boolean purge(Reference ref)
/* */ {
/* 801 */ boolean r = (ReferenceMap.this.keyType > 0) && (this.key == ref);
/* 802 */ r = (r) || ((ReferenceMap.this.valueType > 0) && (this.value == ref));
/* 803 */ if (r) {
/* 804 */ if (ReferenceMap.this.keyType > 0) ((Reference)this.key).clear();
/* 805 */ if (ReferenceMap.this.valueType > 0)
/* 806 */ ((Reference)this.value).clear();
/* 807 */ else if (ReferenceMap.this.purgeValues) {
/* 808 */ this.value = null;
/* */ }
/* */ }
/* 811 */ return r;
/* */ }
/* */ }
/* */ }
/* Location: /home/mnovotny/projects/EMBEDDED_JBOSS_BETA3_COMMUNITY/embedded/output/lib/embedded-jboss/lib/thirdparty-all.jar
* Qualified Name: org.apache.commons.collections.ReferenceMap
* JD-Core Version: 0.6.0
*/