001: /*
002: * Copyright 2001-2004 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.apache.commons.collections.functors;
017:
018: import java.io.Serializable;
019: import java.lang.reflect.Constructor;
020: import java.lang.reflect.InvocationTargetException;
021:
022: import org.apache.commons.collections.FunctorException;
023: import org.apache.commons.collections.Transformer;
024:
025: /**
026: * Transformer implementation that creates a new object instance by reflection.
027: *
028: * @since Commons Collections 3.0
029: * @version $Revision: 348444 $ $Date: 2005-11-23 14:06:56 +0000 (Wed, 23 Nov 2005) $
030: *
031: * @author Stephen Colebourne
032: */
033: public class InstantiateTransformer implements Transformer,
034: Serializable {
035:
036: /** The serial version */
037: private static final long serialVersionUID = 3786388740793356347L;
038:
039: /** Singleton instance that uses the no arg constructor */
040: public static final Transformer NO_ARG_INSTANCE = new InstantiateTransformer();
041:
042: /** The constructor parameter types */
043: private final Class[] iParamTypes;
044: /** The constructor arguments */
045: private final Object[] iArgs;
046:
047: /**
048: * Transformer method that performs validation.
049: *
050: * @param paramTypes the constructor parameter types
051: * @param args the constructor arguments
052: * @return an instantiate transformer
053: */
054: public static Transformer getInstance(Class[] paramTypes,
055: Object[] args) {
056: if (((paramTypes == null) && (args != null))
057: || ((paramTypes != null) && (args == null))
058: || ((paramTypes != null) && (args != null) && (paramTypes.length != args.length))) {
059: throw new IllegalArgumentException(
060: "Parameter types must match the arguments");
061: }
062:
063: if (paramTypes == null || paramTypes.length == 0) {
064: return NO_ARG_INSTANCE;
065: } else {
066: paramTypes = (Class[]) paramTypes.clone();
067: args = (Object[]) args.clone();
068: }
069: return new InstantiateTransformer(paramTypes, args);
070: }
071:
072: /**
073: * Constructor for no arg instance.
074: */
075: private InstantiateTransformer() {
076: super ();
077: iParamTypes = null;
078: iArgs = null;
079: }
080:
081: /**
082: * Constructor that performs no validation.
083: * Use <code>getInstance</code> if you want that.
084: *
085: * @param paramTypes the constructor parameter types, not cloned
086: * @param args the constructor arguments, not cloned
087: */
088: public InstantiateTransformer(Class[] paramTypes, Object[] args) {
089: super ();
090: iParamTypes = paramTypes;
091: iArgs = args;
092: }
093:
094: /**
095: * Transforms the input Class object to a result by instantiation.
096: *
097: * @param input the input object to transform
098: * @return the transformed result
099: */
100: public Object transform(Object input) {
101: try {
102: if (input instanceof Class == false) {
103: throw new FunctorException(
104: "InstantiateTransformer: Input object was not an instanceof Class, it was a "
105: + (input == null ? "null object"
106: : input.getClass().getName()));
107: }
108: Constructor con = ((Class) input)
109: .getConstructor(iParamTypes);
110: return con.newInstance(iArgs);
111:
112: } catch (NoSuchMethodException ex) {
113: throw new FunctorException(
114: "InstantiateTransformer: The constructor must exist and be public ");
115: } catch (InstantiationException ex) {
116: throw new FunctorException(
117: "InstantiateTransformer: InstantiationException",
118: ex);
119: } catch (IllegalAccessException ex) {
120: throw new FunctorException(
121: "InstantiateTransformer: Constructor must be public",
122: ex);
123: } catch (InvocationTargetException ex) {
124: throw new FunctorException(
125: "InstantiateTransformer: Constructor threw an exception",
126: ex);
127: }
128: }
129:
130: }
|