[jboss-svn-commits] JBoss Common SVN: r2517 - in common-core/trunk/src/main/java/org/jboss/util: builder and 1 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Tue Aug 28 06:52:18 EDT 2007
Author: adrian at jboss.org
Date: 2007-08-28 06:52:18 -0400 (Tue, 28 Aug 2007)
New Revision: 2517
Added:
common-core/trunk/src/main/java/org/jboss/util/builder/
common-core/trunk/src/main/java/org/jboss/util/builder/AbstractBuilder.java
common-core/trunk/src/main/java/org/jboss/util/collection/WeakTypeCache.java
Modified:
common-core/trunk/src/main/java/org/jboss/util/collection/WeakValueHashMap.java
Log:
[JBCOMMON-31] - Collections from the Microcontainer project
Added: common-core/trunk/src/main/java/org/jboss/util/builder/AbstractBuilder.java
===================================================================
--- common-core/trunk/src/main/java/org/jboss/util/builder/AbstractBuilder.java (rev 0)
+++ common-core/trunk/src/main/java/org/jboss/util/builder/AbstractBuilder.java 2007-08-28 10:52:18 UTC (rev 2517)
@@ -0,0 +1,72 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2007, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This 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 software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.util.builder;
+
+import java.security.PrivilegedAction;
+
+/**
+ * AbstractBuilder.
+ *
+ * @param <T> the type to be built
+ * @author <a href="adrian at jboss.org">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class AbstractBuilder<T> implements PrivilegedAction<T>
+{
+ /** The factory class */
+ private Class<T> factoryClass;
+
+ /** The default factory */
+ private String defaultFactory;
+
+ /**
+ * Create a new AbstractBuilder.
+ *
+ * @param factoryClass the factory class
+ * @param defaultFactory the default factory
+ * @throws IllegalArgumentException for a null parameter
+ */
+ public AbstractBuilder(Class<T> factoryClass, String defaultFactory)
+ {
+ if (factoryClass == null)
+ throw new IllegalArgumentException("Null factory class");
+ if (defaultFactory == null)
+ throw new IllegalArgumentException("Null default factory");
+ this.factoryClass = factoryClass;
+ this.defaultFactory = defaultFactory;
+ }
+
+ public T run()
+ {
+ try
+ {
+ String className = System.getProperty(factoryClass.getName(), defaultFactory);
+ Class<?> clazz = Thread.currentThread().getContextClassLoader().loadClass(className);
+ Object object = clazz.newInstance();
+ return factoryClass.cast(object);
+ }
+ catch (Throwable t)
+ {
+ throw new RuntimeException("Error constructing " + factoryClass.getName(), t);
+ }
+ }
+}
Added: common-core/trunk/src/main/java/org/jboss/util/collection/WeakTypeCache.java
===================================================================
--- common-core/trunk/src/main/java/org/jboss/util/collection/WeakTypeCache.java (rev 0)
+++ common-core/trunk/src/main/java/org/jboss/util/collection/WeakTypeCache.java 2007-08-28 10:52:18 UTC (rev 2517)
@@ -0,0 +1,301 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This 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 software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.util.collection;
+
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.GenericDeclaration;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.lang.reflect.WildcardType;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+/**
+ * A weak class cache that instantiates does not a hold a
+ * strong reference to either the classloader or class.<p>
+ *
+ * It creates the class specific data in two stages
+ * to avoid recursion.<p>
+ *
+ * instantiate - creates the data<br>
+ * generate - fills in the details
+ *
+ * @param <T> the cached type
+ * @author <a href="mailto:adrian at jboss.org">Adrian Brock</a>
+ */
+public abstract class WeakTypeCache<T>
+{
+ /** The cache */
+ private Map<ClassLoader, Map<String, T>> cache = new WeakHashMap<ClassLoader, Map<String, T>>();
+
+ /**
+ * Get the information for a type
+ *
+ * @param type the type
+ * @return the info
+ */
+ @SuppressWarnings("unchecked")
+ public T get(Type type)
+ {
+ if (type == null)
+ throw new IllegalArgumentException("Null type");
+
+ if (type instanceof ParameterizedType)
+ return getParameterizedType((ParameterizedType) type);
+ else if (type instanceof Class)
+ return getClass((Class<?>) type);
+ else if (type instanceof TypeVariable)
+ return getTypeVariable((TypeVariable) type);
+ else if (type instanceof GenericArrayType)
+ return getGenericArrayType((GenericArrayType) type);
+ else if (type instanceof WildcardType)
+ return getWildcardType((WildcardType) type);
+ else
+ throw new UnsupportedOperationException("Unknown type: " + type + " class=" + type.getClass());
+ }
+
+ /**
+ * Get the information for a class
+ *
+ * @param name the name
+ * @param cl the classloader
+ * @return the info
+ * @throws ClassNotFoundException when the class cannot be found
+ */
+ public T get(String name, ClassLoader cl) throws ClassNotFoundException
+ {
+ if (name == null)
+ throw new IllegalArgumentException("Null name");
+ if (cl == null)
+ throw new IllegalArgumentException("Null classloader");
+
+ Class<?> clazz = cl.loadClass(name);
+ return get(clazz);
+ }
+
+ /**
+ * Instantiate for a class
+ *
+ * @param clazz the class
+ * @return the result
+ */
+ protected abstract T instantiate(Class<?> clazz);
+
+ /**
+ * Fill in the result
+ *
+ * @param clazz the class
+ * @param result the result
+ */
+ protected abstract void generate(Class<?> clazz, T result);
+
+ /**
+ * Instantiate for a parameterized type
+ *
+ * @param type the parameterized type
+ * @return the result
+ */
+ protected abstract T instantiate(ParameterizedType type);
+
+ /**
+ * Fill in the result
+ *
+ * @param type the parameterized type
+ * @param result the result
+ */
+ protected abstract void generate(ParameterizedType type, T result);
+
+ /**
+ * Get the information for a parameterized type
+ *
+ * @param type the paremeterized type
+ * @return the info
+ */
+ private T getParameterizedType(ParameterizedType type)
+ {
+ // First check if we already have it
+ T result = peek(type);
+ if (result != null)
+ return result;
+
+ // Instantiate
+ result = instantiate(type);
+
+ // Put the perlimanary result into the cache
+ put(type, result);
+
+ // Generate the details
+ generate(type, result);
+
+ return result;
+ }
+
+ /**
+ * Get the information for a wildcard type
+ *
+ * @param type the paremeterized type
+ * @return the info
+ */
+ private T getWildcardType(WildcardType type)
+ {
+ // TODO JBMICROCONT-131 improve this
+ return get(type.getUpperBounds()[0]);
+ }
+
+ /**
+ * Get the information for a type variable
+ *
+ * @param <D> the declaration
+ * @param type the type variable
+ * @return the info
+ */
+ private <D extends GenericDeclaration> T getTypeVariable(TypeVariable<D> type)
+ {
+ // TODO JBMICROCONT-131 improve this
+ return get(type.getBounds()[0]);
+ }
+
+ /**
+ * Get the information for an array type
+ *
+ * @param type the array type
+ * @return the info
+ */
+ private T getGenericArrayType(GenericArrayType type)
+ {
+ // TODO JBMICROCONT-131 this needs implementing properly
+ return get(Object[].class);
+ }
+
+ /**
+ * Peek into the cache
+ *
+ * @param type the type
+ * @return the value
+ */
+ private T peek(ParameterizedType type)
+ {
+ Class<?> rawType = (Class<?>) type.getRawType();
+ Map<String, T> classLoaderCache = getClassLoaderCache(rawType.getClassLoader());
+
+ synchronized (classLoaderCache)
+ {
+ return classLoaderCache.get(type.toString());
+ }
+ }
+
+ /**
+ * Put a result into the cache
+ *
+ * @param type the type
+ * @param result the value
+ */
+ private void put(ParameterizedType type, T result)
+ {
+ Class<?> rawType = (Class<?>) type.getRawType();
+ Map<String, T> classLoaderCache = getClassLoaderCache(rawType.getClassLoader());
+
+ synchronized (classLoaderCache)
+ {
+ // TODO JBMICROCONT-131 something better than toString()?
+ classLoaderCache.put(type.toString(), result);
+ }
+ }
+
+ /**
+ * Get the information for a class
+ *
+ * @param clazz the class
+ * @return the info
+ */
+ private T getClass(Class<?> clazz)
+ {
+ // First check if we already have it
+ T result = peek(clazz);
+ if (result != null)
+ return result;
+
+ // Instantiate
+ result = instantiate(clazz);
+
+ // Put the perlimanary result into the cache
+ put(clazz, result);
+
+ // Generate the details
+ generate(clazz, result);
+
+ return result;
+ }
+
+ /**
+ * Peek into the cache
+ *
+ * @param clazz the class
+ * @return the value
+ */
+ private T peek(Class<?> clazz)
+ {
+ Map<String, T> classLoaderCache = getClassLoaderCache(clazz.getClassLoader());
+
+ synchronized (classLoaderCache)
+ {
+ return classLoaderCache.get(clazz.getName());
+ }
+ }
+
+ /**
+ * Put a result into the cache
+ *
+ * @param clazz the class
+ * @param result the value
+ */
+ private void put(Class<?> clazz, T result)
+ {
+ Map<String, T> classLoaderCache = getClassLoaderCache(clazz.getClassLoader());
+
+ synchronized (classLoaderCache)
+ {
+ classLoaderCache.put(clazz.getName(), result);
+ }
+ }
+
+ /**
+ * Get the cache for the classloader
+ *
+ * @param cl the classloader
+ * @return the map
+ */
+ private Map<String, T> getClassLoaderCache(ClassLoader cl)
+ {
+ synchronized (cache)
+ {
+ Map<String, T> result = cache.get(cl);
+ if (result == null)
+ {
+ result = new WeakValueHashMap<String, T>();
+ cache.put(cl, result);
+ }
+ return result;
+ }
+ }
+}
Modified: common-core/trunk/src/main/java/org/jboss/util/collection/WeakValueHashMap.java
===================================================================
--- common-core/trunk/src/main/java/org/jboss/util/collection/WeakValueHashMap.java 2007-08-28 10:43:34 UTC (rev 2516)
+++ common-core/trunk/src/main/java/org/jboss/util/collection/WeakValueHashMap.java 2007-08-28 10:52:18 UTC (rev 2517)
@@ -21,73 +21,34 @@
*/
package org.jboss.util.collection;
-import java.util.Map;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
import java.util.AbstractMap;
+import java.util.AbstractSet;
import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
import java.util.Set;
-import java.lang.ref.WeakReference;
-import java.lang.ref.ReferenceQueue;
-
/**
* This Map will remove entries when the value in the map has been
* cleaned from garbage collection
*
+ * @param <K> the key type
+ * @param <V> the value type
+ * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
+ * @author <a href="mailto:adrian at jboss.org">Adrian Brock</a>
* @version <tt>$Revision$</tt>
- * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
*/
-public class WeakValueHashMap
- extends AbstractMap
- implements Map
+public class WeakValueHashMap<K, V> extends AbstractMap<K, V>
{
- private static class WeakValueRef extends WeakReference
- {
- public Object key;
+ /** Hash table mapping keys to weak values */
+ private Map<K, WeakValueRef<K, V>> hash;
- private WeakValueRef(Object key, Object val, ReferenceQueue q)
- {
- super(val, q);
- this.key = key;
- }
-
- private static WeakValueRef create(Object key, Object val, ReferenceQueue q)
- {
- if (val == null) return null;
- else return new WeakValueRef(key, val, q);
- }
-
- }
- public Set entrySet()
- {
- processQueue();
- return hash.entrySet();
- }
+ /** Reference queue for cleared WeakKeys */
+ private ReferenceQueue<V> queue = new ReferenceQueue<V>();
- /* Hash table mapping WeakKeys to values */
- private Map hash;
-
- /* Reference queue for cleared WeakKeys */
- private ReferenceQueue queue = new ReferenceQueue();
-
- /* Remove all invalidated entries from the map, that is, remove all entries
- whose values have been discarded.
- */
- private void processQueue()
- {
- WeakValueRef ref;
- while ((ref = (WeakValueRef)queue.poll()) != null) {
- if (ref == (WeakValueRef) hash.get(ref.key)) {
- // only remove if it is the *exact* same WeakValueRef
- //
- hash.remove(ref.key);
- }
- }
- }
-
-
- /* -- Constructors -- */
-
/**
* Constructs a new, empty <code>WeakHashMap</code> with the given
* initial capacity and the given load factor.
@@ -103,7 +64,7 @@
*/
public WeakValueHashMap(int initialCapacity, float loadFactor)
{
- hash = new HashMap(initialCapacity, loadFactor);
+ hash = new HashMap<K, WeakValueRef<K, V>>(initialCapacity, loadFactor);
}
/**
@@ -119,7 +80,7 @@
*/
public WeakValueHashMap(int initialCapacity)
{
- hash = new HashMap(initialCapacity);
+ hash = new HashMap<K, WeakValueRef<K, V>>(initialCapacity);
}
/**
@@ -129,7 +90,7 @@
*/
public WeakValueHashMap()
{
- hash = new HashMap();
+ hash = new HashMap<K, WeakValueRef<K, V>>();
}
/**
@@ -140,109 +101,198 @@
* <tt>0.75</tt>.
*
* @param t the map whose mappings are to be placed in this map.
- * @since 1.3
+ * @since 1.3
*/
- public WeakValueHashMap(Map t)
+ public WeakValueHashMap(Map<K, V> t)
{
this(Math.max(2*t.size(), 11), 0.75f);
putAll(t);
}
- /* -- Simple queries -- */
-
- /**
- * Returns the number of key-value mappings in this map.
- * <strong>Note:</strong> <em>In contrast with most implementations of the
- * <code>Map</code> interface, the time required by this operation is
- * linear in the size of the map.</em>
- */
+ @Override
public int size()
{
processQueue();
return hash.size();
}
- /**
- * Returns <code>true</code> if this map contains no key-value mappings.
- */
- public boolean isEmpty()
+ @Override
+ public boolean containsKey(Object key)
{
processQueue();
- return hash.isEmpty();
+ return hash.containsKey(key);
}
- /**
- * Returns <code>true</code> if this map contains a mapping for the
- * specified key.
- *
- * @param key The key whose presence in this map is to be tested
- */
- public boolean containsKey(Object key)
+ @Override
+ public V get(Object key)
{
processQueue();
- return hash.containsKey(key);
+ WeakValueRef<K, V> ref = hash.get(key);
+ if (ref != null)
+ return ref.get();
+ return null;
}
- /* -- Lookup and modification operations -- */
+ @Override
+ public V put(K key, V value)
+ {
+ processQueue();
+ WeakValueRef<K, V> ref = WeakValueRef.create(key, value, queue);
+ WeakValueRef<K, V> result = hash.put(key, ref);
+ if (result != null)
+ return result.get();
+ return null;
+ }
- /**
- * Returns the value to which this map maps the specified <code>key</code>.
- * If this map does not contain a value for this key, then return
- * <code>null</code>.
- *
- * @param key The key whose associated value, if any, is to be returned
- */
- public Object get(Object key)
+ @Override
+ public V remove(Object key)
{
processQueue();
- WeakReference ref = (WeakReference)hash.get(key);
- if (ref != null) return ref.get();
+ WeakValueRef<K, V> result = hash.remove(key);
+ if (result != null)
+ return result.get();
return null;
}
+
+ @Override
+ public Set<Entry<K,V>> entrySet()
+ {
+ processQueue();
+ return new EntrySet();
+ }
+ @Override
+ public void clear()
+ {
+ processQueue();
+ hash.clear();
+ }
+
/**
- * Updates this map so that the given <code>key</code> maps to the given
- * <code>value</code>. If the map previously contained a mapping for
- * <code>key</code> then that mapping is replaced and the previous value is
- * returned.
- *
- * @param key The key that is to be mapped to the given
- * <code>value</code>
- * @param value The value to which the given <code>key</code> is to be
- * mapped
- *
- * @return The previous value to which this key was mapped, or
- * <code>null</code> if if there was no mapping for the key
+ * Remove all entries whose values have been discarded.
*/
- public Object put(Object key, Object value)
+ @SuppressWarnings("unchecked")
+ private void processQueue()
{
- processQueue();
- Object rtn = hash.put(key, WeakValueRef.create(key, value, queue));
- if (rtn != null) rtn = ((WeakReference)rtn).get();
- return rtn;
+ WeakValueRef<K, V> ref = (WeakValueRef<K, V>) queue.poll();
+ while (ref != null)
+ {
+ // only remove if it is the *exact* same WeakValueRef
+ if (ref == hash.get(ref.key))
+ hash.remove(ref.key);
+
+ ref = (WeakValueRef<K, V>) queue.poll();
+ }
}
+
+ /**
+ * EntrySet.
+ */
+ private class EntrySet extends AbstractSet<Entry<K, V>>
+ {
+ @Override
+ public Iterator<Entry<K, V>> iterator()
+ {
+ return new EntrySetIterator(hash.entrySet().iterator());
+ }
+ @Override
+ public int size()
+ {
+ return WeakValueHashMap.this.size();
+ }
+ }
+
/**
- * Removes the mapping for the given <code>key</code> from this map, if
- * present.
- *
- * @param key The key whose mapping is to be removed
- *
- * @return The value to which this key was mapped, or <code>null</code> if
- * there was no mapping for the key
+ * EntrySet iterator
*/
- public Object remove(Object key)
+ private class EntrySetIterator implements Iterator<Entry<K, V>>
{
- processQueue();
- return hash.remove(key);
+ /** The delegate */
+ private Iterator<Entry<K, WeakValueRef<K, V>>> delegate;
+
+ /**
+ * Create a new EntrySetIterator.
+ *
+ * @param delegate the delegate
+ */
+ public EntrySetIterator(Iterator<Entry<K, WeakValueRef<K, V>>> delegate)
+ {
+ this.delegate = delegate;
+ }
+
+ public boolean hasNext()
+ {
+ return delegate.hasNext();
+ }
+
+ public Entry<K, V> next()
+ {
+ Entry<K, WeakValueRef<K, V>> next = delegate.next();
+ return next.getValue();
+ }
+
+ public void remove()
+ {
+ throw new UnsupportedOperationException("remove");
+ }
}
-
+
/**
- * Removes all mappings from this map.
+ * WeakValueRef.
+ *
+ * @param <K> the key type
+ * @param <V> the value type
*/
- public void clear()
+ private static class WeakValueRef<K, V> extends WeakReference<V> implements Map.Entry<K, V>
{
- processQueue();
- hash.clear();
+ /** The key */
+ public K key;
+
+ /**
+ * Safely create a new WeakValueRef
+ *
+ * @param <K> the key type
+ * @param <V> the value type
+ * @param key the key
+ * @param val the value
+ * @param q the reference queue
+ * @return the reference or null if the value is null
+ */
+ private static <K, V> WeakValueRef<K, V> create(K key, V val, ReferenceQueue<V> q)
+ {
+ if (val == null)
+ return null;
+ else
+ return new WeakValueRef<K, V>(key, val, q);
+ }
+
+ /**
+ * Create a new WeakValueRef.
+ *
+ * @param key the key
+ * @param val the value
+ * @param q the reference queue
+ */
+ private WeakValueRef(K key, V val, ReferenceQueue<V> q)
+ {
+ super(val, q);
+ this.key = key;
+ }
+
+ public K getKey()
+ {
+ return key;
+ }
+
+ public V getValue()
+ {
+ return get();
+ }
+
+ public V setValue(V value)
+ {
+ throw new UnsupportedOperationException("setValue");
+ }
}
}
More information about the jboss-svn-commits
mailing list