diff --git a/src/java/org/apache/commons/collections/FactoryUtils.java b/src/java/org/apache/commons/collections/FactoryUtils.java
index c1fd31d4b..aec20a5b6 100644
--- a/src/java/org/apache/commons/collections/FactoryUtils.java
+++ b/src/java/org/apache/commons/collections/FactoryUtils.java
@@ -1,5 +1,5 @@
/*
- * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/FactoryUtils.java,v 1.10 2003/11/23 17:01:36 scolebourne Exp $
+ * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/FactoryUtils.java,v 1.11 2003/11/23 17:48:20 scolebourne Exp $
* ====================================================================
*
* The Apache Software License, Version 1.1
@@ -57,18 +57,10 @@
*/
package org.apache.commons.collections;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
+import org.apache.commons.collections.functors.ConstantFactory;
+import org.apache.commons.collections.functors.InstantiateFactory;
import org.apache.commons.collections.functors.ExceptionFactory;
-import org.apache.commons.collections.functors.FunctorException;
+import org.apache.commons.collections.functors.PrototypeFactory;
/**
* FactoryUtils
provides reference implementations and utilities
@@ -83,17 +75,12 @@ import org.apache.commons.collections.functors.FunctorException;
* All the supplied factories are Serializable.
*
* @since Commons Collections 3.0
- * @version $Revision: 1.10 $ $Date: 2003/11/23 17:01:36 $
+ * @version $Revision: 1.11 $ $Date: 2003/11/23 17:48:20 $
*
* @author Stephen Colebourne
*/
public class FactoryUtils {
- /**
- * A factory that always returns null
- */
- private static final Factory NULL_FACTORY = new ConstantFactory(null);
-
/**
* This class is not normally instantiated.
*/
@@ -118,7 +105,7 @@ public class FactoryUtils {
* @return the factory
*/
public static Factory nullFactory() {
- return NULL_FACTORY;
+ return ConstantFactory.NULL_INSTANCE;
}
/**
@@ -131,7 +118,7 @@ public class FactoryUtils {
* @return the constant
factory.
*/
public static Factory constantFactory(Object constantToReturn) {
- return new ConstantFactory(constantToReturn);
+ return ConstantFactory.getInstance(constantToReturn);
}
/**
@@ -150,25 +137,7 @@ public class FactoryUtils {
* @throws IllegalArgumentException if the prototype cannot be cloned
*/
public static Factory prototypeFactory(Object prototype) {
- if (prototype == null) {
- throw new IllegalArgumentException("The prototype must not be null");
- }
- try {
- prototype.getClass().getMethod("clone", null);
- return new PrototypeCloneFactory(prototype);
-
- } catch (NoSuchMethodException ex) {
- try {
- prototype.getClass().getConstructor(new Class[] { prototype.getClass()});
- return new ReflectionFactory(prototype.getClass(), new Class[] { prototype.getClass()}, new Object[] { prototype });
-
- } catch (NoSuchMethodException ex2) {
- if (prototype instanceof Serializable) {
- return new PrototypeSerializationFactory((Serializable) prototype);
- }
- }
- }
- throw new IllegalArgumentException("The prototype must be cloneable via a public clone method");
+ return PrototypeFactory.getInstance(prototype);
}
/**
@@ -179,8 +148,8 @@ public class FactoryUtils {
* @return the reflection
factory
* @throws IllegalArgumentException if the classToInstantiate is null
*/
- public static Factory reflectionFactory(Class classToInstantiate) {
- return new ReflectionFactory(classToInstantiate);
+ public static Factory instantiateFactory(Class classToInstantiate) {
+ return InstantiateFactory.getInstance(classToInstantiate, null, null);
}
/**
@@ -195,228 +164,8 @@ public class FactoryUtils {
* @throws IllegalArgumentException if the paramTypes and args don't match
* @throws IllegalArgumentException if the constructor doesn't exist
*/
- public static Factory reflectionFactory(Class classToInstantiate, Class[] paramTypes, Object[] args) {
- return new ReflectionFactory(classToInstantiate, paramTypes, args);
- }
-
- // ConstantFactory
- //----------------------------------------------------------------------------------
-
- /**
- * ConstantFactory returns the same instance each time.
- */
- private static class ConstantFactory implements Factory, Serializable {
- /** The constant to return each time */
- private final Object iConstant;
-
- /**
- * Constructor to store constant
- */
- private ConstantFactory(Object constant) {
- super();
- iConstant = constant;
- }
-
- /**
- * Always return constant
- */
- public Object create() {
- return iConstant;
- }
- }
-
- // PrototypeCloneFactory
- //----------------------------------------------------------------------------------
-
- /**
- * PrototypeCloneFactory creates objects by copying a prototype using the clone method.
- */
- private static class PrototypeCloneFactory implements Factory, Serializable {
- /** The object to clone each time */
- private final Object iPrototype;
- /** The method used to clone */
- private transient Method iCloneMethod;
-
- /**
- * Constructor to store prototype
- */
- private PrototypeCloneFactory(Object prototype) {
- super();
- if (prototype == null) {
- throw new IllegalArgumentException("PrototypeCloneFactory: The prototype must not be null");
- }
- iPrototype = prototype;
-
- findCloneMethod();
- }
-
- /**
- * Find the Clone method for the class specified.
- */
- private void findCloneMethod() {
- try {
- iCloneMethod = iPrototype.getClass().getMethod("clone", null);
-
- } catch (NoSuchMethodException ex) {
- throw new IllegalArgumentException("PrototypeCloneFactory: The clone method must exist and be public ");
- }
- }
-
- /**
- * Return clone of prototype
- */
- public Object create() {
- // needed for post-serialization
- if (iCloneMethod == null) {
- findCloneMethod();
- }
-
- try {
- return iCloneMethod.invoke(iPrototype, null);
-
- } catch (IllegalAccessException ex) {
- throw new FunctorException("PrototypeCloneFactory: Clone method must be public", ex);
- } catch (InvocationTargetException ex) {
- throw new FunctorException("PrototypeCloneFactory: Clone method threw an exception", ex);
- }
- }
- }
-
- // PrototypeSerializationFactory
- //----------------------------------------------------------------------------------
-
- /**
- * PrototypeSerializationFactory creates objects by cloning a prototype using serialization.
- */
- private static class PrototypeSerializationFactory implements Factory, Serializable {
- /** The object to clone via serialization each time */
- private final Serializable iPrototype;
-
- /**
- * Constructor to store prototype
- */
- private PrototypeSerializationFactory(Serializable prototype) {
- super();
- if (prototype == null) {
- throw new IllegalArgumentException("PrototypeSerializationFactory: The prototype must not be null");
- }
- iPrototype = prototype;
- }
-
- /**
- * Return clone of prototype by serialization
- */
- public Object create() {
- ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
- ByteArrayInputStream bais = null;
- try {
- ObjectOutputStream out = new ObjectOutputStream(baos);
- out.writeObject(iPrototype);
-
- bais = new ByteArrayInputStream(baos.toByteArray());
- ObjectInputStream in = new ObjectInputStream(bais);
- return in.readObject();
-
- } catch (ClassNotFoundException ex) {
- throw new FunctorException(ex);
- } catch (IOException ex) {
- throw new FunctorException(ex);
- } finally {
- try {
- if (bais != null) {
- bais.close();
- }
- } catch (IOException ignored) {}
- try {
- if (baos != null) {
- baos.close();
- }
- } catch (IOException ignored) {}
- }
- }
- }
-
- // ReflectionFactory
- //----------------------------------------------------------------------------------
-
- /**
- * ReflectionFactory creates objects using reflection.
- */
- private static class ReflectionFactory implements Factory, Serializable {
- /** The class to create */
- private final Class iClassToInstantiate;
- /** The constructor parameter types */
- private final Class[] iParamTypes;
- /** The constructor arguments */
- private final Object[] iArgs;
- /** The constructor */
- private transient Constructor iConstructor = null;
-
- /**
- * Constructor
- */
- public ReflectionFactory(Class classToInstantiate) {
- this(classToInstantiate, null, null);
- }
-
- /* builds the object factory taking all the options needed to provide
- * arguments to a constructor.
- */
- public ReflectionFactory(Class classToInstantiate, Class[] paramTypes, Object[] args) {
- super();
- if (classToInstantiate == null) {
- throw new IllegalArgumentException("ReflectionFactory: The class to instantiate must not be null");
- }
- if (((paramTypes == null) && (args != null))
- || ((paramTypes != null) && (args == null))
- || ((paramTypes != null) && (args != null) && (paramTypes.length != args.length))) {
- throw new IllegalArgumentException("ReflectionFactory: The parameter types must match the arguments");
- }
-
- iClassToInstantiate = classToInstantiate;
- if ((paramTypes == null) && (args == null)) {
- iParamTypes = null;
- iArgs = null;
- } else {
- iParamTypes = (Class[]) paramTypes.clone();
- iArgs = (Object[]) args.clone();
- }
-
- findConstructor();
- }
-
- /**
- * Find the Constructor for the class specified.
- */
- private void findConstructor() {
- try {
- iConstructor = iClassToInstantiate.getConstructor(iParamTypes);
-
- } catch (NoSuchMethodException ex) {
- throw new IllegalArgumentException("ReflectionFactory: The constructor must exist and be public ");
- }
- }
-
- /**
- * Create the object using a constructor
- */
- public Object create() {
- // needed for post-serialization
- if (iConstructor == null) {
- findConstructor();
- }
-
- try {
- return iConstructor.newInstance(iArgs);
-
- } catch (InstantiationException ex) {
- throw new FunctorException("ReflectionFactory: InstantiationException", ex);
- } catch (IllegalAccessException ex) {
- throw new FunctorException("ReflectionFactory: Constructor must be public", ex);
- } catch (InvocationTargetException ex) {
- throw new FunctorException("ReflectionFactory: Constructor threw an exception", ex);
- }
- }
+ public static Factory instantiateFactory(Class classToInstantiate, Class[] paramTypes, Object[] args) {
+ return InstantiateFactory.getInstance(classToInstantiate, paramTypes, args);
}
}
diff --git a/src/java/org/apache/commons/collections/TransformerUtils.java b/src/java/org/apache/commons/collections/TransformerUtils.java
index de661e9d0..4bf486242 100644
--- a/src/java/org/apache/commons/collections/TransformerUtils.java
+++ b/src/java/org/apache/commons/collections/TransformerUtils.java
@@ -1,5 +1,5 @@
/*
- * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/TransformerUtils.java,v 1.7 2003/11/23 17:01:36 scolebourne Exp $
+ * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/TransformerUtils.java,v 1.8 2003/11/23 17:48:20 scolebourne Exp $
* ====================================================================
*
* The Apache Software License, Version 1.1
@@ -90,7 +90,7 @@ import org.apache.commons.collections.functors.FunctorException;
* All the supplied transformers are Serializable.
*
* @since Commons Collections 3.0
- * @version $Revision: 1.7 $ $Date: 2003/11/23 17:01:36 $
+ * @version $Revision: 1.8 $ $Date: 2003/11/23 17:48:20 $
*
* @author Stephen Colebourne
* @author James Carman
@@ -835,7 +835,7 @@ public class TransformerUtils {
"InstantiateTransformer: Input object was not an instanceof Class, it was a "
+ (input == null ? "null object" : input.getClass().getName()));
}
- return FactoryUtils.reflectionFactory((Class) input, iParamTypes, iArgs).create();
+ return FactoryUtils.instantiateFactory((Class) input, iParamTypes, iArgs).create();
} catch (IllegalArgumentException ex) {
throw new FunctorException("InstantiateTransformer", ex);
diff --git a/src/java/org/apache/commons/collections/functors/ConstantFactory.java b/src/java/org/apache/commons/collections/functors/ConstantFactory.java
new file mode 100644
index 000000000..0c7d6ed1b
--- /dev/null
+++ b/src/java/org/apache/commons/collections/functors/ConstantFactory.java
@@ -0,0 +1,118 @@
+/*
+ * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/functors/ConstantFactory.java,v 1.1 2003/11/23 17:48:19 scolebourne Exp $
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowledgement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgement may appear in the software itself,
+ * if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ *
+ * No check is made that the object is immutable. In general, only immutable
+ * objects should use the constant factory. Mutable objects should
+ * use the prototype factory.
+ *
+ * @since Commons Collections 3.0
+ * @version $Revision: 1.1 $ $Date: 2003/11/23 17:48:19 $
+ *
+ * @author Stephen Colebourne
+ */
+public class ConstantFactory implements Factory, Serializable {
+
+ /** Serial version UID */
+ static final long serialVersionUID = -3520677225766901240L;
+
+ /** Returns null each time */
+ public static final Factory NULL_INSTANCE = new ConstantFactory(null);
+
+ /** The closures to call in turn */
+ private final Object iConstant;
+
+ /**
+ * Factory method that performs validation.
+ *
+ * @param constantToReturn the constant object to return each time in the factory
+ * @return the constant
factory.
+ */
+ public static Factory getInstance(Object constantToReturn) {
+ if (constantToReturn == null) {
+ return NULL_INSTANCE;
+ }
+ return new ConstantFactory(constantToReturn);
+ }
+
+ /**
+ * Constructor that performs no validation.
+ * Use getInstance
if you want that.
+ *
+ * @param constantToReturn the constant to return each time
+ */
+ public ConstantFactory(Object constantToReturn) {
+ super();
+ iConstant = constantToReturn;
+ }
+
+ /**
+ * Always return constant
+ */
+ public Object create() {
+ return iConstant;
+ }
+
+}
diff --git a/src/java/org/apache/commons/collections/functors/InstantiateFactory.java b/src/java/org/apache/commons/collections/functors/InstantiateFactory.java
new file mode 100644
index 000000000..cbdbd7733
--- /dev/null
+++ b/src/java/org/apache/commons/collections/functors/InstantiateFactory.java
@@ -0,0 +1,178 @@
+/*
+ * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/functors/InstantiateFactory.java,v 1.1 2003/11/23 17:48:19 scolebourne Exp $
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowledgement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgement may appear in the software itself,
+ * if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * getInstance
if you want that.
+ *
+ * @param classToInstantiate the class to instantiate
+ */
+ public InstantiateFactory(Class classToInstantiate) {
+ super();
+ iClassToInstantiate = classToInstantiate;
+ iParamTypes = null;
+ iArgs = null;
+ findConstructor();
+ }
+
+ /**
+ * Constructor that performs no validation.
+ * Use getInstance
if you want that.
+ *
+ * @param classToInstantiate the class to instantiate
+ * @param paramTypes the constructor parameter types, not cloned
+ * @param args the constructor arguments, not cloned
+ */
+ public InstantiateFactory(Class classToInstantiate, Class[] paramTypes, Object[] args) {
+ super();
+ iClassToInstantiate = classToInstantiate;
+ iParamTypes = paramTypes;
+ iArgs = args;
+ findConstructor();
+ }
+
+ /**
+ * Find the Constructor for the class specified.
+ */
+ private void findConstructor() {
+ try {
+ iConstructor = iClassToInstantiate.getConstructor(iParamTypes);
+
+ } catch (NoSuchMethodException ex) {
+ throw new IllegalArgumentException("InstantiateFactory: The constructor must exist and be public ");
+ }
+ }
+
+ /**
+ * Create the object using a constructor
+ */
+ public Object create() {
+ // needed for post-serialization
+ if (iConstructor == null) {
+ findConstructor();
+ }
+
+ try {
+ return iConstructor.newInstance(iArgs);
+
+ } catch (InstantiationException ex) {
+ throw new FunctorException("InstantiateFactory: InstantiationException", ex);
+ } catch (IllegalAccessException ex) {
+ throw new FunctorException("InstantiateFactory: Constructor must be public", ex);
+ } catch (InvocationTargetException ex) {
+ throw new FunctorException("InstantiateFactory: Constructor threw an exception", ex);
+ }
+ }
+
+}
diff --git a/src/java/org/apache/commons/collections/functors/PrototypeFactory.java b/src/java/org/apache/commons/collections/functors/PrototypeFactory.java
new file mode 100644
index 000000000..7f689d017
--- /dev/null
+++ b/src/java/org/apache/commons/collections/functors/PrototypeFactory.java
@@ -0,0 +1,251 @@
+/*
+ * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/functors/PrototypeFactory.java,v 1.1 2003/11/23 17:48:19 scolebourne Exp $
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowledgement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgement may appear in the software itself,
+ * if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ *
+ * Creates a Factory that will return a clone of the same prototype object + * each time the factory is used. The prototype will be cloned using one of these + * techniques (in order): + *
prototype
factory
+ * @throws IllegalArgumentException if the prototype is null
+ * @throws IllegalArgumentException if the prototype cannot be cloned
+ */
+ public static Factory getInstance(Object prototype) {
+ if (prototype == null) {
+ throw new IllegalArgumentException("The prototype must not be null");
+ }
+ try {
+ prototype.getClass().getMethod("clone", null);
+ return new PrototypeCloneFactory(prototype);
+
+ } catch (NoSuchMethodException ex) {
+ try {
+ prototype.getClass().getConstructor(new Class[] { prototype.getClass()});
+ return new InstantiateFactory(
+ prototype.getClass(),
+ new Class[] { prototype.getClass()},
+ new Object[] { prototype });
+
+ } catch (NoSuchMethodException ex2) {
+ if (prototype instanceof Serializable) {
+ return new PrototypeSerializationFactory((Serializable) prototype);
+ }
+ }
+ }
+ throw new IllegalArgumentException("The prototype must be cloneable via a public clone method");
+ }
+
+ /**
+ * Constructor that performs no validation.
+ * Use getInstance
if you want that.
+ *
+ * @param constantToReturn the constant to return each time
+ */
+ private PrototypeFactory() {
+ }
+
+ // PrototypeCloneFactory
+ //-----------------------------------------------------------------------
+ /**
+ * PrototypeCloneFactory creates objects by copying a prototype using the clone method.
+ */
+ static class PrototypeCloneFactory implements Factory, Serializable {
+
+ /** The serial version */
+ static final long serialVersionUID = 5604271422565175555L;
+
+ /** The object to clone each time */
+ private final Object iPrototype;
+ /** The method used to clone */
+ private transient Method iCloneMethod;
+
+ /**
+ * Constructor to store prototype
+ */
+ private PrototypeCloneFactory(Object prototype) {
+ super();
+ if (prototype == null) {
+ throw new IllegalArgumentException("PrototypeCloneFactory: The prototype must not be null");
+ }
+ iPrototype = prototype;
+
+ findCloneMethod();
+ }
+
+ /**
+ * Find the Clone method for the class specified.
+ */
+ private void findCloneMethod() {
+ try {
+ iCloneMethod = iPrototype.getClass().getMethod("clone", null);
+
+ } catch (NoSuchMethodException ex) {
+ throw new IllegalArgumentException("PrototypeCloneFactory: The clone method must exist and be public ");
+ }
+ }
+
+ /**
+ * Return clone of prototype
+ */
+ public Object create() {
+ // needed for post-serialization
+ if (iCloneMethod == null) {
+ findCloneMethod();
+ }
+
+ try {
+ return iCloneMethod.invoke(iPrototype, null);
+
+ } catch (IllegalAccessException ex) {
+ throw new FunctorException("PrototypeCloneFactory: Clone method must be public", ex);
+ } catch (InvocationTargetException ex) {
+ throw new FunctorException("PrototypeCloneFactory: Clone method threw an exception", ex);
+ }
+ }
+ }
+
+ // PrototypeSerializationFactory
+ //-----------------------------------------------------------------------
+ /**
+ * PrototypeSerializationFactory creates objects by cloning a prototype using serialization.
+ */
+ static class PrototypeSerializationFactory implements Factory, Serializable {
+
+ /** The serial version */
+ static final long serialVersionUID = -8704966966139178833L;
+
+ /** The object to clone via serialization each time */
+ private final Serializable iPrototype;
+
+ /**
+ * Constructor to store prototype
+ */
+ private PrototypeSerializationFactory(Serializable prototype) {
+ super();
+ if (prototype == null) {
+ throw new IllegalArgumentException("PrototypeSerializationFactory: The prototype must not be null");
+ }
+ iPrototype = prototype;
+ }
+
+ /**
+ * Return clone of prototype by serialization
+ */
+ public Object create() {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
+ ByteArrayInputStream bais = null;
+ try {
+ ObjectOutputStream out = new ObjectOutputStream(baos);
+ out.writeObject(iPrototype);
+
+ bais = new ByteArrayInputStream(baos.toByteArray());
+ ObjectInputStream in = new ObjectInputStream(bais);
+ return in.readObject();
+
+ } catch (ClassNotFoundException ex) {
+ throw new FunctorException(ex);
+ } catch (IOException ex) {
+ throw new FunctorException(ex);
+ } finally {
+ try {
+ if (bais != null) {
+ bais.close();
+ }
+ } catch (IOException ignored) {
+ }
+ try {
+ if (baos != null) {
+ baos.close();
+ }
+ } catch (IOException ignored) {
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/test/org/apache/commons/collections/TestFactoryUtils.java b/src/test/org/apache/commons/collections/TestFactoryUtils.java
index dcc489ef5..592fe14ad 100644
--- a/src/test/org/apache/commons/collections/TestFactoryUtils.java
+++ b/src/test/org/apache/commons/collections/TestFactoryUtils.java
@@ -1,5 +1,5 @@
/*
- * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/test/org/apache/commons/collections/TestFactoryUtils.java,v 1.6 2003/11/23 14:41:27 scolebourne Exp $
+ * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/test/org/apache/commons/collections/TestFactoryUtils.java,v 1.7 2003/11/23 17:48:19 scolebourne Exp $
* ====================================================================
*
* The Apache Software License, Version 1.1
@@ -72,7 +72,7 @@ import junit.textui.TestRunner;
* Tests the org.apache.commons.collections.FactoryUtils class.
*
* @since Commons Collections 3.0
- * @version $Revision: 1.6 $ $Date: 2003/11/23 14:41:27 $
+ * @version $Revision: 1.7 $ $Date: 2003/11/23 17:48:19 $
*
* @author Stephen Colebourne
*/
@@ -267,12 +267,12 @@ public class TestFactoryUtils extends junit.framework.TestCase {
}
}
- // reflectionFactory
+ // instantiateFactory
//------------------------------------------------------------------
public void testReflectionFactoryNull() {
try {
- Factory factory = FactoryUtils.reflectionFactory(null);
+ Factory factory = FactoryUtils.instantiateFactory(null);
} catch (IllegalArgumentException ex) {
return;
@@ -281,7 +281,7 @@ public class TestFactoryUtils extends junit.framework.TestCase {
}
public void testReflectionFactorySimple() {
- Factory factory = FactoryUtils.reflectionFactory(Mock3.class);
+ Factory factory = FactoryUtils.instantiateFactory(Mock3.class);
assertNotNull(factory);
Object created = factory.create();
assertEquals(0, ((Mock3) created).getValue());
@@ -291,7 +291,7 @@ public class TestFactoryUtils extends junit.framework.TestCase {
public void testReflectionFactoryMismatch() {
try {
- Factory factory = FactoryUtils.reflectionFactory(Date.class, null, new Object[] {null});
+ Factory factory = FactoryUtils.instantiateFactory(Date.class, null, new Object[] {null});
} catch (IllegalArgumentException ex) {
return;
@@ -301,7 +301,7 @@ public class TestFactoryUtils extends junit.framework.TestCase {
public void testReflectionFactoryNoConstructor() {
try {
- Factory factory = FactoryUtils.reflectionFactory(Date.class, new Class[] {Long.class}, new Object[] {null});
+ Factory factory = FactoryUtils.instantiateFactory(Date.class, new Class[] {Long.class}, new Object[] {null});
} catch (IllegalArgumentException ex) {
return;
@@ -312,7 +312,7 @@ public class TestFactoryUtils extends junit.framework.TestCase {
public void testReflectionFactoryComplex() {
TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
// 2nd Jan 1970
- Factory factory = FactoryUtils.reflectionFactory(Date.class,
+ Factory factory = FactoryUtils.instantiateFactory(Date.class,
new Class[] {Integer.TYPE, Integer.TYPE, Integer.TYPE},
new Object[] {new Integer(70), new Integer(0), new Integer(2)});
assertNotNull(factory);