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