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 ( ReflectiveOperationException e )
98          {
99              throw new SurefireReflectionException( e );
100         }
101     }
102 
103     public static <T> T instantiate( ClassLoader classLoader, String classname, Class<T> returnType )
104     {
105         try
106         {
107             Class<?> clazz = loadClass( classLoader, classname );
108             return returnType.cast( clazz.newInstance() );
109         }
110         catch ( ReflectiveOperationException e )
111         {
112             throw new SurefireReflectionException( e );
113         }
114     }
115 
116     public static Object instantiateOneArg( ClassLoader classLoader, String className, Class<?> param1Class,
117                                             Object param1 )
118     {
119         try
120         {
121             Class<?> aClass = loadClass( classLoader, className );
122             Constructor constructor = getConstructor( aClass, param1Class );
123             return constructor.newInstance( param1 );
124         }
125         catch ( InvocationTargetException e )
126         {
127             throw new SurefireReflectionException( e.getTargetException() );
128         }
129         catch ( ReflectiveOperationException e )
130         {
131             throw new SurefireReflectionException( e );
132         }
133     }
134 
135     public static Object instantiateTwoArgs( ClassLoader classLoader, String className, Class<?> param1Class,
136                                              Object param1, Class param2Class, Object param2 )
137     {
138         try
139         {
140             Class<?> aClass = loadClass( classLoader, className );
141             Constructor constructor = getConstructor( aClass, param1Class, param2Class );
142             return constructor.newInstance( param1, param2 );
143         }
144         catch ( InvocationTargetException e )
145         {
146             throw new SurefireReflectionException( e.getTargetException() );
147         }
148         catch ( ReflectiveOperationException e )
149         {
150             throw new SurefireReflectionException( e );
151         }
152     }
153 
154     public static void invokeSetter( Object o, String name, Class<?> value1clazz, Object value )
155     {
156         Method setter = getMethod( o, name, value1clazz );
157         invokeSetter( o, setter, value );
158     }
159 
160     public static Object invokeSetter( Object target, Method method, Object value )
161     {
162         return invokeMethodWithArray( target, method, value );
163     }
164 
165     public static Object invokeMethodWithArray( Object target, Method method, Object... args )
166     {
167         try
168         {
169             return method.invoke( target, args );
170         }
171         catch ( IllegalAccessException e )
172         {
173             throw new SurefireReflectionException( e );
174         }
175         catch ( InvocationTargetException e )
176         {
177             throw new SurefireReflectionException( e.getTargetException() );
178         }
179     }
180 
181     public static Object invokeMethodWithArray2( Object target, Method method, Object... args )
182         throws InvocationTargetException
183     {
184         try
185         {
186             return method.invoke( target, args );
187         }
188         catch ( IllegalAccessException e )
189         {
190             throw new SurefireReflectionException( e );
191         }
192     }
193 
194     public static Object instantiateObject( String className, Class[] types, Object[] params, ClassLoader classLoader )
195     {
196         Class<?> clazz = loadClass( classLoader, className );
197         final Constructor constructor = getConstructor( clazz, types );
198         return newInstance( constructor, params );
199     }
200 
201     @SuppressWarnings( "checkstyle:emptyblock" )
202     public static Class<?> tryLoadClass( ClassLoader classLoader, String className )
203     {
204         try
205         {
206             return classLoader.loadClass( className );
207         }
208         catch ( NoClassDefFoundError | ClassNotFoundException ignore )
209         {
210         }
211         return null;
212     }
213 
214     public static Class<?> loadClass( ClassLoader classLoader, String className )
215     {
216         try
217         {
218             return classLoader.loadClass( className );
219         }
220         catch ( NoClassDefFoundError | ClassNotFoundException e )
221         {
222             throw new SurefireReflectionException( e );
223         }
224     }
225 
226     /**
227      * Invoker of public static no-argument method.
228      *
229      * @param clazz         class on which public static no-argument {@code methodName} is invoked
230      * @param methodName    public static no-argument method to be called
231      * @param parameterTypes    method parameter types
232      * @param parameters    method parameters
233      * @return value returned by {@code methodName}
234      * @throws RuntimeException if no such method found
235      * @throws SurefireReflectionException if the method could not be called or threw an exception.
236      * It has original cause Exception.
237      */
238     public static Object invokeStaticMethod( Class<?> clazz, String methodName,
239                                              Class<?>[] parameterTypes, Object[] parameters )
240     {
241         if ( parameterTypes.length != parameters.length )
242         {
243             throw new IllegalArgumentException( "arguments length do not match" );
244         }
245         Method method = getMethod( clazz, methodName, parameterTypes );
246         return invokeMethodWithArray( null, method, parameters );
247     }
248 
249     /**
250      * Method chain invoker.
251      *
252      * @param classesChain        classes to invoke on method chain
253      * @param noArgMethodNames    chain of public methods to call
254      * @param fallback            returned value if a chain could not be invoked due to an error
255      * @return successfully returned value from the last method call; {@code fallback} otherwise
256      * @throws IllegalArgumentException if {@code classes} and {@code noArgMethodNames} have different array length
257      */
258     public static Object invokeMethodChain( Class<?>[] classesChain, String[] noArgMethodNames, Object fallback )
259     {
260         if ( classesChain.length != noArgMethodNames.length )
261         {
262             throw new IllegalArgumentException( "arrays must have the same length" );
263         }
264         Object obj = null;
265         try
266         {
267             for ( int i = 0, len = noArgMethodNames.length; i < len; i++ )
268             {
269                 if ( i == 0 )
270                 {
271                     obj = invokeStaticMethod( classesChain[i], noArgMethodNames[i],
272                                                     EMPTY_CLASS_ARRAY, EMPTY_OBJECT_ARRAY );
273                 }
274                 else
275                 {
276                     Method method = getMethod( classesChain[i], noArgMethodNames[i] );
277                     obj = invokeMethodWithArray( obj, method );
278                 }
279             }
280             return obj;
281         }
282         catch ( RuntimeException e )
283         {
284             return fallback;
285         }
286     }
287 }