You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@turbine.apache.org by gk...@apache.org on 2021/09/08 13:19:24 UTC
[turbine-fulcrum-factory] 22/49: Add generics and use concurrent
collections
This is an automated email from the ASF dual-hosted git repository.
gk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/turbine-fulcrum-factory.git
commit 65055553b6fbb56a1b18e1808550b295f6df5692
Author: Thomas Vandahl <tv...@apache.org>
AuthorDate: Sun Nov 27 11:44:21 2016 +0000
Add generics and use concurrent collections
git-svn-id: https://svn.apache.org/repos/asf/turbine/fulcrum/trunk/factory@1771565 13f79535-47bb-0310-9956-ffa450edef68
---
.../fulcrum/factory/DefaultFactoryService.java | 208 ++++++++++++++-------
src/java/org/apache/fulcrum/factory/Factory.java | 23 +--
.../org/apache/fulcrum/factory/FactoryService.java | 16 +-
.../factory/utils/ObjectInputStreamForContext.java | 9 +-
.../apache/fulcrum/factory/FactoryServiceTest.java | 5 +-
5 files changed, 166 insertions(+), 95 deletions(-)
diff --git a/src/java/org/apache/fulcrum/factory/DefaultFactoryService.java b/src/java/org/apache/fulcrum/factory/DefaultFactoryService.java
index 3034c19..f058372 100644
--- a/src/java/org/apache/fulcrum/factory/DefaultFactoryService.java
+++ b/src/java/org/apache/fulcrum/factory/DefaultFactoryService.java
@@ -21,11 +21,13 @@ package org.apache.fulcrum.factory;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.Iterator;
+import java.util.concurrent.ConcurrentHashMap;
+import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
@@ -48,7 +50,7 @@ import org.apache.fulcrum.factory.utils.ObjectInputStreamForContext;
*/
public class DefaultFactoryService
extends AbstractLogEnabled
- implements FactoryService, Configurable, Initializable
+ implements FactoryService, Configurable, Initializable, Disposable
{
protected boolean initialized = false;
//private boolean disposed = false;
@@ -67,9 +69,10 @@ public class DefaultFactoryService
/**
* Primitive classes for reflection of constructors.
*/
- private static HashMap primitiveClasses;
+ private static HashMap<String, Class<?>> primitiveClasses;
+
{
- primitiveClasses = new HashMap(8);
+ primitiveClasses = new HashMap<String, Class<?>>(8);
primitiveClasses.put(Boolean.TYPE.toString(), Boolean.TYPE);
primitiveClasses.put(Character.TYPE.toString(), Character.TYPE);
primitiveClasses.put(Byte.TYPE.toString(), Byte.TYPE);
@@ -86,20 +89,27 @@ public class DefaultFactoryService
/**
* Additional class loaders.
*/
- private ArrayList classLoaders = new ArrayList();
+ private ArrayList<ClassLoader> classLoaders = new ArrayList<ClassLoader>();
/**
* Customized object factories.
*/
- private HashMap objectFactories = new HashMap();
+ private ConcurrentHashMap<String, Factory<?>> objectFactories =
+ new ConcurrentHashMap<String, Factory<?>>();
+ /**
+ * Customized object factory classes.
+ */
+ private ConcurrentHashMap<String, String> objectFactoryClasses =
+ new ConcurrentHashMap<String, String>();
+
/**
* Gets the class of a primitive type.
*
* @param type a primitive type.
* @return the corresponding class, or null.
*/
- protected static Class getPrimitiveClass(String type)
+ protected static Class<?> getPrimitiveClass(String type)
{
- return (Class) primitiveClasses.get(type);
+ return primitiveClasses.get(type);
}
/**
@@ -109,16 +119,17 @@ public class DefaultFactoryService
* @return the instance.
* @throws FactoryException if instantiation fails.
*/
- public Object getInstance(String className) throws FactoryException
+ @Override
+ public <T> T getInstance(String className) throws FactoryException
{
if (className == null)
{
throw new FactoryException("Missing String className");
}
- Factory factory = getFactory(className);
+ Factory<T> factory = getFactory(className);
if (factory == null)
{
- Class clazz;
+ Class<T> clazz;
try
{
clazz = loadClass(className);
@@ -145,14 +156,15 @@ public class DefaultFactoryService
* @return the instance.
* @throws FactoryException if instantiation fails.
*/
- public Object getInstance(String className, ClassLoader loader) throws FactoryException
+ @Override
+ public <T> T getInstance(String className, ClassLoader loader) throws FactoryException
{
- Factory factory = getFactory(className);
+ Factory<T> factory = getFactory(className);
if (factory == null)
{
if (loader != null)
{
- Class clazz;
+ Class<T> clazz;
try
{
clazz = loadClass(className, loader);
@@ -184,12 +196,13 @@ public class DefaultFactoryService
* @return the instance.
* @throws FactoryException if instantiation fails.
*/
- public Object getInstance(String className, Object[] params, String[] signature) throws FactoryException
+ @Override
+ public <T> T getInstance(String className, Object[] params, String[] signature) throws FactoryException
{
- Factory factory = getFactory(className);
+ Factory<T> factory = getFactory(className);
if (factory == null)
{
- Class clazz;
+ Class<T> clazz;
try
{
clazz = loadClass(className);
@@ -220,15 +233,16 @@ public class DefaultFactoryService
* @return the instance.
* @throws FactoryException if instantiation fails.
*/
- public Object getInstance(String className, ClassLoader loader, Object[] params, String[] signature)
+ @Override
+ public <T> T getInstance(String className, ClassLoader loader, Object[] params, String[] signature)
throws FactoryException
{
- Factory factory = getFactory(className);
+ Factory<T> factory = getFactory(className);
if (factory == null)
{
if (loader != null)
{
- Class clazz;
+ Class<T> clazz;
try
{
clazz = loadClass(className, loader);
@@ -256,9 +270,10 @@ public class DefaultFactoryService
* @return true if class loaders are supported, false otherwise.
* @throws FactoryException if test fails.
*/
+ @Override
public boolean isLoaderSupported(String className) throws FactoryException
{
- Factory factory = getFactory(className);
+ Factory<?> factory = getFactory(className);
return factory != null ? factory.isLoaderSupported() : true;
}
/**
@@ -268,7 +283,8 @@ public class DefaultFactoryService
* @return the instance.
* @throws FactoryException if instantiation fails.
*/
- public Object getInstance(Class clazz) throws FactoryException
+ @Override
+ public <T> T getInstance(Class<T> clazz) throws FactoryException
{
try
{
@@ -290,12 +306,12 @@ public class DefaultFactoryService
* @return the instance.
* @throws FactoryException if instantiation fails.
*/
- protected Object getInstance(Class clazz, Object params[], String signature[]) throws FactoryException
+ protected <T> T getInstance(Class<T> clazz, Object params[], String signature[]) throws FactoryException
{
/* Try to construct. */
try
{
- Class[] sign = getSignature(clazz, params, signature);
+ Class<?>[] sign = getSignature(clazz, params, signature);
return clazz.getConstructor(sign).newInstance(params);
}
catch (Exception x)
@@ -314,14 +330,15 @@ public class DefaultFactoryService
* of a different class loader.
* @throws ClassNotFoundException if any of the classes is not found.
*/
- public Class[] getSignature(Class clazz, Object params[], String signature[]) throws ClassNotFoundException
+ @Override
+ public Class<?>[] getSignature(Class<?> clazz, Object params[], String signature[]) throws ClassNotFoundException
{
if (signature != null)
{
/* We have parameters. */
ClassLoader tempLoader;
ClassLoader loader = clazz.getClassLoader();
- Class[] sign = new Class[signature.length];
+ Class<?>[] sign = new Class[signature.length];
for (int i = 0; i < signature.length; i++)
{
/* Check primitive types. */
@@ -368,26 +385,44 @@ public class DefaultFactoryService
protected Object switchObjectContext(Object object, ClassLoader loader)
{
ByteArrayOutputStream bout = new ByteArrayOutputStream();
+
try
{
ObjectOutputStream out = new ObjectOutputStream(bout);
out.writeObject(object);
out.flush();
}
- catch (Exception x)
+ catch (IOException x)
{
return object;
}
+
+ ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+ ObjectInputStreamForContext in = null;
+
try
{
- ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
- ObjectInputStreamForContext in = new ObjectInputStreamForContext(bin, loader);
+ in = new ObjectInputStreamForContext(bin, loader);
return in.readObject();
}
catch (Exception x)
{
return object;
}
+ finally
+ {
+ if (in != null)
+ {
+ try
+ {
+ in.close();
+ }
+ catch (IOException e)
+ {
+ // close quietly
+ }
+ }
+ }
}
/**
* Loads the named class using the default class loader.
@@ -396,21 +431,33 @@ public class DefaultFactoryService
* @return the loaded class.
* @throws ClassNotFoundException if the class was not found.
*/
- protected Class loadClass(String className) throws ClassNotFoundException
+ @SuppressWarnings("unchecked")
+ protected <T> Class<T> loadClass(String className) throws ClassNotFoundException
{
ClassLoader loader = this.getClass().getClassLoader();
try
{
- return loader != null ? loader.loadClass(className) : Class.forName(className);
+ Class<T> clazz;
+
+ if (loader != null)
+ {
+ clazz = (Class<T>) loader.loadClass(className);
+ }
+ else
+ {
+ clazz = (Class<T>) Class.forName(className);
+ }
+
+ return clazz;
}
catch (ClassNotFoundException x)
{
/* Go through additional loaders. */
- for (Iterator i = classLoaders.iterator(); i.hasNext();)
+ for (ClassLoader l : classLoaders)
{
try
{
- return ((ClassLoader) i.next()).loadClass(className);
+ return (Class<T>) l.loadClass(className);
}
catch (ClassNotFoundException xx)
{
@@ -429,9 +476,17 @@ public class DefaultFactoryService
* @return the loaded class.
* @throws ClassNotFoundException if the class was not found.
*/
- protected Class loadClass(String className, ClassLoader loader) throws ClassNotFoundException
+ @SuppressWarnings("unchecked")
+ protected <T> Class<T> loadClass(String className, ClassLoader loader) throws ClassNotFoundException
{
- return loader != null ? loader.loadClass(className) : loadClass(className);
+ if (loader != null)
+ {
+ return (Class<T>) loader.loadClass(className);
+ }
+ else
+ {
+ return loadClass(className);
+ }
}
/**
* Gets a customized factory for a named class. If no class-specific
@@ -442,49 +497,54 @@ public class DefaultFactoryService
* @return the factory, or null if not specified and no default.
* @throws FactoryException if instantiation of the factory fails.
*/
- protected Factory getFactory(String className) throws FactoryException
+ @SuppressWarnings("unchecked")
+ protected <T> Factory<T> getFactory(String className) throws FactoryException
{
- HashMap factories = objectFactories;
- Object factory = factories.get(className);
+ Factory<T> factory = (Factory<T>) objectFactories.get(className);
if (factory == null)
{
//No named factory for this; try the default, if one
//exists.
- factory = factories.get(DEFAULT_FACTORY);
+ factory = (Factory<T>) objectFactories.get(DEFAULT_FACTORY);
}
- if (factory != null)
+ if (factory == null)
{
- if (factory instanceof String)
+ /* Not yet instantiated... */
+ String factoryClass = objectFactoryClasses.get(className);
+ if (factoryClass == null)
{
- /* Not yet instantiated... */
- try
- {
- factory = (Factory) getInstance((String) factory);
- ((Factory) factory).init(className);
- }
- catch (FactoryException x)
- {
- throw x;
- }
- catch (ClassCastException x)
- {
- throw new FactoryException("Incorrect factory " + (String) factory + " for class " + className, x);
- }
- factories = (HashMap) factories.clone();
- factories.put(className, factory);
- objectFactories = factories;
+ factoryClass = objectFactoryClasses.get(DEFAULT_FACTORY);
+ }
+ if (factoryClass == null)
+ {
+ return null;
+ }
+
+ try
+ {
+ factory = getInstance(factoryClass);
+ factory.init(className);
+ }
+ catch (ClassCastException x)
+ {
+ throw new FactoryException("Incorrect factory " + factoryClass + " for class " + className, x);
+ }
+ Factory<T> _factory = (Factory<T>) objectFactories.putIfAbsent(className, factory);
+ if (_factory != null)
+ {
+ // Already created - take first instance
+ factory = _factory;
}
- return (Factory) factory;
- }
- else
- {
- return null;
}
+
+ return factory;
}
+
// ---------------- Avalon Lifecycle Methods ---------------------
/**
* Avalon component lifecycle method
*/
+ @Override
public void configure(Configuration conf) throws ConfigurationException
{
final Configuration[] loaders = conf.getChildren(CLASS_LOADER);
@@ -506,10 +566,11 @@ public class DefaultFactoryService
String factory = nameVal[i].getValue();
// Store the factory to the table as a string and
// instantiate it by using the service when needed.
- objectFactories.put(key, factory);
+ objectFactoryClasses.put(key, factory);
}
}
}
+
/**
* Avalon component lifecycle method
* Initializes the service by loading default class loaders
@@ -517,6 +578,7 @@ public class DefaultFactoryService
*
* @throws InitializationException if initialization fails.
*/
+ @Override
public void initialize() throws Exception
{
if (loaderNames != null)
@@ -525,16 +587,28 @@ public class DefaultFactoryService
{
try
{
- classLoaders.add(loadClass(loaderNames[i]).newInstance());
+ ClassLoader loader = (ClassLoader) loadClass(loaderNames[i]).newInstance();
+ classLoaders.add(loader);
}
catch (Exception x)
{
throw new Exception(
- "No such class loader '" + loaderNames[i] + "' for DefaultFactoryService",
- x);
+ "No such class loader '" + loaderNames[i] + "' for DefaultFactoryService", x);
}
}
loaderNames = null;
}
}
+
+ /**
+ * Avalon component lifecycle method
+ * Clear lists and maps
+ */
+ @Override
+ public void dispose()
+ {
+ objectFactories.clear();
+ objectFactoryClasses.clear();
+ classLoaders.clear();
+ }
}
diff --git a/src/java/org/apache/fulcrum/factory/Factory.java b/src/java/org/apache/fulcrum/factory/Factory.java
index 841d30c..bb7e7b4 100644
--- a/src/java/org/apache/fulcrum/factory/Factory.java
+++ b/src/java/org/apache/fulcrum/factory/Factory.java
@@ -1,6 +1,5 @@
package org.apache.fulcrum.factory;
-
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -20,8 +19,6 @@ package org.apache.fulcrum.factory;
* under the License.
*/
-
-
/**
* Factory is an interface for object factories. Object factories
* can be registered with the Factory Service to support customized
@@ -34,7 +31,7 @@ package org.apache.fulcrum.factory;
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Id$
*/
-public interface Factory
+public interface Factory<T>
{
/**
* Initializes the factory. This method is called by
@@ -43,8 +40,7 @@ public interface Factory
* @param className the name of the production class
* @throws FactoryException if initialization fails.
*/
- public void init(String className)
- throws FactoryException;
+ void init(String className) throws FactoryException;
/**
* Gets an instance of a class.
@@ -52,8 +48,7 @@ public interface Factory
* @return the instance.
* @throws FactoryException if instantiation fails.
*/
- public Object getInstance()
- throws FactoryException;
+ T getInstance() throws FactoryException;
/**
* Gets an instance of a class using a specified class loader.
@@ -65,8 +60,7 @@ public interface Factory
* @return the instance.
* @throws FactoryException if instantiation fails.
*/
- public Object getInstance(ClassLoader loader)
- throws FactoryException;
+ T getInstance(ClassLoader loader) throws FactoryException;
/**
* Gets an instance of a named class.
@@ -78,8 +72,7 @@ public interface Factory
* @return the instance.
* @throws FactoryException if instantiation fails.
*/
- public Object getInstance(Object[] params,
- String[] signature)
+ T getInstance(Object[] params, String[] signature)
throws FactoryException;
/**
@@ -96,9 +89,7 @@ public interface Factory
* @return the instance.
* @throws FactoryException if instantiation fails.
*/
- public Object getInstance(ClassLoader loader,
- Object[] params,
- String[] signature)
+ T getInstance(ClassLoader loader, Object[] params, String[] signature)
throws FactoryException;
/**
@@ -106,5 +97,5 @@ public interface Factory
*
* @return true if class loaders are supported, false otherwise.
*/
- public boolean isLoaderSupported();
+ boolean isLoaderSupported();
}
diff --git a/src/java/org/apache/fulcrum/factory/FactoryService.java b/src/java/org/apache/fulcrum/factory/FactoryService.java
index e4e2f5f..9c42e19 100644
--- a/src/java/org/apache/fulcrum/factory/FactoryService.java
+++ b/src/java/org/apache/fulcrum/factory/FactoryService.java
@@ -1,5 +1,7 @@
package org.apache.fulcrum.factory;
+import org.apache.avalon.framework.service.ServiceException;
+
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -47,7 +49,7 @@ public interface FactoryService
* @return the instance.
* @throws ServiceException if instantiation fails.
*/
- public Object getInstance(Class clazz)
+ <T> T getInstance(Class<T> clazz)
throws FactoryException;
/**
@@ -57,7 +59,7 @@ public interface FactoryService
* @return the instance.
* @throws ServiceException if instantiation fails.
*/
- public Object getInstance(String className)
+ <T> T getInstance(String className)
throws FactoryException;
/**
@@ -71,7 +73,7 @@ public interface FactoryService
* @return the instance.
* @throws ServiceException if instantiation fails.
*/
- public Object getInstance(String className,
+ <T> T getInstance(String className,
ClassLoader loader)
throws FactoryException;
@@ -86,7 +88,7 @@ public interface FactoryService
* @return the instance.
* @throws ServiceException if instantiation fails.
*/
- public Object getInstance(String className,
+ <T> T getInstance(String className,
Object[] params,
String[] signature)
throws FactoryException;
@@ -106,7 +108,7 @@ public interface FactoryService
* @return the instance.
* @throws ServiceException if instantiation fails.
*/
- public Object getInstance(String className,
+ <T> T getInstance(String className,
ClassLoader loader,
Object[] params,
String[] signature)
@@ -119,7 +121,7 @@ public interface FactoryService
* @return true if class loaders are supported, false otherwise.
* @throws ServiceException if test fails.
*/
- public boolean isLoaderSupported(String className)
+ boolean isLoaderSupported(String className)
throws FactoryException;
/**
@@ -133,7 +135,7 @@ public interface FactoryService
* of a different class loader.
* @throws ClassNotFoundException if any of the classes is not found.
*/
- Class[] getSignature(Class clazz,
+ Class<?>[] getSignature(Class<?> clazz,
Object params[],
String signature[])
throws ClassNotFoundException;
diff --git a/src/java/org/apache/fulcrum/factory/utils/ObjectInputStreamForContext.java b/src/java/org/apache/fulcrum/factory/utils/ObjectInputStreamForContext.java
index a0fb934..513448f 100644
--- a/src/java/org/apache/fulcrum/factory/utils/ObjectInputStreamForContext.java
+++ b/src/java/org/apache/fulcrum/factory/utils/ObjectInputStreamForContext.java
@@ -1,5 +1,6 @@
package org.apache.fulcrum.factory.utils;
+import java.io.IOException;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -20,11 +21,9 @@ package org.apache.fulcrum.factory.utils;
* under the License.
*/
-
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectStreamClass;
-import java.io.IOException;
/**
* A deserialization stream for a specific class loader context.
@@ -60,7 +59,11 @@ public class ObjectInputStreamForContext extends ObjectInputStream
classLoader = loader;
}
- protected Class resolveClass(ObjectStreamClass v)
+ /**
+ * @see java.io.ObjectInputStream#resolveClass()
+ */
+ @Override
+ protected Class<?> resolveClass(ObjectStreamClass v)
throws IOException,
ClassNotFoundException
{
diff --git a/src/test/org/apache/fulcrum/factory/FactoryServiceTest.java b/src/test/org/apache/fulcrum/factory/FactoryServiceTest.java
index eb97a08..f82256d 100644
--- a/src/test/org/apache/fulcrum/factory/FactoryServiceTest.java
+++ b/src/test/org/apache/fulcrum/factory/FactoryServiceTest.java
@@ -21,6 +21,7 @@ package org.apache.fulcrum.factory;
import java.util.ArrayList;
+
import org.apache.fulcrum.testcontainer.BaseUnitTest;
/**
@@ -43,6 +44,7 @@ public class FactoryServiceTest extends BaseUnitTest
super(name);
}
+ @Override
public void setUp() throws Exception
{
super.setUp();
@@ -116,7 +118,7 @@ public class FactoryServiceTest extends BaseUnitTest
params[0] = sourceValu;
String signature[] = new String[1];
signature[0] = "java.lang.String";
- Class[] results = factoryService.getSignature(StringBuffer.class, params, signature);
+ Class<?>[] results = factoryService.getSignature(StringBuffer.class, params, signature);
assertEquals(1, results.length);
assertTrue(results[0].equals(String.class));
@@ -126,6 +128,5 @@ public class FactoryServiceTest extends BaseUnitTest
results = factoryService.getSignature(ArrayList.class, params, signature);
assertEquals(1, results.length);
assertTrue("Result:" + results[0].getName(),results[0].equals(Integer.class));
-
}
}