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);
+	}
 }