Author: brentworden
Date: Sun Aug 26 19:35:45 2012
New Revision: 1377492

URL: http://svn.apache.org/viewvc?rev=1377492&view=rev
Log:
fix indentation

Modified:
    
commons/proper/collections/trunk/src/main/java/org/apache/commons/collections/map/PassiveExpiringMap.java
    
commons/proper/collections/trunk/src/test/java/org/apache/commons/collections/map/TestPassiveExpiringMap.java

Modified: 
commons/proper/collections/trunk/src/main/java/org/apache/commons/collections/map/PassiveExpiringMap.java
URL: 
http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/main/java/org/apache/commons/collections/map/PassiveExpiringMap.java?rev=1377492&r1=1377491&r2=1377492&view=diff
==============================================================================
--- 
commons/proper/collections/trunk/src/main/java/org/apache/commons/collections/map/PassiveExpiringMap.java
 (original)
+++ 
commons/proper/collections/trunk/src/main/java/org/apache/commons/collections/map/PassiveExpiringMap.java
 Sun Aug 26 19:35:45 2012
@@ -55,523 +55,484 @@ import java.util.concurrent.TimeUnit;
  * synchronization.
  * </p>
  * 
- * @param <K>
- *            the type of the keys in the map
- * 
- * @param <V>
- *            the type of the values in the map
- * 
+ * @param <K> the type of the keys in the map
+ * @param <V> the type of the values in the map
  * @since 4.0
  * @version $Id: $
  */
-public class PassiveExpiringMap<K, V> extends AbstractMapDecorator<K, V>
-               implements Serializable {
-
-       /**
-        * A {@link ExpirationPolicy} that returns a expiration time that is a
-        * constant about of time in the future from the current time.
-        * 
-        * @param <K>
-        *            the type of the keys in the map
-        * @param <V>
-        *            the type of the values in the map
-        * 
-        * @since 4.0
-        * @version $Id: $
-        */
-       public static class ConstantTimeToLiveExpirationPolicy<K, V> implements
-                       ExpirationPolicy<K, V> {
-
-               /** Serialization version */
-               private static final long serialVersionUID = 1L;
-
-               /** the constant time-to-live value measured in milliseconds. */
-               private final long timeToLiveMillis;
-
-               /**
-                * Default constructor. Constructs a policy using a negative
-                * time-to-live value that results in entries never expiring.
-                */
-               public ConstantTimeToLiveExpirationPolicy() {
-                       this(-1L);
-               }
-
-               /**
-                * Construct a policy with the given time-to-live constant 
measured in
-                * milliseconds. A negative time-to-live value indicates 
entries never
-                * expire. A zero time-to-live value indicates entries expire 
(nearly)
-                * immediately.
-                * 
-                * @param timeToLiveMillis
-                *            the constant amount of time (in milliseconds) an 
entry is
-                *            available before it expires. A negative value 
results in
-                *            entries that NEVER expire. A zero value results 
in entries
-                *            that ALWAYS expire.
-                */
-               public ConstantTimeToLiveExpirationPolicy(long 
timeToLiveMillis) {
-                       super();
-                       this.timeToLiveMillis = timeToLiveMillis;
-               }
-
-               /**
-                * Construct a policy with the given time-to-live constant 
measured in
-                * the given time unit of measure.
-                * 
-                * @param timeToLive
-                *            the constant amount of time an entry is available 
before
-                *            it expires. A negative value results in entries 
that NEVER
-                *            expire. A zero value results in entries that 
ALWAYS
-                *            expire.
-                * @param timeUnit
-                *            the unit of time for the <code>timeToLive</code>
-                *            parameter, must not be null.
-                * @throws IllegalArgumentException
-                *             if the time unit is null.
-                */
-               public ConstantTimeToLiveExpirationPolicy(long timeToLive,
-                               TimeUnit timeUnit) {
-                       this(validateAndConvertToMillis(timeToLive, 
TimeUnit.MILLISECONDS));
-               }
-
-               /**
-                * Determine the expiration time for the given key-value entry.
-                * 
-                * @param key
-                *            the key for the entry (ignored).
-                * @param value
-                *            the value for the entry (ignored).
-                * @return if {@link #timeToLiveMillis} &ge; 0, an expiration 
time of
-                *         {@link #timeToLiveMillis} +
-                *         {@link System#currentTimeMillis()} is returned. 
Otherwise, -1
-                *         is returned indicating the entry never expires.
-                */
-               public long expirationTime(K key, V value) {
-                       if (timeToLiveMillis >= 0L) {
-                               // avoid numerical overflow
-                               long now = System.currentTimeMillis();
-                               if (now > Long.MAX_VALUE - timeToLiveMillis) {
-                                       // expiration would be greater than 
Long.MAX_VALUE
-                                       // never expire
-                                       return -1;
-                               }
-
-                               // timeToLiveMillis in the future
-                               return now + timeToLiveMillis;
-                       }
-                       
-                       // never expire
-                       return -1L;
-               }
-       }
-
-       /**
-        * A policy to determine the expiration time for key-value entries.
-        * 
-        * @param <K>
-        *            the key object type.
-        * @param <V>
-        *            the value object type
-        * 
-        * @since 4.0
-        * @version $Id: $
-        */
-       public static interface ExpirationPolicy<K, V> extends Serializable {
-               /**
-                * Determine the expiration time for the given key-value entry.
-                * 
-                * @param key
-                *            the key for the entry.
-                * @param value
-                *            the value for the entry.
-                * @return the expiration time value measured in milliseconds. A
-                *         negative return value indicates the entry never 
expires.
-                */
-               long expirationTime(K key, V value);
-       }
-
-       /** Serialization version */
-       private static final long serialVersionUID = 1L;
-
-       /**
-        * First validate the input parameters. If the parameters are valid, 
convert
-        * the given time measured in the given units to the same time measured 
in
-        * milliseconds. If the parameters are invalid, an
-        * {@link IllegalArgumentException} is thrown.
-        * 
-        * @param timeToLive
-        *            the constant amount of time an entry is available before 
it
-        *            expires. A negative value results in entries that NEVER
-        *            expire. A zero value results in entries that ALWAYS 
expire.
-        * @param timeUnit
-        *            the unit of time for the <code>timeToLive</code> 
parameter,
-        *            must not be null.
-        * @throws IllegalArgumentException
-        *             if the time unit is null.
-        */
-       private static long validateAndConvertToMillis(long timeToLive,
-                       TimeUnit timeUnit) {
-               if (timeUnit == null) {
-                       throw new IllegalArgumentException("Time unit must not 
be null");
-               }
-               return timeUnit.convert(timeToLive, TimeUnit.MILLISECONDS);
-       }
-
-       /** map used to manage expiration times for the actual map entries. */
-       private final Map<Object, Long> expirationMap = new HashMap<Object, 
Long>();
-
-       /** the policy used to determine time-to-live values for map entries. */
-       private final ExpirationPolicy<K, V> expiringPolicy;
-
-       /**
-        * Default constructor. Constructs a map decorator that results in 
entries
-        * NEVER expiring.
-        */
-       public PassiveExpiringMap() {
-               this(-1L);
-       }
-
-       /**
-        * Construct a map decorator using the given expiration policy to 
determine
-        * expiration times.
-        * 
-        * @param expiringPolicy
-        *            the policy used to determine expiration times of entries 
as
-        *            they are added.
-        */
-       public PassiveExpiringMap(ExpirationPolicy<K, V> expiringPolicy) {
-               this(expiringPolicy, new HashMap<K, V>());
-       }
-
-       /**
-        * Construct a map decorator that decorates the given map and uses the 
given
-        * expiration policy to determine expiration times. If there are any
-        * elements already in the map being decorated, they will NEVER expire
-        * unless they are replaced.
-        * 
-        * @param expiringPolicy
-        *            the policy used to determine expiration times of entries 
as
-        *            they are added.
-        * @param map
-        *            the map to decorate, must not be null.
-        * @throws IllegalArgumentException
-        *             if the map is null.
-        */
-       public PassiveExpiringMap(ExpirationPolicy<K, V> expiringPolicy,
-                       Map<K, V> map) {
-               super(map);
-               if (expiringPolicy == null) {
-                       throw new IllegalArgumentException("Policy must not be 
null.");
-               }
-               this.expiringPolicy = expiringPolicy;
-       }
-
-       /**
-        * Construct a map decorator that decorates the given map using the 
given
-        * time-to-live value measured in milliseconds to create and use a
-        * {@link ConstantTimeToLiveExpirationPolicy} expiration policy.
-        * 
-        * @param timeToLiveMillis
-        *            the constant amount of time (in milliseconds) an entry is
-        *            available before it expires. A negative value results in
-        *            entries that NEVER expire. A zero value results in entries
-        *            that ALWAYS expire.
-        */
-       public PassiveExpiringMap(long timeToLiveMillis) {
-               this(new ConstantTimeToLiveExpirationPolicy<K, 
V>(timeToLiveMillis),
-                               new HashMap<K, V>());
-       }
-
-       /**
-        * Construct a map decorator using the given time-to-live value 
measured in
-        * milliseconds to create and use a
-        * {@link ConstantTimeToLiveExpirationPolicy} expiration policy. If 
there
-        * are any elements already in the map being decorated, they will NEVER
-        * expire unless they are replaced.
-        * 
-        * @param timeToLiveMillis
-        *            the constant amount of time (in milliseconds) an entry is
-        *            available before it expires. A negative value results in
-        *            entries that NEVER expire. A zero value results in entries
-        *            that ALWAYS expire.
-        * @param map
-        *            the map to decorate, must not be null.
-        * @throws IllegalArgumentException
-        *             if the map is null.
-        */
-       public PassiveExpiringMap(long timeToLiveMillis, Map<K, V> map) {
-               this(new ConstantTimeToLiveExpirationPolicy<K, 
V>(timeToLiveMillis),
-                               map);
-       }
-
-       /**
-        * Construct a map decorator using the given time-to-live value 
measured in
-        * the given time units of measure to create and use a
-        * {@link ConstantTimeToLiveExpirationPolicy} expiration policy.
-        * 
-        * @param timeToLive
-        *            the constant amount of time an entry is available before 
it
-        *            expires. A negative value results in entries that NEVER
-        *            expire. A zero value results in entries that ALWAYS 
expire.
-        * @param timeUnit
-        *            the unit of time for the <code>timeToLive</code> 
parameter,
-        *            must not be null.
-        * @throws IllegalArgumentException
-        *             if the time unit is null.
-        */
-       public PassiveExpiringMap(long timeToLive, TimeUnit timeUnit) {
-               this(validateAndConvertToMillis(timeToLive, timeUnit));
-       }
-
-       /**
-        * Construct a map decorator that decorates the given map using the 
given
-        * time-to-live value measured in the given time units of measure to 
create
-        * {@link ConstantTimeToLiveExpirationPolicy} expiration policy. This 
policy
-        * is used to determine expiration times. If there are any elements 
already
-        * in the map being decorated, they will NEVER expire unless they are
-        * replaced.
-        * 
-        * @param timeToLive
-        *            the constant amount of time an entry is available before 
it
-        *            expires. A negative value results in entries that NEVER
-        *            expire. A zero value results in entries that ALWAYS 
expire.
-        * @param timeUnit
-        *            the unit of time for the <code>timeToLive</code> 
parameter,
-        *            must not be null.
-        * @throws IllegalArgumentException
-        *             if the time unit is null.
-        * @param map
-        *            the map to decorate, must not be null.
-        * @throws IllegalArgumentException
-        *             if the map is null.
-        */
-       public PassiveExpiringMap(long timeToLive, TimeUnit timeUnit, Map<K, V> 
map) {
-               this(validateAndConvertToMillis(timeToLive, timeUnit), map);
-       }
-
-       /**
-        * Constructs a map decorator that decorates the given map and results 
in
-        * entries NEVER expiring. If there are any elements already in the map
-        * being decorated, they also will NEVER expire.
-        * 
-        * @param map
-        *            the map to decorate, must not be null.
-        * @throws IllegalArgumentException
-        *             if the map is null.
-        */
-       public PassiveExpiringMap(Map<K, V> map) {
-               this(-1L, map);
-       }
-
-       /**
-        * Normal {@link Map#clear()} behavior with the addition of clearing all
-        * expiration entries as well.
-        */
-       @Override
-       public void clear() {
-               super.clear();
-               expirationMap.clear();
-       }
-
-       /**
-        * All expired entries are removed from the map prior to determining the
-        * contains result.
-        */
-       @Override
-       public boolean containsKey(Object key) {
-               removeIfExpired(key, now());
-               return super.containsKey(key);
-       }
-
-       /**
-        * All expired entries are removed from the map prior to determining the
-        * contains result.
-        */
-       @Override
-       public boolean containsValue(Object value) {
-               removeAllExpired(now());
-               return super.containsValue(value);
-       }
-
-       /**
-        * All expired entries are removed from the map prior to returning the 
entry
-        * set.
-        */
-       @Override
-       public Set<Entry<K, V>> entrySet() {
-               removeAllExpired(now());
-               return super.entrySet();
-       }
-
-       /**
-        * All expired entries are removed from the map prior to returning the 
entry
-        * value.
-        */
-       @Override
-       public V get(Object key) {
-               removeIfExpired(key, now());
-               return super.get(key);
-       }
-
-       /**
-        * All expired entries are removed from the map prior to determining if 
it
-        * is empty.
-        */
-       @Override
-       public boolean isEmpty() {
-               removeAllExpired(now());
-               return super.isEmpty();
-       }
-
-       /**
-        * Determines if the given expiration time is less than <code>now</code>
-        * 
-        * @param now
-        *            the time in milliseconds used to compare against the
-        *            expiration time.
-        * @param expirationTimeObject
-        *            the expiration time value retrieved from
-        *            {@link #expirationMap}, can be null.
-        * @return <code>true</code> if <code>expirationTimeObject</code> is 
&ge; 0
-        *         and <code>expirationTimeObject</code> &lt; <code>now</code>.
-        *         <code>false</code> otherwise.
-        */
-       private boolean isExpired(long now, Long expirationTimeObject) {
-               if (expirationTimeObject != null) {
-                       long expirationTime = expirationTimeObject.longValue();
-                       return (expirationTime >= 0 && now >= expirationTime);
-               }
-               return false;
-       }
-
-       /**
-        * All expired entries are removed from the map prior to returning the 
key
-        * set.
-        */
-       @Override
-       public Set<K> keySet() {
-               removeAllExpired(now());
-               return super.keySet();
-       }
-
-       /**
-        * The current time in milliseconds.
-        */
-       private long now() {
-               return System.currentTimeMillis();
-       }
-
-       @Override
-       public V put(K key, V value) {
-               return put(key, value, now());
-       }
-
-       /**
-        * Add the given key-value pair to this map as well as recording the 
entry's
-        * expiration time based on the current time in milliseconds,
-        * <code>now</code> and this map's {@link #expiringPolicy}.
-        */
-       private V put(K key, V value, long now) {
-               // record expiration time of new entry
-               long expirationTime = expiringPolicy.expirationTime(key, value);
-               expirationMap.put(key, Long.valueOf(expirationTime));
-
-               return super.put(key, value);
-       }
-
-       @Override
-       public void putAll(Map<? extends K, ? extends V> mapToCopy) {
-               for (Map.Entry<? extends K, ? extends V> entry : 
mapToCopy.entrySet()) {
-                       put(entry.getKey(), entry.getValue());
-               }
-       }
-
-       /**
-        * Normal {@link Map#remove(Object)} behavior with the addition of 
removing
-        * any expiration entry as well.
-        */
-       @Override
-       public V remove(Object key) {
-               expirationMap.remove(key);
-               return super.remove(key);
-       }
-
-       /**
-        * Removes all entries in the map whose expiration time is less than
-        * <code>now</code>. The exceptions are entries with negative expiration
-        * times; those entries are never removed.
-        * 
-        * @see #isExpired(long, Long)
-        */
-       private void removeAllExpired(long now) {
-               Iterator<Map.Entry<Object, Long>> iter = 
expirationMap.entrySet()
-                               .iterator();
-               while (iter.hasNext()) {
-                       Map.Entry<Object, Long> expirationEntry = iter.next();
-                       if (isExpired(now, expirationEntry.getValue())) {
-                               // remove entry from collection
-                               super.remove(expirationEntry.getKey());
-                               // remove entry from expiration map
-                               iter.remove();
-                       }
-               }
-       }
-
-       /**
-        * Removes the entry with the given key if the entry's expiration time 
is
-        * less than <code>now</code>. If the entry has a negative expiration 
time,
-        * the entry is never removed.
-        */
-       private void removeIfExpired(Object key, long now) {
-               Long expirationTimeObject = expirationMap.get(key);
-               if (isExpired(now, expirationTimeObject)) {
-                       remove(key);
-               }
-       }
-
-       /**
-        * All expired entries are removed from the map prior to returning the 
size.
-        */
-       @Override
-       public int size() {
-               removeAllExpired(now());
-               return super.size();
-       }
-
-       /**
-        * Read the map in using a custom routine.
-        * 
-        * @param in
-        *            the input stream
-        * @throws IOException
-        * @throws ClassNotFoundException
-        */
-       @SuppressWarnings("unchecked")
-       // (1) should only fail if input stream is incorrect
-       private void readObject(ObjectInputStream in) throws IOException,
-                       ClassNotFoundException {
-               in.defaultReadObject();
-               map = (Map<K, V>) in.readObject(); // (1)
-       }
-
-       /**
-        * Write the map out using a custom routine.
-        * 
-        * @param out
-        *            the output stream
-        * @throws IOException
-        */
-       private void writeObject(ObjectOutputStream out) throws IOException {
-               out.defaultWriteObject();
-               out.writeObject(map);
-       }
-
-       /**
-        * All expired entries are removed from the map prior to returning the 
value
-        * collection.
-        */
-       @Override
-       public Collection<V> values() {
-               removeAllExpired(now());
-               return super.values();
-       }
+public class PassiveExpiringMap<K, V>
+    extends AbstractMapDecorator<K, V>
+    implements Serializable {
+
+    /**
+     * A {@link ExpirationPolicy} that returns a expiration time that is a
+     * constant about of time in the future from the current time.
+     * 
+     * @param <K> the type of the keys in the map
+     * @param <V> the type of the values in the map
+     * @since 4.0
+     * @version $Id: $
+     */
+    public static class ConstantTimeToLiveExpirationPolicy<K, V>
+        implements ExpirationPolicy<K, V> {
+
+        /** Serialization version */
+        private static final long serialVersionUID = 1L;
+
+        /** the constant time-to-live value measured in milliseconds. */
+        private final long timeToLiveMillis;
+
+        /**
+         * Default constructor. Constructs a policy using a negative
+         * time-to-live value that results in entries never expiring.
+         */
+        public ConstantTimeToLiveExpirationPolicy() {
+            this(-1L);
+        }
+
+        /**
+         * Construct a policy with the given time-to-live constant measured in
+         * milliseconds. A negative time-to-live value indicates entries never
+         * expire. A zero time-to-live value indicates entries expire (nearly)
+         * immediately.
+         * 
+         * @param timeToLiveMillis the constant amount of time (in 
milliseconds)
+         *        an entry is available before it expires. A negative value
+         *        results in entries that NEVER expire. A zero value results in
+         *        entries that ALWAYS expire.
+         */
+        public ConstantTimeToLiveExpirationPolicy(long timeToLiveMillis) {
+            super();
+            this.timeToLiveMillis = timeToLiveMillis;
+        }
+
+        /**
+         * Construct a policy with the given time-to-live constant measured in
+         * the given time unit of measure.
+         * 
+         * @param timeToLive the constant amount of time an entry is available
+         *        before it expires. A negative value results in entries that
+         *        NEVER expire. A zero value results in entries that ALWAYS
+         *        expire.
+         * @param timeUnit the unit of time for the <code>timeToLive</code>
+         *        parameter, must not be null.
+         * @throws IllegalArgumentException if the time unit is null.
+         */
+        public ConstantTimeToLiveExpirationPolicy(long timeToLive,
+                                                  TimeUnit timeUnit) {
+            this(validateAndConvertToMillis(timeToLive, 
TimeUnit.MILLISECONDS));
+        }
+
+        /**
+         * Determine the expiration time for the given key-value entry.
+         * 
+         * @param key the key for the entry (ignored).
+         * @param value the value for the entry (ignored).
+         * @return if {@link #timeToLiveMillis} &ge; 0, an expiration time of
+         *         {@link #timeToLiveMillis} +
+         *         {@link System#currentTimeMillis()} is returned. Otherwise, 
-1
+         *         is returned indicating the entry never expires.
+         */
+        public long expirationTime(K key, V value) {
+            if (timeToLiveMillis >= 0L) {
+                // avoid numerical overflow
+                long now = System.currentTimeMillis();
+                if (now > Long.MAX_VALUE - timeToLiveMillis) {
+                    // expiration would be greater than Long.MAX_VALUE
+                    // never expire
+                    return -1;
+                }
+
+                // timeToLiveMillis in the future
+                return now + timeToLiveMillis;
+            }
+
+            // never expire
+            return -1L;
+        }
+    }
+
+    /**
+     * A policy to determine the expiration time for key-value entries.
+     * 
+     * @param <K> the key object type.
+     * @param <V> the value object type
+     * @since 4.0
+     * @version $Id: $
+     */
+    public static interface ExpirationPolicy<K, V>
+        extends Serializable {
+
+        /**
+         * Determine the expiration time for the given key-value entry.
+         * 
+         * @param key the key for the entry.
+         * @param value the value for the entry.
+         * @return the expiration time value measured in milliseconds. A
+         *         negative return value indicates the entry never expires.
+         */
+        long expirationTime(K key, V value);
+    }
+
+    /** Serialization version */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * First validate the input parameters. If the parameters are valid, 
convert
+     * the given time measured in the given units to the same time measured in
+     * milliseconds. If the parameters are invalid, an
+     * {@link IllegalArgumentException} is thrown.
+     * 
+     * @param timeToLive the constant amount of time an entry is available
+     *        before it expires. A negative value results in entries that NEVER
+     *        expire. A zero value results in entries that ALWAYS expire.
+     * @param timeUnit the unit of time for the <code>timeToLive</code>
+     *        parameter, must not be null.
+     * @throws IllegalArgumentException if the time unit is null.
+     */
+    private static long validateAndConvertToMillis(long timeToLive,
+                                                   TimeUnit timeUnit) {
+        if (timeUnit == null) {
+            throw new IllegalArgumentException("Time unit must not be null");
+        }
+        return timeUnit.convert(timeToLive, TimeUnit.MILLISECONDS);
+    }
+
+    /** map used to manage expiration times for the actual map entries. */
+    private final Map<Object, Long> expirationMap = new HashMap<Object, 
Long>();
+
+    /** the policy used to determine time-to-live values for map entries. */
+    private final ExpirationPolicy<K, V> expiringPolicy;
+
+    /**
+     * Default constructor. Constructs a map decorator that results in entries
+     * NEVER expiring.
+     */
+    public PassiveExpiringMap() {
+        this(-1L);
+    }
+
+    /**
+     * Construct a map decorator using the given expiration policy to determine
+     * expiration times.
+     * 
+     * @param expiringPolicy the policy used to determine expiration times of
+     *        entries as they are added.
+     */
+    public PassiveExpiringMap(ExpirationPolicy<K, V> expiringPolicy) {
+        this(expiringPolicy, new HashMap<K, V>());
+    }
+
+    /**
+     * Construct a map decorator that decorates the given map and uses the 
given
+     * expiration policy to determine expiration times. If there are any
+     * elements already in the map being decorated, they will NEVER expire
+     * unless they are replaced.
+     * 
+     * @param expiringPolicy the policy used to determine expiration times of
+     *        entries as they are added.
+     * @param map the map to decorate, must not be null.
+     * @throws IllegalArgumentException if the map is null.
+     */
+    public PassiveExpiringMap(ExpirationPolicy<K, V> expiringPolicy,
+                              Map<K, V> map) {
+        super(map);
+        if (expiringPolicy == null) {
+            throw new IllegalArgumentException("Policy must not be null.");
+        }
+        this.expiringPolicy = expiringPolicy;
+    }
+
+    /**
+     * Construct a map decorator that decorates the given map using the given
+     * time-to-live value measured in milliseconds to create and use a
+     * {@link ConstantTimeToLiveExpirationPolicy} expiration policy.
+     * 
+     * @param timeToLiveMillis the constant amount of time (in milliseconds) an
+     *        entry is available before it expires. A negative value results in
+     *        entries that NEVER expire. A zero value results in entries that
+     *        ALWAYS expire.
+     */
+    public PassiveExpiringMap(long timeToLiveMillis) {
+        this(new ConstantTimeToLiveExpirationPolicy<K, V>(timeToLiveMillis),
+             new HashMap<K, V>());
+    }
+
+    /**
+     * Construct a map decorator using the given time-to-live value measured in
+     * milliseconds to create and use a
+     * {@link ConstantTimeToLiveExpirationPolicy} expiration policy. If there
+     * are any elements already in the map being decorated, they will NEVER
+     * expire unless they are replaced.
+     * 
+     * @param timeToLiveMillis the constant amount of time (in milliseconds) an
+     *        entry is available before it expires. A negative value results in
+     *        entries that NEVER expire. A zero value results in entries that
+     *        ALWAYS expire.
+     * @param map the map to decorate, must not be null.
+     * @throws IllegalArgumentException if the map is null.
+     */
+    public PassiveExpiringMap(long timeToLiveMillis, Map<K, V> map) {
+        this(new ConstantTimeToLiveExpirationPolicy<K, V>(timeToLiveMillis),
+             map);
+    }
+
+    /**
+     * Construct a map decorator using the given time-to-live value measured in
+     * the given time units of measure to create and use a
+     * {@link ConstantTimeToLiveExpirationPolicy} expiration policy.
+     * 
+     * @param timeToLive the constant amount of time an entry is available
+     *        before it expires. A negative value results in entries that NEVER
+     *        expire. A zero value results in entries that ALWAYS expire.
+     * @param timeUnit the unit of time for the <code>timeToLive</code>
+     *        parameter, must not be null.
+     * @throws IllegalArgumentException if the time unit is null.
+     */
+    public PassiveExpiringMap(long timeToLive, TimeUnit timeUnit) {
+        this(validateAndConvertToMillis(timeToLive, timeUnit));
+    }
+
+    /**
+     * Construct a map decorator that decorates the given map using the given
+     * time-to-live value measured in the given time units of measure to create
+     * {@link ConstantTimeToLiveExpirationPolicy} expiration policy. This 
policy
+     * is used to determine expiration times. If there are any elements already
+     * in the map being decorated, they will NEVER expire unless they are
+     * replaced.
+     * 
+     * @param timeToLive the constant amount of time an entry is available
+     *        before it expires. A negative value results in entries that NEVER
+     *        expire. A zero value results in entries that ALWAYS expire.
+     * @param timeUnit the unit of time for the <code>timeToLive</code>
+     *        parameter, must not be null.
+     * @throws IllegalArgumentException if the time unit is null.
+     * @param map the map to decorate, must not be null.
+     * @throws IllegalArgumentException if the map is null.
+     */
+    public PassiveExpiringMap(long timeToLive, TimeUnit timeUnit, Map<K, V> 
map) {
+        this(validateAndConvertToMillis(timeToLive, timeUnit), map);
+    }
+
+    /**
+     * Constructs a map decorator that decorates the given map and results in
+     * entries NEVER expiring. If there are any elements already in the map
+     * being decorated, they also will NEVER expire.
+     * 
+     * @param map the map to decorate, must not be null.
+     * @throws IllegalArgumentException if the map is null.
+     */
+    public PassiveExpiringMap(Map<K, V> map) {
+        this(-1L, map);
+    }
+
+    /**
+     * Normal {@link Map#clear()} behavior with the addition of clearing all
+     * expiration entries as well.
+     */
+    @Override
+    public void clear() {
+        super.clear();
+        expirationMap.clear();
+    }
+
+    /**
+     * All expired entries are removed from the map prior to determining the
+     * contains result.
+     */
+    @Override
+    public boolean containsKey(Object key) {
+        removeIfExpired(key, now());
+        return super.containsKey(key);
+    }
+
+    /**
+     * All expired entries are removed from the map prior to determining the
+     * contains result.
+     */
+    @Override
+    public boolean containsValue(Object value) {
+        removeAllExpired(now());
+        return super.containsValue(value);
+    }
+
+    /**
+     * All expired entries are removed from the map prior to returning the 
entry
+     * set.
+     */
+    @Override
+    public Set<Entry<K, V>> entrySet() {
+        removeAllExpired(now());
+        return super.entrySet();
+    }
+
+    /**
+     * All expired entries are removed from the map prior to returning the 
entry
+     * value.
+     */
+    @Override
+    public V get(Object key) {
+        removeIfExpired(key, now());
+        return super.get(key);
+    }
+
+    /**
+     * All expired entries are removed from the map prior to determining if it
+     * is empty.
+     */
+    @Override
+    public boolean isEmpty() {
+        removeAllExpired(now());
+        return super.isEmpty();
+    }
+
+    /**
+     * Determines if the given expiration time is less than <code>now</code>
+     * 
+     * @param now the time in milliseconds used to compare against the
+     *        expiration time.
+     * @param expirationTimeObject the expiration time value retrieved from
+     *        {@link #expirationMap}, can be null.
+     * @return <code>true</code> if <code>expirationTimeObject</code> is &ge; 0
+     *         and <code>expirationTimeObject</code> &lt; <code>now</code>.
+     *         <code>false</code> otherwise.
+     */
+    private boolean isExpired(long now, Long expirationTimeObject) {
+        if (expirationTimeObject != null) {
+            long expirationTime = expirationTimeObject.longValue();
+            return (expirationTime >= 0 && now >= expirationTime);
+        }
+        return false;
+    }
+
+    /**
+     * All expired entries are removed from the map prior to returning the key
+     * set.
+     */
+    @Override
+    public Set<K> keySet() {
+        removeAllExpired(now());
+        return super.keySet();
+    }
+
+    /**
+     * The current time in milliseconds.
+     */
+    private long now() {
+        return System.currentTimeMillis();
+    }
+
+    @Override
+    public V put(K key, V value) {
+        return put(key, value, now());
+    }
+
+    /**
+     * Add the given key-value pair to this map as well as recording the 
entry's
+     * expiration time based on the current time in milliseconds,
+     * <code>now</code> and this map's {@link #expiringPolicy}.
+     */
+    private V put(K key, V value, long now) {
+        // record expiration time of new entry
+        long expirationTime = expiringPolicy.expirationTime(key, value);
+        expirationMap.put(key, Long.valueOf(expirationTime));
+
+        return super.put(key, value);
+    }
+
+    @Override
+    public void putAll(Map<? extends K, ? extends V> mapToCopy) {
+        for (Map.Entry<? extends K, ? extends V> entry : mapToCopy.entrySet()) 
{
+            put(entry.getKey(), entry.getValue());
+        }
+    }
+
+    /**
+     * Normal {@link Map#remove(Object)} behavior with the addition of removing
+     * any expiration entry as well.
+     */
+    @Override
+    public V remove(Object key) {
+        expirationMap.remove(key);
+        return super.remove(key);
+    }
+
+    /**
+     * Removes all entries in the map whose expiration time is less than
+     * <code>now</code>. The exceptions are entries with negative expiration
+     * times; those entries are never removed.
+     * 
+     * @see #isExpired(long, Long)
+     */
+    private void removeAllExpired(long now) {
+        Iterator<Map.Entry<Object, Long>> iter = expirationMap.entrySet()
+            .iterator();
+        while (iter.hasNext()) {
+            Map.Entry<Object, Long> expirationEntry = iter.next();
+            if (isExpired(now, expirationEntry.getValue())) {
+                // remove entry from collection
+                super.remove(expirationEntry.getKey());
+                // remove entry from expiration map
+                iter.remove();
+            }
+        }
+    }
+
+    /**
+     * Removes the entry with the given key if the entry's expiration time is
+     * less than <code>now</code>. If the entry has a negative expiration time,
+     * the entry is never removed.
+     */
+    private void removeIfExpired(Object key, long now) {
+        Long expirationTimeObject = expirationMap.get(key);
+        if (isExpired(now, expirationTimeObject)) {
+            remove(key);
+        }
+    }
+
+    /**
+     * All expired entries are removed from the map prior to returning the 
size.
+     */
+    @Override
+    public int size() {
+        removeAllExpired(now());
+        return super.size();
+    }
+
+    /**
+     * Read the map in using a custom routine.
+     * 
+     * @param in the input stream
+     * @throws IOException
+     * @throws ClassNotFoundException
+     */
+    @SuppressWarnings("unchecked")
+    // (1) should only fail if input stream is incorrect
+    private void readObject(ObjectInputStream in)
+        throws IOException, ClassNotFoundException {
+        in.defaultReadObject();
+        map = (Map<K, V>) in.readObject(); // (1)
+    }
+
+    /**
+     * Write the map out using a custom routine.
+     * 
+     * @param out the output stream
+     * @throws IOException
+     */
+    private void writeObject(ObjectOutputStream out)
+        throws IOException {
+        out.defaultWriteObject();
+        out.writeObject(map);
+    }
+
+    /**
+     * All expired entries are removed from the map prior to returning the 
value
+     * collection.
+     */
+    @Override
+    public Collection<V> values() {
+        removeAllExpired(now());
+        return super.values();
+    }
 }

Modified: 
commons/proper/collections/trunk/src/test/java/org/apache/commons/collections/map/TestPassiveExpiringMap.java
URL: 
http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/test/java/org/apache/commons/collections/map/TestPassiveExpiringMap.java?rev=1377492&r1=1377491&r2=1377492&view=diff
==============================================================================
--- 
commons/proper/collections/trunk/src/test/java/org/apache/commons/collections/map/TestPassiveExpiringMap.java
 (original)
+++ 
commons/proper/collections/trunk/src/test/java/org/apache/commons/collections/map/TestPassiveExpiringMap.java
 Sun Aug 26 19:35:45 2012
@@ -9,199 +9,201 @@ import junit.framework.Test;
 import org.apache.commons.collections.BulkTest;
 import org.apache.commons.collections.map.PassiveExpiringMap.ExpirationPolicy;
 
-public class TestPassiveExpiringMap<K, V> extends AbstractTestMap<K, V> {
+public class TestPassiveExpiringMap<K, V>
+    extends AbstractTestMap<K, V> {
 
-       private static class TestExpirationPolicy implements
-                       ExpirationPolicy<Integer, String> {
+    private static class TestExpirationPolicy
+        implements ExpirationPolicy<Integer, String> {
 
-               private static final long serialVersionUID = 1L;
+        private static final long serialVersionUID = 1L;
 
-               public long expirationTime(Integer key, String value) {
-                       // odd keys expire immediately, even keys never expire
-                       if (key == null) {
-                               return 0;
-                       }
-
-                       if (key.intValue() % 2 == 0) {
-                               return -1;
-                       }
-
-                       return 0;
-               }
-       }
-
-       public static Test suite() {
-               return BulkTest.makeSuite(TestPassiveExpiringMap.class);
-       }
-
-       public TestPassiveExpiringMap(String testName) {
-               super(testName);
-       }
-
-       // public void testCreate() throws Exception {
-       // writeExternalFormToDisk((java.io.Serializable) makeObject(),
-       // "PassiveExpiringMap.emptyCollection.version4.obj");
-       //
-       // writeExternalFormToDisk((java.io.Serializable) makeFullMap(),
-       // "PassiveExpiringMap.fullCollection.version4.obj");
-       // }
-
-       @Override
-       public String getCompatibilityVersion() {
-               return "4";
-       }
-
-       private Map<Integer, String> makeDecoratedTestMap() {
-               Map<Integer, String> m = new HashMap<Integer, String>();
-               m.put(Integer.valueOf(1), "one");
-               m.put(Integer.valueOf(2), "two");
-               m.put(Integer.valueOf(3), "three");
-               m.put(Integer.valueOf(4), "four");
-               m.put(Integer.valueOf(5), "five");
-               m.put(Integer.valueOf(6), "six");
-               return new PassiveExpiringMap<Integer, String>(
-                               new TestExpirationPolicy(), m);
-       }
-
-       @Override
-       public Map<K, V> makeObject() {
-               return new PassiveExpiringMap<K, V>();
-       }
-
-       private Map<Integer, String> makeTestMap() {
-               Map<Integer, String> m = new PassiveExpiringMap<Integer, 
String>(
-                               new TestExpirationPolicy());
-               m.put(Integer.valueOf(1), "one");
-               m.put(Integer.valueOf(2), "two");
-               m.put(Integer.valueOf(3), "three");
-               m.put(Integer.valueOf(4), "four");
-               m.put(Integer.valueOf(5), "five");
-               m.put(Integer.valueOf(6), "six");
-               return m;
-       }
-
-       public void testConstructors() {
-               try {
-                       Map<String, String> map = null;
-                       new PassiveExpiringMap<String, String>(map);
-                       fail("constructor - exception should have been 
thrown.");
-               } catch (IllegalArgumentException ex) {
-                       // success
-               }
-
-               try {
-                       ExpirationPolicy<String, String> policy = null;
-                       new PassiveExpiringMap<String, String>(policy);
-                       fail("constructor - exception should have been 
thrown.");
-               } catch (IllegalArgumentException ex) {
-                       // success
-               }
-
-               try {
-                       TimeUnit unit = null;
-                       new PassiveExpiringMap<String, String>(10L, unit);
-                       fail("constructor - exception should have been 
thrown.");
-               } catch (IllegalArgumentException ex) {
-                       // success
-               }
-       }
-
-       public void testContainsKey() {
-               Map<Integer, String> m = makeTestMap();
-               assertFalse(m.containsKey(Integer.valueOf(1)));
-               assertFalse(m.containsKey(Integer.valueOf(3)));
-               assertFalse(m.containsKey(Integer.valueOf(5)));
-               assertTrue(m.containsKey(Integer.valueOf(2)));
-               assertTrue(m.containsKey(Integer.valueOf(4)));
-               assertTrue(m.containsKey(Integer.valueOf(6)));
-       }
-
-       public void testContainsValue() {
-               Map<Integer, String> m = makeTestMap();
-               assertFalse(m.containsValue("one"));
-               assertFalse(m.containsValue("three"));
-               assertFalse(m.containsValue("five"));
-               assertTrue(m.containsValue("two"));
-               assertTrue(m.containsValue("four"));
-               assertTrue(m.containsValue("six"));
-       }
-
-       public void testDecoratedMap() {
-               // entries shouldn't expire
-               Map<Integer, String> m = makeDecoratedTestMap();
-               assertEquals(6, m.size());
-               assertEquals("one", m.get(Integer.valueOf(1)));
-
-               // removing a single item shouldn't affect any other items
-               assertEquals("two", m.get(Integer.valueOf(2)));
-               m.remove(Integer.valueOf(2));
-               assertEquals(5, m.size());
-               assertEquals("one", m.get(Integer.valueOf(1)));
-               assertNull(m.get(Integer.valueOf(2)));
-
-               // adding a single, even item shouldn't affect any other items
-               assertNull(m.get(Integer.valueOf(2)));
-               m.put(Integer.valueOf(2), "two");
-               assertEquals(6, m.size());
-               assertEquals("one", m.get(Integer.valueOf(1)));
-               assertEquals("two", m.get(Integer.valueOf(2)));
-
-               // adding a single, odd item (one that expires) shouldn't 
affect any
-               // other items
-               // put the entry expires immediately
-               m.put(Integer.valueOf(1), "one-one");
-               assertEquals(5, m.size());
-               assertNull(m.get(Integer.valueOf(1)));
-               assertEquals("two", m.get(Integer.valueOf(2)));
-       }
-
-       public void testEntrySet() {
-               Map<Integer, String> m = makeTestMap();
-               assertEquals(3, m.entrySet().size());
-       }
-
-       public void testGet() {
-               Map<Integer, String> m = makeTestMap();
-               assertNull(m.get(Integer.valueOf(1)));
-               assertEquals("two", m.get(Integer.valueOf(2)));
-               assertNull(m.get(Integer.valueOf(3)));
-               assertEquals("four", m.get(Integer.valueOf(4)));
-               assertNull(m.get(Integer.valueOf(5)));
-               assertEquals("six", m.get(Integer.valueOf(6)));
-       }
-
-       public void testIsEmpty() {
-               Map<Integer, String> m = makeTestMap();
-               assertFalse(m.isEmpty());
-
-               // remove just evens
-               m = makeTestMap();
-               m.remove(Integer.valueOf(2));
-               m.remove(Integer.valueOf(4));
-               m.remove(Integer.valueOf(6));
-               assertTrue(m.isEmpty());
-       }
-
-       public void testKeySet() {
-               Map<Integer, String> m = makeTestMap();
-               assertEquals(3, m.keySet().size());
-       }
-
-       public void testSize() {
-               Map<Integer, String> m = makeTestMap();
-               assertEquals(3, m.size());
-       }
-
-       public void testValues() {
-               Map<Integer, String> m = makeTestMap();
-               assertEquals(3, m.values().size());
-       }
-
-       public void testZeroTimeToLive() {
-               // item should not be available
-               PassiveExpiringMap<String, String> m = new 
PassiveExpiringMap<String, String>(
-                               0L);
-               m.put("a", "b");
-               assertNull(m.get("a"));
-       }
+        public long expirationTime(Integer key, String value) {
+            // odd keys expire immediately, even keys never expire
+            if (key == null) {
+                return 0;
+            }
+
+            if (key.intValue() % 2 == 0) {
+                return -1;
+            }
+
+            return 0;
+        }
+    }
+
+    public static Test suite() {
+        return BulkTest.makeSuite(TestPassiveExpiringMap.class);
+    }
+
+    public TestPassiveExpiringMap(String testName) {
+        super(testName);
+    }
+
+    // public void testCreate() throws Exception {
+    // writeExternalFormToDisk((java.io.Serializable) makeObject(),
+    // "PassiveExpiringMap.emptyCollection.version4.obj");
+    //
+    // writeExternalFormToDisk((java.io.Serializable) makeFullMap(),
+    // "PassiveExpiringMap.fullCollection.version4.obj");
+    // }
+
+    @Override
+    public String getCompatibilityVersion() {
+        return "4";
+    }
+
+    private Map<Integer, String> makeDecoratedTestMap() {
+        Map<Integer, String> m = new HashMap<Integer, String>();
+        m.put(Integer.valueOf(1), "one");
+        m.put(Integer.valueOf(2), "two");
+        m.put(Integer.valueOf(3), "three");
+        m.put(Integer.valueOf(4), "four");
+        m.put(Integer.valueOf(5), "five");
+        m.put(Integer.valueOf(6), "six");
+        return new PassiveExpiringMap<Integer, String>(
+                                                       new 
TestExpirationPolicy(),
+                                                       m);
+    }
+
+    @Override
+    public Map<K, V> makeObject() {
+        return new PassiveExpiringMap<K, V>();
+    }
+
+    private Map<Integer, String> makeTestMap() {
+        Map<Integer, String> m = new PassiveExpiringMap<Integer, String>(
+                                                                         new 
TestExpirationPolicy());
+        m.put(Integer.valueOf(1), "one");
+        m.put(Integer.valueOf(2), "two");
+        m.put(Integer.valueOf(3), "three");
+        m.put(Integer.valueOf(4), "four");
+        m.put(Integer.valueOf(5), "five");
+        m.put(Integer.valueOf(6), "six");
+        return m;
+    }
+
+    public void testConstructors() {
+        try {
+            Map<String, String> map = null;
+            new PassiveExpiringMap<String, String>(map);
+            fail("constructor - exception should have been thrown.");
+        } catch (IllegalArgumentException ex) {
+            // success
+        }
+
+        try {
+            ExpirationPolicy<String, String> policy = null;
+            new PassiveExpiringMap<String, String>(policy);
+            fail("constructor - exception should have been thrown.");
+        } catch (IllegalArgumentException ex) {
+            // success
+        }
+
+        try {
+            TimeUnit unit = null;
+            new PassiveExpiringMap<String, String>(10L, unit);
+            fail("constructor - exception should have been thrown.");
+        } catch (IllegalArgumentException ex) {
+            // success
+        }
+    }
+
+    public void testContainsKey() {
+        Map<Integer, String> m = makeTestMap();
+        assertFalse(m.containsKey(Integer.valueOf(1)));
+        assertFalse(m.containsKey(Integer.valueOf(3)));
+        assertFalse(m.containsKey(Integer.valueOf(5)));
+        assertTrue(m.containsKey(Integer.valueOf(2)));
+        assertTrue(m.containsKey(Integer.valueOf(4)));
+        assertTrue(m.containsKey(Integer.valueOf(6)));
+    }
+
+    public void testContainsValue() {
+        Map<Integer, String> m = makeTestMap();
+        assertFalse(m.containsValue("one"));
+        assertFalse(m.containsValue("three"));
+        assertFalse(m.containsValue("five"));
+        assertTrue(m.containsValue("two"));
+        assertTrue(m.containsValue("four"));
+        assertTrue(m.containsValue("six"));
+    }
+
+    public void testDecoratedMap() {
+        // entries shouldn't expire
+        Map<Integer, String> m = makeDecoratedTestMap();
+        assertEquals(6, m.size());
+        assertEquals("one", m.get(Integer.valueOf(1)));
+
+        // removing a single item shouldn't affect any other items
+        assertEquals("two", m.get(Integer.valueOf(2)));
+        m.remove(Integer.valueOf(2));
+        assertEquals(5, m.size());
+        assertEquals("one", m.get(Integer.valueOf(1)));
+        assertNull(m.get(Integer.valueOf(2)));
+
+        // adding a single, even item shouldn't affect any other items
+        assertNull(m.get(Integer.valueOf(2)));
+        m.put(Integer.valueOf(2), "two");
+        assertEquals(6, m.size());
+        assertEquals("one", m.get(Integer.valueOf(1)));
+        assertEquals("two", m.get(Integer.valueOf(2)));
+
+        // adding a single, odd item (one that expires) shouldn't affect any
+        // other items
+        // put the entry expires immediately
+        m.put(Integer.valueOf(1), "one-one");
+        assertEquals(5, m.size());
+        assertNull(m.get(Integer.valueOf(1)));
+        assertEquals("two", m.get(Integer.valueOf(2)));
+    }
+
+    public void testEntrySet() {
+        Map<Integer, String> m = makeTestMap();
+        assertEquals(3, m.entrySet().size());
+    }
+
+    public void testGet() {
+        Map<Integer, String> m = makeTestMap();
+        assertNull(m.get(Integer.valueOf(1)));
+        assertEquals("two", m.get(Integer.valueOf(2)));
+        assertNull(m.get(Integer.valueOf(3)));
+        assertEquals("four", m.get(Integer.valueOf(4)));
+        assertNull(m.get(Integer.valueOf(5)));
+        assertEquals("six", m.get(Integer.valueOf(6)));
+    }
+
+    public void testIsEmpty() {
+        Map<Integer, String> m = makeTestMap();
+        assertFalse(m.isEmpty());
+
+        // remove just evens
+        m = makeTestMap();
+        m.remove(Integer.valueOf(2));
+        m.remove(Integer.valueOf(4));
+        m.remove(Integer.valueOf(6));
+        assertTrue(m.isEmpty());
+    }
+
+    public void testKeySet() {
+        Map<Integer, String> m = makeTestMap();
+        assertEquals(3, m.keySet().size());
+    }
+
+    public void testSize() {
+        Map<Integer, String> m = makeTestMap();
+        assertEquals(3, m.size());
+    }
+
+    public void testValues() {
+        Map<Integer, String> m = makeTestMap();
+        assertEquals(3, m.values().size());
+    }
+
+    public void testZeroTimeToLive() {
+        // item should not be available
+        PassiveExpiringMap<String, String> m = new PassiveExpiringMap<String, 
String>(
+                                                                               
       0L);
+        m.put("a", "b");
+        assertNull(m.get("a"));
+    }
 }


Reply via email to