package org.freehep.util.parameterdatabase; import java.util.LinkedList; public class ParameterKey { /** * The object to which this parameter belongs. */ private Object object; /** * The name of this parameter. */ private String name; /** * This monitors the state of this ParameterKey. If this key has been * cleared, then this ParameterKey is invalid and most user-visible calls * will return an IllegalStateException. */ private boolean isValid; /** * This contains the maximum number of recycled keys. */ static private int inventoryLimit = 10000; /** * This linked list contains the set of recycled keys. */ static private LinkedList inventory = new LinkedList(); /** * This protected constructor creates a new ParameterKey with the given * parameters. Users should not create ParameterKeys via this constructor, * but should instead use the static factory method createParameterKey(). */ protected ParameterKey(Object object, String name) { this.object = object; this.name = name; isValid = true; } /** * This static factory method returns a ParameterKey using the given * arguments. This method will try to use a recycled ParameterKey if one is * available. */ static public ParameterKey createParameterKey(Object object, String name) { // Check the validity of the input parameters. Neither one // can be null. if (object == null || name == null) { throw new IllegalArgumentException(); } ParameterKey newKey = null; // First check to see if a key is already available. This // must be synchronized to guarantee that the same key isn't // given out twice by accident. synchronized (inventory) { if (!inventory.isEmpty()) { newKey = (ParameterKey) inventory.removeFirst(); newKey.object = object; newKey.name = name; newKey.isValid = true; } } // If we couldn't find an existing key, then make a new one. if (newKey == null) { newKey = new ParameterKey(object, name); } return newKey; } /** * Return the object associated with this ParameterKey. Note that no * operations should be performed on the returned object which will affect * the results of the equals() method. */ public Object getObject() { if (!isValid) throw new IllegalStateException(); return object; } /** * Return the name of the parameter. */ public String getName() { if (!isValid) throw new IllegalStateException(); return name; } /** * This method will recycle this ParameterKey. Any further user method calls * on this object will result in an IllegalStateException being thrown. This * object will be available for reuse only after the JVM determines that * there are no more outstanding references to this ParameterKey and the JVM * runs the finalize() method. */ protected void recycle() { isValid = false; object = null; name = null; } /** * Two ParameterKeys are equal if and only if the corresponding objects and * names are equal. */ public boolean equals(Object otherKey) { if (!isValid) throw new IllegalStateException(); if (!(otherKey instanceof ParameterKey)) { return false; } else { ParameterKey other = (ParameterKey) otherKey; if (!other.isValid) throw new IllegalStateException(); return (object.equals(other.object) && name.equals(other.name)); } } /** * The hashcode returned is simply the exclusive-or of the hashcodes of the * object and the name. */ public int hashCode() { if (!isValid) throw new IllegalStateException(); return (object.hashCode() ^ name.hashCode()); } /** * We override the finalize method to allow this ParameterKey to be * recycled. It is added to the list of recycled keys if the inventory is * below the given limit. */ public void finalize() throws Throwable { // Recycle this key if we haven't exceeded the limit. A // normal return will allow this key to be garbage collected // normally. synchronized (inventory) { if (inventory.size() < inventoryLimit) { recycle(); inventory.add(this); throw new Throwable(); } } } }