[Arakhnę-Dev] [319] * Reimplement the Weak maps. |
[ Thread Index |
Date Index
| More arakhne.org/dev Archives
]
Revision: 319
Author: galland
Date: 2011-12-17 12:43:54 +0100 (Sat, 17 Dec 2011)
Log Message:
-----------
* Reimplement the Weak maps.
* Provide HashMap- and TreeMap-based implementation of the weak maps.
* Support Weak, Soft and Phantom references.
Modified Paths:
--------------
trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueMap.java
trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakArrayList.java
trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueMap.java
Added Paths:
-----------
trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractPhantomValueMap.java
trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractReferencedValueMap.java
trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractSoftValueMap.java
trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractWeakValueMap.java
trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/PhantomValueHashMap.java
trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/PhantomValueTreeMap.java
trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueHashMap.java
trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueTreeMap.java
trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueHashMap.java
trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueTreeMap.java
trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractCollectionTestCase.java
trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractMapTestCase.java
trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractReferencableValueMapTestCase.java
trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractTestCase.java
trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractWeakCollectionTestCase.java
trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/PhantomValueHashMapTest.java
trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/PhantomValueTreeMapTest.java
trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueHashMapTest.java
trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueTreeMapTest.java
trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueHashMapTest.java
trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueTreeMapTest.java
Removed Paths:
-------------
trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractWeakSoftValueMap.java
trunk/arakhneRefs/src/test/java/org/arakhne/junit/
trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueMapTest.java
trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueMapTest.java
Added: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractPhantomValueMap.java
===================================================================
--- trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractPhantomValueMap.java (rev 0)
+++ trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractPhantomValueMap.java 2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,63 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2005-2009 Stephane GALLAND.
+ * Copyright (C) 2011 Stephane GALLAND.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.util.ref;
+
+import java.lang.ref.ReferenceQueue;
+import java.util.Map;
+
+/**
+ * A <tt>Map</tt> implementation with <em>phantom values</em>. An entry in a
+ * <tt>AbstractPhantomValueMap</tt> will automatically be removed when its value is no
+ * longer in ordinary use or <code>null</code>.
+ * <p>
+ * This abstract implementation does not decide if the map is based on a tree or on a hashtable.
+ *
+ * @param <K> is the type of the keys.
+ * @param <V> is the type of the values.
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 5.8
+ */
+public abstract class AbstractPhantomValueMap<K,V> extends AbstractReferencedValueMap<K,V> {
+
+ /**
+ * Constructs an empty <tt>Map</tt>.
+ *
+ * @param map is the map instance to use to store the entries.
+ * @throws IllegalArgumentException if the initial capacity is negative
+ * or the load factor is nonpositive
+ */
+ public AbstractPhantomValueMap(Map<K,ReferencableValue<K,V>> map) {
+ super(map);
+ }
+
+ /** {@inheritDoc}
+ */
+ @Override
+ protected final ReferencableValue<K,V> makeValue(K k, V v, ReferenceQueue<V> queue) {
+ return new PhantomReferencedValue<K,V>(k, v, queue);
+ }
+
+}
Property changes on: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractPhantomValueMap.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractReferencedValueMap.java
===================================================================
--- trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractReferencedValueMap.java (rev 0)
+++ trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractReferencedValueMap.java 2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,902 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2005-2009 Stephane GALLAND.
+ * Copyright (C) 2011 Stephane GALLAND.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.util.ref;
+
+import java.lang.ref.PhantomReference;
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.SoftReference;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Array;
+import java.util.AbstractMap;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A <tt>Map</tt> implementation with <em>weak/soft values</em>. An entry in a
+ * <tt>AbstractReferencedValueMap</tt> will automatically be removed when its value is no
+ * longer in ordinary use or <code>null</code>.
+ * <p>
+ * This abstract implementation does not decide if the map is based on a tree or on a hashtable;
+ * it does not impose soft or weak references.
+ *
+ * @param <K> is the type of the keys.
+ * @param <V> is the type of the values.
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 5.8
+ */
+public abstract class AbstractReferencedValueMap<K,V> extends AbstractMap<K,V> {
+
+ /** Defines the NULL object inside a WeakValueMap.
+ *
+ * @see #maskNull(Object)
+ */
+ protected static final Object NULL_VALUE = new Object();
+
+ /** Mask the null values given by the used of this map.
+ * <p>
+ * This method replaces the <code>null</code> value by
+ * the internal representation {@link #NULL_VALUE}.
+ *
+ * @param <MV> is the type of the value.
+ * @param value is the value given by the user of this map.
+ * @return the internal representation of the value.
+ * @see #unmaskNull(Object)
+ */
+ @SuppressWarnings("unchecked")
+ protected static <MV> MV maskNull(MV value) {
+ return (value==null) ? (MV)NULL_VALUE : value;
+ }
+
+ /** Unmask the null values given by the used of this map.
+ * <p>
+ * This method replaces the internal representation
+ * {@link #NULL_VALUE} of null values by its user representation
+ * <code>null</code>.
+ *
+ * @param <MV> is the type of the value.
+ * @param value is the value given by the user of this map.
+ * @return the internal representation of the value.
+ * @see #maskNull(Object)
+ */
+ protected static <MV> MV unmaskNull(MV value) {
+ return (value==NULL_VALUE) ? null : value;
+ }
+
+ /**
+ * Reallocates the array being used within toArray when the iterator
+ * returned more elements than expected, and finishes filling it from
+ * the iterator.
+ *
+ * @param r the array, replete with previously stored elements
+ * @param it the in-progress iterator over this collection
+ * @return array containing the elements in the given array, plus any
+ * further elements returned by the iterator, trimmed to size
+ */
+ @SuppressWarnings("unchecked")
+ static <T> T[] finishToArray(T[] r, Iterator<?> it) {
+ T[] rp = r;
+ int i = rp.length;
+ while (it.hasNext()) {
+ int cap = rp.length;
+ if (i == cap) {
+ int newCap = ((cap / 2) + 1) * 3;
+ if (newCap <= cap) { // integer overflow
+ if (cap == Integer.MAX_VALUE)
+ throw new OutOfMemoryError("Required array size too large"); //$NON-NLS-1$
+ newCap = Integer.MAX_VALUE;
+ }
+ rp = Arrays.copyOf(rp, newCap);
+ }
+ rp[++i] = (T)it.next();
+ }
+ // trim if overallocated
+ return (i == rp.length) ? rp : Arrays.copyOf(rp, i);
+ }
+
+ private boolean autoExpurge = false;
+ private final ReferenceQueue<V> queue = new ReferenceQueue<V>();
+
+ /** Internal map.
+ */
+ protected final Map<K,ReferencableValue<K,V>> map;
+
+ /**
+ * Constructs an empty <tt>Map</tt>.
+ *
+ * @param map is the map instance to use to store the entries.
+ * @throws IllegalArgumentException if the initial capacity is negative
+ * or the load factor is nonpositive
+ */
+ public AbstractReferencedValueMap(Map<K,ReferencableValue<K,V>> map) {
+ this.map = map;
+ }
+
+ /** Clean the references that was marked as released inside
+ * the queue.
+ */
+ protected final void expurgeNow() {
+ if (this.autoExpurge)
+ expurge();
+ else
+ expurgeQueuedReferences();
+ }
+
+ /** Replies if this map expurge all the released references
+ * even if they are not enqueued by the virtual machine
+ *
+ * @return <code>true</code> is the values are deeply expurged when they
+ * are released from the moemory, otherwise <code>false</code>
+ */
+ public final boolean isDeeplyExpurge() {
+ return this.autoExpurge;
+ }
+
+ /** Set if this map expurge all the released references
+ * even if they are not enqueued by the virtual machine
+ *
+ * @param deeplyExpurge must be <code>true</code> to
+ * expurge all the released values, otherwise <code>false</code>
+ * to expurge only the enqueued values.
+ * @return the old value of this flag
+ */
+ public final boolean setDeeplyExpurge(boolean deeplyExpurge) {
+ boolean old = this.autoExpurge;
+ this.autoExpurge = deeplyExpurge;
+ return old;
+ }
+
+ /** Clean the references that was marked as released inside
+ * the queue.
+ */
+ public final void expurgeQueuedReferences() {
+ Reference<? extends V> o;
+ while((o = this.queue.poll()) != null) {
+ if (o instanceof ReferencableValue<?,?>) {
+ this.map.remove(((ReferencableValue<?,?>)o).getKey());
+ }
+ o.clear();
+ }
+ }
+
+ /** Clean the references that was released.
+ */
+ public final void expurge() {
+ Reference<? extends V> o;
+
+ Iterator<Entry<K,ReferencableValue<K,V>>> iter = this.map.entrySet().iterator();
+ Entry<K,ReferencableValue<K,V>> entry;
+ ReferencableValue<K,V> value;
+ while (iter.hasNext()) {
+ entry = iter.next();
+ if (entry!=null) {
+ value = entry.getValue();
+ if ((value!=null)&&
+ ((value.isEnqueued())||(value.get()==null))) {
+ value.enqueue();
+ value.clear();
+ }
+ }
+ }
+ entry = null;
+ value = null;
+
+ while((o = this.queue.poll()) != null) {
+ if (o instanceof ReferencableValue<?,?>) {
+ this.map.remove(((ReferencableValue<?,?>)o).getKey());
+ }
+ o.clear();
+ }
+ }
+
+ /** Create a storage object that permits to put the specified
+ * elements inside this map.
+ *
+ * @param k is the key associated to the value
+ * @param v is the value
+ * @param refQueue is the reference queue to use
+ * @return the new storage object
+ */
+ protected abstract ReferencableValue<K,V> makeValue(K k, V v, ReferenceQueue<V> refQueue);
+
+ /** Create a storage object that permits to put the specified
+ * elements inside this map.
+ *
+ * @param k is the key associated to the value
+ * @param v is the value
+ * @return the new storage object
+ */
+ protected final ReferencableValue<K,V> makeValue(K k, V v) {
+ return makeValue(k, v, this.queue);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final V put(K key, V value) {
+ expurgeNow();
+ ReferencableValue<K,V> ret = this.map.put(key, makeValue(key, value, this.queue));
+ if(ret == null) return null;
+ return ret.getValue();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final Set<Entry<K,V>> entrySet() {
+ expurgeNow();
+ return new InnerEntrySet();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final boolean equals(Object o) {
+ expurgeNow();
+ return super.equals(o);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public final int hashCode() {
+ expurgeNow();
+ return super.hashCode();
+ }
+
+ /**
+ * This interface provides information about the pairs inside
+ * a map with weak/soft reference values.
+ *
+ * @param <K> is the type of the map keys.
+ * @param <V> is the type of the map values.
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+ protected static interface ReferencableValue<K,V> extends Entry<K,V> {
+
+ /**
+ * @return if the value is enqueued into a reference queue.
+ */
+ public boolean isEnqueued();
+
+ /**
+ * @return the weak/soft reference.
+ */
+ public V get();
+
+ /**
+ * @return if the value was enqueued
+ */
+ public boolean enqueue();
+
+ /**
+ */
+ public void clear();
+
+ } // interface ReferencableValue
+
+ /**
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+ private class InnerEntrySet implements Set<Entry<K,V>> {
+
+ /**
+ */
+ public InnerEntrySet() {
+ //
+ }
+
+ @Override
+ public final boolean add(java.util.Map.Entry<K, V> e) {
+ K key = e.getKey();
+ V value = e.getValue();
+ return AbstractReferencedValueMap.this.map.put(key, makeValue(key, value)) == null;
+ }
+
+ @Override
+ public final boolean addAll(Collection<? extends java.util.Map.Entry<K, V>> c) {
+ boolean changed = true;
+ for(java.util.Map.Entry<K, V> entry : c) {
+ changed = add(entry) | changed;
+ }
+ return changed;
+ }
+
+ @Override
+ public final void clear() {
+ AbstractReferencedValueMap.this.map.clear();
+ }
+
+ @Override
+ public final boolean contains(Object o) {
+ if (o instanceof Entry<?,?>) {
+ try {
+ expurgeNow();
+ return AbstractReferencedValueMap.this.map.containsKey(((Entry<?,?>)o).getKey());
+ }
+ catch(AssertionError e) {
+ throw e;
+ }
+ catch(Throwable _) {
+ //
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public final boolean containsAll(Collection<?> c) {
+ boolean ok;
+ expurgeNow();
+ for(Object o : c) {
+ ok = false;
+ if (o instanceof Entry<?,?>) {
+ try {
+ ok = AbstractReferencedValueMap.this.map.containsKey(((Entry<?,?>)o).getKey());
+ }
+ catch(AssertionError e) {
+ throw e;
+ }
+ catch(Throwable _) {
+ //
+ }
+ }
+ if (!ok) return false;
+ }
+ return true;
+ }
+
+ @Override
+ public final boolean isEmpty() {
+ expurgeNow();
+ return AbstractReferencedValueMap.this.map.isEmpty();
+ }
+
+ @Override
+ public final Iterator<java.util.Map.Entry<K, V>> iterator() {
+ return new InnerIterator();
+ }
+
+ @Override
+ public final boolean remove(Object o) {
+ if (o instanceof Entry<?,?>) {
+ try {
+ return AbstractReferencedValueMap.this.map.remove(((Entry<?,?>)o).getKey())!=null;
+ }
+ catch(AssertionError e) {
+ throw e;
+ }
+ catch(Throwable _) {
+ //
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public final boolean removeAll(Collection<?> c) {
+ boolean changed = true;
+ for(Object o : c) {
+ changed = remove(o) || changed;
+ }
+ return changed;
+ }
+
+ @Override
+ public final boolean retainAll(Collection<?> c) {
+ expurgeNow();
+ Collection<K> keys = AbstractReferencedValueMap.this.map.keySet();
+ Iterator<K> iterator = keys.iterator();
+ K key;
+ boolean changed = false;
+ while (iterator.hasNext()) {
+ key = iterator.next();
+ if (!c.contains(key)) {
+ iterator.remove();
+ changed = true;
+ }
+ }
+ return changed;
+ }
+
+ @Override
+ public final int size() {
+ expurgeNow();
+ return AbstractReferencedValueMap.this.map.size();
+ }
+
+ @Override
+ public final Object[] toArray() {
+ expurgeNow();
+ Object[] tab = new Object[AbstractReferencedValueMap.this.map.size()];
+ return toArray(tab);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public final <T> T[] toArray(T[] a) {
+ expurgeNow();
+ // Estimate size of array; be prepared to see more or fewer elements
+ int size = AbstractReferencedValueMap.this.map.size();
+ T[] r = a.length >= size ? a :
+ (T[])Array.newInstance(a.getClass().getComponentType(), size);
+ Iterator<Entry<K,V>> it = iterator();
+
+ for (int i=0; i<r.length; ++i) {
+ if (!it.hasNext()) { // fewer elements than expected
+ if (a != r) {
+ return Arrays.copyOf(r, i);
+ }
+ r[i] = null; // null-terminate
+ return r;
+ }
+ r[i] = (T)it.next();
+ }
+ return it.hasNext() ? finishToArray(r, it) : r;
+ }
+
+ } // class InnerEntrySet
+
+ /**
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+ private class InnerIterator implements Iterator<Entry<K,V>> {
+
+ private final Iterator<Entry<K,ReferencableValue<K,V>>> originalIterator;
+ private Entry<K,V> next = null;
+ private boolean nextSearchProceeded = false;
+ private boolean enableRemove = false;
+
+ public InnerIterator() {
+ this.originalIterator = AbstractReferencedValueMap.this.map.entrySet().iterator();
+ }
+
+ private void searchNext() {
+ if (!this.nextSearchProceeded) {
+ this.nextSearchProceeded = true;
+ this.next = null;
+ Entry<K,ReferencableValue<K,V>> originalNext;
+ ReferencableValue<K,V> wValue;
+ while (this.next==null && this.originalIterator.hasNext()) {
+ originalNext = this.originalIterator.next();
+ if (originalNext!=null) {
+ wValue = originalNext.getValue();
+ if (wValue!=null) {
+ this.next = new InnerEntry(
+ originalNext.getKey(),
+ wValue.getValue(),
+ originalNext);
+ return;
+ }
+ // Remove the original entry because the pointer was lost.
+ this.originalIterator.remove();
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean hasNext() {
+ searchNext();
+ assert(this.nextSearchProceeded);
+ this.enableRemove = false;
+ return this.next!=null;
+ }
+
+ @Override
+ public java.util.Map.Entry<K, V> next() {
+ searchNext();
+ assert(this.nextSearchProceeded);
+ Entry<K,V> cnext = this.next;
+
+ // Reset the research flags
+ this.next = null;
+ this.nextSearchProceeded = false;
+ this.enableRemove = true;
+
+ return cnext;
+ }
+
+ @Override
+ public void remove() {
+ if (!this.enableRemove)
+ throw new IllegalStateException("you must not invoke the remove function between hasNext and next functions."); //$NON-NLS-1$
+ this.originalIterator.remove();
+ }
+
+ } // class InnerIterator
+
+ /**
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+ private class InnerEntry implements Entry<K,V> {
+
+ private final Entry<K,ReferencableValue<K,V>> original;
+ private final K key;
+ private V value;
+
+ public InnerEntry(K k, V v, Entry<K,ReferencableValue<K,V>> o) {
+ this.original = o;
+ this.key = k;
+ this.value = v;
+ }
+
+ @Override
+ public K getKey() {
+ return this.key;
+ }
+
+ @Override
+ public V getValue() {
+ return this.value;
+ }
+
+ @Override
+ public V setValue(V value) {
+ this.value = value;
+ return this.original.getValue().setValue(value);
+ }
+
+ } // class InnerEntry
+
+ /**
+ * Value stored in a {@link AbstractReferencedValueMap} inside a {@link SoftReference}.
+ *
+ * @param <VK> is the type of the key associated to the value.
+ * @param <VV> is the type of the value.
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+ protected static class SoftReferencedValue<VK,VV> extends SoftReference<VV> implements ReferencableValue<VK,VV> {
+
+ private final VK k;
+
+ /**
+ * @param k is the key.
+ * @param v is the value.
+ * @param queue is the memory-release listener.
+ */
+ public SoftReferencedValue(VK k, VV v, ReferenceQueue<VV> queue) {
+ super(maskNull(v), queue);
+ this.k = k;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append('{');
+ VK key = getKey();
+ buffer.append(key==null ? null : key.toString());
+ buffer.append('=');
+ if (isEnqueued()) {
+ buffer.append("Q#"); //$NON-NLS-1$
+ }
+ else {
+ buffer.append("P#"); //$NON-NLS-1$
+ }
+ VV v = getValue();
+ buffer.append((v==null ? null : v.toString()));
+ buffer.append('}');
+ return buffer.toString();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public VK getKey() {
+ return this.k;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public VV getValue() {
+ return unmaskNull(get());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public VV setValue(VV o) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ Object val = getValue();
+ return (getKey()==null ? 0 : getKey().hashCode()) ^
+ (val==null ? 0 : val.hashCode());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @param o {@inheritDoc}
+ * @return {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof Entry) {
+ Entry<VK,VV> e = (Entry<VK,VV>)o;
+ Object e1val = getValue();
+ Object e2val = e.getValue();
+ return (getKey()==null ?
+ e.getKey()==null : getKey().equals(e.getKey())) &&
+ (e1val==null ? e2val==null : e1val.equals(e2val));
+ }
+ return false;
+ }
+
+ } // class SoftReferencedValue
+
+ /**
+ * Value stored in a {@link AbstractReferencedValueMap} inside a {@link WeakReference}.
+ *
+ * @param <VK> is the type of the key associated to the value.
+ * @param <VV> is the type of the value.
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+ protected static class WeakReferencedValue<VK,VV> extends WeakReference<VV> implements ReferencableValue<VK,VV> {
+
+ private final VK k;
+
+ /**
+ * @param k is the key.
+ * @param v is the value.
+ * @param queue is the memory-release listener.
+ */
+ public WeakReferencedValue(VK k, VV v, ReferenceQueue<VV> queue) {
+ super(maskNull(v), queue);
+ this.k = k;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append('{');
+ VK key = getKey();
+ buffer.append(key==null ? null : key.toString());
+ buffer.append('=');
+ if (isEnqueued()) {
+ buffer.append("Q#"); //$NON-NLS-1$
+ }
+ else {
+ buffer.append("P#"); //$NON-NLS-1$
+ }
+ VV v = getValue();
+ buffer.append((v==null ? null : v.toString()));
+ buffer.append('}');
+ return buffer.toString();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public VK getKey() {
+ return this.k;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public VV getValue() {
+ return unmaskNull(get());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public VV setValue(VV o) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ Object val = getValue();
+ return (getKey()==null ? 0 : getKey().hashCode()) ^
+ (val==null ? 0 : val.hashCode());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @param o {@inheritDoc}
+ * @return {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof Entry) {
+ Entry<VK,VV> e = (Entry<VK,VV>)o;
+ Object e1val = getValue();
+ Object e2val = e.getValue();
+ return (getKey()==null ?
+ e.getKey()==null : getKey().equals(e.getKey())) &&
+ (e1val==null ? e2val==null : e1val.equals(e2val));
+ }
+ return false;
+ }
+
+ } // class WeakReferencedValue
+
+ /**
+ * Value stored in a {@link AbstractReferencedValueMap} inside a {@link PhantomReference}.
+ *
+ * @param <VK> is the type of the key associated to the value.
+ * @param <VV> is the type of the value.
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+ protected static class PhantomReferencedValue<VK,VV> extends PhantomReference<VV> implements ReferencableValue<VK,VV> {
+
+ private final VK k;
+
+ /**
+ * @param k is the key.
+ * @param v is the value.
+ * @param queue is the memory-release listener.
+ */
+ public PhantomReferencedValue(VK k, VV v, ReferenceQueue<VV> queue) {
+ super(maskNull(v), queue);
+ this.k = k;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append('{');
+ VK key = getKey();
+ buffer.append(key==null ? null : key.toString());
+ buffer.append('=');
+ if (isEnqueued()) {
+ buffer.append("Q#"); //$NON-NLS-1$
+ }
+ else {
+ buffer.append("P#"); //$NON-NLS-1$
+ }
+ VV v = getValue();
+ buffer.append((v==null ? null : v.toString()));
+ buffer.append('}');
+ return buffer.toString();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public VK getKey() {
+ return this.k;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public VV getValue() {
+ return unmaskNull(get());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public VV setValue(VV o) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ Object val = getValue();
+ return (getKey()==null ? 0 : getKey().hashCode()) ^
+ (val==null ? 0 : val.hashCode());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @param o {@inheritDoc}
+ * @return {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof Entry) {
+ Entry<VK,VV> e = (Entry<VK,VV>)o;
+ Object e1val = getValue();
+ Object e2val = e.getValue();
+ return (getKey()==null ?
+ e.getKey()==null : getKey().equals(e.getKey())) &&
+ (e1val==null ? e2val==null : e1val.equals(e2val));
+ }
+ return false;
+ }
+
+ } // class PhantomReferencedValue
+
+}
Property changes on: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractReferencedValueMap.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractSoftValueMap.java
===================================================================
--- trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractSoftValueMap.java (rev 0)
+++ trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractSoftValueMap.java 2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,63 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2005-2009 Stephane GALLAND.
+ * Copyright (C) 2011 Stephane GALLAND.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.util.ref;
+
+import java.lang.ref.ReferenceQueue;
+import java.util.Map;
+
+/**
+ * A <tt>Map</tt> implementation with <em>soft values</em>. An entry in a
+ * <tt>AbstractSoftValueMap</tt> will automatically be removed when its value is no
+ * longer in ordinary use or <code>null</code>.
+ * <p>
+ * This abstract implementation does not decide if the map is based on a tree or on a hashtable.
+ *
+ * @param <K> is the type of the keys.
+ * @param <V> is the type of the values.
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 5.8
+ */
+public abstract class AbstractSoftValueMap<K,V> extends AbstractReferencedValueMap<K,V> {
+
+ /**
+ * Constructs an empty <tt>Map</tt>.
+ *
+ * @param map is the map instance to use to store the entries.
+ * @throws IllegalArgumentException if the initial capacity is negative
+ * or the load factor is nonpositive
+ */
+ public AbstractSoftValueMap(Map<K,ReferencableValue<K,V>> map) {
+ super(map);
+ }
+
+ /** {@inheritDoc}
+ */
+ @Override
+ protected final ReferencableValue<K,V> makeValue(K k, V v, ReferenceQueue<V> queue) {
+ return new SoftReferencedValue<K,V>(k, v, queue);
+ }
+
+}
Property changes on: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractSoftValueMap.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Deleted: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractWeakSoftValueMap.java
===================================================================
--- trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractWeakSoftValueMap.java 2011-11-30 09:10:39 UTC (rev 318)
+++ trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractWeakSoftValueMap.java 2011-12-17 11:43:54 UTC (rev 319)
@@ -1,551 +0,0 @@
-/*
- * $Id: WeakValueMap.java,v 1.1 2007-02-20 08:52:37 sgalland Exp $
- *
- * Copyright (C) 2005-2009 Stephane GALLAND This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * This program is free software; you can redistribute it and/or modify
- */
-
-package org.arakhne.util.ref;
-
-import java.lang.ref.Reference;
-import java.lang.ref.ReferenceQueue;
-import java.util.AbstractMap;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * A <tt>Map</tt> implementation with <em>weak/soft values</em>. An entry in a
- * <tt>AbstractWeakSoftValueMap</tt> will automatically be removed when its value is no
- * longer in ordinary use or null.
- *
- * @param <K> is the type of the keys.
- * @param <V> is the type of the values.
- * @author $Author: galland$
- * @version $FullVersion$
- * @mavengroupid $GroupId$
- * @mavenartifactid $ArtifactId$
- */
-public abstract class AbstractWeakSoftValueMap<K,V> extends AbstractMap<K,V> {
-
- /** Defines the NULL object inside a WeakValueMap.
- *
- * @see #maskNull(Object)
- */
- protected static final Object NULL_VALUE = new Object();
-
- /** Mask the null values given by the used of this map.
- * <p>
- * This method replaces the <code>null</code> value by
- * the internal representation {@link #NULL_VALUE}.
- *
- * @param <V> is the type of the value.
- * @param value is the value given by the user of this map.
- * @return the internal representation of the value.
- * @see #unmaskNull(Object)
- */
- @SuppressWarnings("unchecked")
- protected static <V> V maskNull(V value) {
- return (value==null) ? (V)NULL_VALUE : value;
- }
-
- /** Unmask the null values given by the used of this map.
- * <p>
- * This method replaces the internal representation
- * {@link #NULL_VALUE} of null values by its user representation
- * <code>null</code>.
- *
- * @param <V> is the type of the value.
- * @param value is the value given by the user of this map.
- * @return the internal representation of the value.
- * @see #maskNull(Object)
- */
- protected static <V> V unmaskNull(V value) {
- return (value==NULL_VALUE) ? null : value;
- }
-
- private boolean autoExpurge = false;
- private final HashMap<K,WeakSoftValue<K,V>> map;
- private final ReferenceQueue<V> queue = new ReferenceQueue<V>();
-
- /**
- * Constructs an empty <tt>HashMap</tt> with the specified initial
- * capacity and load factor.
- *
- * @param initialCapacity the initial capacity
- * @param loadFactor the load factor
- * @throws IllegalArgumentException if the initial capacity is negative
- * or the load factor is nonpositive
- */
- public AbstractWeakSoftValueMap(int initialCapacity, float loadFactor) {
- this.map = new HashMap<K,WeakSoftValue<K,V>>(initialCapacity, loadFactor);
- }
-
- /**
- * Constructs an empty <tt>HashMap</tt> with the specified initial
- * capacity and the default load factor (0.75).
- *
- * @param initialCapacity the initial capacity.
- * @throws IllegalArgumentException if the initial capacity is negative.
- */
- public AbstractWeakSoftValueMap(int initialCapacity) {
- this.map = new HashMap<K,WeakSoftValue<K,V>>(initialCapacity);
- }
-
- /**
- * Constructs an empty <tt>HashMap</tt> with the default initial capacity
- * (16) and the default load factor (0.75).
- */
- public AbstractWeakSoftValueMap() {
- this.map = new HashMap<K,WeakSoftValue<K,V>>();
- }
-
- /**
- * Constructs a new <tt>HashMap</tt> with the same mappings as the
- * specified <tt>Map</tt>. The <tt>HashMap</tt> is created with
- * default load factor (0.75) and an initial capacity sufficient to
- * hold the mappings in the specified <tt>Map</tt>.
- *
- * @param m the map whose mappings are to be placed in this map
- * @throws NullPointerException if the specified map is null
- */
- public AbstractWeakSoftValueMap(Map<? extends K, ? extends V> m) {
- this.map = new HashMap<K,WeakSoftValue<K,V>>();
- putAll(m);
- }
-
- /** Clean the references that was marked as released inside
- * the queue.
- */
- protected final void expurgeNow() {
- if (this.autoExpurge)
- expurge();
- else
- expurgeQueuedReferences();
- }
-
- /** Replies if this map expurge all the released references
- * even if they are not enqueued by the virtual machine
- *
- * @return <code>true</code> is the values are deeply expurged when they
- * are released from the moemory, otherwise <code>false</code>
- */
- public final boolean isDeeplyExpurge() {
- return this.autoExpurge;
- }
-
- /** Set if this map expurge all the released references
- * even if they are not enqueued by the virtual machine
- *
- * @param deeplyExpurge must be <code>true</code> to
- * expurge all the released values, otherwise <code>false</code>
- * to expurge only the enqueued values.
- * @return the old value of this flag
- */
- public final boolean setDeeplyExpurge(boolean deeplyExpurge) {
- boolean old = this.autoExpurge;
- this.autoExpurge = deeplyExpurge;
- return old;
- }
-
- /** Clean the references that was marked as released inside
- * the queue.
- */
- public final void expurgeQueuedReferences() {
- Reference<? extends V> o;
- while((o = this.queue.poll()) != null) {
- if (o instanceof WeakSoftValue<?,?>) {
- this.map.remove(((WeakSoftValue<?,?>)o).getKey());
- }
- o.clear();
- }
- }
-
- /** Clean the references that was released.
- */
- public final void expurge() {
- Reference<? extends V> o;
-
- Iterator<Entry<K,WeakSoftValue<K,V>>> iter = this.map.entrySet().iterator();
- Entry<K,WeakSoftValue<K,V>> entry;
- WeakSoftValue<K,V> value;
- while (iter.hasNext()) {
- entry = iter.next();
- if (entry!=null) {
- value = entry.getValue();
- if ((value!=null)&&
- ((value.isEnqueued())||(value.get()==null))) {
- value.enqueue();
- value.clear();
- }
- }
- }
- entry = null;
- value = null;
-
- while((o = this.queue.poll()) != null) {
- if (o instanceof WeakSoftValue<?,?>) {
- this.map.remove(((WeakSoftValue<?,?>)o).getKey());
- }
- o.clear();
- }
- }
-
- /** Create a storage object that permits to put the specified
- * elements inside this map.
- *
- * @param k is the key associated to the value
- * @param v is the value
- * @param refQueue is the reference queue to use
- * @return the new storage object
- */
- protected abstract WeakSoftValue<K,V> makeValue(K k, V v, ReferenceQueue<V> refQueue);
-
- /** Create a storage object that permits to put the specified
- * elements inside this map.
- *
- * @param k is the key associated to the value
- * @param v is the value
- * @return the new storage object
- */
- protected final WeakSoftValue<K,V> makeValue(K k, V v) {
- return makeValue(k, v, this.queue);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public final V put(K key, V value) {
- expurgeNow();
- WeakSoftValue<K,V> ret = this.map.put(key, makeValue(key, value, this.queue));
- if(ret == null) return null;
- return ret.getValue();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public final Set<Entry<K,V>> entrySet() {
- expurgeNow();
- return new InnerEntrySet();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public final boolean equals(Object o) {
- expurgeNow();
- return super.equals(o);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public final int hashCode() {
- expurgeNow();
- return hashCode();
- }
-
- /**
- * This interface provides information about the pairs inside
- * a map with weak/soft reference values.
- *
- * @param <K> is the type of the map keys.
- * @param <V> is the type of the map values.
- * @author $Author: galland$
- * @version $FullVersion$
- * @mavengroupid $GroupId$
- * @mavenartifactid $ArtifactId$
- */
- protected interface WeakSoftValue<K,V> extends Entry<K,V> {
-
- /**
- * @return if the value is enqueued into a reference queue.
- */
- public boolean isEnqueued();
-
- /**
- * @return the weak/soft reference.
- */
- public V get();
-
- /**
- * @return if the value was enqueued
- */
- public boolean enqueue();
-
- /**
- */
- public void clear();
-
- }
-
- /**
- * @author $Author: galland$
- * @version $FullVersion$
- * @mavengroupid $GroupId$
- * @mavenartifactid $ArtifactId$
- */
- @SuppressWarnings("synthetic-access")
- private class InnerEntrySet implements Set<Entry<K,V>> {
-
- public InnerEntrySet() {
- //
- }
-
- @Override
- public final boolean add(java.util.Map.Entry<K, V> e) {
- K key = e.getKey();
- V value = e.getValue();
- return AbstractWeakSoftValueMap.this.map.put(key,
- makeValue(key, value)) == null;
- }
-
- @Override
- public final boolean addAll(Collection<? extends java.util.Map.Entry<K, V>> c) {
- boolean ok = true;
- for(java.util.Map.Entry<K, V> entry : c) {
- ok = add(entry) && ok;
- }
- return ok;
- }
-
- @Override
- public final void clear() {
- AbstractWeakSoftValueMap.this.map.clear();
- }
-
- @Override
- public final boolean contains(Object o) {
- if (o instanceof Entry<?,?>) {
- try {
- expurgeNow();
- return AbstractWeakSoftValueMap.this.map.containsKey(((Entry<?,?>)o).getKey());
- }
- catch(AssertionError e) {
- throw e;
- }
- catch(Throwable _) {
- //
- }
- }
- return false;
- }
-
- @Override
- public final boolean containsAll(Collection<?> c) {
- boolean ok;
- expurgeNow();
- for(Object o : c) {
- ok = false;
- if (o instanceof Entry<?,?>) {
- try {
- ok = AbstractWeakSoftValueMap.this.map.containsKey(((Entry<?,?>)o).getKey());
- }
- catch(AssertionError e) {
- throw e;
- }
- catch(Throwable _) {
- //
- }
- }
- if (!ok) return false;
- }
- return true;
- }
-
- @Override
- public final boolean isEmpty() {
- expurgeNow();
- return AbstractWeakSoftValueMap.this.map.isEmpty();
- }
-
- @Override
- public final Iterator<java.util.Map.Entry<K, V>> iterator() {
- return new InnerIterator();
- }
-
- @Override
- public final boolean remove(Object o) {
- if (o instanceof Entry<?,?>) {
- try {
- return AbstractWeakSoftValueMap.this.map.remove(((Entry<?,?>)o).getKey())!=null;
- }
- catch(AssertionError e) {
- throw e;
- }
- catch(Throwable _) {
- //
- }
- }
- return false;
- }
-
- @Override
- public final boolean removeAll(Collection<?> c) {
- boolean ok = true;
- for(Object o : c) {
- ok = remove(o) && ok;
- }
- return ok;
- }
-
- @Override
- public final boolean retainAll(Collection<?> c) {
- expurgeNow();
- Collection<K> keys = AbstractWeakSoftValueMap.this.map.keySet();
- Iterator<K> iterator = keys.iterator();
- K key;
- boolean changed = false;
- while (iterator.hasNext()) {
- key = iterator.next();
- if (!c.contains(key)) {
- iterator.remove();
- changed = true;
- }
- }
- return changed;
- }
-
- @Override
- public final int size() {
- expurgeNow();
- return AbstractWeakSoftValueMap.this.map.size();
- }
-
- @Override
- public final Object[] toArray() {
- expurgeNow();
- Object[] tab = new Object[AbstractWeakSoftValueMap.this.map.size()];
- return toArray(tab);
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public final <T> T[] toArray(T[] a) {
- Entry<?,?>[] tab;
- expurgeNow();
- int count = AbstractWeakSoftValueMap.this.map.size();
- if (a==null || a.length<count) {
- tab = new Entry[count];
- }
- else {
- tab = (Entry[])a;
- }
-
- Iterator<java.util.Map.Entry<K, V>> iterator = iterator();
- int i = 0;
- while (i<tab.length && iterator.hasNext()) {
- tab[i] = iterator.next();
- }
-
- return (T[])tab;
- }
-
- }
-
- /**
- * @author $Author: galland$
- * @version $FullVersion$
- * @mavengroupid $GroupId$
- * @mavenartifactid $ArtifactId$
- */
- private class InnerIterator implements Iterator<Entry<K,V>> {
-
- private final Iterator<Entry<K,WeakSoftValue<K,V>>> originalIterator;
- private Entry<K,V> next;
-
- @SuppressWarnings("synthetic-access")
- public InnerIterator() {
- this.originalIterator = AbstractWeakSoftValueMap.this.map.entrySet().iterator();
- this.next = searchNext();
- }
-
- private Entry<K,V> searchNext() {
- Entry<K,WeakSoftValue<K,V>> originalNext;
- WeakSoftValue<K,V> wValue;
- Entry<K,V> cnext = null;
- while (cnext==null && this.originalIterator.hasNext()) {
- originalNext = this.originalIterator.next();
- if (originalNext!=null) {
- wValue = originalNext.getValue();
- if (wValue!=null) {
- cnext = new InnerEntry(wValue.getValue(), originalNext);
- }
- }
- }
- return cnext;
- }
-
- @Override
- public boolean hasNext() {
- return this.next!=null;
- }
-
- @Override
- public java.util.Map.Entry<K, V> next() {
- Entry<K,V> cnext = this.next;
- this.next = searchNext();
- return cnext;
- }
-
- @Override
- public void remove() {
- this.originalIterator.remove();
- }
-
- }
-
- /**
- * @author $Author: galland$
- * @version $FullVersion$
- * @mavengroupid $GroupId$
- * @mavenartifactid $ArtifactId$
- */
- private class InnerEntry implements Entry<K,V> {
-
- private final Entry<K,WeakSoftValue<K,V>> original;
- private V value;
-
- public InnerEntry(V v, Entry<K,WeakSoftValue<K,V>> o) {
- this.original = o;
- this.value = v;
- }
-
- @Override
- public K getKey() {
- return this.original.getKey();
- }
-
- @Override
- public V getValue() {
- return this.value;
- }
-
- @Override
- public V setValue(V value) {
- this.value = value;
- return this.original.getValue().setValue(value);
- }
-
- }
-
-}
Added: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractWeakValueMap.java
===================================================================
--- trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractWeakValueMap.java (rev 0)
+++ trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractWeakValueMap.java 2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,63 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2005-2009 Stephane GALLAND.
+ * Copyright (C) 2011 Stephane GALLAND.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.util.ref;
+
+import java.lang.ref.ReferenceQueue;
+import java.util.Map;
+
+/**
+ * A <tt>Map</tt> implementation with <em>weak values</em>. An entry in a
+ * <tt>AbstractWeakValueMap</tt> will automatically be removed when its value is no
+ * longer in ordinary use or <code>null</code>.
+ * <p>
+ * This abstract implementation does not decide if the map is based on a tree or on a hashtable.
+ *
+ * @param <K> is the type of the keys.
+ * @param <V> is the type of the values.
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 5.8
+ */
+public abstract class AbstractWeakValueMap<K,V> extends AbstractReferencedValueMap<K,V> {
+
+ /**
+ * Constructs an empty <tt>Map</tt>.
+ *
+ * @param map is the map instance to use to store the entries.
+ * @throws IllegalArgumentException if the initial capacity is negative
+ * or the load factor is nonpositive
+ */
+ public AbstractWeakValueMap(Map<K,ReferencableValue<K,V>> map) {
+ super(map);
+ }
+
+ /** {@inheritDoc}
+ */
+ @Override
+ protected final ReferencableValue<K,V> makeValue(K k, V v, ReferenceQueue<V> queue) {
+ return new WeakReferencedValue<K,V>(k, v, queue);
+ }
+
+}
Property changes on: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractWeakValueMap.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/PhantomValueHashMap.java
===================================================================
--- trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/PhantomValueHashMap.java (rev 0)
+++ trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/PhantomValueHashMap.java 2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,115 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2005-2007 Stephane GALLAND.
+ * Copyright (C) 2011 Stephane GALLAND.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.util.ref;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+/**
+ * A <tt>Map</tt> implementation with <em>phantom values</em>. An entry in a
+ * <tt>PhantomValueHashMap</tt> will automatically be removed when its value is no
+ * longer in ordinary use or null.
+ * <p>
+ * This class was inspirated from {@link WeakHashMap} and uses a {@link HashMap}
+ * as its internal data structure.
+ * <p>
+ * This class has a special flag which permits to control the
+ * way how the released references are expurged: {@link #isDeeplyExpurge()},
+ * {@link #setDeeplyExpurge(boolean)}. If this flag is <code>true</code>,
+ * all the released references will be immediately removed from the map even
+ * if they are not enqueued by the virtual machine (see {@link #expurge()}.
+ * If this flag is <code>false</code>,
+ * only the enqueued references will be removed from the map
+ * (see {@link #expurgeQueuedReferences()}.
+ * <p>
+ * If this map does not use a "deep expurge" of the released references,
+ * it could contains <code>null</code> values that corresponds to
+ * values that are released by the garbage collector. If a "deep expurge"
+ * is used, all the values released by the garbage collector will be
+ * removed from the map.
+ * <p>
+ * "Deep expurge" consumes much more time that "No deep expurge". This is the
+ * reason why this feature is not activated by default.
+ * <p>
+ * The "deep expurge" feature was added to fix the uncoherent behavior
+ * of the garbage collector which seems to not always enqueued the
+ * released values (sometimes the queue is empty even if a value was released).
+ *
+ * @param <K> is the type of the keys.
+ * @param <V> is the type of the values.
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 5.8
+ */
+public class PhantomValueHashMap<K,V> extends AbstractSoftValueMap<K,V> {
+
+ /**
+ * Constructs an empty <tt>HashMap</tt> with the specified initial
+ * capacity and load factor.
+ *
+ * @param initialCapacity the initial capacity
+ * @param loadFactor the load factor
+ * @throws IllegalArgumentException if the initial capacity is negative
+ * or the load factor is nonpositive
+ */
+ public PhantomValueHashMap(int initialCapacity, float loadFactor) {
+ super(new HashMap<K,ReferencableValue<K,V>>(initialCapacity, loadFactor));
+ }
+
+ /**
+ * Constructs an empty <tt>HashMap</tt> with the specified initial
+ * capacity and the default load factor (0.75).
+ *
+ * @param initialCapacity the initial capacity.
+ * @throws IllegalArgumentException if the initial capacity is negative.
+ */
+ public PhantomValueHashMap(int initialCapacity) {
+ super(new HashMap<K,ReferencableValue<K,V>>(initialCapacity));
+ }
+
+ /**
+ * Constructs an empty <tt>HashMap</tt> with the default initial capacity
+ * (16) and the default load factor (0.75).
+ */
+ public PhantomValueHashMap() {
+ super(new HashMap<K,ReferencableValue<K,V>>());
+ }
+
+ /**
+ * Constructs a new <tt>HashMap</tt> with the same mappings as the
+ * specified <tt>Map</tt>. The <tt>HashMap</tt> is created with
+ * default load factor (0.75) and an initial capacity sufficient to
+ * hold the mappings in the specified <tt>Map</tt>.
+ *
+ * @param m the map whose mappings are to be placed in this map
+ * @throws NullPointerException if the specified map is null
+ */
+ public PhantomValueHashMap(Map<? extends K, ? extends V> m) {
+ super(new HashMap<K,ReferencableValue<K,V>>());
+ putAll(m);
+ }
+
+}
Property changes on: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/PhantomValueHashMap.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/PhantomValueTreeMap.java
===================================================================
--- trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/PhantomValueTreeMap.java (rev 0)
+++ trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/PhantomValueTreeMap.java 2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,113 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2005-2007 Stephane GALLAND.
+ * Copyright (C) 2011 Stephane GALLAND.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.util.ref;
+
+import java.util.Comparator;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.WeakHashMap;
+
+/**
+ * A <tt>Map</tt> implementation with <em>phantom values</em>. An entry in a
+ * <tt>PhantomValueTreeMap</tt> will automatically be removed when its value is no
+ * longer in ordinary use or null.
+ * <p>
+ * This class was inspirated from {@link WeakHashMap} and uses a {@link TreeMap}
+ * as its internal data structure.
+ * <p>
+ * This class has a special flag which permits to control the
+ * way how the released references are expurged: {@link #isDeeplyExpurge()},
+ * {@link #setDeeplyExpurge(boolean)}. If this flag is <code>true</code>,
+ * all the released references will be immediately removed from the map even
+ * if they are not enqueued by the virtual machine (see {@link #expurge()}.
+ * If this flag is <code>false</code>,
+ * only the enqueued references will be removed from the map
+ * (see {@link #expurgeQueuedReferences()}.
+ * <p>
+ * If this map does not use a "deep expurge" of the released references,
+ * it could contains <code>null</code> values that corresponds to
+ * values that are released by the garbage collector. If a "deep expurge"
+ * is used, all the values released by the garbage collector will be
+ * removed from the map.
+ * <p>
+ * "Deep expurge" consumes much more time that "No deep expurge". This is the
+ * reason why this feature is not activated by default.
+ * <p>
+ * The "deep expurge" feature was added to fix the uncoherent behavior
+ * of the garbage collector which seems to not always enqueued the
+ * released values (sometimes the queue is empty even if a value was released).
+ *
+ * @param <K> is the type of the keys.
+ * @param <V> is the type of the values.
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 5.8
+ */
+public class PhantomValueTreeMap<K,V> extends AbstractSoftValueMap<K,V> {
+
+ /**
+ * Constructs an empty <tt>TreeMap</tt> with the specified comparator.
+ *
+ * @param comparator the comparator that will be used to order this map.
+ * If <tt>null</tt>, the {@linkplain Comparable natural
+ * ordering} of the keys will be used.
+ */
+ public PhantomValueTreeMap(Comparator<? super K> comparator) {
+ super(new TreeMap<K,ReferencableValue<K,V>>(comparator));
+ }
+
+ /**
+ * Constructs an empty <tt>TreeMap</tt>.
+ */
+ public PhantomValueTreeMap() {
+ super(new TreeMap<K,ReferencableValue<K,V>>());
+ }
+
+ /**
+ * Constructs a new <tt>TreeMap</tt> with the same mappings as the
+ * specified <tt>Map</tt>.
+ *
+ * @param m the map whose mappings are to be placed in this map
+ * @throws NullPointerException if the specified map is null
+ */
+ public PhantomValueTreeMap(Map<? extends K, ? extends V> m) {
+ super(new TreeMap<K,ReferencableValue<K,V>>());
+ putAll(m);
+ }
+
+ /**
+ * Constructs a new <tt>TreeMap</tt> with the same mappings and
+ * comparator as the specified <tt>Map</tt>.
+ *
+ * @param m the map whose mappings are to be placed in this map
+ * @throws NullPointerException if the specified map is null
+ */
+ public PhantomValueTreeMap(SortedMap<K, ? extends V> m) {
+ super(new TreeMap<K,ReferencableValue<K,V>>(m.comparator()));
+ putAll(m);
+ }
+
+}
Property changes on: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/PhantomValueTreeMap.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueHashMap.java
===================================================================
--- trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueHashMap.java (rev 0)
+++ trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueHashMap.java 2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,115 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2005-2007 Stephane GALLAND.
+ * Copyright (C) 2011 Stephane GALLAND.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.util.ref;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+/**
+ * A <tt>Map</tt> implementation with <em>soft values</em>. An entry in a
+ * <tt>SoftValueHashMap</tt> will automatically be removed when its value is no
+ * longer in ordinary use or null.
+ * <p>
+ * This class was inspirated from {@link WeakHashMap} and uses a {@link HashMap}
+ * as its internal data structure.
+ * <p>
+ * This class has a special flag which permits to control the
+ * way how the released references are expurged: {@link #isDeeplyExpurge()},
+ * {@link #setDeeplyExpurge(boolean)}. If this flag is <code>true</code>,
+ * all the released references will be immediately removed from the map even
+ * if they are not enqueued by the virtual machine (see {@link #expurge()}.
+ * If this flag is <code>false</code>,
+ * only the enqueued references will be removed from the map
+ * (see {@link #expurgeQueuedReferences()}.
+ * <p>
+ * If this map does not use a "deep expurge" of the released references,
+ * it could contains <code>null</code> values that corresponds to
+ * values that are released by the garbage collector. If a "deep expurge"
+ * is used, all the values released by the garbage collector will be
+ * removed from the map.
+ * <p>
+ * "Deep expurge" consumes much more time that "No deep expurge". This is the
+ * reason why this feature is not activated by default.
+ * <p>
+ * The "deep expurge" feature was added to fix the uncoherent behavior
+ * of the garbage collector which seems to not always enqueued the
+ * released values (sometimes the queue is empty even if a value was released).
+ *
+ * @param <K> is the type of the keys.
+ * @param <V> is the type of the values.
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 5.8
+ */
+public class SoftValueHashMap<K,V> extends AbstractSoftValueMap<K,V> {
+
+ /**
+ * Constructs an empty <tt>HashMap</tt> with the specified initial
+ * capacity and load factor.
+ *
+ * @param initialCapacity the initial capacity
+ * @param loadFactor the load factor
+ * @throws IllegalArgumentException if the initial capacity is negative
+ * or the load factor is nonpositive
+ */
+ public SoftValueHashMap(int initialCapacity, float loadFactor) {
+ super(new HashMap<K,ReferencableValue<K,V>>(initialCapacity, loadFactor));
+ }
+
+ /**
+ * Constructs an empty <tt>HashMap</tt> with the specified initial
+ * capacity and the default load factor (0.75).
+ *
+ * @param initialCapacity the initial capacity.
+ * @throws IllegalArgumentException if the initial capacity is negative.
+ */
+ public SoftValueHashMap(int initialCapacity) {
+ super(new HashMap<K,ReferencableValue<K,V>>(initialCapacity));
+ }
+
+ /**
+ * Constructs an empty <tt>HashMap</tt> with the default initial capacity
+ * (16) and the default load factor (0.75).
+ */
+ public SoftValueHashMap() {
+ super(new HashMap<K,ReferencableValue<K,V>>());
+ }
+
+ /**
+ * Constructs a new <tt>HashMap</tt> with the same mappings as the
+ * specified <tt>Map</tt>. The <tt>HashMap</tt> is created with
+ * default load factor (0.75) and an initial capacity sufficient to
+ * hold the mappings in the specified <tt>Map</tt>.
+ *
+ * @param m the map whose mappings are to be placed in this map
+ * @throws NullPointerException if the specified map is null
+ */
+ public SoftValueHashMap(Map<? extends K, ? extends V> m) {
+ super(new HashMap<K,ReferencableValue<K,V>>());
+ putAll(m);
+ }
+
+}
Property changes on: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueHashMap.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueMap.java
===================================================================
--- trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueMap.java 2011-11-30 09:10:39 UTC (rev 318)
+++ trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueMap.java 2011-12-17 11:43:54 UTC (rev 319)
@@ -1,7 +1,10 @@
/*
- * $Id: SoftValueMap.java,v 1.1 2007-02-20 08:52:37 sgalland Exp $
+ * $Id$
*
- * Copyright (C) 2005-2007 Stephane GALLAND This library is free software; you can redistribute it and/or
+ * Copyright (C) 2005-2007 Stephane GALLAND.
+ * Copyright (C) 2011 Stephane GALLAND.
+ *
+ * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
@@ -19,16 +22,15 @@
package org.arakhne.util.ref;
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.SoftReference;
import java.util.Map;
+import java.util.WeakHashMap;
/**
* A <tt>Map</tt> implementation with <em>soft values</em>. An entry in a
* <tt>SoftValueMap</tt> will automatically be removed when its value is no
* longer in ordinary use or null.
* <p>
- * This class was inspirated from <code>WeakHashMap</code>
+ * This class was inspirated from {@link WeakHashMap}.
* <p>
* This class has a special flag which permits to control the
* way how the released references are expurged: {@link #isDeeplyExpurge()},
@@ -58,8 +60,10 @@
* @version $FullVersion$
* @mavengroupid $GroupId$
* @mavenartifactid $ArtifactId$
+ * @deprecated replace by {@link SoftValueHashMap}
*/
-public class SoftValueMap<K,V> extends AbstractWeakSoftValueMap<K,V> {
+@Deprecated
+public class SoftValueMap<K,V> extends SoftValueHashMap<K,V> {
/**
* Constructs an empty <tt>HashMap</tt> with the specified initial
@@ -106,119 +110,4 @@
super(m);
}
- /** Create a storage object that permits to put the specified
- * elements inside this map.
- *
- * @param k is the key associated to the value
- * @param v is the value
- * @param queue is the reference queue to use
- * @return the new storage object
- */
- @Override
- protected WeakSoftValue<K,V> makeValue(K k, V v, ReferenceQueue<V> queue) {
- return new Value<K,V>(k, v, queue);
- }
-
- /**
- * @author $Author: galland$
- * @version $FullVersion$
- * @mavengroupid $GroupId$
- * @mavenartifactid $ArtifactId$
- */
- private static class Value<K,V> extends SoftReference<V> implements WeakSoftValue<K,V> {
-
- private final K k;
-
- /**
- * @param k is the key.
- * @param v is the value.
- * @param queue is the memory-release listener.
- */
- Value(K k, V v, ReferenceQueue<V> queue) {
- super(maskNull(v), queue);
- this.k = k;
- }
-
- /**
- * {@inheritDoc}
- *
- * @return {@inheritDoc}
- */
- @Override
- public String toString() {
- StringBuffer buffer = new StringBuffer();
- buffer.append('{');
- K key = getKey();
- buffer.append(key==null ? null : key.toString());
- buffer.append('=');
- if (isEnqueued()) {
- buffer.append("Q#"); //$NON-NLS-1$
- }
- else {
- buffer.append("P#"); //$NON-NLS-1$
- }
- V v = getValue();
- buffer.append((v==null ? null : v.toString()));
- buffer.append('}');
- return buffer.toString();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public K getKey() {
- return this.k;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public V getValue() {
- return unmaskNull(get());
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public V setValue(V o) {
- throw new UnsupportedOperationException();
- }
-
- /**
- * {@inheritDoc}
- *
- * @return {@inheritDoc}
- */
- @Override
- public int hashCode() {
- Object val = getValue();
- return (getKey()==null ? 0 : getKey().hashCode()) ^
- (val==null ? 0 : val.hashCode());
- }
-
- /**
- * {@inheritDoc}
- *
- * @param o {@inheritDoc}
- * @return {@inheritDoc}
- */
- @SuppressWarnings("unchecked")
- @Override
- public boolean equals(Object o) {
- if (o instanceof Entry) {
- Entry<K,V> e = (Entry<K,V>)o;
- Object e1val = getValue();
- Object e2val = e.getValue();
- return (getKey()==null ?
- e.getKey()==null : getKey().equals(e.getKey())) &&
- (e1val==null ? e2val==null : e1val.equals(e2val));
- }
- return false;
- }
-
- }
-
}
Added: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueTreeMap.java
===================================================================
--- trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueTreeMap.java (rev 0)
+++ trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueTreeMap.java 2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,113 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2005-2007 Stephane GALLAND.
+ * Copyright (C) 2011 Stephane GALLAND.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.util.ref;
+
+import java.util.Comparator;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.WeakHashMap;
+
+/**
+ * A <tt>Map</tt> implementation with <em>soft values</em>. An entry in a
+ * <tt>SoftValueMap</tt> will automatically be removed when its value is no
+ * longer in ordinary use or null.
+ * <p>
+ * This class was inspirated from {@link WeakHashMap} and uses a {@link TreeMap}
+ * as its internal data structure.
+ * <p>
+ * This class has a special flag which permits to control the
+ * way how the released references are expurged: {@link #isDeeplyExpurge()},
+ * {@link #setDeeplyExpurge(boolean)}. If this flag is <code>true</code>,
+ * all the released references will be immediately removed from the map even
+ * if they are not enqueued by the virtual machine (see {@link #expurge()}.
+ * If this flag is <code>false</code>,
+ * only the enqueued references will be removed from the map
+ * (see {@link #expurgeQueuedReferences()}.
+ * <p>
+ * If this map does not use a "deep expurge" of the released references,
+ * it could contains <code>null</code> values that corresponds to
+ * values that are released by the garbage collector. If a "deep expurge"
+ * is used, all the values released by the garbage collector will be
+ * removed from the map.
+ * <p>
+ * "Deep expurge" consumes much more time that "No deep expurge". This is the
+ * reason why this feature is not activated by default.
+ * <p>
+ * The "deep expurge" feature was added to fix the uncoherent behavior
+ * of the garbage collector which seems to not always enqueued the
+ * released values (sometimes the queue is empty even if a value was released).
+ *
+ * @param <K> is the type of the keys.
+ * @param <V> is the type of the values.
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 5.8
+ */
+public class SoftValueTreeMap<K,V> extends AbstractSoftValueMap<K,V> {
+
+ /**
+ * Constructs an empty <tt>TreeMap</tt> with the specified comparator.
+ *
+ * @param comparator the comparator that will be used to order this map.
+ * If <tt>null</tt>, the {@linkplain Comparable natural
+ * ordering} of the keys will be used.
+ */
+ public SoftValueTreeMap(Comparator<? super K> comparator) {
+ super(new TreeMap<K,ReferencableValue<K,V>>(comparator));
+ }
+
+ /**
+ * Constructs an empty <tt>TreeMap</tt>.
+ */
+ public SoftValueTreeMap() {
+ super(new TreeMap<K,ReferencableValue<K,V>>());
+ }
+
+ /**
+ * Constructs a new <tt>TreeMap</tt> with the same mappings as the
+ * specified <tt>Map</tt>.
+ *
+ * @param m the map whose mappings are to be placed in this map
+ * @throws NullPointerException if the specified map is null
+ */
+ public SoftValueTreeMap(Map<? extends K, ? extends V> m) {
+ super(new TreeMap<K,ReferencableValue<K,V>>());
+ putAll(m);
+ }
+
+ /**
+ * Constructs a new <tt>TreeMap</tt> with the same mappings and
+ * comparator as the specified <tt>Map</tt>.
+ *
+ * @param m the map whose mappings are to be placed in this map
+ * @throws NullPointerException if the specified map is null
+ */
+ public SoftValueTreeMap(SortedMap<K, ? extends V> m) {
+ super(new TreeMap<K,ReferencableValue<K,V>>(m.comparator()));
+ putAll(m);
+ }
+
+}
Property changes on: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/SoftValueTreeMap.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakArrayList.java
===================================================================
--- trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakArrayList.java 2011-11-30 09:10:39 UTC (rev 318)
+++ trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakArrayList.java 2011-12-17 11:43:54 UTC (rev 319)
@@ -1,7 +1,9 @@
/*
- * $Id: WeakArrayList.java,v 1.1 2007-02-20 08:52:37 sgalland Exp $
+ * $Id$
*
- * Copyright (C) 2005-2009 Stephane GALLAND This library is free software; you can redistribute it and/or
+ * Copyright (C) 2005-2009 Stephane GALLAND.
+ *
+ * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
Added: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueHashMap.java
===================================================================
--- trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueHashMap.java (rev 0)
+++ trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueHashMap.java 2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,115 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2005-2007 Stephane GALLAND.
+ * Copyright (C) 2011 Stephane GALLAND.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.util.ref;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+/**
+ * A <tt>Map</tt> implementation with <em>weak values</em>. An entry in a
+ * <tt>WeakValueHashMap</tt> will automatically be removed when its value is no
+ * longer in ordinary use or null.
+ * <p>
+ * This class was inspirated from {@link WeakHashMap} and uses a {@link HashMap}
+ * as its internal data structure.
+ * <p>
+ * This class has a special flag which permits to control the
+ * way how the released references are expurged: {@link #isDeeplyExpurge()},
+ * {@link #setDeeplyExpurge(boolean)}. If this flag is <code>true</code>,
+ * all the released references will be immediately removed from the map even
+ * if they are not enqueued by the virtual machine (see {@link #expurge()}.
+ * If this flag is <code>false</code>,
+ * only the enqueued references will be removed from the map
+ * (see {@link #expurgeQueuedReferences()}.
+ * <p>
+ * If this map does not use a "deep expurge" of the released references,
+ * it could contains <code>null</code> values that corresponds to
+ * values that are released by the garbage collector. If a "deep expurge"
+ * is used, all the values released by the garbage collector will be
+ * removed from the map.
+ * <p>
+ * "Deep expurge" consumes much more time that "No deep expurge". This is the
+ * reason why this feature is not activated by default.
+ * <p>
+ * The "deep expurge" feature was added to fix the uncoherent behavior
+ * of the garbage collector which seems to not always enqueued the
+ * released values (sometimes the queue is empty even if a value was released).
+ *
+ * @param <K> is the type of the keys.
+ * @param <V> is the type of the values.
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 5.8
+ */
+public class WeakValueHashMap<K,V> extends AbstractWeakValueMap<K,V> {
+
+ /**
+ * Constructs an empty <tt>HashMap</tt> with the specified initial
+ * capacity and load factor.
+ *
+ * @param initialCapacity the initial capacity
+ * @param loadFactor the load factor
+ * @throws IllegalArgumentException if the initial capacity is negative
+ * or the load factor is nonpositive
+ */
+ public WeakValueHashMap(int initialCapacity, float loadFactor) {
+ super(new HashMap<K,ReferencableValue<K,V>>(initialCapacity, loadFactor));
+ }
+
+ /**
+ * Constructs an empty <tt>HashMap</tt> with the specified initial
+ * capacity and the default load factor (0.75).
+ *
+ * @param initialCapacity the initial capacity.
+ * @throws IllegalArgumentException if the initial capacity is negative.
+ */
+ public WeakValueHashMap(int initialCapacity) {
+ super(new HashMap<K,ReferencableValue<K,V>>(initialCapacity));
+ }
+
+ /**
+ * Constructs an empty <tt>HashMap</tt> with the default initial capacity
+ * (16) and the default load factor (0.75).
+ */
+ public WeakValueHashMap() {
+ super(new HashMap<K,ReferencableValue<K,V>>());
+ }
+
+ /**
+ * Constructs a new <tt>HashMap</tt> with the same mappings as the
+ * specified <tt>Map</tt>. The <tt>HashMap</tt> is created with
+ * default load factor (0.75) and an initial capacity sufficient to
+ * hold the mappings in the specified <tt>Map</tt>.
+ *
+ * @param m the map whose mappings are to be placed in this map
+ * @throws NullPointerException if the specified map is null
+ */
+ public WeakValueHashMap(Map<? extends K, ? extends V> m) {
+ super(new HashMap<K,ReferencableValue<K,V>>());
+ putAll(m);
+ }
+
+}
Property changes on: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueHashMap.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueMap.java
===================================================================
--- trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueMap.java 2011-11-30 09:10:39 UTC (rev 318)
+++ trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueMap.java 2011-12-17 11:43:54 UTC (rev 319)
@@ -1,7 +1,10 @@
/*
- * $Id: WeakValueMap.java,v 1.1 2007-02-20 08:52:37 sgalland Exp $
+ * $Id$
*
- * Copyright (C) 2005-2007 Stephane GALLAND This library is free software; you can redistribute it and/or
+ * Copyright (C) 2005-2007 Stephane GALLAND.
+ * Copyright (C) 2011 Stephane GALLAND.
+ *
+ * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
@@ -19,8 +22,6 @@
package org.arakhne.util.ref;
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.WeakReference;
import java.util.Map;
import java.util.WeakHashMap;
@@ -59,8 +60,10 @@
* @version $FullVersion$
* @mavengroupid $GroupId$
* @mavenartifactid $ArtifactId$
+ * @deprecated replace by {@link WeakValueHashMap}
*/
-public class WeakValueMap<K,V> extends AbstractWeakSoftValueMap<K,V> {
+@Deprecated
+public class WeakValueMap<K,V> extends WeakValueHashMap<K,V> {
/**
* Constructs an empty <tt>HashMap</tt> with the specified initial
@@ -106,120 +109,5 @@
public WeakValueMap(Map<? extends K, ? extends V> m) {
super(m);
}
-
- /** Create a storage object that permits to put the specified
- * elements inside this map.
- *
- * @param k is the key associated to the value
- * @param v is the value
- * @param queue is the reference queue to use
- * @return the new storage object
- */
- @Override
- protected WeakSoftValue<K,V> makeValue(K k, V v, ReferenceQueue<V> queue) {
- return new Value<K,V>(k, v, queue);
- }
-
- /**
- * @author $Author: galland$
- * @version $FullVersion$
- * @mavengroupid $GroupId$
- * @mavenartifactid $ArtifactId$
- */
- private static class Value<K,V> extends WeakReference<V> implements WeakSoftValue<K,V> {
-
- private final K k;
-
- /**
- * @param k is the key.
- * @param v is the value.
- * @param queue is the memory-release listener.
- */
- Value(K k, V v, ReferenceQueue<V> queue) {
- super(maskNull(v), queue);
- this.k = k;
- }
-
- /**
- * {@inheritDoc}
- *
- * @return {@inheritDoc}
- */
- @Override
- public String toString() {
- StringBuffer buffer = new StringBuffer();
- buffer.append('{');
- K key = getKey();
- buffer.append(key==null ? null : key.toString());
- buffer.append('=');
- if (isEnqueued()) {
- buffer.append("Q#"); //$NON-NLS-1$
- }
- else {
- buffer.append("P#"); //$NON-NLS-1$
- }
- V v = getValue();
- buffer.append((v==null ? null : v.toString()));
- buffer.append('}');
- return buffer.toString();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public K getKey() {
- return this.k;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public V getValue() {
- return unmaskNull(get());
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public V setValue(V o) {
- throw new UnsupportedOperationException();
- }
-
- /**
- * {@inheritDoc}
- *
- * @return {@inheritDoc}
- */
- @Override
- public int hashCode() {
- Object val = getValue();
- return (getKey()==null ? 0 : getKey().hashCode()) ^
- (val==null ? 0 : val.hashCode());
- }
-
- /**
- * {@inheritDoc}
- *
- * @param o {@inheritDoc}
- * @return {@inheritDoc}
- */
- @SuppressWarnings("unchecked")
- @Override
- public boolean equals(Object o) {
- if (o instanceof Entry) {
- Entry<K,V> e = (Entry<K,V>)o;
- Object e1val = getValue();
- Object e2val = e.getValue();
- return (getKey()==null ?
- e.getKey()==null : getKey().equals(e.getKey())) &&
- (e1val==null ? e2val==null : e1val.equals(e2val));
- }
- return false;
- }
-
- }
}
Added: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueTreeMap.java
===================================================================
--- trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueTreeMap.java (rev 0)
+++ trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueTreeMap.java 2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,113 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2005-2007 Stephane GALLAND.
+ * Copyright (C) 2011 Stephane GALLAND.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.util.ref;
+
+import java.util.Comparator;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.WeakHashMap;
+
+/**
+ * A <tt>Map</tt> implementation with <em>weak values</em>. An entry in a
+ * <tt>WeakValueTreeMap</tt> will automatically be removed when its value is no
+ * longer in ordinary use or null.
+ * <p>
+ * This class was inspirated from {@link WeakHashMap} and uses a {@link TreeMap}
+ * as its internal data structure.
+ * <p>
+ * This class has a special flag which permits to control the
+ * way how the released references are expurged: {@link #isDeeplyExpurge()},
+ * {@link #setDeeplyExpurge(boolean)}. If this flag is <code>true</code>,
+ * all the released references will be immediately removed from the map even
+ * if they are not enqueued by the virtual machine (see {@link #expurge()}.
+ * If this flag is <code>false</code>,
+ * only the enqueued references will be removed from the map
+ * (see {@link #expurgeQueuedReferences()}.
+ * <p>
+ * If this map does not use a "deep expurge" of the released references,
+ * it could contains <code>null</code> values that corresponds to
+ * values that are released by the garbage collector. If a "deep expurge"
+ * is used, all the values released by the garbage collector will be
+ * removed from the map.
+ * <p>
+ * "Deep expurge" consumes much more time that "No deep expurge". This is the
+ * reason why this feature is not activated by default.
+ * <p>
+ * The "deep expurge" feature was added to fix the uncoherent behavior
+ * of the garbage collector which seems to not always enqueued the
+ * released values (sometimes the queue is empty even if a value was released).
+ *
+ * @param <K> is the type of the keys.
+ * @param <V> is the type of the values.
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ * @since 5.8
+ */
+public class WeakValueTreeMap<K,V> extends AbstractWeakValueMap<K,V> {
+
+ /**
+ * Constructs an empty <tt>TreeMap</tt> with the specified comparator.
+ *
+ * @param comparator the comparator that will be used to order this map.
+ * If <tt>null</tt>, the {@linkplain Comparable natural
+ * ordering} of the keys will be used.
+ */
+ public WeakValueTreeMap(Comparator<? super K> comparator) {
+ super(new TreeMap<K,ReferencableValue<K,V>>(comparator));
+ }
+
+ /**
+ * Constructs an empty <tt>TreeMap</tt>.
+ */
+ public WeakValueTreeMap() {
+ super(new TreeMap<K,ReferencableValue<K,V>>());
+ }
+
+ /**
+ * Constructs a new <tt>TreeMap</tt> with the same mappings as the
+ * specified <tt>Map</tt>.
+ *
+ * @param m the map whose mappings are to be placed in this map
+ * @throws NullPointerException if the specified map is null
+ */
+ public WeakValueTreeMap(Map<? extends K, ? extends V> m) {
+ super(new TreeMap<K,ReferencableValue<K,V>>());
+ putAll(m);
+ }
+
+ /**
+ * Constructs a new <tt>TreeMap</tt> with the same mappings and
+ * comparator as the specified <tt>Map</tt>.
+ *
+ * @param m the map whose mappings are to be placed in this map
+ * @throws NullPointerException if the specified map is null
+ */
+ public WeakValueTreeMap(SortedMap<K, ? extends V> m) {
+ super(new TreeMap<K,ReferencableValue<K,V>>(m.comparator()));
+ putAll(m);
+ }
+
+}
Property changes on: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/WeakValueTreeMap.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractCollectionTestCase.java
===================================================================
--- trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractCollectionTestCase.java (rev 0)
+++ trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractCollectionTestCase.java 2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,280 @@
+/* $Id$
+ *
+ * Copyright (c) 2006-10, Multiagent Team, Laboratoire Systemes et Transport,
+ * Universite de Technologie de Belfort-Montbeliard.
+ * Copyright (C) 2011 Stephane GALLAND.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.util.ref;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Random;
+
+/**
+ * @param <OBJ>
+ * @author $Author: sgalland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public abstract class AbstractCollectionTestCase<OBJ> extends AbstractTestCase {
+
+ private final Random RANDOM = new Random();
+
+ /**
+ */
+ protected ArrayList<OBJ> reference;
+ /**
+ */
+ protected ArrayList<OBJ> unreference;
+ /**
+ */
+ protected Collection<OBJ> collection;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ int count = this.RANDOM.nextInt(400)+100;
+ this.reference = new ArrayList<OBJ>(count);
+ for(int idx=0; idx<count; idx++) {
+ this.reference.add(createContentInstance());
+ }
+
+ count = this.RANDOM.nextInt(5)+5;
+ this.unreference = new ArrayList<OBJ>(count);
+ for(int idx=0; idx<count; idx++) {
+ this.unreference.add(createContentInstance());
+ }
+
+ this.collection = createCollection();
+ }
+
+ /**
+ * @return an instance
+ */
+ protected abstract OBJ createContentInstance();
+
+ /**
+ * @return a collection
+ */
+ protected abstract Collection<OBJ> createCollection();
+
+ /**
+ * @param toAdd
+ */
+ protected abstract void initCollectionWith(Collection<OBJ> toAdd);
+ /**
+ * @param toAdd
+ */
+ protected abstract void fillCollectionWith(Collection<OBJ> toAdd);
+
+ @Override
+ public void tearDown() throws Exception {
+ this.collection = null;
+ this.unreference = null;
+ this.reference = null;
+ super.tearDown();
+ }
+
+ /**
+ */
+ public void testAddAll() {
+ assertTrue(this.collection.addAll(this.reference));
+ assertEpsilonEquals(this.reference, this.collection);
+ }
+
+ /**
+ */
+ public void testSize() {
+ assertEquals(0, this.collection.size());
+ initCollectionWith(this.reference);
+ assertEquals(this.reference.size(), this.collection.size());
+ }
+
+ /**
+ */
+ public void testIsEmpty() {
+ assertTrue(this.collection.isEmpty());
+ initCollectionWith(this.reference);
+ assertFalse(this.collection.isEmpty());
+ }
+
+ /**
+ */
+ public void testContains() {
+ initCollectionWith(this.reference);
+
+ int count = this.RANDOM.nextInt(50)+50;
+ for(int idx=0; idx<count; idx++) {
+ int index = this.RANDOM.nextInt(this.reference.size());
+
+ assertTrue(this.collection.contains(this.reference.get(index)));
+ }
+
+ count = this.RANDOM.nextInt(5)+5;
+ int index;
+ OBJ elt;
+ for(int idx=0; idx<count; idx++) {
+ index = this.RANDOM.nextInt(this.unreference.size());
+
+ elt = this.unreference.get(index);
+ assertFalse(this.collection.contains(elt));
+ }
+ }
+
+ /**
+ */
+ public void testIterator() {
+ initCollectionWith(this.reference);
+
+ // Test the content
+ OBJ s;
+ Iterator<OBJ> iter = this.collection.iterator();
+ boolean asOne = false;
+ while (iter.hasNext()) {
+ s = iter.next();
+ asOne = true;
+ assertTrue(this.reference.remove(s));
+ }
+
+ assertTrue(asOne);
+ assertTrue(this.reference.isEmpty());
+ }
+
+ /**
+ */
+ public void testContainsAll() {
+ initCollectionWith(this.reference);
+
+ // Test the content
+ assertTrue(this.reference.containsAll(this.collection));
+ assertTrue(this.collection.containsAll(this.reference));
+ }
+
+ /**
+ */
+ public void testToArray() {
+ initCollectionWith(this.reference);
+
+ // Test the content
+ assertEpsilonEquals(this.reference.toArray(),this.collection.toArray());
+ }
+
+ /**
+ */
+ public void testToArrayArray() {
+ initCollectionWith(this.reference);
+
+ // Test the content if the array has the right size
+ Object[] tab = new Object[this.reference.size()];
+ assertEpsilonEquals(this.reference.toArray(),this.collection.toArray(tab));
+ assertEpsilonEquals(this.reference.toArray(),tab);
+
+ // Test the content if the array is too small
+ tab = new Object[this.reference.size()/2];
+ Object[] tab2 = this.collection.toArray(tab);
+ assertEpsilonEquals(this.reference.toArray(),tab2);
+ assertNotEpsilonEquals(tab2,tab);
+ }
+
+ /**
+ */
+ public void testClear() {
+ initCollectionWith(this.reference);
+
+ // Remove elements
+ this.collection.clear();
+
+ // Collects the objects
+ assertTrue(this.collection.isEmpty());
+ }
+
+ /**
+ */
+ public void testAddE() {
+ initCollectionWith(this.reference);
+
+ String msg;
+ int testCount = this.RANDOM.nextInt(5)+1;
+
+ for(int i=0; i<testCount; i++) {
+ msg = "test "+(i+1)+"/"+testCount; //$NON-NLS-1$ //$NON-NLS-2$
+
+ // Add an element
+ OBJ newElement = createContentInstance();
+ this.reference.add(newElement);
+ assertTrue(msg,this.collection.add(newElement));
+ assertEquals(msg,this.reference.size(), this.collection.size());
+ assertTrue(msg,this.collection.contains(newElement));
+ assertEpsilonEquals(msg,this.reference.toArray(),this.collection.toArray());
+ }
+ }
+
+ /**
+ */
+ public void testRemoveObject() {
+ String msg;
+ int testCount = this.RANDOM.nextInt(5)+5;
+ int removalIndex;
+
+ for(int i=0; i<testCount; i++) {
+ msg = "test "+(i+1)+"/"+testCount; //$NON-NLS-1$ //$NON-NLS-2$
+
+ removalIndex = this.RANDOM.nextInt(this.reference.size());
+
+ initCollectionWith(this.reference);
+
+ OBJ toRemove = this.reference.get(removalIndex);
+
+ // Remove elements
+ assertTrue(msg,this.collection.remove(toRemove));
+
+ assertFalse(msg,this.collection.contains(toRemove));
+ this.reference.remove(toRemove);
+ assertEpsilonEquals(msg,this.reference.toArray(),this.collection.toArray());
+ }
+ }
+
+ /**
+ */
+ public void testRemoveAll() {
+ initCollectionWith(this.reference);
+
+ fillCollectionWith(this.unreference);
+ assertEquals(this.reference.size()+this.unreference.size(), this.collection.size());
+
+ assertTrue(this.collection.removeAll(this.reference));
+ assertEquals(this.unreference.size(), this.collection.size());
+ assertEpsilonEquals(this.unreference,this.collection);
+ }
+
+ /**
+ */
+ public void testRetainAll() {
+ initCollectionWith(this.reference);
+
+ fillCollectionWith(this.unreference);
+ assertEquals(this.reference.size()+this.unreference.size(), this.collection.size());
+
+ assertTrue(this.collection.retainAll(this.reference));
+ assertEquals(this.reference.size(), this.collection.size());
+ assertEpsilonEquals(this.reference,this.collection);
+ }
+
+}
Property changes on: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractCollectionTestCase.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractMapTestCase.java
===================================================================
--- trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractMapTestCase.java (rev 0)
+++ trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractMapTestCase.java 2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,335 @@
+/* $Id$
+ *
+ * Copyright (c) 2006-10, Multiagent Team, Laboratoire Systemes et Transport,
+ * Universite de Technologie de Belfort-Montbeliard.
+ * Copyright (C) 2011 Stephane GALLAND.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.util.ref;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Random;
+import java.util.Set;
+
+/**
+ * @param <K>
+ * @param <V>
+ * @author $Author: sgalland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public abstract class AbstractMapTestCase<K,V> extends AbstractTestCase {
+
+ private final Random RANDOM = new Random();
+
+ /**
+ */
+ protected HashMap<K,V> reference;
+ /**
+ */
+ protected HashMap<K,V> unreference;
+ /**
+ */
+ protected Map<K,V> map;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ int count = this.RANDOM.nextInt(400)+100;
+ this.reference = new HashMap<K,V>(count);
+ for(int idx=0; idx<count; idx++) {
+ this.reference.put(createKeyInstance("in/"), createValueInstance("in/")); //$NON-NLS-1$//$NON-NLS-2$
+ }
+
+ count = this.RANDOM.nextInt(5)+5;
+ this.unreference = new HashMap<K,V>(count);
+ for(int idx=0; idx<count; idx++) {
+ this.unreference.put(createKeyInstance("out/"), createValueInstance("out/")); //$NON-NLS-1$//$NON-NLS-2$
+ }
+
+ this.map = createMap();
+ }
+
+ /**
+ * @param prefix
+ * @return an instance
+ */
+ protected abstract K createKeyInstance(String prefix);
+
+ /**
+ * @param prefix
+ * @return an instance
+ */
+ protected abstract V createValueInstance(String prefix);
+
+ /**
+ * @return a map
+ */
+ protected abstract Map<K,V> createMap();
+
+ /**
+ * @param toAdd
+ */
+ protected void initMapWith(Map<K,V> toAdd) {
+ this.map.clear();
+ this.map.putAll(toAdd);
+ }
+
+ /**
+ * @param toAdd
+ */
+ protected void fillMapWith(Map<K,V> toAdd) {
+ this.map.putAll(toAdd);
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ this.map = null;
+ this.unreference = null;
+ this.reference = null;
+ super.tearDown();
+ }
+
+ private static <KK> KK key(Map<KK,?> map, int index) {
+ int i = 0;
+ for(KK key : map.keySet()) {
+ if (i==index) return key;
+ ++i;
+ }
+ throw new IndexOutOfBoundsException();
+ }
+
+ private static <VV> VV value(Map<?,VV> map, int index) {
+ int i = 0;
+ for(VV value : map.values()) {
+ if (i==index) return value;
+ ++i;
+ }
+ throw new IndexOutOfBoundsException();
+ }
+
+ /**
+ */
+ public void testSize() {
+ assertEquals(0, this.map.size());
+ initMapWith(this.reference);
+ assertEquals(this.reference.size(), this.map.size());
+ }
+
+ /**
+ */
+ public void testIsEmpty() {
+ assertTrue(this.map.isEmpty());
+ initMapWith(this.reference);
+ assertFalse(this.map.isEmpty());
+ }
+
+ /**
+ */
+ public void testEntrySet() {
+ Set<Entry<K,V>> entries;
+
+ entries = this.map.entrySet();
+ assertTrue(entries.isEmpty());
+
+ initMapWith(this.reference);
+
+ entries = this.map.entrySet();
+ assertFalse(entries.isEmpty());
+ assertEpsilonEquals(this.reference.entrySet(), entries);
+ }
+
+ /**
+ */
+ public void testContainsKey() {
+ initMapWith(this.reference);
+ int count = this.RANDOM.nextInt(50)+50;
+ for(int idx=0; idx<count; idx++) {
+ int index = this.RANDOM.nextInt(this.reference.size());
+ assertTrue("#"+idx, this.map.containsKey(key(this.reference,index))); //$NON-NLS-1$
+ }
+ count = this.RANDOM.nextInt(5)+5;
+ int index;
+ K elt;
+ for(int idx=0; idx<count; idx++) {
+ index = this.RANDOM.nextInt(this.unreference.size());
+ elt = key(this.unreference, index);
+ assertFalse("#"+idx, this.map.containsKey(elt)); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ */
+ public void testContainsValue() {
+ initMapWith(this.reference);
+ int count = this.RANDOM.nextInt(50)+50;
+ for(int idx=0; idx<count; idx++) {
+ int index = this.RANDOM.nextInt(this.reference.size());
+ assertTrue("#"+idx, this.map.containsValue(value(this.reference,index))); //$NON-NLS-1$
+ }
+ count = this.RANDOM.nextInt(5)+5;
+ int index;
+ V elt;
+ for(int idx=0; idx<count; idx++) {
+ index = this.RANDOM.nextInt(this.unreference.size());
+ elt = value(this.unreference, index);
+ assertFalse("#"+idx, this.map.containsValue(elt)); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ */
+ public void testGet() {
+ int count = this.RANDOM.nextInt(50)+50;
+ for(int idx=0; idx<count; idx++) {
+ int index = this.RANDOM.nextInt(this.reference.size());
+ assertNull("#"+idx, this.map.get(key(this.reference,index))); //$NON-NLS-1$
+ }
+ count = this.RANDOM.nextInt(5)+5;
+ int index;
+ K elt;
+ for(int idx=0; idx<count; idx++) {
+ index = this.RANDOM.nextInt(this.unreference.size());
+ elt = key(this.unreference, index);
+ assertNull("#"+idx, this.map.get(elt)); //$NON-NLS-1$
+ }
+
+ initMapWith(this.reference);
+
+ count = this.RANDOM.nextInt(50)+50;
+ for(int idx=0; idx<count; idx++) {
+ index = this.RANDOM.nextInt(this.reference.size());
+ elt = key(this.reference, index);
+ assertEquals("#"+idx, this.reference.get(elt), this.map.get(elt)); //$NON-NLS-1$
+ }
+ count = this.RANDOM.nextInt(5)+5;
+ for(int idx=0; idx<count; idx++) {
+ index = this.RANDOM.nextInt(this.unreference.size());
+ elt = key(this.unreference, index);
+ assertNull("#"+idx, this.map.get(elt)); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ */
+ public void testPut() {
+ int count = this.RANDOM.nextInt(50)+50;
+ for(int idx=0; idx<count; idx++) {
+ K key = createKeyInstance("tmp/"); //$NON-NLS-1$
+ V value = createValueInstance("tmp/"); //$NON-NLS-1$
+ this.map.put(key, value);
+ assertSame(value, this.map.get(key));
+ }
+ }
+
+ /**
+ */
+ public void testRemove() {
+ initMapWith(this.reference);
+
+ int index, count;
+ K elt;
+
+ count = this.RANDOM.nextInt(50)+50;
+ for(int idx=0; !this.reference.isEmpty() && idx<count; idx++) {
+ index = this.RANDOM.nextInt(this.reference.size());
+ elt = key(this.reference, index);
+ assertSame("#"+idx, this.reference.get(elt), this.map.remove(elt)); //$NON-NLS-1$
+ this.reference.remove(elt);
+ assertNull("#"+idx, this.map.get(elt)); //$NON-NLS-1$
+ }
+ count = this.RANDOM.nextInt(5)+5;
+ for(int idx=0; idx<count; idx++) {
+ index = this.RANDOM.nextInt(this.unreference.size());
+ elt = key(this.unreference, index);
+ assertNull("#"+idx, this.map.remove(elt)); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ */
+ public void testPutAll() {
+ int index, count;
+ K elt;
+
+ this.map.putAll(this.reference);
+
+ count = this.RANDOM.nextInt(50)+50;
+ for(int idx=0; idx<count; idx++) {
+ index = this.RANDOM.nextInt(this.reference.size());
+ elt = key(this.reference, index);
+ assertEquals("#"+idx, this.reference.get(elt), this.map.get(elt)); //$NON-NLS-1$
+ }
+ count = this.RANDOM.nextInt(5)+5;
+ for(int idx=0; idx<count; idx++) {
+ index = this.RANDOM.nextInt(this.unreference.size());
+ elt = key(this.unreference, index);
+ assertNull("#"+idx, this.map.get(elt)); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ */
+ public void testClear() {
+ assertEquals(0, this.map.size());
+ assertTrue(this.map.isEmpty());
+
+ initMapWith(this.reference);
+ assertEquals(this.reference.size(), this.map.size());
+ assertFalse(this.map.isEmpty());
+
+ this.map.clear();
+
+ assertEquals(0, this.map.size());
+ assertTrue(this.map.isEmpty());
+ }
+
+ /**
+ */
+ public void testKeySet() {
+ Set<K> keys;
+
+ keys = this.map.keySet();
+ assertTrue(keys.isEmpty());
+
+ initMapWith(this.reference);
+
+ keys = this.map.keySet();
+ assertFalse(keys.isEmpty());
+ assertEpsilonEquals(this.reference.keySet(), keys);
+ }
+
+ /**
+ */
+ public void testValues() {
+ Collection<V> values;
+
+ values = this.map.values();
+ assertTrue(values.isEmpty());
+
+ initMapWith(this.reference);
+
+ values = this.map.values();
+ assertFalse(values.isEmpty());
+ assertEpsilonEquals(this.reference.values(), values);
+ }
+
+}
Property changes on: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractMapTestCase.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractReferencableValueMapTestCase.java
===================================================================
--- trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractReferencableValueMapTestCase.java (rev 0)
+++ trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractReferencableValueMapTestCase.java 2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,48 @@
+/* $Id$
+ *
+ * Copyright (C) 2011 Stephane GALLAND.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.util.ref;
+
+import java.util.UUID;
+
+/**
+ * @author $Author: sgalland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public abstract class AbstractReferencableValueMapTestCase extends AbstractMapTestCase<String,String> {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected String createKeyInstance(String prefix) {
+ return prefix+UUID.randomUUID().toString();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected String createValueInstance(String prefix) {
+ return prefix+UUID.randomUUID().toString();
+ }
+
+}
Property changes on: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractReferencableValueMapTestCase.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Copied: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractTestCase.java (from rev 312, trunk/arakhneRefs/src/test/java/org/arakhne/junit/AbstractTestCase.java)
===================================================================
--- trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractTestCase.java (rev 0)
+++ trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractTestCase.java 2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,852 @@
+/* $Id$
+ *
+ * Copyright (C) 2007-09 Stephane GALLAND.
+ * Copyright (C) 2011 Stephane GALLAND.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.util.ref;
+
+import java.awt.geom.Point2D;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.Map.Entry;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+
+/** Test case with utility functions.
+ *
+ * @author $Author: galland$
+ * @version $FullVersion$
+ * @mavengroupid org.arakhne.afc
+ * @mavenartifactid arakhneRefs
+ */
+public abstract class AbstractTestCase extends TestCase {
+
+ private static String arrayToString(Object o) {
+ if (o==null) return null;
+ if (o instanceof boolean[])
+ return Arrays.toString((boolean[])o);
+ if (o instanceof byte[])
+ return Arrays.toString((byte[])o);
+ if (o instanceof char[])
+ return Arrays.toString((char[])o);
+ if (o instanceof short[])
+ return Arrays.toString((short[])o);
+ if (o instanceof int[])
+ return Arrays.toString((int[])o);
+ if (o instanceof long[])
+ return Arrays.toString((long[])o);
+ if (o instanceof float[])
+ return Arrays.toString((float[])o);
+ if (o instanceof double[])
+ return Arrays.toString((double[])o);
+ if (o instanceof Object[])
+ return Arrays.toString((Object[])o);
+ return o.toString();
+ }
+
+ /** Replies if the given elements is in the array.
+ * <p>
+ * This function is based on {@link Object#equals(java.lang.Object)}.
+ */
+ private static <T> boolean arrayContainsAll(T[] elts, T[] array) {
+ boolean found;
+ for (T elt : elts) {
+ found = false;
+ for (T t : array) {
+ if ((t==elt)||
+ ((t!=null)&&(t.equals(elt)))) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) return false;
+ }
+ return true;
+ }
+
+ /**
+ * Format a failure message for invalid value.
+ *
+ * @param message is the message to reply.
+ * @param expected is the expected object.
+ * @param actual is the actual value of the object.
+ * @return the message
+ */
+ protected String formatFailMessage(String message, Object expected, Object actual) {
+ StringBuffer formatted = new StringBuffer();
+ if (message!=null) {
+ formatted.append(message);
+ formatted.append(' ');
+ }
+ formatted.append("expected:<"); //$NON-NLS-1$
+ formatted.append(arrayToString(expected));
+ formatted.append("> but was:<"); //$NON-NLS-1$
+ formatted.append(arrayToString(actual));
+ formatted.append(">"); //$NON-NLS-1$
+ return formatted.toString();
+ }
+
+ /**
+ * Format a failure message for invalid value.
+ *
+ * @param message is the first part of the message (optional).
+ * @param msg is the second part of the message (mandatory).
+ * @param actual is the actual value of the object.
+ * @return the message
+ */
+ protected String formatFailMessage(String message, String msg, Object actual) {
+ StringBuffer formatted = new StringBuffer();
+ if (message!=null) {
+ formatted.append(message);
+ formatted.append(' ');
+ }
+ formatted.append(msg);
+ formatted.append(" but was:<"); //$NON-NLS-1$
+ formatted.append(arrayToString(actual));
+ formatted.append(">"); //$NON-NLS-1$
+ return formatted.toString();
+ }
+
+ /**
+ * Format a failure message for not-expected values.
+ *
+ * @param message is the message to reply.
+ * @param notexpected is the not-expected object.
+ * @return the message
+ */
+ protected String formatFailNegMessage(String message, Object notexpected) {
+ StringBuffer formatted = new StringBuffer();
+ if (message!=null) {
+ formatted.append(message);
+ formatted.append(' ');
+ }
+ formatted.append("not expected:<"); //$NON-NLS-1$
+ formatted.append(arrayToString(notexpected));
+ formatted.append("> but the same"); //$NON-NLS-1$
+ return formatted.toString();
+ }
+
+ /** Asserts that two objects are not equal. If they are
+ * an AssertionFailedError is thrown with the given message.
+ *
+ * @param message is the error message to put inside the assertion.
+ * @param notexpected is the value which is not expected by the unit test.
+ * @param actual is the actual value of the object in the unit test.
+ */
+ protected void assertNotEquals(String message, Object notexpected, Object actual) {
+ if ((notexpected!=actual)&&
+ ((notexpected==null)
+ ||
+ (!notexpected.equals(actual)))) return;
+ fail(formatFailNegMessage(message, notexpected));
+ }
+
+ /** Asserts that two objects are not equal. If they are
+ * an AssertionFailedError is thrown with the given message.
+ *
+ * @param notexpected is the value which is not expected by the unit test.
+ * @param actual is the actual value of the object in the unit test.
+ */
+ protected void assertNotEquals(Object notexpected, Object actual) {
+ assertNotEquals(null, notexpected, actual);
+ }
+
+ /** Asserts that the actuel object is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown with the given message.
+ *
+ * @param message is the error message to put inside the assertion.
+ * @param expectedObjects are the set of expected values during the unit test.
+ * @param actual is the actual value of the object in the unit test.
+ */
+ protected void assertEquals(String message, Object[] expectedObjects, Object actual) {
+ if ((expectedObjects!=null)&&(expectedObjects.length>0)) {
+ for (Object object : expectedObjects) {
+ if ((object==null)&&(actual==null)) return;
+ if ((object!=null)&&(object.equals(actual))) return;
+ }
+ }
+ fail(formatFailMessage(message, expectedObjects, actual));
+ }
+
+ /** Asserts that the actuel object is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param expectedObjects are the set of expected values during the unit test.
+ * @param actual is the actual value of the object in the unit test.
+ */
+ protected void assertEquals(Object[] expectedObjects, Object actual) {
+ assertEquals(null, expectedObjects, actual);
+ }
+
+ /** Asserts that the actuel object is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown with the given message.
+ *
+ * @param <T> is the type of the array.
+ * @param message is the error message to put inside the assertion.
+ * @param expectedObjects are the set of expected values during the unit test.
+ * @param actual is the actual value of the objects in the unit test.
+ */
+ protected <T> void assertEquals(String message, T[] expectedObjects, T[] actual) {
+ if (expectedObjects==actual) return;
+ if ((expectedObjects!=null)&&(actual!=null)&&
+ (expectedObjects.length==actual.length)) {
+ boolean ok = true;
+ for(int i=0; i<expectedObjects.length; i++) {
+ if ((expectedObjects[i]!=null)||(actual[i]!=null)) {
+ if ((expectedObjects[i]==null)||(!expectedObjects[i].equals(actual[i]))) {
+ ok = false;
+ break;
+ }
+ }
+ }
+ if (ok) return;
+ }
+ fail(formatFailMessage(message, expectedObjects, actual));
+ }
+
+ /** Asserts that the actuel object is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <T> is the type of the array.
+ * @param expectedObjects are the set of expected values during the unit test.
+ * @param actual is the actual value of the objects in the unit test.
+ */
+ protected <T> void assertEquals(T[] expectedObjects, T[] actual) {
+ assertEquals(null, expectedObjects, actual);
+ }
+
+ /** Asserts that the actuel object is not equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown with the given message.
+ *
+ * @param <T> is the type of the array.
+ * @param message is the error message to put inside the assertion.
+ * @param expectedObjects are the set of expected values during the unit test.
+ * @param actual is the actual value of the objects in the unit test.
+ */
+ protected <T> void assertNotEquals(String message, T[] expectedObjects, T[] actual) {
+ if (expectedObjects!=actual) {
+ if ((expectedObjects!=null)&&(actual!=null)) {
+ if (expectedObjects.length!=actual.length) return;
+ boolean ok = true;
+ for(int i=0; i<expectedObjects.length; i++) {
+ if ((expectedObjects[i]!=null)||(actual[i]!=null)) {
+ if ((expectedObjects[i]==null)||(!expectedObjects[i].equals(actual[i]))) {
+ ok = false;
+ break;
+ }
+ }
+ }
+ if (!ok) return;
+ }
+ else return;
+ }
+ fail(formatFailMessage(message, expectedObjects, actual));
+ }
+
+ /** Asserts that the actuel object is not equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <T> is the type of the array.
+ * @param expectedObjects are the set of expected values during the unit test.
+ * @param actual is the actual value of the objects in the unit test.
+ */
+ protected <T> void assertNotEquals(T[] expectedObjects, T[] actual) {
+ assertNotEquals(null, expectedObjects, actual);
+ }
+
+ /** Asserts that the actuel object is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ * This assertion function tests the types of its parameters to call the best
+ * {@code assertEquals} function.
+ *
+ * @param expected is the expected value during the unit test.
+ * @param actual is the actual value of the object during the unit test.
+ * @see #assertEquals(Object, Object)
+ * @see #assertEquals(Object[], Object)
+ * @see #assertEquals(Object[], Object[])
+ */
+ protected void assertEqualsGeneric(Object expected, Object actual) {
+ assertEqualsGeneric(null, expected, actual);
+ }
+
+ /** Asserts that the actuel object is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ * This assertion function tests the types of its parameters to call the best
+ * {@code assertEquals} function.
+ *
+ * @param message is the error message to put inside the assertion.
+ * @param expected is the expected value during the unit test.
+ * @param actual is the actual value of the object during the unit test.
+ * @see #assertEquals(Object, Object)
+ * @see #assertEquals(Object[], Object)
+ * @see #assertEquals(Object[], Object[])
+ */
+ protected void assertEqualsGeneric(String message, Object expected, Object actual) {
+ if ((expected!=null)&&(actual!=null)&&(expected.getClass().isArray())) {
+ if (actual.getClass().isArray())
+ assertEquals(message, (Object[])expected, (Object[])actual);
+ else
+ assertEquals(message, (Object[])expected, actual);
+ }
+ else assertEquals(message, expected, actual);
+ }
+
+ /** Asserts that the actuel similar is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <T> is the type of the values
+ * @param expectedObjects are the expected values during the unit test.
+ * @param actual are the actual values of the objects during the unit test.
+ */
+ protected <T> void assertSimilars(T[] expectedObjects, T[] actual) {
+ assertSimilars(null, expectedObjects, actual);
+ }
+
+ /** Asserts that the actuel similar is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <T> is the type of the values
+ * @param message is the error message to put inside the assertion.
+ * @param expectedObjects are the expected values during the unit test.
+ * @param actual are the actual values of the objects during the unit test.
+ */
+ protected <T> void assertSimilars(String message, T[] expectedObjects, T[] actual) {
+ if (expectedObjects==actual) return;
+ if ((arrayContainsAll(expectedObjects, actual))&&(arrayContainsAll(actual, expectedObjects)))
+ return;
+ fail(formatFailMessage(message, expectedObjects, actual));
+ }
+
+ /** Asserts that the actuel similar is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <T> is the type of the values
+ * @param expectedObjects are the expected values during the unit test.
+ * @param actual are the actual values of the objects during the unit test.
+ */
+ protected <T> void assertSimilars(Collection<T> expectedObjects, Collection<T> actual) {
+ assertSimilars(null, expectedObjects, actual);
+ }
+
+ /** Asserts that the actuel similar is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <T> is the type of the values
+ * @param message is the error message to put inside the assertion.
+ * @param expectedObjects are the expected values during the unit test.
+ * @param actual are the actual values of the objects during the unit test.
+ */
+ protected <T> void assertSimilars(String message, Collection<T> expectedObjects, Collection<T> actual) {
+ if (expectedObjects==actual) return;
+ if (similars(expectedObjects,actual)) return;
+ fail(formatFailMessage(message, expectedObjects, actual));
+ }
+
+ private <T> boolean similars(Collection<T> c1, Collection<T> c2) {
+ ArrayList<T> a = new ArrayList<T>();
+ a.addAll(c2);
+ for(T elt : c1) {
+ if (!a.remove(elt)) {
+ return false;
+ }
+ }
+ return a.isEmpty();
+ }
+
+ /** Asserts that the actuel similar is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <T> is the type of the values
+ * @param expectedObjects are the expected values during the unit test.
+ * @param actual are the actual values of the objects during the unit test.
+ */
+ protected <T> void assertEquals(List<T> expectedObjects, List<T> actual) {
+ assertEquals(null, expectedObjects, actual);
+ }
+
+ /** Asserts that the actuel similar is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <T> is the type of the values.
+ * @param message is the error message to put inside the assertion.
+ * @param expectedObjects are the expected values during the unit test.
+ * @param actual are the actual values of the objects during the unit test.
+ */
+ protected <T> void assertEquals(String message, List<T> expectedObjects, List<T> actual) {
+ if (expectedObjects==actual) return;
+ if (equals(expectedObjects,actual)) return;
+ fail(formatFailMessage(message, expectedObjects, actual));
+ }
+
+ private <T> boolean equals(List<T> c1, List<T> c2) {
+ if (c1.size()!=c2.size()) return false;
+ int count = c1.size();
+ T e1, e2;
+ for(int i=0; i<count; i++) {
+ e1 = c1.get(i);
+ e2 = c2.get(i);
+ if ((e1!=e2)&&(!e1.equals(e2))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /** Asserts that the actuel similar is not equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <T> is the type of the values
+ * @param expectedObjects are the expected values during the unit test.
+ * @param actual are the actual values of the objects during the unit test.
+ */
+ protected <T> void assertNotEquals(List<T> expectedObjects, List<T> actual) {
+ assertNotEquals(null, expectedObjects, actual);
+ }
+
+ /** Asserts that the actuel object is not equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <T> is the type of the values
+ * @param message is the error message to put inside the assertion.
+ * @param expectedObjects are the expected values during the unit test.
+ * @param actual are the actual values of the objects during the unit test.
+ */
+ protected <T> void assertNotEquals(String message, List<T> expectedObjects, List<T> actual) {
+ if ((expectedObjects!=actual)&&(!equals(expectedObjects,actual))) return;
+ fail(formatFailMessage(message, expectedObjects, actual));
+ }
+
+ /** Asserts that the actual object is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <T> is the type of the values
+ * @param <X> is the element's type of the values if they are arrays.
+ * @param message is the error message to put inside the assertion.
+ * @param expected is the expected value during the unit test.
+ * @param actual are the actual value of the object during the unit test.
+ */
+ @SuppressWarnings("unchecked")
+ protected <T, X> void assertSimilars(String message, T expected, T actual) {
+ if (expected==actual) return;
+ if (expected instanceof Collection)
+ assertSimilars(message, (Collection<?>)expected, (Collection<?>)actual);
+ else if (expected instanceof Point2D)
+ assertSimilars(message, (Point2D)expected, (Point2D)actual);
+ else if (expected instanceof Date)
+ assertSimilars(message, (Date)expected, (Date)actual);
+ else if (expected.getClass().isArray())
+ assertSimilars(message, (X[])expected, (X[])actual);
+ else
+ assertEquals(message, expected, actual);
+ }
+
+ /** Asserts that the actual object is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <T> is the type of the values.
+ * @param <X> is the element's type of the values if they are arrays.
+ * @param message is the error message to put inside the assertion.
+ * @param expected is the expected value.
+ * @param actual is the current value.
+ */
+ protected <T, X> void assertNotSimilars(String message, T expected, T actual) {
+ if (expected!=actual) {
+ try {
+ assertSimilars(message,expected, actual);
+ }
+ catch(AssertionError _) {
+ // ok
+ return;
+ }
+ catch(AssertionFailedError _) {
+ // ok
+ return;
+ }
+ }
+ fail(formatFailMessage(message, expected, actual));
+ }
+
+ /** Replies if the two objects are similars.
+ *
+ * @param <T> is the type of the values
+ * @param <X> is the element's type of the values if they are arrays.
+ * @param obj1
+ * @param obj2
+ * @return <code>true</code> if the objects are similar, otherwise <code>false</code>
+ */
+ protected <T, X> boolean isSimilarObjects(T obj1, T obj2) {
+ if (obj1==obj2) return true;
+ try {
+ assertSimilars(null,obj1, obj2);
+ return true;
+ }
+ catch(AssertionError _) {
+ return false;
+ }
+ catch(AssertionFailedError _) {
+ return false;
+ }
+ }
+
+ /** Asserts that the actuel similar is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <K> is the type of the map keys.
+ * @param <V> is the type of the map values.
+ * @param expectedObjects is the expected map.
+ * @param actual is the current map.
+ */
+ protected <K,V> void assertDeepSimilars(Map<K,V> expectedObjects, Map<K,V> actual) {
+ assertDeepSimilars(null, expectedObjects, actual);
+ }
+
+ /** Asserts that the actuel similar is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <K> is the type of the map keys.
+ * @param <V> is the type of the map values.
+ * @param message is the error message to put inside the assertion.
+ * @param expectedObjects is the expected map.
+ * @param actual is the current map.
+ */
+ protected <K,V> void assertDeepSimilars(String message, Map<K,V> expectedObjects, Map<K,V> actual) {
+ if (expectedObjects==actual) return;
+ if (similars(expectedObjects.keySet(), actual.keySet())) {
+ for(Entry<K,V> entry : expectedObjects.entrySet()) {
+ V v1 = entry.getValue();
+ V v2 = actual.get(entry.getKey());
+ assertSimilars(message, v1, v2);
+ }
+ // all values are correct
+ return;
+ }
+ fail(formatFailMessage(message, expectedObjects, actual));
+ }
+
+ /** Asserts that the actuel similar is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <K> is the type of the map keys.
+ * @param <V> is the type of the map values.
+ * @param expectedObjects is the expected map.
+ * @param actual is the current map.
+ */
+ protected <K,V> void assertNotDeepSimilars(Map<K,V> expectedObjects, Map<K,V> actual) {
+ assertNotDeepSimilars(null, expectedObjects, actual);
+ }
+
+ /** Asserts that the actuel similar is equal to one of the expected objects. If not
+ * an AssertionFailedError is thrown.
+ *
+ * @param <K> is the type of the map keys.
+ * @param <V> is the type of the map values.
+ * @param message is the error message to put inside the assertion.
+ * @param expectedObjects is the expected map.
+ * @param actual is the current map.
+ */
+ protected <K,V> void assertNotDeepSimilars(String message, Map<K,V> expectedObjects, Map<K,V> actual) {
+ if (expectedObjects!=actual) {
+ if (!similars(expectedObjects.keySet(), actual.keySet())) return;
+
+ for(Entry<K,V> entry : expectedObjects.entrySet()) {
+ V v1 = entry.getValue();
+ V v2 = actual.get(entry.getKey());
+ if (!isSimilarObjects(v1, v2)) return;
+ }
+ }
+ fail(formatFailMessage(message, expectedObjects, actual));
+ }
+
+ /** Asserts that the specified value is stricly negative.
+ *
+ * @param number
+ */
+ protected void assertStrictlyNegative(Number number) {
+ assertStrictlyNegative(null,number);
+ }
+
+ /** Asserts that the specified value is stricly negative.
+ *
+ * @param message is the error message to put inside the assertion.
+ * @param number
+ */
+ protected void assertStrictlyNegative(String message, Number number) {
+ if (number.doubleValue()<0.) return;
+ fail(formatFailMessage(message, "expected negative value", number)); //$NON-NLS-1$
+ }
+
+ /** Asserts that the specified value is stricly positive.
+ *
+ * @param number
+ */
+ protected void assertStrictlyPositive(Number number) {
+ assertStrictlyPositive(null,number);
+ }
+
+ /** Asserts that the specified value is stricly positive.
+ *
+ * @param message is the error message to put inside the assertion.
+ * @param number
+ */
+ protected void assertStrictlyPositive(String message, Number number) {
+ if (number.doubleValue()>0.) return;
+ fail(formatFailMessage(message, "expected positive value", number)); //$NON-NLS-1$
+ }
+
+ /** Asserts that the specified value is negative.
+ *
+ * @param number
+ */
+ protected void assertNegative(Number number) {
+ assertNegative(null,number);
+ }
+
+ /** Asserts that the specified value is negative.
+ *
+ * @param message is the error message to put inside the assertion.
+ * @param number
+ */
+ protected void assertNegative(String message, Number number) {
+ if (number.doubleValue()<=0.) return;
+ fail(formatFailMessage(message, "expected negative value", number)); //$NON-NLS-1$
+ }
+
+ /** Asserts that the specified value is positive.
+ *
+ * @param number
+ */
+ protected void assertPositive(Number number) {
+ assertPositive(null,number);
+ }
+
+ /** Asserts that the specified value is positive.
+ *
+ * @param message is the error message to put inside the assertion.
+ * @param number
+ */
+ protected void assertPositive(String message, Number number) {
+ if (number.doubleValue()>=0.) return;
+ fail(formatFailMessage(message, "expected positive value", number)); //$NON-NLS-1$
+ }
+
+ /**
+ * Replies an array which is containing values randomly selected from the parameter.
+ * Duplicate values are allowed.
+ *
+ * @param <T> is the type of the values.
+ * @param availableValues is the collection of available values.
+ * @return the selected values (possible duplicated)
+ */
+ @SuppressWarnings("unchecked")
+ protected <T> T[] extractRandomValues(T[] availableValues) {
+ Random rnd = new Random();
+ int count = rnd.nextInt(500);
+ ArrayList<T> tab = new ArrayList<T>(count);
+ for(int i=0; i<count; i++) {
+ tab.add(availableValues[rnd.nextInt(availableValues.length)]);
+ }
+ Class<?> clazz = availableValues.getClass().getComponentType();
+ T[] array = (T[])Array.newInstance(clazz, tab.size());
+ tab.toArray(array);
+ tab.clear();
+ return array;
+ }
+
+ /** Replies a randomized string.
+ *
+ * @return a random string.
+ */
+ protected String randomString() {
+ return randomString(-1);
+ }
+
+ /** Replies a randomized string with a max length.
+ *
+ * @param maxSize is the max length of the string.
+ * @return a random string with a max length.
+ */
+ protected String randomString(int maxSize) {
+ Random rnd = new Random();
+ StringBuffer b = new StringBuffer();
+ int count = rnd.nextInt(maxSize<=0 ? 255 : maxSize-1)+1;
+ for(int i=0; i<count; i++) {
+ char c = (char)('A' + rnd.nextInt(26));
+ b.append(c);
+ }
+ return b.toString();
+ }
+
+ /** Assert the the specified method thrown an exception
+ *
+ * @param self is the calling object
+ * @param method is the name of the method to invoke
+ * @param types is the parameter types of the method
+ * @param parameters is the parameter values to pass at invocation.
+ */
+ protected void assertException(Object self, String method, Class<?>[] types, Object[] parameters) {
+ assertException(null, self, method, types, parameters);
+ }
+
+ /** Assert the the specified method thrown an exception
+ *
+ * @param message is the error message to put in the assertion.
+ * @param self is the calling object
+ * @param method is the name of the method to invoke
+ * @param types is the parameter types of the method
+ * @param parameters is the parameter values to pass at invocation.
+ */
+ protected void assertException(String message, Object self, String method, Class<?>[] types, Object[] parameters) {
+ try {
+ Class<?> clazz = self.getClass();
+ Method methodFunc = clazz.getMethod(method, types);
+ methodFunc.invoke(self, parameters);
+ fail((message==null ? "" : message)+"An exception was attempted but never thrown."); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ catch(Exception _) {
+ // Expected behavior
+ }
+ }
+
+ /** Assert the the specified method thrown an exception
+ *
+ * @param self is the calling object
+ * @param method is the name of the method to invoke
+ */
+ protected void assertException(Object self, String method) {
+ assertException(null, self, method, new Class<?>[0], new Object[0]);
+ }
+
+ /** Assert the the specified method thrown an exception
+ *
+ * @param message is the error message to put in the assertion.
+ * @param self is the calling object
+ * @param method is the name of the method to invoke
+ */
+ protected void assertException(String message, Object self, String method) {
+ assertException(message, self, method, new Class<?>[0], new Object[0]);
+ }
+
+ /** Test if the two collections contain the same elements without
+ * taking into account the order of the elements in the collections.
+ *
+ * @param <T>
+ * @param expected
+ * @param actual
+ */
+ protected <T> void assertEpsilonEquals(Collection<? extends T> expected, Collection<? extends T> actual) {
+ assertEpsilonEquals(null, expected, actual);
+ }
+
+ /** Test if the two collections contain the same elements without
+ * taking into account the order of the elements in the collections.
+ *
+ * @param <T>
+ * @param message
+ * @param expected
+ * @param actual
+ */
+ protected <T> void assertEpsilonEquals(String message, Collection<? extends T> expected, Collection<? extends T> actual) {
+ ArrayList<T> l = new ArrayList<T>(actual);
+ for(T e : expected) {
+ if (!l.remove(e)) {
+ fail((message==null ? "" : (message+": ")) //$NON-NLS-1$//$NON-NLS-2$
+ +"not similar collections, expected element:"+ //$NON-NLS-1$
+ expected);
+ }
+ }
+ if (!l.isEmpty()) {
+ fail((message==null ? "" : (message+": ")) //$NON-NLS-1$//$NON-NLS-2$
+ +"not similar collections, not expected elements:"+ //$NON-NLS-1$
+ l);
+ }
+ }
+
+ /** Test if the two collections contain the same elements without
+ * taking into account the order of the elements in the collections.
+ *
+ * @param <T>
+ * @param expected
+ * @param actual
+ */
+ protected <T> void assertEpsilonEquals(T[] expected, T[] actual) {
+ assertEpsilonEquals(null, expected, actual);
+ }
+
+ /** Test if the two collections contain the same elements without
+ * taking into account the order of the elements in the collections.
+ *
+ * @param <T>
+ * @param message
+ * @param expected
+ * @param actual
+ */
+ protected <T> void assertEpsilonEquals(String message, T[] expected, T[] actual) {
+ ArrayList<T> l = new ArrayList<T>(Arrays.asList(actual));
+ for(T e : expected) {
+ if (!l.remove(e)) {
+ fail((message==null ? "" : (message+": ")) //$NON-NLS-1$//$NON-NLS-2$
+ +"not similar collections, expected element:"+ //$NON-NLS-1$
+ expected.toString());
+ }
+ }
+ if (!l.isEmpty()) {
+ fail((message==null ? "" : (message+": ")) //$NON-NLS-1$//$NON-NLS-2$
+ +"not similar collections, not expected elements:"+ //$NON-NLS-1$
+ l.toString());
+ }
+ }
+
+ /** Test if the two collections do no contain the same elements without
+ * taking into account the order of the elements in the collections.
+ *
+ * @param <T>
+ * @param expected
+ * @param actual
+ */
+ protected <T> void assertNotEpsilonEquals(T[] expected, T[] actual) {
+ assertNotEpsilonEquals(null, expected, actual);
+ }
+
+ /** Test if the two collections do no contain the same elements without
+ * taking into account the order of the elements in the collections.
+ *
+ * @param <T>
+ * @param message
+ * @param expected
+ * @param actual
+ */
+ protected <T> void assertNotEpsilonEquals(String message, T[] expected, T[] actual) {
+ ArrayList<T> l = new ArrayList<T>(Arrays.asList(actual));
+ for(T e : expected) {
+ if (!l.remove(e)) return;
+ }
+ if (l.isEmpty()) {
+ fail((message==null ? "" : (message+": ")) //$NON-NLS-1$//$NON-NLS-2$
+ +"similar collections when not attempted"); //$NON-NLS-1$
+ }
+ }
+
+}
Added: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractWeakCollectionTestCase.java
===================================================================
--- trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractWeakCollectionTestCase.java (rev 0)
+++ trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractWeakCollectionTestCase.java 2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,41 @@
+/* $Id$
+ *
+ * Copyright (C) 2011 Stephane GALLAND.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.util.ref;
+
+import java.util.UUID;
+
+/**
+ * @author $Author: sgalland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public abstract class AbstractWeakCollectionTestCase extends AbstractCollectionTestCase<String> {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected String createContentInstance() {
+ return UUID.randomUUID().toString();
+ }
+
+
+}
Property changes on: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/AbstractWeakCollectionTestCase.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/PhantomValueHashMapTest.java
===================================================================
--- trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/PhantomValueHashMapTest.java (rev 0)
+++ trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/PhantomValueHashMapTest.java 2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,40 @@
+/* $Id$
+ *
+ * Copyright (C) 2011 Stephane GALLAND.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.util.ref;
+
+import java.util.Map;
+
+/**
+ * @author $Author: sgalland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public class PhantomValueHashMapTest extends AbstractReferencableValueMapTestCase {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Map<String,String> createMap() {
+ return new PhantomValueHashMap<String,String>();
+ }
+
+}
Property changes on: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/PhantomValueHashMapTest.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/PhantomValueTreeMapTest.java
===================================================================
--- trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/PhantomValueTreeMapTest.java (rev 0)
+++ trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/PhantomValueTreeMapTest.java 2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,40 @@
+/* $Id$
+ *
+ * Copyright (C) 2011 Stephane GALLAND.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.util.ref;
+
+import java.util.Map;
+
+/**
+ * @author $Author: sgalland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public class PhantomValueTreeMapTest extends AbstractReferencableValueMapTestCase {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Map<String,String> createMap() {
+ return new PhantomValueTreeMap<String,String>();
+ }
+
+}
Property changes on: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/PhantomValueTreeMapTest.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueHashMapTest.java
===================================================================
--- trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueHashMapTest.java (rev 0)
+++ trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueHashMapTest.java 2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,40 @@
+/* $Id$
+ *
+ * Copyright (C) 2011 Stephane GALLAND.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.util.ref;
+
+import java.util.Map;
+
+/**
+ * @author $Author: sgalland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public class SoftValueHashMapTest extends AbstractReferencableValueMapTestCase {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Map<String,String> createMap() {
+ return new SoftValueHashMap<String,String>();
+ }
+
+}
Property changes on: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueHashMapTest.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Deleted: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueMapTest.java
===================================================================
--- trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueMapTest.java 2011-11-30 09:10:39 UTC (rev 318)
+++ trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueMapTest.java 2011-12-17 11:43:54 UTC (rev 319)
@@ -1,382 +0,0 @@
-/* $Id$
- *
- * Copyright (C) 2007-09 Stephane GALLAND This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * This program is free software; you can redistribute it and/or modify
- */
-package org.arakhne.util.ref;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Random;
-import java.util.Map.Entry;
-
-import org.arakhne.junit.AbstractTestCase;
-
-/**
- * @author $Author: galland$
- * @version $FullVersion$
- * @mavengroupid $GroupId$
- * @mavenartifactid $ArtifactId$
- */
-public class SoftValueMapTest extends AbstractTestCase {
-
- private static final int REFERENCE_SIZE = 0;
-
- private final HashMap<String,String> reference = new HashMap<String,String>();
-
- private static void collect() {
- System.gc();System.gc();System.gc();
- }
-
- private void spawnReference() {
- this.reference.clear();
- Random rnd = new Random();
- int count = rnd.nextInt(REFERENCE_SIZE+1)+5;
- String str;
- for(int i=0; i<count; i++) {
- str = randomString(10);
- this.reference.put(
- Integer.toString(i)+str,
- str);
- }
- str = null;
- }
-
- private String getReferenceObject(int index) {
- Object[] tab = this.reference.keySet().toArray();
- return (String)tab[index];
- }
-
- private Map<String,String> removeElementsFromReference() {
- HashMap<String,String> removed = new HashMap<String,String>();
- Random rnd = new Random();
- int index;
- int count = rnd.nextInt(this.reference.size()/4)+1;
- String key, value;
- for(int i=0; i<count; i++) {
- index = rnd.nextInt(this.reference.size());
- key = getReferenceObject(index);
- value = this.reference.remove(key);
- removed.put(key,value);
- }
- key = null;
- value = null;
- return removed;
- }
-
- @Override
- public void setUp() {
- spawnReference();
- }
-
- @Override
- public void tearDown() {
- this.reference.clear();
- }
-
- /**
- */
- public void testSoftValueMapMap() {
- SoftValueMap<String,String> test = new SoftValueMap<String,String>(this.reference);
- assertDeepSimilars(this.reference, test);
- }
-
- /**
- */
- public void testSize() {
- SoftValueMap<String,String> test = new SoftValueMap<String,String>();
- assertEquals(0, test.size());
-
- test = new SoftValueMap<String,String>(this.reference);
- test.setDeeplyExpurge(true);
- assertEquals(this.reference.size(), test.size());
-
- Map<String,String> removed = removeElementsFromReference();
- assertNotNull(removed);
- int count = removed.size();
- removed = null;
-
- collect();
-
- assertTrue(((this.reference.size()-count)<=test.size())||(this.reference.size()>test.size()));
- }
-
- /**
- */
- public void testIsEmpty() {
- SoftValueMap<String,String> test = new SoftValueMap<String,String>();
- assertTrue(test.isEmpty());
-
- test = new SoftValueMap<String,String>(this.reference);
- test.setDeeplyExpurge(true);
- assertFalse(test.isEmpty());
-
- removeElementsFromReference();
-
- collect();
-
- assertFalse(test.isEmpty());
-
- this.reference.clear();
-
- collect();
-
- assertFalse(test.isEmpty());
- }
-
- /**
- */
- public void testContainsKey() {
- SoftValueMap<String,String> test = new SoftValueMap<String,String>(this.reference);
- test.setDeeplyExpurge(true);
- assertDeepSimilars(this.reference, test);
-
- // Test the content
- {
- String elt;
- Iterator<String> iter = this.reference.keySet().iterator();
- while (iter.hasNext()) {
- elt = iter.next();
- assertTrue(test.containsKey(elt));
- }
- elt = null;
- }
- assertDeepSimilars(this.reference, test);
-
- Map<String,String> removedElements = removeElementsFromReference();
- int originalSize = removedElements.size() + this.reference.size();
-
- // Collects the objects
- collect();
-
- // Test the content
- assertEquals(originalSize, test.size());
- assertNotDeepSimilars(this.reference, test);
-
- // Clear the list of removed elements, which will cause collecting
- removedElements.clear();
- removedElements = null;
-
- // Collects the objects
- collect();
-
- // Test the content
- assertNotEquals(this.reference.size(), test.size());
- for(String elt : this.reference.keySet()) {
- assertTrue(test.containsKey(elt));
- }
- }
-
- /**
- */
- public void testContainsValue() {
- SoftValueMap<String,String> test = new SoftValueMap<String,String>(this.reference);
- test.setDeeplyExpurge(true);
- assertDeepSimilars(this.reference, test);
-
- // Test the content
- {
- String elt;
- Iterator<String> iter = this.reference.values().iterator();
- while (iter.hasNext()) {
- elt = iter.next();
- assertTrue(test.containsValue(elt));
- }
- elt = null;
- }
- assertDeepSimilars(this.reference, test);
-
- Map<String,String> removedElements = removeElementsFromReference();
- int originalSize = removedElements.size() + this.reference.size();
-
- // Collects the objects
- collect();
-
- // Test the content
- assertEquals(originalSize, test.size());
- assertNotDeepSimilars(this.reference, test);
-
- // Clear the list of removed elements, which will cause collecting
- removedElements.clear();
- removedElements = null;
-
- // Collects the objects
- collect();
-
- // Test the content
- assertNotEquals(this.reference.size(), test.size());
- for(String elt : this.reference.values()) {
- assertTrue(test.containsValue(elt));
- }
- }
-
- /**
- */
- public void testEntryIterator() {
- SoftValueMap<String,String> test = new SoftValueMap<String,String>(this.reference);
- test.setDeeplyExpurge(true);
-
- // Test the content
- {
- assertDeepSimilars(this.reference, test);
- Entry<String,String> e;
- Iterator<Entry<String,String>> iter = test.entrySet().iterator();
- while (iter.hasNext()) {
- e = iter.next();
- assertTrue(this.reference.containsKey(e.getKey()));
- assertEquals(this.reference.get(e.getKey()),this.reference.get(e.getKey()));
- }
- }
-
- // Remove elements
- Map<String,String> baseElements = new HashMap<String,String>(this.reference);
- removeElementsFromReference();
-
- // Collects the objects
- collect();
-
- // Test the content
- {
- assertNotDeepSimilars(this.reference, test);
- Entry<String,String> e;
- Iterator<Entry<String,String>> iter = test.entrySet().iterator();
- while (iter.hasNext()) {
- e = iter.next();
- assertTrue(baseElements.containsKey(e.getKey()));
- assertEquals(baseElements.get(e.getKey()),baseElements.get(e.getKey()));
- }
- }
-
- // Clear the list of removed elements, which will cause collecting
- baseElements.clear();
- baseElements = null;
-
- // Collects the objects
- collect();
-
- // Test the content
- {
- assertNotDeepSimilars(this.reference, test);
- Entry<String,String> e;
- Iterator<Entry<String,String>> iter = test.entrySet().iterator();
- while (iter.hasNext()) {
- e = iter.next();
- assertEquals(this.reference.get(e.getKey()),this.reference.get(e.getKey()));
- }
- }
- }
-
- /**
- */
- public void testKeyIterator() {
- SoftValueMap<String,String> test = new SoftValueMap<String,String>(this.reference);
- test.setDeeplyExpurge(true);
-
- // Test the content
- {
- assertDeepSimilars(this.reference, test);
- String k;
- Iterator<String> iter = test.keySet().iterator();
- while (iter.hasNext()) {
- k = iter.next();
- assertTrue(this.reference.containsKey(k));
- }
- }
-
- // Remove elements
- Map<String,String> baseElements = new HashMap<String,String>(this.reference);
- removeElementsFromReference();
-
- // Collects the objects
- collect();
-
- // Test the content
- {
- assertNotDeepSimilars(this.reference, test);
- String k;
- Iterator<String> iter = test.keySet().iterator();
- while (iter.hasNext()) {
- k = iter.next();
- assertTrue(baseElements.containsKey(k));
- }
- }
-
- // Clear the list of removed elements, which will cause collecting
- baseElements.clear();
- baseElements = null;
-
- // Collects the objects
- collect();
-
- // Test the content
- {
- assertNotDeepSimilars(this.reference, test);
- }
- }
-
- /**
- */
- public void testValueIterator() {
- SoftValueMap<String,String> test = new SoftValueMap<String,String>(this.reference);
- test.setDeeplyExpurge(true);
-
- // Test the content
- {
- assertDeepSimilars(this.reference, test);
- String v;
- Iterator<String> iter = test.values().iterator();
- while (iter.hasNext()) {
- v = iter.next();
- assertTrue(this.reference.containsValue(v));
- }
- v = null;
- iter = null;
- }
-
- // Remove elements
- Map<String,String> baseElements = new HashMap<String,String>(this.reference);
- removeElementsFromReference();
-
- // Collects the objects
- collect();
-
- // Test the content
- {
- assertNotDeepSimilars(this.reference, test);
- String v;
- Iterator<String> iter = test.values().iterator();
- while (iter.hasNext()) {
- v = iter.next();
- assertTrue(baseElements.containsValue(v));
- }
- v = null;
- iter = null;
- }
-
- // Clear the list of removed elements, which will cause collecting
- baseElements.clear();
- baseElements = null;
-
- // Collects the objects
- collect();
-
- // Test the content
- {
- assertNotDeepSimilars(this.reference, test);
- }
- }
-
-}
Added: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueTreeMapTest.java
===================================================================
--- trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueTreeMapTest.java (rev 0)
+++ trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueTreeMapTest.java 2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,40 @@
+/* $Id$
+ *
+ * Copyright (C) 2011 Stephane GALLAND.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.util.ref;
+
+import java.util.Map;
+
+/**
+ * @author $Author: sgalland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public class SoftValueTreeMapTest extends AbstractReferencableValueMapTestCase {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Map<String,String> createMap() {
+ return new SoftValueTreeMap<String,String>();
+ }
+
+}
Property changes on: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/SoftValueTreeMapTest.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueHashMapTest.java
===================================================================
--- trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueHashMapTest.java (rev 0)
+++ trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueHashMapTest.java 2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,40 @@
+/* $Id$
+ *
+ * Copyright (C) 2011 Stephane GALLAND.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.util.ref;
+
+import java.util.Map;
+
+/**
+ * @author $Author: sgalland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public class WeakValueHashMapTest extends AbstractReferencableValueMapTestCase {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Map<String,String> createMap() {
+ return new WeakValueHashMap<String,String>();
+ }
+
+}
Property changes on: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueHashMapTest.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Deleted: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueMapTest.java
===================================================================
--- trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueMapTest.java 2011-11-30 09:10:39 UTC (rev 318)
+++ trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueMapTest.java 2011-12-17 11:43:54 UTC (rev 319)
@@ -1,399 +0,0 @@
-/* $Id$
- *
- * Copyright (C) 2007-09 Stephane GALLAND This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * This program is free software; you can redistribute it and/or modify
- */
-package org.arakhne.util.ref;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Random;
-import java.util.Map.Entry;
-
-import org.arakhne.junit.AbstractTestCase;
-
-/**
- * @author $Author: galland$
- * @version $FullVersion$
- * @mavengroupid $GroupId$
- * @mavenartifactid $ArtifactId$
- */
-public class WeakValueMapTest extends AbstractTestCase {
-
- private static final int REFERENCE_SIZE = 0;
-
- private final HashMap<String,String> reference = new HashMap<String,String>();
-
- private static void collect() {
- System.gc();System.gc();System.gc();
- }
-
- private void spawnReference() {
- this.reference.clear();
- Random rnd = new Random();
- int count = rnd.nextInt(REFERENCE_SIZE+1)+5;
- String str;
- for(int i=0; i<count; i++) {
- str = randomString(10);
- this.reference.put(
- Integer.toString(i)+str,
- str);
- }
- str = null;
- }
-
- private String getReferenceObject(int index) {
- Object[] tab = this.reference.keySet().toArray();
- return (String)tab[index];
- }
-
- private Map<String,String> removeElementsFromReference() {
- HashMap<String,String> removed = new HashMap<String,String>();
- Random rnd = new Random();
- int index;
- int count = rnd.nextInt(this.reference.size()/4)+1;
- String key, value;
- for(int i=0; i<count; i++) {
- index = rnd.nextInt(this.reference.size());
- key = getReferenceObject(index);
- value = this.reference.remove(key);
- removed.put(key,value);
- }
- key = null;
- value = null;
- return removed;
- }
-
- @Override
- public void setUp() {
- spawnReference();
- }
-
- @Override
- public void tearDown() {
- this.reference.clear();
- }
-
- /**
- */
- public void testEntryIterator() {
- WeakValueMap<String,String> test = new WeakValueMap<String,String>(this.reference);
- test.setDeeplyExpurge(true);
-
- // Test the content
- {
- assertDeepSimilars(this.reference, test);
- Entry<String,String> e;
- Iterator<Entry<String,String>> iter = test.entrySet().iterator();
- while (iter.hasNext()) {
- e = iter.next();
- assertTrue(this.reference.containsKey(e.getKey()));
- assertEquals(this.reference.get(e.getKey()),this.reference.get(e.getKey()));
- }
- }
-
- {
- // Remove elements
- Map<String,String> baseElements = new HashMap<String,String>(this.reference);
- removeElementsFromReference();
-
- // Collects the objects
- collect();
-
- // Test the content
- {
- assertNotDeepSimilars(this.reference, test);
- Entry<String,String> e;
- Iterator<Entry<String,String>> iter = test.entrySet().iterator();
- while (iter.hasNext()) {
- e = iter.next();
- assertTrue(baseElements.containsKey(e.getKey()));
- assertEquals(baseElements.get(e.getKey()),baseElements.get(e.getKey()));
- }
- }
-
- // Clear the list of removed elements, which will cause collecting
- baseElements.clear();
- baseElements = null;
-
- // Collects the objects
- collect();
- collect();
- }
-
- // Test the content
- /*{
- assertDeepSimilars(this.reference, test);
- Entry<String,String> e;
- Iterator<Entry<String,String>> iter = test.entrySet().iterator();
- while (iter.hasNext()) {
- e = iter.next();
- assertTrue(this.reference.containsKey(e.getKey()));
- assertEquals(this.reference.get(e.getKey()),this.reference.get(e.getKey()));
- }
- }*/
- }
-
- /**
- */
- public void testWeakValueMapMap() {
- WeakValueMap<String,String> test = new WeakValueMap<String,String>(this.reference);
- assertDeepSimilars(this.reference, test);
- }
-
- /**
- */
- public void testSize() {
- WeakValueMap<String,String> test = new WeakValueMap<String,String>();
- assertEquals(0, test.size());
-
- test = new WeakValueMap<String,String>(this.reference);
- test.setDeeplyExpurge(true);
- assertEquals(this.reference.size(), test.size());
-
- removeElementsFromReference();
-
- collect();
-
- assertEquals(this.reference.size(), test.size());
- }
-
- /**
- */
- public void testIsEmpty() {
- WeakValueMap<String,String> test = new WeakValueMap<String,String>();
- assertTrue(test.isEmpty());
-
- test = new WeakValueMap<String,String>(this.reference);
- test.setDeeplyExpurge(true);
- assertFalse(test.isEmpty());
-
- removeElementsFromReference();
-
- collect();
-
- assertFalse(test.isEmpty());
-
- this.reference.clear();
-
- collect();
-
- assertTrue(test.isEmpty());
- }
-
- /**
- */
- public void testContainsKey() {
- WeakValueMap<String,String> test = new WeakValueMap<String,String>(this.reference);
- test.setDeeplyExpurge(true);
- assertDeepSimilars(this.reference, test);
-
- // Test the content
- {
- String elt;
- Iterator<String> iter = this.reference.keySet().iterator();
- while (iter.hasNext()) {
- elt = iter.next();
- assertTrue(test.containsKey(elt));
- }
- elt = null;
- }
- assertDeepSimilars(this.reference, test);
-
- Map<String,String> removedElements = removeElementsFromReference();
- int originalSize = removedElements.size() + this.reference.size();
-
- // Collects the objects
- collect();
-
- // Test the content
- assertEquals(originalSize, test.size());
- assertNotDeepSimilars(this.reference, test);
-
- // Clear the list of removed elements, which will cause collecting
- removedElements.clear();
- removedElements = null;
-
- // Collects the objects
- collect();
-
- // Test the content
- assertEquals(this.reference.size(), test.size());
- assertDeepSimilars(this.reference, test);
- for(String elt : this.reference.keySet()) {
- assertTrue(test.containsKey(elt));
- }
- }
-
- /**
- */
- public void testContainsValue() {
- WeakValueMap<String,String> test = new WeakValueMap<String,String>(this.reference);
- test.setDeeplyExpurge(true);
- assertDeepSimilars(this.reference, test);
-
- // Test the content
- {
- String elt;
- Iterator<String> iter = this.reference.values().iterator();
- while (iter.hasNext()) {
- elt = iter.next();
- assertTrue(test.containsValue(elt));
- }
- elt = null;
- }
- assertDeepSimilars(this.reference, test);
-
- Map<String,String> removedElements = removeElementsFromReference();
- int originalSize = removedElements.size() + this.reference.size();
-
- // Collects the objects
- collect();
-
- // Test the content
- assertEquals(originalSize, test.size());
- assertNotDeepSimilars(this.reference, test);
-
- // Clear the list of removed elements, which will cause collecting
- removedElements.clear();
- removedElements = null;
-
- // Collects the objects
- collect();
-
- // Test the content
- assertEquals(this.reference.size(), test.size());
- assertDeepSimilars(this.reference, test);
- for(String elt : this.reference.values()) {
- assertTrue(test.containsValue(elt));
- }
- }
-
- /**
- */
- public void testKeyIterator() {
- WeakValueMap<String,String> test = new WeakValueMap<String,String>(this.reference);
- test.setDeeplyExpurge(true);
-
- // Test the content
- {
- assertDeepSimilars(this.reference, test);
- String k;
- Iterator<String> iter = test.keySet().iterator();
- while (iter.hasNext()) {
- k = iter.next();
- assertTrue(this.reference.containsKey(k));
- }
- }
-
- // Remove elements
- Map<String,String> baseElements = new HashMap<String,String>(this.reference);
- removeElementsFromReference();
-
- // Collects the objects
- collect();
-
- // Test the content
- {
- assertNotDeepSimilars(this.reference, test);
- String k;
- Iterator<String> iter = test.keySet().iterator();
- while (iter.hasNext()) {
- k = iter.next();
- assertTrue(baseElements.containsKey(k));
- }
- }
-
- // Clear the list of removed elements, which will cause collecting
- baseElements.clear();
- baseElements = null;
-
- // Collects the objects
- collect();
-
- // Test the content
- {
- assertDeepSimilars(this.reference, test);
- String k;
- Iterator<String> iter = test.keySet().iterator();
- while (iter.hasNext()) {
- k = iter.next();
- assertTrue(this.reference.containsKey(k));
- }
- }
- }
-
- /**
- */
- public void testValueIterator() {
- WeakValueMap<String,String> test = new WeakValueMap<String,String>(this.reference);
- test.setDeeplyExpurge(true);
-
- // Test the content
- {
- assertDeepSimilars(this.reference, test);
- String v;
- Iterator<String> iter = test.values().iterator();
- while (iter.hasNext()) {
- v = iter.next();
- assertTrue(this.reference.containsValue(v));
- }
- v = null;
- iter = null;
- }
-
- // Remove elements
- Map<String,String> baseElements = new HashMap<String,String>(this.reference);
- removeElementsFromReference();
-
- // Collects the objects
- collect();
-
- // Test the content
- {
- assertNotDeepSimilars(this.reference, test);
- String v;
- Iterator<String> iter = test.values().iterator();
- while (iter.hasNext()) {
- v = iter.next();
- assertTrue(baseElements.containsValue(v));
- }
- v = null;
- iter = null;
- }
-
- // Clear the list of removed elements, which will cause collecting
- baseElements.clear();
- baseElements = null;
-
- // Collects the objects
- collect();
-
- // Test the content
- {
- assertDeepSimilars(this.reference, test);
- String v;
- Iterator<String> iter = test.values().iterator();
- while (iter.hasNext()) {
- v = iter.next();
- assertTrue(this.reference.containsValue(v));
- }
- v = null;
- iter = null;
- }
- }
-
-}
Added: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueTreeMapTest.java
===================================================================
--- trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueTreeMapTest.java (rev 0)
+++ trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueTreeMapTest.java 2011-12-17 11:43:54 UTC (rev 319)
@@ -0,0 +1,40 @@
+/* $Id$
+ *
+ * Copyright (C) 2011 Stephane GALLAND.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+package org.arakhne.util.ref;
+
+import java.util.Map;
+
+/**
+ * @author $Author: sgalland$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public class WeakValueTreeMapTest extends AbstractReferencableValueMapTestCase {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Map<String,String> createMap() {
+ return new WeakValueTreeMap<String,String>();
+ }
+
+}
Property changes on: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueTreeMapTest.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain