View Javadoc
1   package org.apache.maven.surefire.util;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.lang.reflect.Constructor;
23  import java.lang.reflect.InvocationTargetException;
24  import java.lang.reflect.Method;
25  
26  /**
27   * @author Kristian Rosenvold
28   */
29  public final class ReflectionUtils
30  {
31      private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];
32      private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
33  
34      private ReflectionUtils()
35      {
36          throw new IllegalStateException( "no instantiable constructor" );
37      }
38  
39      public static Method getMethod( Object instance, String methodName, Class<?>... parameters )
40      {
41          return getMethod( instance.getClass(), methodName, parameters );
42      }
43  
44      public static Method getMethod( Class<?> clazz, String methodName, Class<?>... parameters )
45      {
46          try
47          {
48              return clazz.getMethod( methodName, parameters );
49          }
50          catch ( NoSuchMethodException e )
51          {
52              throw new RuntimeException( "When finding method " + methodName, e );
53          }
54      }
55  
56      public static Method tryGetMethod( Class<?> clazz, String methodName, Class<?>... parameters )
57      {
58          try
59          {
60              return clazz.getMethod( methodName, parameters );
61          }
62          catch ( NoSuchMethodException e )
63          {
64              return null;
65          }
66      }
67  
68      public static Object invokeGetter( Object instance, String methodName )
69      {
70          return invokeGetter( instance.getClass(), instance, methodName );
71      }
72  
73      public static Object invokeGetter( Class<?> instanceType, Object instance, String methodName )
74      {
75          Method method = getMethod( instanceType, methodName );
76          return invokeMethodWithArray( instance, method );
77      }
78  
79      public static Constructor getConstructor( Class<?> clazz, Class<?>... arguments )
80      {
81          try
82          {
83              return clazz.getConstructor( arguments );
84          }
85          catch ( NoSuchMethodException e )
86          {
87              throw new SurefireReflectionException( e );
88          }
89      }
90  
91      public static Object newInstance( Constructor constructor, Object... params )
92      {
93          try
94          {
95              return constructor.newInstance( params );
96          }
97          catch ( InvocationTargetException e )
98          {
99              throw new SurefireReflectionException( e );
100         }
101         catch ( InstantiationException e )
102         {
103             throw new SurefireReflectionException( e );
104         }
105         catch ( IllegalAccessException e )
106         {
107             throw new SurefireReflectionException( e );
108         }
109     }
110 
111     public static <T> T instantiate( ClassLoader classLoader, String classname, Class<T> returnType )
112     {
113         try
114         {
115             Class<?> clazz = loadClass( classLoader, classname );
116             return returnType.cast( clazz.newInstance() );
117         }
118         catch ( InstantiationException e )
119         {
120             throw new SurefireReflectionException( e );
121         }
122         catch ( IllegalAccessException e )
123         {
124             throw new SurefireReflectionException( e );
125         }
126     }
127 
128     public static Object instantiateOneArg( ClassLoader classLoader, String className, Class<?> param1Class,
129                                             Object param1 )
130     {
131         try
132         {
133             Class<?> aClass = loadClass( classLoader, className );
134             Constructor constructor = getConstructor( aClass, param1Class );
135             return constructor.newInstance( param1 );
136         }
137         catch ( InvocationTargetException e )
138         {
139             throw new SurefireReflectionException( e.getTargetException() );
140         }
141         catch ( InstantiationException e )
142         {
143             throw new SurefireReflectionException( e );
144         }
145         catch ( IllegalAccessException e )
146         {
147             throw new SurefireReflectionException( e );
148         }
149     }
150 
151     public static Object instantiateTwoArgs( ClassLoader classLoader, String className, Class<?> param1Class,
152                                              Object param1, Class param2Class, Object param2 )
153     {
154         try
155         {
156             Class<?> aClass = loadClass( classLoader, className );
157             Constructor constructor = getConstructor( aClass, param1Class, param2Class );
158             return constructor.newInstance( param1, param2 );
159         }
160         catch ( InvocationTargetException e )
161         {
162             throw new SurefireReflectionException( e.getTargetException() );
163         }
164         catch ( InstantiationException e )
165         {
166             throw new SurefireReflectionException( e );
167         }
168         catch ( IllegalAccessException e )
169         {
170             throw new SurefireReflectionException( e );
171         }
172     }
173 
174     public static void invokeSetter( Object o, String name, Class<?> value1clazz, Object value )
175     {
176         Method setter = getMethod( o, name, value1clazz );
177         invokeSetter( o, setter, value );
178     }
179 
180     public static Object invokeSetter( Object target, Method method, Object value )
181     {
182         return invokeMethodWithArray( target, method, value );
183     }
184 
185     public static Object invokeMethodWithArray( Object target, Method method, Object... args )
186     {
187         try
188         {
189             return method.invoke( target, args );
190         }
191         catch ( IllegalAccessException e )
192         {
193             throw new SurefireReflectionException( e );
194         }
195         catch ( InvocationTargetException e )
196         {
197             throw new SurefireReflectionException( e.getTargetException() );
198         }
199     }
200 
201     public static Object invokeMethodWithArray2( Object target, Method method, Object... args )
202         throws InvocationTargetException
203     {
204         try
205         {
206             return method.invoke( target, args );
207         }
208         catch ( IllegalAccessException e )
209         {
210             throw new SurefireReflectionException( e );
211         }
212     }
213 
214     public static Object instantiateObject( String className, Class[] types, Object[] params, ClassLoader classLoader )
215     {
216         Class<?> clazz = loadClass( classLoader, className );
217         final Constructor constructor = getConstructor( clazz, types );
218         return newInstance( constructor, params );
219     }
220 
221     @SuppressWarnings( "checkstyle:emptyblock" )
222     public static Class<?> tryLoadClass( ClassLoader classLoader, String className )
223     {
224         try
225         {
226             return classLoader.loadClass( className );
227         }
228         catch ( NoClassDefFoundError ignore )
229         {
230         }
231         catch ( ClassNotFoundException ignore )
232         {
233         }
234         return null;
235     }
236 
237     public static Class<?> loadClass( ClassLoader classLoader, String className )
238     {
239         try
240         {
241             return classLoader.loadClass( className );
242         }
243         catch ( NoClassDefFoundError e )
244         {
245             throw new SurefireReflectionException( e );
246         }
247         catch ( ClassNotFoundException e )
248         {
249             throw new SurefireReflectionException( e );
250         }
251     }
252 
253     /**
254      * Invoker of public static no-argument method.
255      *
256      * @param clazz         class on which public static no-argument {@code methodName} is invoked
257      * @param methodName    public static no-argument method to be called
258      * @param parameterTypes    method parameter types
259      * @param parameters    method parameters
260      * @return value returned by {@code methodName}
261      * @throws RuntimeException if no such method found
262      * @throws SurefireReflectionException if the method could not be called or threw an exception.
263      * It has original cause Exception.
264      */
265     public static Object invokeStaticMethod( Class<?> clazz, String methodName,
266                                              Class<?>[] parameterTypes, Object[] parameters )
267     {
268         if ( parameterTypes.length != parameters.length )
269         {
270             throw new IllegalArgumentException( "arguments length do not match" );
271         }
272         Method method = getMethod( clazz, methodName, parameterTypes );
273         return invokeMethodWithArray( null, method, parameters );
274     }
275 
276     /**
277      * Method chain invoker.
278      *
279      * @param classesChain        classes to invoke on method chain
280      * @param noArgMethodNames    chain of public methods to call
281      * @param fallback            returned value if a chain could not be invoked due to an error
282      * @return successfully returned value from the last method call; {@code fallback} otherwise
283      * @throws IllegalArgumentException if {@code classes} and {@code noArgMethodNames} have different array length
284      */
285     public static Object invokeMethodChain( Class<?>[] classesChain, String[] noArgMethodNames, Object fallback )
286     {
287         if ( classesChain.length != noArgMethodNames.length )
288         {
289             throw new IllegalArgumentException( "arrays must have the same length" );
290         }
291         Object obj = null;
292         try
293         {
294             for ( int i = 0, len = noArgMethodNames.length; i < len; i++ )
295             {
296                 if ( i == 0 )
297                 {
298                     obj = invokeStaticMethod( classesChain[i], noArgMethodNames[i],
299                                                     EMPTY_CLASS_ARRAY, EMPTY_OBJECT_ARRAY );
300                 }
301                 else
302                 {
303                     Method method = getMethod( classesChain[i], noArgMethodNames[i] );
304                     obj = invokeMethodWithArray( obj, method );
305                 }
306             }
307             return obj;
308         }
309         catch ( RuntimeException e )
310         {
311             return fallback;
312         }
313     }
314 }