Clover Coverage Report - EasyMock 3.0
Coverage timestamp: sam. mai 8 2010 14:37:27 CEST
../../../img/srcFileCovDistChart10.png 0% of files have more coverage
49   201   22   8,17
30   93   0,45   6
6     3,67  
1    
1,2% of code in this file is excluded from these metrics.
 
  ReflectionUtils       Line # 29 49 1,2% 22 0 100% 1.0
 
  (70)
 
1    /**
2    * Copyright 2001-2010 the original author or authors.
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   
17    package org.easymock.internal;
18   
19    import java.lang.reflect.Constructor;
20    import java.lang.reflect.Method;
21    import java.lang.reflect.Modifier;
22    import java.util.Arrays;
23    import java.util.HashMap;
24    import java.util.Map;
25   
26    /**
27    * @author Henri Tremblay
28    */
 
29    public final class ReflectionUtils {
30   
31    private static Map<Class<?>, Class<?>> primitiveToWrapperType = new HashMap<Class<?>, Class<?>>();
32   
 
33  2 toggle static {
34  2 primitiveToWrapperType.put(boolean.class, Boolean.class);
35  2 primitiveToWrapperType.put(byte.class, Byte.class);
36  2 primitiveToWrapperType.put(short.class, Short.class);
37  2 primitiveToWrapperType.put(char.class, Character.class);
38  2 primitiveToWrapperType.put(int.class, Integer.class);
39  2 primitiveToWrapperType.put(long.class, Long.class);
40  2 primitiveToWrapperType.put(float.class, Float.class);
41  2 primitiveToWrapperType.put(double.class, Double.class);
42    }
43   
44    // ///CLOVER:OFF
 
45    toggle private ReflectionUtils() {
46    }
47   
48    // ///CLOVER:ON
49   
50    /**
51    * Attempt to find a {@link Method} on the supplied class with the supplied
52    * name and no parameters. Searches all superclasses up to
53    * <code>Object</code>.
54    * <p>
55    * Returns <code>null</code> if no {@link Method} can be found.
56    *
57    * @param clazz
58    * the class to introspect
59    * @param name
60    * the name of the method
61    * @return the Method object, or <code>null</code> if none found
62    */
 
63  52 toggle public static Method findMethod(final Class<?> clazz, final String name) {
64  52 return findMethod(clazz, name, (Class<?>[]) null);
65    }
66   
67    /**
68    * Attempt to find a {@link Method} on the supplied class with the supplied
69    * name and parameter types. Searches all superclasses up to
70    * <code>Object</code>.
71    * <p>
72    * Returns <code>null</code> if no {@link Method} can be found.
73    *
74    * @param clazz
75    * the class to introspect
76    * @param name
77    * the name of the method
78    * @param paramTypes
79    * the parameter types of the method (may be <code>null</code> to
80    * indicate any signature)
81    * @return the Method object, or <code>null</code> if none found
82    */
 
83  66 toggle public static Method findMethod(final Class<?> clazz, final String name, final Class<?>... paramTypes) {
84  66 Class<?> searchType = clazz;
85  114 while (!Object.class.equals(searchType) && searchType != null) {
86  106 final Method[] methods = searchType.getDeclaredMethods();
87  106 Method result = null;
88  106 for (final Method method : methods) {
89    // Private methods can't be mocked so just skip them
90  1940 if (Modifier.isPrivate(method.getModifiers())) {
91  198 continue;
92    }
93  1742 if (name.equals(method.getName())) {
94  72 if (paramTypes == null) {
95  50 if (result != null) {
96  2 throw new RuntimeException("Ambiguous name: More than one method are named "
97    + name);
98    }
99  48 result = method;
100  22 } else if (Arrays.equals(paramTypes, method.getParameterTypes())) {
101  10 return method;
102    }
103    }
104    }
105  94 if (result != null) {
106  46 return result;
107    }
108  48 searchType = searchType.getSuperclass();
109    }
110  8 return null;
111    }
112   
113    /**
114    * Returns a constructor that contains {@code objs} as arguments.
115    *
116    * <p>
117    * We could not do something like {@code clazz.getConstructor(objs.class())}
118    * because that would require casting all the passed arguments to the exact
119    * parameter types of the desired constructor.
120    *
121    * @param clazz
122    * class on which we are searching the constructor
123    * @param <T>
124    * type of the class searched
125    * @param objs
126    * list of arguments of the constructor
127    * @return a constructor with the arguments in {@code objs}
128    * @throws NoSuchMethodException
129    * when the constructor with {@code args} does not exist or is
130    * ambiguous
131    */
 
132  32 toggle @SuppressWarnings("unchecked")
133    public static <T> Constructor<T> getConstructor(final Class<T> clazz, final Object... objs)
134    throws NoSuchMethodException {
135  32 Constructor<T> ret = null;
136  32 for (final Constructor<?> classConstructor : clazz.getDeclaredConstructors()) {
137  150 if (isMatchingConstructor(classConstructor, objs)) {
138  24 if (ret != null) {
139    // We had already found a constructor, so this is ambiguous
140  2 throw new IllegalArgumentException("Ambiguity in the constructors for " + clazz.getName()
141    + ".");
142    }
143   
144    // This unsafe cast is guaranteed to be correct by Class#getConstructors()
145  22 ret = (Constructor<T>) classConstructor;
146    }
147    }
148   
149  30 if (ret != null) {
150  20 return ret;
151    }
152   
153    // Not found
154  10 throw new NoSuchMethodException("Couldn't find constructor for class " + clazz.getName());
155    }
156   
157    /**
158    * Returns true if objects in {@code objs} are eligible to be passed to
159    * {@code classConstructor}.
160    */
 
161  150 toggle private static boolean isMatchingConstructor(final Constructor<?> classConstructor, final Object... objs) {
162   
163  150 if (Modifier.isPrivate(classConstructor.getModifiers())) {
164  18 return false;
165    }
166   
167  132 final Class<?>[] parameterTypes = classConstructor.getParameterTypes();
168  132 if (parameterTypes.length != objs.length) {
169  52 return false;
170    }
171   
172  114 for (int i = 0; i < objs.length; ++i) {
173  90 Class<?> parameterType = parameterTypes[i];
174   
175    // If the parameter is a primitive, we need to get the boxed equivalent type
176  90 if (parameterType.isPrimitive()) {
177  56 parameterType = wrapPrimitive(parameterType);
178    }
179   
180    // Check if parameter type matches
181  90 if (!parameterType.isInstance(objs[i])) {
182  56 return false;
183    }
184    }
185   
186  24 return true;
187    }
188   
189    /**
190    * Given a primitive type, returns its boxed equivalent. For instance, given
191    * {@code int}, returns {@code Integer}.
192    *
193    * @param parameterType
194    * the primitive type
195    * @return the boxed equivalent
196    */
 
197  56 toggle private static Class<?> wrapPrimitive(final Class<?> parameterType) {
198  56 return primitiveToWrapperType.get(parameterType);
199    }
200   
201    }