View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.collections.functors;
18  
19  import java.io.Serializable;
20  import java.lang.reflect.Constructor;
21  import java.lang.reflect.InvocationTargetException;
22  
23  import org.apache.commons.collections.FunctorException;
24  import org.apache.commons.collections.Transformer;
25  
26  /**
27   * Transformer implementation that creates a new object instance by reflection.
28   *
29   * @since 3.0
30   * @version $Id: InstantiateTransformer.java 1435965 2013-01-20 21:13:18Z tn $
31   */
32  public class InstantiateTransformer<T> implements Transformer<Class<? extends T>, T>, Serializable {
33  
34      /** The serial version */
35      private static final long serialVersionUID = 3786388740793356347L;
36  
37      /** Singleton instance that uses the no arg constructor */
38      public static final Transformer<Class<?>, ?> NO_ARG_INSTANCE = new InstantiateTransformer<Object>();
39  
40      /** The constructor parameter types */
41      private final Class<?>[] iParamTypes;
42      /** The constructor arguments */
43      private final Object[] iArgs;
44  
45      /**
46       * Get a typed no-arg instance.
47       *
48       * @param <T>  the type of the objects to be created
49       * @return Transformer<Class<? extends T>, T>
50       */
51      public static <T> Transformer<Class<? extends T>, T> instantiateTransformer() {
52          return new InstantiateTransformer<T>();
53      }
54  
55      /**
56       * Transformer method that performs validation.
57       *
58       * @param <T>  the type of the objects to be created
59       * @param paramTypes  the constructor parameter types
60       * @param args  the constructor arguments
61       * @return an instantiate transformer
62       */
63      public static <T> Transformer<Class<? extends T>, T> instantiateTransformer(Class<?>[] paramTypes, Object[] args) {
64          if (((paramTypes == null) && (args != null))
65              || ((paramTypes != null) && (args == null))
66              || ((paramTypes != null) && (args != null) && (paramTypes.length != args.length))) {
67              throw new IllegalArgumentException("Parameter types must match the arguments");
68          }
69  
70          if (paramTypes == null || paramTypes.length == 0) {
71              return new InstantiateTransformer<T>();
72          }
73          paramTypes = paramTypes.clone();
74          args = args.clone();
75          return new InstantiateTransformer<T>(paramTypes, args);
76      }
77  
78      /**
79       * Constructor for no arg instance.
80       */
81      private InstantiateTransformer() {
82          super();
83          iParamTypes = null;
84          iArgs = null;
85      }
86  
87      /**
88       * Constructor that performs no validation.
89       * Use <code>getInstance</code> if you want that.
90       *
91       * @param paramTypes  the constructor parameter types, not cloned
92       * @param args  the constructor arguments, not cloned
93       */
94      public InstantiateTransformer(final Class<?>[] paramTypes, final Object[] args) {
95          super();
96          iParamTypes = paramTypes;
97          iArgs = args;
98      }
99  
100     /**
101      * Transforms the input Class object to a result by instantiation.
102      *
103      * @param input  the input object to transform
104      * @return the transformed result
105      */
106     public T transform(final Class<? extends T> input) {
107         try {
108             if (input == null) {
109                 throw new FunctorException(
110                     "InstantiateTransformer: Input object was not an instanceof Class, it was a null object");
111             }
112             final Constructor<? extends T> con = input.getConstructor(iParamTypes);
113             return con.newInstance(iArgs);
114         } catch (final NoSuchMethodException ex) {
115             throw new FunctorException("InstantiateTransformer: The constructor must exist and be public ");
116         } catch (final InstantiationException ex) {
117             throw new FunctorException("InstantiateTransformer: InstantiationException", ex);
118         } catch (final IllegalAccessException ex) {
119             throw new FunctorException("InstantiateTransformer: Constructor must be public", ex);
120         } catch (final InvocationTargetException ex) {
121             throw new FunctorException("InstantiateTransformer: Constructor threw an exception", ex);
122         }
123     }
124 
125 }