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.InvocationTargetException;
020: import java.lang.reflect.Method;
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 InvokerTransformer implements Transformer, Serializable {
034:
035: /** The serial version */
036: private static final long serialVersionUID = -8653385846894047688L;
037:
038: /** The method name to call */
039: private final String iMethodName;
040: /** The array of reflection parameter types */
041: private final Class[] iParamTypes;
042: /** The array of reflection arguments */
043: private final Object[] iArgs;
044:
045: /**
046: * Gets an instance of this transformer calling a specific method with no arguments.
047: *
048: * @param methodName the method name to call
049: * @return an invoker transformer
050: * @since Commons Collections 3.1
051: */
052: public static Transformer getInstance(String methodName) {
053: if (methodName == null) {
054: throw new IllegalArgumentException(
055: "The method to invoke must not be null");
056: }
057: return new InvokerTransformer(methodName);
058: }
059:
060: /**
061: * Gets an instance of this transformer calling a specific method with specific values.
062: *
063: * @param methodName the method name to call
064: * @param paramTypes the parameter types of the method
065: * @param args the arguments to pass to the method
066: * @return an invoker transformer
067: */
068: public static Transformer getInstance(String methodName,
069: Class[] paramTypes, Object[] args) {
070: if (methodName == null) {
071: throw new IllegalArgumentException(
072: "The method to invoke must not be null");
073: }
074: if (((paramTypes == null) && (args != null))
075: || ((paramTypes != null) && (args == null))
076: || ((paramTypes != null) && (args != null) && (paramTypes.length != args.length))) {
077: throw new IllegalArgumentException(
078: "The parameter types must match the arguments");
079: }
080: if (paramTypes == null || paramTypes.length == 0) {
081: return new InvokerTransformer(methodName);
082: } else {
083: paramTypes = (Class[]) paramTypes.clone();
084: args = (Object[]) args.clone();
085: return new InvokerTransformer(methodName, paramTypes, args);
086: }
087: }
088:
089: /**
090: * Constructor for no arg instance.
091: *
092: * @param methodName the method to call
093: */
094: private InvokerTransformer(String methodName) {
095: super ();
096: iMethodName = methodName;
097: iParamTypes = null;
098: iArgs = null;
099: }
100:
101: /**
102: * Constructor that performs no validation.
103: * Use <code>getInstance</code> if you want that.
104: *
105: * @param methodName the method to call
106: * @param paramTypes the constructor parameter types, not cloned
107: * @param args the constructor arguments, not cloned
108: */
109: public InvokerTransformer(String methodName, Class[] paramTypes,
110: Object[] args) {
111: super ();
112: iMethodName = methodName;
113: iParamTypes = paramTypes;
114: iArgs = args;
115: }
116:
117: /**
118: * Transforms the input to result by invoking a method on the input.
119: *
120: * @param input the input object to transform
121: * @return the transformed result, null if null input
122: */
123: public Object transform(Object input) {
124: if (input == null) {
125: return null;
126: }
127: try {
128: Class cls = input.getClass();
129: Method method = cls.getMethod(iMethodName, iParamTypes);
130: return method.invoke(input, iArgs);
131:
132: } catch (NoSuchMethodException ex) {
133: throw new FunctorException(
134: "InvokerTransformer: The method '" + iMethodName
135: + "' on '" + input.getClass()
136: + "' does not exist");
137: } catch (IllegalAccessException ex) {
138: throw new FunctorException(
139: "InvokerTransformer: The method '" + iMethodName
140: + "' on '" + input.getClass()
141: + "' cannot be accessed");
142: } catch (InvocationTargetException ex) {
143: throw new FunctorException(
144: "InvokerTransformer: The method '" + iMethodName
145: + "' on '" + input.getClass()
146: + "' threw an exception", ex);
147: }
148: }
149:
150: }
|