Clover icon

jalviewX

  1. Project Clover database Wed Oct 31 2018 15:13:58 GMT
  2. Package junit.extensions

File PrivilegedAccessor.java

 

Coverage histogram

../../img/srcFileCovDistChart2.png
51% of files have more coverage

Code metrics

58
155
26
1
647
316
68
0.44
5.96
26
2.62

Classes

Class Line # Actions
PrivilegedAccessor 54 155 68 202
0.1548117115.5%
 

Contributing tests

This file is covered by 24 tests. .

Source view

1    /*
2    * Copyright 2004-2012 Sebastian Dietrich (Sebastian.Dietrich@e-movimento.com)
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10    * Unless required by applicable law or agreed to in writing, software
11    * distributed under the License is distributed on an "AS IS" BASIS,
12    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13    * See the License for the specific language governing permissions and
14    * limitations under the License.
15    */
16    package junit.extensions;
17   
18    import java.lang.reflect.Array;
19    import java.lang.reflect.Constructor;
20    import java.lang.reflect.Field;
21    import java.lang.reflect.InvocationTargetException;
22    import java.lang.reflect.Method;
23    import java.lang.reflect.Modifier;
24    import java.security.InvalidParameterException;
25    import java.util.ArrayList;
26    import java.util.Collection;
27    import java.util.Collections;
28    import java.util.HashMap;
29    import java.util.Map;
30    import java.util.StringTokenizer;
31   
32    /**
33    * This class is used to access a method or field of an object no matter what the access modifier of the method or field. The syntax
34    * for accessing fields and methods is out of the ordinary because this class uses reflection to peel away protection.
35    * <p>
36    * a.k.a. The "ObjectMolester"
37    * <p>
38    * Here is an example of using this to access a private member: <br>
39    * <code>myObject</code> is an object of type <code>MyClass</code>. <code>setName(String)</code> is a private method of
40    * <code>MyClass</code>.
41    *
42    * <pre>
43    * PrivilegedAccessor.invokeMethod(myObject, &quot;setName(java.lang.String)&quot;, &quot;newName&quot;);
44    * </pre>
45    *
46    * @author Charlie Hubbard (chubbard@iss.net)
47    * @author Prashant Dhokte (pdhokte@iss.net)
48    * @author Sebastian Dietrich (sebastian.dietrich@e-movimento.com)
49    *
50    * @deprecated use PA instead. PA improves the functionality of PrivilegedAccessor by introducing support for varargs and removal of
51    * the necessity to catch exceptions.
52    */
53    @Deprecated
 
54    final class PrivilegedAccessor
55    {
56    /**
57    * Private constructor to make it impossible to instantiate this class.
58    */
 
59  0 toggle private PrivilegedAccessor() {
60    assert false : "You mustn't instantiate PrivilegedAccessor, use its methods statically";
61    }
62   
63    /**
64    * Returns a string representation of the given object. The string has the following format: "<classname> {<attributes and values>}"
65    * whereas <attributes and values> is a comma separated list with <attributeName>=<attributeValue> <atributes and values> includes
66    * all attributes of the objects class followed by the attributes of its superclass (if any) and so on.
67    *
68    * @param instanceOrClass the object or class to get a string representation of
69    * @return a string representation of the given object
70    */
 
71  0 toggle public static String toString(final Object instanceOrClass) {
72  0 Collection<String> fields = getFieldNames(instanceOrClass);
73   
74  0 if (fields.isEmpty())
75    {
76  0 return getClass(instanceOrClass).getName();
77    }
78   
79  0 StringBuffer stringBuffer = new StringBuffer();
80   
81  0 stringBuffer.append(getClass(instanceOrClass).getName() + " {");
82   
83  0 for (String fieldName : fields) {
84  0 try {
85  0 stringBuffer.append(fieldName + "=" + getValue(instanceOrClass, fieldName) + ", ");
86    } catch (NoSuchFieldException e) {
87    assert false : "It should always be possible to get a field that was just here";
88    }
89    }
90   
91  0 stringBuffer.replace(stringBuffer.lastIndexOf(", "), stringBuffer.length(), "}");
92  0 return stringBuffer.toString();
93    }
94   
95    /**
96    * Gets the name of all fields (public, private, protected, default) of the given instance or class. This includes as well all
97    * fields (public, private, protected, default) of all its super classes.
98    *
99    * @param instanceOrClass the instance or class to get the fields of
100    * @return the collection of field names of the given instance or class
101    */
 
102  0 toggle public static Collection<String> getFieldNames(final Object instanceOrClass) {
103  0 if (instanceOrClass == null)
104    {
105  0 return Collections.EMPTY_LIST;
106    }
107   
108  0 Class<?> clazz = getClass(instanceOrClass);
109  0 Field[] fields = clazz.getDeclaredFields();
110  0 Collection<String> fieldNames = new ArrayList<String>(fields.length);
111   
112  0 for (Field field : fields) {
113  0 fieldNames.add(field.getName());
114    }
115  0 fieldNames.addAll(getFieldNames(clazz.getSuperclass()));
116   
117  0 return fieldNames;
118    }
119   
120    /**
121    * Gets the signatures of all methods (public, private, protected, default) of the given instance or class. This includes as well
122    * all methods (public, private, protected, default) of all its super classes. This does not include constructors.
123    *
124    * @param instanceOrClass the instance or class to get the method signatures of
125    * @return the collection of method signatures of the given instance or class
126    */
 
127  0 toggle public static Collection<String> getMethodSignatures(final Object instanceOrClass) {
128  0 if (instanceOrClass == null)
129    {
130  0 return Collections.EMPTY_LIST;
131    }
132   
133  0 Class<?> clazz = getClass(instanceOrClass);
134  0 Method[] methods = clazz.getDeclaredMethods();
135  0 Collection<String> methodSignatures = new ArrayList<String>(methods.length + Object.class.getDeclaredMethods().length);
136   
137  0 for (Method method : methods) {
138  0 methodSignatures.add(method.getName() + "(" + getParameterTypesAsString(method.getParameterTypes()) + ")");
139    }
140  0 methodSignatures.addAll(getMethodSignatures(clazz.getSuperclass()));
141   
142  0 return methodSignatures;
143    }
144   
145    /**
146    * Gets the value of the named field and returns it as an object. If instanceOrClass is a class then a static field is returned.
147    *
148    * @param instanceOrClass the instance or class to get the field from
149    * @param fieldName the name of the field
150    * @return an object representing the value of the field
151    * @throws NoSuchFieldException if the field does not exist
152    */
 
153  126 toggle public static Object getValue(final Object instanceOrClass, final String fieldName) throws NoSuchFieldException {
154  126 Field field = getField(instanceOrClass, fieldName);
155  126 try {
156  126 return field.get(instanceOrClass);
157    } catch (IllegalAccessException e) {
158    assert false : "getField() should have setAccessible(true), so an IllegalAccessException should not occur in this place";
159  0 return null;
160    }
161    }
162   
163    /**
164    * Instantiates an object of the given class with the given arguments. If you want to instantiate a member class, you must provide
165    * the object it is a member of as first argument.
166    *
167    * @param fromClass the class to instantiate an object from
168    * @param args the arguments to pass to the constructor
169    * @return an object of the given type
170    * @throws IllegalArgumentException if the number of actual and formal parameters differ; if an unwrapping conversion for primitive
171    * arguments fails; or if, after possible unwrapping, a parameter value cannot be converted to the corresponding formal
172    * parameter type by a method invocation conversion.
173    * @throws IllegalAccessException if this Constructor object enforces Java language access control and the underlying constructor is
174    * inaccessible.
175    * @throws InvocationTargetException if the underlying constructor throws an exception.
176    * @throws NoSuchMethodException if the constructor could not be found
177    * @throws InstantiationException if the class that declares the underlying constructor represents an abstract class.
178    *
179    * @see PrivilegedAccessor#instantiate(Class,Class[],Object[])
180    */
 
181  0 toggle public static <T> T instantiate(final Class<? extends T> fromClass, final Object[] args) throws IllegalArgumentException,
182    InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
183  0 return instantiate(fromClass, getParameterTypes(args), args);
184    }
185   
186    /**
187    * Instantiates an object of the given class with the given arguments and the given argument types. If you want to instantiate a
188    * member class, you must provide the object it is a member of as first argument.
189    *
190    *
191    * @param fromClass the class to instantiate an object from
192    * @param args the arguments to pass to the constructor
193    * @param argumentTypes the fully qualified types of the arguments of the constructor
194    * @return an object of the given type
195    * @throws IllegalArgumentException if the number of actual and formal parameters differ; if an unwrapping conversion for primitive
196    * arguments fails; or if, after possible unwrapping, a parameter value cannot be converted to the corresponding formal
197    * parameter type by a method invocation conversion.
198    * @throws IllegalAccessException if this Constructor object enforces Java language access control and the underlying constructor is
199    * inaccessible.
200    * @throws InvocationTargetException if the underlying constructor throws an exception.
201    * @throws NoSuchMethodException if the constructor could not be found
202    * @throws InstantiationException if the class that declares the underlying constructor represents an abstract class.
203    *
204    * @see PrivilegedAccessor#instantiate(Class,Object[])
205    */
 
206  0 toggle public static <T> T instantiate(final Class<? extends T> fromClass, final Class<?>[] argumentTypes, final Object[] args)
207    throws IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException,
208    NoSuchMethodException {
209  0 return getConstructor(fromClass, argumentTypes).newInstance(args);
210    }
211   
212    /**
213    * Calls a method on the given object instance with the given arguments. Arguments can be object types or representations for
214    * primitives.
215    *
216    * @param instanceOrClass the instance or class to invoke the method on
217    * @param methodSignature the name of the method and the parameters <br>
218    * (e.g. "myMethod(java.lang.String, com.company.project.MyObject)")
219    * @param arguments an array of objects to pass as arguments
220    * @return the return value of this method or null if void
221    * @throws IllegalAccessException if the method is inaccessible
222    * @throws InvocationTargetException if the underlying method throws an exception.
223    * @throws NoSuchMethodException if no method with the given <code>methodSignature</code> could be found
224    * @throws IllegalArgumentException if an argument couldn't be converted to match the expected type
225    */
 
226  0 toggle public static Object invokeMethod(final Object instanceOrClass, final String methodSignature, final Object[] arguments)
227    throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
228  0 if ((methodSignature.indexOf('(') == -1) || (methodSignature.indexOf('(') >= methodSignature.indexOf(')')))
229    {
230  0 throw new NoSuchMethodException(methodSignature);
231    }
232  0 Class<?>[] parameterTypes = getParameterTypes(methodSignature);
233  0 return getMethod(instanceOrClass, getMethodName(methodSignature), parameterTypes).invoke(instanceOrClass,
234    getCorrectedArguments(parameterTypes, arguments));
235    }
236   
237    /**
238    * Gets the given arguments corrected to match the given methodSignature. Correction is necessary for array arguments not to be
239    * mistaken by varargs.
240    *
241    * @param parameterTypes the method signatue the given arguments should match
242    * @param arguments the arguments that should be corrected
243    * @return the corrected arguments
244    */
 
245  0 toggle private static Object[] getCorrectedArguments(Class<?>[] parameterTypes, Object[] arguments) {
246  0 if (arguments == null)
247    {
248  0 return arguments;
249    }
250  0 if (parameterTypes.length > arguments.length)
251    {
252  0 return arguments;
253    }
254  0 if (parameterTypes.length < arguments.length)
255    {
256  0 return getCorrectedArguments(parameterTypes, new Object[] {arguments});
257    }
258   
259  0 Object[] correctedArguments = new Object[arguments.length];
260  0 int currentArgument = 0;
261  0 for (Class<?> parameterType : parameterTypes) {
262  0 correctedArguments[currentArgument] = getCorrectedArgument(parameterType, arguments[currentArgument]);
263  0 currentArgument++;
264    }
265  0 return correctedArguments;
266    }
267   
268    /**
269    * Gets the given argument corrected to match the given parameterType. Correction is necessary for array arguments not to be
270    * mistaken by varargs.
271    *
272    * @param parameterType the type to match the given argument upon
273    * @param argument the argument to match the given parameterType
274    * @return the corrected argument
275    */
 
276  0 toggle private static Object getCorrectedArgument(Class<?> parameterType, Object argument) {
277  0 if (!parameterType.isArray() || (argument == null)) {
278  0 return argument; // normal argument for normal parameterType
279    }
280   
281  0 if (!argument.getClass().isArray()) {
282  0 return new Object[] {argument};
283    }
284   
285  0 if (parameterType.equals(argument.getClass()))
286    {
287  0 return argument; // no need to cast
288    }
289   
290    // (typed) array argument for (object) array parameterType, elements need to be casted
291  0 Object correctedArrayArgument = Array.newInstance(parameterType.getComponentType(), Array.getLength(argument));
292  0 for (int index = 0; index < Array.getLength(argument); index++) {
293  0 if (parameterType.getComponentType().isPrimitive()) { // rely on autoboxing
294  0 Array.set(correctedArrayArgument, index, Array.get(argument, index));
295    } else { // cast to expected type
296  0 try {
297  0 Array.set(correctedArrayArgument, index, parameterType.getComponentType().cast(Array.get(argument, index)));
298    } catch (ClassCastException e) {
299  0 throw new IllegalArgumentException("Argument " + argument + " of type " + argument.getClass()
300    + " does not match expected argument type " + parameterType + ".");
301    }
302    }
303    }
304  0 return correctedArrayArgument;
305    }
306   
307    /**
308    * Sets the value of the named field. If fieldName denotes a static field, provide a class, otherwise provide an instance. If the
309    * fieldName denotes a final field, this method could fail with an IllegalAccessException, since setting the value of final fields
310    * at other times than instantiation can have unpredictable effects.<br/>
311    * <br/>
312    * Example:<br/>
313    * <br/>
314    * <code>
315    * String myString = "Test"; <br/>
316    * <br/>
317    * //setting the private field value<br/>
318    * PrivilegedAccessor.setValue(myString, "value", new char[] {'T', 'e', 's', 't'});<br/>
319    * <br/>
320    * //setting the static final field serialVersionUID - MIGHT FAIL<br/>
321    * PrivilegedAccessor.setValue(myString.getClass(), "serialVersionUID", 1);<br/>
322    * <br/>
323    * </code>
324    *
325    * @param instanceOrClass the instance or class to set the field
326    * @param fieldName the name of the field
327    * @param value the new value of the field
328    * @throws NoSuchFieldException if no field with the given <code>fieldName</code> can be found
329    * @throws IllegalAccessException possibly if the field was final
330    */
 
331  30 toggle public static void setValue(final Object instanceOrClass, final String fieldName, final Object value) throws NoSuchFieldException,
332    IllegalAccessException {
333  30 Field field = getField(instanceOrClass, fieldName);
334  30 if (Modifier.isFinal(field.getModifiers())) {
335  12 PrivilegedAccessor.setValue(field, "modifiers", field.getModifiers() ^ Modifier.FINAL);
336    }
337  30 field.set(instanceOrClass, value);
338    }
339   
340    /**
341    * Gets the class with the given className.
342    *
343    * @param className the name of the class to get
344    * @return the class for the given className
345    * @throws ClassNotFoundException if the class could not be found
346    */
 
347  0 toggle private static Class<?> getClassForName(final String className) throws ClassNotFoundException {
348  0 if (className.indexOf('[') > -1) {
349  0 Class<?> clazz = getClassForName(className.substring(0, className.indexOf('[')));
350  0 return Array.newInstance(clazz, 0).getClass();
351    }
352   
353  0 if (className.indexOf("...") > -1) {
354  0 Class<?> clazz = getClassForName(className.substring(0, className.indexOf("...")));
355  0 return Array.newInstance(clazz, 0).getClass();
356    }
357   
358  0 try {
359  0 return Class.forName(className, false, Thread.currentThread().getContextClassLoader());
360    } catch (ClassNotFoundException e) {
361  0 return getSpecialClassForName(className);
362    }
363    }
364   
365    /**
366    * Maps string representation of primitives to their corresponding classes.
367    */
368    private static final Map<String, Class<?>> PRIMITIVE_MAPPER = new HashMap<String, Class<?>>(8);
369   
370    /**
371    * Fills the map with all java primitives and their corresponding classes.
372    */
 
373  1 toggle static {
374  1 PRIMITIVE_MAPPER.put("int", Integer.TYPE);
375  1 PRIMITIVE_MAPPER.put("float", Float.TYPE);
376  1 PRIMITIVE_MAPPER.put("double", Double.TYPE);
377  1 PRIMITIVE_MAPPER.put("short", Short.TYPE);
378  1 PRIMITIVE_MAPPER.put("long", Long.TYPE);
379  1 PRIMITIVE_MAPPER.put("byte", Byte.TYPE);
380  1 PRIMITIVE_MAPPER.put("char", Character.TYPE);
381  1 PRIMITIVE_MAPPER.put("boolean", Boolean.TYPE);
382    }
383   
384    /**
385    * Gets special classes for the given className. Special classes are primitives and "standard" Java types (like String)
386    *
387    * @param className the name of the class to get
388    * @return the class for the given className
389    * @throws ClassNotFoundException if the class could not be found
390    */
 
391  0 toggle private static Class<?> getSpecialClassForName(final String className) throws ClassNotFoundException {
392  0 if (PRIMITIVE_MAPPER.containsKey(className))
393    {
394  0 return PRIMITIVE_MAPPER.get(className);
395    }
396   
397  0 if (missesPackageName(className))
398    {
399  0 return getStandardClassForName(className);
400    }
401   
402  0 throw new ClassNotFoundException(className);
403    }
404   
405    /**
406    * Gets a 'standard' java class for the given className.
407    *
408    * @param className the className
409    * @return the class for the given className (if any)
410    * @throws ClassNotFoundException of no 'standard' java class was found for the given className
411    */
 
412  0 toggle private static Class<?> getStandardClassForName(String className) throws ClassNotFoundException {
413  0 try {
414  0 return Class.forName("java.lang." + className, false, Thread.currentThread().getContextClassLoader());
415    } catch (ClassNotFoundException e) {
416  0 try {
417  0 return Class.forName("java.util." + className, false, Thread.currentThread().getContextClassLoader());
418    } catch (ClassNotFoundException e1) {
419  0 throw new ClassNotFoundException(className);
420    }
421    }
422    }
423   
424    /**
425    * Tests if the given className possibly misses its package name.
426    *
427    * @param className the className
428    * @return true if the className might miss its package name, otherwise false
429    */
 
430  0 toggle private static boolean missesPackageName(String className) {
431  0 if (className.contains("."))
432    {
433  0 return false;
434    }
435  0 if (className.startsWith(className.substring(0, 1).toUpperCase()))
436    {
437  0 return true;
438    }
439  0 return false;
440    }
441   
442    /**
443    * Gets the constructor for a given class with the given parameters.
444    *
445    * @param type the class to instantiate
446    * @param parameterTypes the types of the parameters
447    * @return the constructor
448    * @throws NoSuchMethodException if the method could not be found
449    */
 
450  0 toggle private static <T> Constructor<T> getConstructor(final Class<T> type, final Class<?>[] parameterTypes) throws NoSuchMethodException {
451  0 Constructor<T> constructor = type.getDeclaredConstructor(parameterTypes);
452  0 constructor.setAccessible(true);
453  0 return constructor;
454    }
455   
456    /**
457    * Return the named field from the given instance or class. Returns a static field if instanceOrClass is a class.
458    *
459    * @param instanceOrClass the instance or class to get the field from
460    * @param fieldName the name of the field to get
461    * @return the field
462    * @throws NoSuchFieldException if no such field can be found
463    * @throws InvalidParameterException if instanceOrClass was null
464    */
 
465  158 toggle private static Field getField(final Object instanceOrClass, final String fieldName) throws NoSuchFieldException,
466    InvalidParameterException {
467  158 if (instanceOrClass == null)
468    {
469  0 throw new InvalidParameterException("Can't get field on null object/class");
470    }
471   
472  158 Class<?> type = getClass(instanceOrClass);
473   
474  158 try {
475  158 Field field = type.getDeclaredField(fieldName);
476  156 field.setAccessible(true);
477  156 return field;
478    } catch (NoSuchFieldException e) {
479  2 if (type.getSuperclass() == null)
480    {
481  0 throw e;
482    }
483  2 return getField(type.getSuperclass(), fieldName);
484    }
485    }
486   
487    /**
488    * Gets the class of the given parameter. If the parameter is a class, it is returned, if it is an object, its class is returned
489    *
490    * @param instanceOrClass the instance or class to get the class of
491    * @return the class of the given parameter
492    */
 
493  158 toggle private static Class<?> getClass(final Object instanceOrClass) {
494  158 if (instanceOrClass instanceof Class)
495    {
496  4 return (Class<?>) instanceOrClass;
497    }
498   
499  154 return instanceOrClass.getClass();
500    }
501   
502    /**
503    * Return the named method with a method signature matching classTypes from the given class.
504    *
505    * @param type the class to get the method from
506    * @param methodName the name of the method to get
507    * @param parameterTypes the parameter-types of the method to get
508    * @return the method
509    * @throws NoSuchMethodException if the method could not be found
510    */
 
511  0 toggle private static Method getMethod(final Class<?> type, final String methodName, final Class<?>[] parameterTypes)
512    throws NoSuchMethodException {
513  0 try {
514  0 return type.getDeclaredMethod(methodName, parameterTypes);
515    } catch (NoSuchMethodException e) {
516  0 if (type.getSuperclass() == null)
517    {
518  0 throw e;
519    }
520  0 return getMethod(type.getSuperclass(), methodName, parameterTypes);
521    }
522    }
523   
524    /**
525    * Gets the method with the given name and parameters from the given instance or class. If instanceOrClass is a class, then we get a
526    * static method.
527    *
528    * @param instanceOrClass the instance or class to get the method of
529    * @param methodName the name of the method
530    * @param parameterTypes the parameter-types of the method to get
531    * @return the method
532    * @throws NoSuchMethodException if the method could not be found
533    */
 
534  0 toggle private static Method getMethod(final Object instanceOrClass, final String methodName, final Class<?>[] parameterTypes)
535    throws NoSuchMethodException {
536  0 Class<?> type;
537   
538  0 type = getClass(instanceOrClass);
539   
540  0 Method accessMethod = getMethod(type, methodName, parameterTypes);
541  0 accessMethod.setAccessible(true);
542  0 return accessMethod;
543    }
544   
545    /**
546    * Gets the name of a method.
547    *
548    * @param methodSignature the signature of the method
549    * @return the name of the method
550    */
 
551  0 toggle private static String getMethodName(final String methodSignature) {
552  0 try {
553  0 return methodSignature.substring(0, methodSignature.indexOf('(')).trim();
554    } catch (StringIndexOutOfBoundsException e) {
555    assert false : "Signature must have been checked before this method was called";
556  0 return null;
557    }
558    }
559   
560    /**
561    * Gets the types of the parameters.
562    *
563    * @param parameters the parameters
564    * @return the class-types of the arguments
565    */
 
566  0 toggle private static Class<?>[] getParameterTypes(final Object[] parameters) {
567  0 if (parameters == null)
568    {
569  0 return new Class[0];
570    }
571   
572  0 Class<?>[] typesOfParameters = new Class[parameters.length];
573   
574  0 for (int i = 0; i < parameters.length; i++) {
575  0 typesOfParameters[i] = parameters[i].getClass();
576    }
577  0 return typesOfParameters;
578    }
579   
580    /**
581    * Gets the types of the given parameters. If the parameters don't match the given methodSignature an IllegalArgumentException is
582    * thrown.
583    *
584    * @param methodSignature the signature of the method
585    * @return the parameter types as class[]
586    * @throws NoSuchMethodException if the method could not be found
587    * @throws IllegalArgumentException if one of the given parameters doesn't math the given methodSignature
588    */
 
589  0 toggle private static Class<?>[] getParameterTypes(final String methodSignature) throws NoSuchMethodException, IllegalArgumentException {
590  0 String signature = getSignatureWithoutBraces(methodSignature);
591   
592  0 StringTokenizer tokenizer = new StringTokenizer(signature, ", *");
593  0 Class<?>[] typesInSignature = new Class[tokenizer.countTokens()];
594   
595  0 for (int x = 0; tokenizer.hasMoreTokens(); x++) {
596  0 String className = tokenizer.nextToken();
597  0 try {
598  0 typesInSignature[x] = getClassForName(className);
599    } catch (ClassNotFoundException e) {
600  0 NoSuchMethodException noSuchMethodException = new NoSuchMethodException(methodSignature);
601  0 noSuchMethodException.initCause(e);
602  0 throw noSuchMethodException;
603    }
604    }
605  0 return typesInSignature;
606    }
607   
608    /**
609    * Gets the parameter types as a string.
610    *
611    * @param classTypes the types to get as names.
612    * @return the parameter types as a string
613    *
614    * @see java.lang.Class#argumentTypesToString(Class[])
615    */
 
616  0 toggle private static String getParameterTypesAsString(final Class<?>[] classTypes) {
617  0 assert classTypes != null : "getParameterTypes() should have been called before this method and should have provided not-null classTypes";
618  0 if (classTypes.length == 0)
619    {
620  0 return "";
621    }
622   
623  0 StringBuilder parameterTypes = new StringBuilder();
624  0 for (Class<?> clazz : classTypes) {
625  0 assert clazz != null : "getParameterTypes() should have been called before this method and should have provided not-null classTypes";
626  0 parameterTypes.append(clazz.getName()).append(", ");
627    }
628   
629  0 return parameterTypes.substring(0, parameterTypes.length() - 2);
630    }
631   
632    /**
633    * Removes the braces around the methods signature.
634    *
635    * @param methodSignature the signature with braces
636    * @return the signature without braces
637    */
 
638  0 toggle private static String getSignatureWithoutBraces(final String methodSignature) {
639  0 try {
640  0 return methodSignature.substring(methodSignature.indexOf('(') + 1, methodSignature.indexOf(')'));
641    } catch (IndexOutOfBoundsException e) {
642    assert false : "signature must have been checked before this method";
643  0 return null;
644    }
645    }
646   
647    }