You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@turbine.apache.org by pa...@apache.org on 2018/12/13 21:50:53 UTC
svn commit: r1848903 - in /turbine/fulcrum/trunk/factory/src:
changes/changes.xml
java/org/apache/fulcrum/factory/DefaultFactoryService.java
java/org/apache/fulcrum/factory/FactoryException.java
Author: painter
Date: Thu Dec 13 21:50:53 2018
New Revision: 1848903
URL: http://svn.apache.org/viewvc?rev=1848903&view=rev
Log:
Code cleanup, more Java 8 syntax, cleared all Findbugs and PMD reports, update changes.xml
Modified:
turbine/fulcrum/trunk/factory/src/changes/changes.xml
turbine/fulcrum/trunk/factory/src/java/org/apache/fulcrum/factory/DefaultFactoryService.java
turbine/fulcrum/trunk/factory/src/java/org/apache/fulcrum/factory/FactoryException.java
Modified: turbine/fulcrum/trunk/factory/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/turbine/fulcrum/trunk/factory/src/changes/changes.xml?rev=1848903&r1=1848902&r2=1848903&view=diff
==============================================================================
--- turbine/fulcrum/trunk/factory/src/changes/changes.xml (original)
+++ turbine/fulcrum/trunk/factory/src/changes/changes.xml Thu Dec 13 21:50:53 2018
@@ -25,6 +25,15 @@
<body>
<release version="1.1.1" date="in SVN">
+ <action dev="painter" type="update">
+ Addressed all PMD static code analyzer issues and corrected where appropriate
+ </action>
+ <action dev="painter" type="update">
+ Derive from Turbine parent POM 5
+ </action>
+ <action dev="painter" type="update">
+ Require Java 8
+ </action>
</release>
<release version="1.1.0" date="2016-11-27">
<action dev="tv" type="add">
Modified: turbine/fulcrum/trunk/factory/src/java/org/apache/fulcrum/factory/DefaultFactoryService.java
URL: http://svn.apache.org/viewvc/turbine/fulcrum/trunk/factory/src/java/org/apache/fulcrum/factory/DefaultFactoryService.java?rev=1848903&r1=1848902&r2=1848903&view=diff
==============================================================================
--- turbine/fulcrum/trunk/factory/src/java/org/apache/fulcrum/factory/DefaultFactoryService.java (original)
+++ turbine/fulcrum/trunk/factory/src/java/org/apache/fulcrum/factory/DefaultFactoryService.java Thu Dec 13 21:50:53 2018
@@ -36,585 +36,485 @@ import org.apache.avalon.framework.logge
import org.apache.fulcrum.factory.utils.ObjectInputStreamForContext;
/**
- * The Factory Service instantiates objects using specified
- * class loaders. If none is specified, the default one
- * will be used.
+ * The Factory Service instantiates objects using specified class loaders. If
+ * none is specified, the default one will be used.
*
- * avalon.component name="factory" lifestyle="singleton"
- * avalon.service type="org.apache.fulcrum.factory.FactoryService"
+ * avalon.component name="factory" lifestyle="singleton" avalon.service
+ * type="org.apache.fulcrum.factory.FactoryService"
*
* @author <a href="mailto:epugh@upstate.com">Eric Pugh</a>
* @author <a href="mailto:ilkka.priha@simsoft.fi">Ilkka Priha</a>
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
- * @version $Id$
+ * @version $Id: DefaultFactoryService.java 1844842 2018-10-25 15:33:42Z painter
+ * $
*
*/
-public class DefaultFactoryService
- extends AbstractLogEnabled
- implements FactoryService, Configurable, Initializable, Disposable
-{
- protected boolean initialized = false;
-
- /**
- * The property specifying a set of additional class loaders.
- */
- private static final String CLASS_LOADER = "classloader";
-
- /**
- * The property prefix specifying additional object factories.
- */
- private static final String OBJECT_FACTORY = "object-factory";
-
- /**
- * The name of the default factory.
- */
- protected static final String DEFAULT_FACTORY = "default";
-
- /**
- * Primitive classes for reflection of constructors.
- */
- private static HashMap<String, Class<?>> 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);
- primitiveClasses.put(Short.TYPE.toString(), Short.TYPE);
- primitiveClasses.put(Integer.TYPE.toString(), Integer.TYPE);
- primitiveClasses.put(Long.TYPE.toString(), Long.TYPE);
- primitiveClasses.put(Float.TYPE.toString(), Float.TYPE);
- primitiveClasses.put(Double.TYPE.toString(), Double.TYPE);
- }
-
- /**
- * temporary storage of class names between configure and initialize
- */
- private String[] loaderNames;
- /**
- * Additional class loaders.
- */
- private ArrayList<ClassLoader> classLoaders = new ArrayList<ClassLoader>();
- /**
- * Customized object factories.
- */
- 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)
- {
- return primitiveClasses.get(type);
- }
-
- /**
- * Gets an instance of a named class.
- *
- * @param className the name of the class.
- * @return the instance.
- * @throws FactoryException if instantiation fails.
- */
- @Override
- public <T> T getInstance(String className) throws FactoryException
- {
- if (className == null)
- {
- throw new FactoryException("Missing String className");
- }
- Factory<T> factory = getFactory(className);
- if (factory == null)
- {
- Class<T> clazz;
- try
- {
- clazz = loadClass(className);
- }
- catch (ClassNotFoundException x)
- {
- throw new FactoryException("Instantiation failed for class " + className, x);
- }
- return getInstance(clazz);
- }
- else
- {
- return factory.getInstance();
- }
- }
- /**
- * Gets an instance of a named class using a specified class loader.
- *
- * <p>Class loaders are supported only if the isLoaderSupported
- * method returns true. Otherwise the loader parameter is ignored.
- *
- * @param className the name of the class.
- * @param loader the class loader.
- * @return the instance.
- * @throws FactoryException if instantiation fails.
- */
- @Override
- public <T> T getInstance(String className, ClassLoader loader) throws FactoryException
- {
- Factory<T> factory = getFactory(className);
- if (factory == null)
- {
- if (loader != null)
- {
- Class<T> clazz;
- try
- {
- clazz = loadClass(className, loader);
- }
- catch (ClassNotFoundException x)
- {
- throw new FactoryException("Instantiation failed for class " + className, x);
- }
- return getInstance(clazz);
- }
- else
- {
- return getInstance(className);
- }
- }
- else
- {
- return factory.getInstance(loader);
- }
- }
- /**
- * Gets an instance of a named class.
- * Parameters for its constructor are given as an array of objects,
- * primitive types must be wrapped with a corresponding class.
- *
- * @param className the name of the class.
- * @param params an array containing the parameters of the constructor.
- * @param signature an array containing the signature of the constructor.
- * @return the instance.
- * @throws FactoryException if instantiation fails.
- */
- @Override
- public <T> T getInstance(String className, Object[] params, String[] signature) throws FactoryException
- {
- Factory<T> factory = getFactory(className);
- if (factory == null)
- {
- Class<T> clazz;
- try
- {
- clazz = loadClass(className);
- }
- catch (ClassNotFoundException x)
- {
- throw new FactoryException("Instantiation failed for class " + className, x);
- }
- return getInstance(clazz, params, signature);
- }
- else
- {
- return factory.getInstance(params, signature);
- }
- }
- /**
- * Gets an instance of a named class using a specified class loader.
- * Parameters for its constructor are given as an array of objects,
- * primitive types must be wrapped with a corresponding class.
- *
- * <p>Class loaders are supported only if the isLoaderSupported
- * method returns true. Otherwise the loader parameter is ignored.
- *
- * @param className the name of the class.
- * @param loader the class loader.
- * @param params an array containing the parameters of the constructor.
- * @param signature an array containing the signature of the constructor.
- * @return the instance.
- * @throws FactoryException if instantiation fails.
- */
- @Override
- public <T> T getInstance(String className, ClassLoader loader, Object[] params, String[] signature)
- throws FactoryException
- {
- Factory<T> factory = getFactory(className);
- if (factory == null)
- {
- if (loader != null)
- {
- Class<T> clazz;
- try
- {
- clazz = loadClass(className, loader);
- }
- catch (ClassNotFoundException x)
- {
- throw new FactoryException("Instantiation failed for class " + className, x);
- }
- return getInstance(clazz, params, signature);
- }
- else
- {
- return getInstance(className, params, signature);
- }
- }
- else
- {
- return factory.getInstance(loader, params, signature);
- }
- }
- /**
- * Tests if specified class loaders are supported for a named class.
- *
- * @param className the name of the class.
- * @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);
- return factory != null ? factory.isLoaderSupported() : true;
- }
- /**
- * Gets an instance of a specified class.
- *
- * @param clazz the class.
- * @return the instance.
- * @throws FactoryException if instantiation fails.
- */
- @Override
- public <T> T getInstance(Class<T> clazz) throws FactoryException
- {
- try
- {
- return clazz.newInstance();
- }
- catch (Exception x)
- {
- throw new FactoryException("Instantiation failed for " + clazz.getName(), x);
- }
- }
- /**
- * Gets an instance of a specified class.
- * Parameters for its constructor are given as an array of objects,
- * primitive types must be wrapped with a corresponding class.
- *
- * @param clazz the class.
- * @param params an array containing the parameters of the constructor.
- * @param signature an array containing the signature of the constructor.
- * @return the instance.
- * @throws FactoryException if instantiation fails.
- */
- protected <T> T getInstance(Class<T> clazz, Object params[], String signature[]) throws FactoryException
- {
- /* Try to construct. */
- try
- {
- Class<?>[] sign = getSignature(clazz, params, signature);
- return clazz.getConstructor(sign).newInstance(params);
- }
- catch (Exception x)
- {
- throw new FactoryException("Instantiation failed for " + clazz.getName(), x);
- }
- }
- /**
- * Gets the signature classes for parameters of a method of a class.
- *
- * @param clazz the class.
- * @param params an array containing the parameters of the method.
- * @param signature an array containing the signature of the method.
- * @return an array of signature classes. Note that in some cases
- * objects in the parameter array can be switched to the context
- * of a different class loader.
- * @throws ClassNotFoundException if any of the classes is not found.
- */
- @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];
- for (int i = 0; i < signature.length; i++)
- {
- /* Check primitive types. */
- sign[i] = getPrimitiveClass(signature[i]);
- if (sign[i] == null)
- {
- /* Not a primitive one, continue building. */
- if (loader != null)
- {
- /* Use the class loader of the target object. */
- sign[i] = loader.loadClass(signature[i]);
- tempLoader = sign[i].getClassLoader();
- if ((params[i] != null)
- && (tempLoader != null)
- && !tempLoader.equals(params[i].getClass().getClassLoader()))
- {
- /*
- * The class uses a different class loader,
- * switch the parameter.
- */
- params[i] = switchObjectContext(params[i], loader);
- }
- }
- else
- {
- /* Use the default class loader. */
- sign[i] = loadClass(signature[i]);
- }
- }
- }
- return sign;
- }
- else
- {
- return null;
- }
- }
- /**
- * Switches an object into the context of a different class loader.
- *
- * @param object an object to switch.
- * @param loader the ClassLoader to use
- * @param loader the loader of the new context.
- * @return the object
- */
- protected Object switchObjectContext(Object object, ClassLoader loader)
- {
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
-
- try
- {
- ObjectOutputStream out = new ObjectOutputStream(bout);
- out.writeObject(object);
- out.flush();
- }
- catch (IOException x)
- {
- return object;
- }
-
- ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
- ObjectInputStreamForContext in = null;
-
- try
- {
- 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.
- *
- * @param className the name of the class to load.
- * @return {@inheritDoc} the loaded class.
- * @throws ClassNotFoundException if the class was not found.
- */
- @SuppressWarnings("unchecked")
- protected <T> Class<T> loadClass(String className) throws ClassNotFoundException
- {
- ClassLoader loader = this.getClass().getClassLoader();
- try
- {
- 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 (ClassLoader l : classLoaders)
- {
- try
- {
- return (Class<T>) l.loadClass(className);
- }
- catch (ClassNotFoundException xx)
- {
- // continue
- }
- }
- /* Give up. */
- throw x;
- }
- }
- /**
- * Loads the named class using a specified class loader.
- *
- * @param className the name of the class to load.
- * @param loader the loader to use.
- * @return {@inheritDoc} the loaded class.
- * @throws ClassNotFoundException if the class was not found.
- */
- @SuppressWarnings("unchecked")
- protected <T> Class<T> loadClass(String className, ClassLoader loader) throws ClassNotFoundException
- {
- 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
- * factory is specified but a default factory is, will use the default
- * factory.
- *
- * @param className the name of the class to load.
- * @return {@inheritDoc} the factory, or null if not specified and no default.
- * @throws FactoryException if instantiation of the factory fails.
- */
- @SuppressWarnings("unchecked")
- protected <T> Factory<T> getFactory(String className) throws FactoryException
- {
- Factory<T> factory = (Factory<T>) objectFactories.get(className);
- if (factory == null)
- {
- //No named factory for this; try the default, if one
- //exists.
- factory = (Factory<T>) objectFactories.get(DEFAULT_FACTORY);
- }
- if (factory == null)
- {
- /* Not yet instantiated... */
- String factoryClass = objectFactoryClasses.get(className);
- if (factoryClass == null)
- {
- 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;
- }
-
- // ---------------- Avalon Lifecycle Methods ---------------------
- /**
- * Avalon component lifecycle method
- */
- @Override
- public void configure(Configuration conf) throws ConfigurationException
- {
- final Configuration[] loaders = conf.getChildren(CLASS_LOADER);
- if (loaders != null)
- {
- loaderNames = new String[loaders.length];
- for (int i = 0; i < loaders.length; i++)
- {
- loaderNames[i] = loaders[i].getValue();
- }
- }
- final Configuration factories = conf.getChild(OBJECT_FACTORY, false);
- if (factories != null)
- {
- Configuration[] nameVal = factories.getChildren();
- for (int i = 0; i < nameVal.length; i++)
- {
- String key = nameVal[i].getName();
- String factory = nameVal[i].getValue();
- // Store the factory to the table as a string and
- // instantiate it by using the service when needed.
- objectFactoryClasses.put(key, factory);
- }
- }
- }
-
- /**
- * Avalon component lifecycle method
- * Initializes the service by loading default class loaders
- * and customized object factories.
- *
- * @throws Exception if initialization fails.
- */
- @Override
- public void initialize() throws Exception
- {
- if (loaderNames != null)
- {
- for (int i = 0; i < loaderNames.length; i++)
- {
- try
- {
- 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);
- }
- }
- loaderNames = null;
- }
- }
-
- /**
- * Avalon component lifecycle method
- * Clear lists and maps
- */
- @Override
- public void dispose()
- {
- objectFactories.clear();
- objectFactoryClasses.clear();
- classLoaders.clear();
- }
+public class DefaultFactoryService extends AbstractLogEnabled
+ implements FactoryService, Configurable, Initializable, Disposable {
+
+ /**
+ * The property specifying a set of additional class loaders.
+ */
+ private static final String CLASS_LOADER = "classloader";
+
+ /**
+ * The property prefix specifying additional object factories.
+ */
+ private static final String OBJECT_FACTORY = "object-factory";
+
+ /**
+ * The name of the default factory.
+ */
+ protected static final String DEFAULT_FACTORY = "default";
+
+ /**
+ * Primitive classes for reflection of constructors.
+ */
+ private static HashMap<String, Class<?>> 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);
+ primitiveClasses.put(Short.TYPE.toString(), Short.TYPE);
+ primitiveClasses.put(Integer.TYPE.toString(), Integer.TYPE);
+ primitiveClasses.put(Long.TYPE.toString(), Long.TYPE);
+ primitiveClasses.put(Float.TYPE.toString(), Float.TYPE);
+ primitiveClasses.put(Double.TYPE.toString(), Double.TYPE);
+ }
+
+ /**
+ * temporary storage of class names between configure and initialize
+ */
+ private String[] loaderNames;
+ /**
+ * Additional class loaders.
+ */
+ private ArrayList<ClassLoader> classLoaders = new ArrayList<ClassLoader>();
+ /**
+ * Customized object factories.
+ */
+ 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) {
+ return primitiveClasses.get(type);
+ }
+
+ /**
+ * Gets an instance of a named class.
+ *
+ * @param className the name of the class.
+ * @return the instance.
+ * @throws FactoryException if instantiation fails.
+ */
+ @Override
+ public <T> T getInstance(String className) throws FactoryException {
+ if (className == null) {
+ throw new FactoryException("Missing String className");
+ }
+ Factory<T> factory = getFactory(className);
+ if (factory == null) {
+ Class<T> clazz;
+ try {
+ clazz = loadClass(className);
+ } catch (ClassNotFoundException x) {
+ throw new FactoryException("Instantiation failed for class " + className, x);
+ }
+ return getInstance(clazz);
+ } else {
+ return factory.getInstance();
+ }
+ }
+
+ /**
+ * Gets an instance of a named class using a specified class loader.
+ *
+ * <p>
+ * Class loaders are supported only if the isLoaderSupported method returns
+ * true. Otherwise the loader parameter is ignored.
+ *
+ * @param className the name of the class.
+ * @param loader the class loader.
+ * @return the instance.
+ * @throws FactoryException if instantiation fails.
+ */
+ @Override
+ public <T> T getInstance(String className, ClassLoader loader) throws FactoryException {
+ Factory<T> factory = getFactory(className);
+ if (factory == null) {
+ if (loader != null) {
+ Class<T> clazz;
+ try {
+ clazz = loadClass(className, loader);
+ } catch (ClassNotFoundException x) {
+ throw new FactoryException("Instantiation failed for class " + className, x);
+ }
+ return getInstance(clazz);
+ } else {
+ return getInstance(className);
+ }
+ } else {
+ return factory.getInstance(loader);
+ }
+ }
+
+ /**
+ * Gets an instance of a named class. Parameters for its constructor are given
+ * as an array of objects, primitive types must be wrapped with a corresponding
+ * class.
+ *
+ * @param className the name of the class.
+ * @param params an array containing the parameters of the constructor.
+ * @param signature an array containing the signature of the constructor.
+ * @return the instance.
+ * @throws FactoryException if instantiation fails.
+ */
+ @Override
+ public <T> T getInstance(String className, Object[] params, String[] signature) throws FactoryException {
+ Factory<T> factory = getFactory(className);
+ if (factory == null) {
+ Class<T> clazz;
+ try {
+ clazz = loadClass(className);
+ } catch (ClassNotFoundException x) {
+ throw new FactoryException("Instantiation failed for class " + className, x);
+ }
+ return getInstance(clazz, params, signature);
+ } else {
+ return factory.getInstance(params, signature);
+ }
+ }
+
+ /**
+ * Gets an instance of a named class using a specified class loader. Parameters
+ * for its constructor are given as an array of objects, primitive types must be
+ * wrapped with a corresponding class.
+ *
+ * <p>
+ * Class loaders are supported only if the isLoaderSupported method returns
+ * true. Otherwise the loader parameter is ignored.
+ *
+ * @param className the name of the class.
+ * @param loader the class loader.
+ * @param params an array containing the parameters of the constructor.
+ * @param signature an array containing the signature of the constructor.
+ * @return the instance.
+ * @throws FactoryException if instantiation fails.
+ */
+ @Override
+ public <T> T getInstance(String className, ClassLoader loader, Object[] params, String[] signature)
+ throws FactoryException {
+ Factory<T> factory = getFactory(className);
+ if (factory == null) {
+ if (loader != null) {
+ Class<T> clazz;
+ try {
+ clazz = loadClass(className, loader);
+ } catch (ClassNotFoundException x) {
+ throw new FactoryException("Instantiation failed for class " + className, x);
+ }
+ return getInstance(clazz, params, signature);
+ } else {
+ return getInstance(className, params, signature);
+ }
+ } else {
+ return factory.getInstance(loader, params, signature);
+ }
+ }
+
+ /**
+ * Tests if specified class loaders are supported for a named class.
+ *
+ * @param className the name of the class.
+ * @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);
+ return factory != null ? factory.isLoaderSupported() : true;
+ }
+
+ /**
+ * Gets an instance of a specified class.
+ *
+ * @param clazz the class.
+ * @return the instance.
+ * @throws FactoryException if instantiation fails.
+ */
+ @Override
+ public <T> T getInstance(Class<T> clazz) throws FactoryException {
+ try {
+ return clazz.newInstance();
+ } catch (Exception x) {
+ throw new FactoryException("Instantiation failed for " + clazz.getName(), x);
+ }
+ }
+
+ /**
+ * Gets an instance of a specified class. Parameters for its constructor are
+ * given as an array of objects, primitive types must be wrapped with a
+ * corresponding class.
+ *
+ * @param <T> Type of the class
+ * @param clazz the class
+ * @param params an array containing the parameters of the constructor
+ * @param signature an array containing the signature of the constructor
+ * @return the instance
+ * @throws FactoryException if instantiation fails.
+ */
+ protected <T> T getInstance(Class<T> clazz, Object params[], String signature[]) throws FactoryException {
+ /* Try to construct. */
+ try {
+ Class<?>[] sign = getSignature(clazz, params, signature);
+ return clazz.getConstructor(sign).newInstance(params);
+ } catch (Exception x) {
+ throw new FactoryException("Instantiation failed for " + clazz.getName(), x);
+ }
+ }
+
+ /**
+ * Gets the signature classes for parameters of a method of a class.
+ *
+ * @param clazz the class.
+ * @param params an array containing the parameters of the method.
+ * @param signature an array containing the signature of the method.
+ * @return an array of signature classes. Note that in some cases objects in the
+ * parameter array can be switched to the context of a different class
+ * loader.
+ * @throws ClassNotFoundException if any of the classes is not found.
+ */
+ @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];
+ for (int i = 0; i < signature.length; i++) {
+ /* Check primitive types. */
+ sign[i] = getPrimitiveClass(signature[i]);
+ if (sign[i] == null) {
+ /* Not a primitive one, continue building. */
+ if (loader != null) {
+ /* Use the class loader of the target object. */
+ sign[i] = loader.loadClass(signature[i]);
+ tempLoader = sign[i].getClassLoader();
+ if (params[i] != null && tempLoader != null
+ && !tempLoader.equals(params[i].getClass().getClassLoader())) {
+ /*
+ * The class uses a different class loader, switch the parameter.
+ */
+ params[i] = switchObjectContext(params[i], loader);
+ }
+ } else {
+ /* Use the default class loader. */
+ sign[i] = loadClass(signature[i]);
+ }
+ }
+ }
+ return sign;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Switches an object into the context of a different class loader.
+ *
+ * @param object an object to switch.
+ * @param loader the ClassLoader to use
+ * @param loader the loader of the new context.
+ * @return the object
+ */
+ protected Object switchObjectContext(Object object, ClassLoader loader) {
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+
+ try {
+ ObjectOutputStream out = new ObjectOutputStream(bout);
+ out.writeObject(object);
+ out.flush();
+ } catch (IOException x) {
+ return object;
+ }
+
+ ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+ ObjectInputStreamForContext in = null;
+
+ try {
+ 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.
+ *
+ * @param className the name of the class to load.
+ * @return {@inheritDoc} the loaded class.
+ * @throws ClassNotFoundException if the class was not found.
+ */
+ @SuppressWarnings("unchecked")
+ protected <T> Class<T> loadClass(String className) throws ClassNotFoundException {
+ ClassLoader loader = this.getClass().getClassLoader();
+ try {
+ 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 (ClassLoader l : classLoaders) {
+ try {
+ return (Class<T>) l.loadClass(className);
+ } catch (ClassNotFoundException xx) {
+ // continue
+ }
+ }
+ /* Give up. */
+ throw x;
+ }
+ }
+
+ /**
+ * Loads the named class using a specified class loader.
+ *
+ * @param className the name of the class to load.
+ * @param loader the loader to use.
+ * @return {@inheritDoc} the loaded class.
+ * @throws ClassNotFoundException if the class was not found.
+ */
+ @SuppressWarnings("unchecked")
+ protected <T> Class<T> loadClass(String className, ClassLoader loader) throws ClassNotFoundException {
+ 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 factory is
+ * specified but a default factory is, will use the default factory.
+ *
+ * @param className the name of the class to load.
+ * @return {@inheritDoc} the factory, or null if not specified and no default.
+ * @throws FactoryException if instantiation of the factory fails.
+ */
+ @SuppressWarnings("unchecked")
+ protected <T> Factory<T> getFactory(String className) throws FactoryException {
+ Factory<T> factory = (Factory<T>) objectFactories.get(className);
+ if (factory == null) {
+ // No named factory for this; try the default, if one
+ // exists.
+ factory = (Factory<T>) objectFactories.get(DEFAULT_FACTORY);
+ }
+ if (factory == null) {
+ /* Not yet instantiated... */
+ String factoryClass = objectFactoryClasses.get(className);
+ if (factoryClass == null) {
+ 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;
+ }
+
+ // ---------------- Avalon Lifecycle Methods ---------------------
+
+ /* (non-Javadoc)
+ * Avalon component lifecycle method
+ * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
+ */
+ @Override
+ public void configure(Configuration conf) throws ConfigurationException {
+ final Configuration[] loaders = conf.getChildren(CLASS_LOADER);
+ if (loaders != null) {
+ loaderNames = new String[loaders.length];
+ for (int i = 0; i < loaders.length; i++) {
+ loaderNames[i] = loaders[i].getValue();
+ }
+ }
+
+ final Configuration factories = conf.getChild(OBJECT_FACTORY, false);
+ if (factories != null) {
+ // Store the factory to the table as a string and
+ // instantiate it by using the service when needed.
+ Configuration[] nameVal = factories.getChildren();
+ for (Configuration entry : nameVal)
+ objectFactoryClasses.put(entry.getName(), entry.getValue());
+
+ }
+ }
+
+ /**
+ * Avalon component lifecycle method Initializes the service by loading default
+ * class loaders and customized object factories.
+ *
+ * @throws Exception if initialization fails.
+ */
+ @Override
+ public void initialize() throws Exception {
+ if (loaderNames != null) {
+ for (String className : loaderNames) {
+ try {
+ ClassLoader loader = (ClassLoader) loadClass(className).newInstance();
+ classLoaders.add(loader);
+ } catch (Exception x) {
+ throw new Exception("No such class loader '" + className + "' for DefaultFactoryService", x);
+ }
+ }
+ loaderNames = null;
+ }
+ }
+
+ /**
+ * Avalon component lifecycle method Clear lists and maps
+ */
+ @Override
+ public void dispose() {
+ objectFactories.clear();
+ objectFactoryClasses.clear();
+ classLoaders.clear();
+ }
}
Modified: turbine/fulcrum/trunk/factory/src/java/org/apache/fulcrum/factory/FactoryException.java
URL: http://svn.apache.org/viewvc/turbine/fulcrum/trunk/factory/src/java/org/apache/fulcrum/factory/FactoryException.java?rev=1848903&r1=1848902&r2=1848903&view=diff
==============================================================================
--- turbine/fulcrum/trunk/factory/src/java/org/apache/fulcrum/factory/FactoryException.java (original)
+++ turbine/fulcrum/trunk/factory/src/java/org/apache/fulcrum/factory/FactoryException.java Thu Dec 13 21:50:53 2018
@@ -19,54 +19,50 @@ package org.apache.fulcrum.factory;
* under the License.
*/
-import java.lang.Exception;
-
/**
* Exception thrown when there is a problem with the FactoryService
*
* @author <a href="mailto:epugh@upstate.com">Eric Pugh</a>
* @version $Id$
*/
-public class FactoryException extends Exception
-{
- /**
- * Serial number
- */
- private static final long serialVersionUID = 8954422192583295720L;
-
- /**
- * Default constructor
- */
- public FactoryException()
- {
- super();
- }
-
- /**
- * {@link java.lang.Exception#Exception(String, Throwable)}
- * @param message the message
- * @param e the exception
- */
- public FactoryException(String message, Throwable e)
- {
- super(message, e);
- }
-
- /**
- * {@link java.lang.Exception#Exception(Throwable)}
- * @param e the exception to bubble up
- */
- public FactoryException(Throwable e)
- {
- super(e);
- }
-
- /**
- * {@link java.lang.Exception#Exception(String)}
- * @param msg the message to bubble up
- */
- public FactoryException(String msg)
- {
- super(msg);
- }
+public class FactoryException extends Exception {
+ /**
+ * Serial number
+ */
+ private static final long serialVersionUID = 8954422192583295720L;
+
+ /**
+ * Default constructor
+ */
+ public FactoryException() {
+ super();
+ }
+
+ /**
+ * {@link java.lang.Exception#Exception(String, Throwable)}
+ *
+ * @param message the message
+ * @param e the exception
+ */
+ public FactoryException(String message, Throwable e) {
+ super(message, e);
+ }
+
+ /**
+ * {@link java.lang.Exception#Exception(Throwable)}
+ *
+ * @param e the exception to bubble up
+ */
+ public FactoryException(Throwable e) {
+ super(e);
+ }
+
+ /**
+ * {@link java.lang.Exception#Exception(String)}
+ *
+ * @param msg the message to bubble up
+ */
+ public FactoryException(String msg) {
+ super(msg);
+ }
}