1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
8 |
|
|
9 |
|
|
10 |
|
|
11 |
|
|
12 |
|
|
13 |
|
|
14 |
|
|
15 |
|
|
16 |
|
|
17 |
|
package org.easymock.internal; |
18 |
|
|
19 |
|
import java.io.*; |
20 |
|
import java.lang.reflect.*; |
21 |
|
|
22 |
|
import org.easymock.EasyMock; |
23 |
|
|
24 |
|
|
25 |
|
|
26 |
|
|
27 |
|
|
28 |
|
@author |
29 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (68) |
Complexity: 22 |
Complexity Density: 0,46 |
|
30 |
|
public class DefaultClassInstantiator implements IClassInstantiator { |
31 |
|
|
32 |
|
|
33 |
|
|
34 |
|
|
35 |
|
|
36 |
|
@param |
37 |
|
|
38 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (10) |
Complexity: 7 |
Complexity Density: 0,88 |
|
39 |
32
|
public Object newInstance(final Class<?> c) throws InstantiationException {... |
40 |
|
|
41 |
32
|
if (isSerializable(c)) { |
42 |
8
|
try { |
43 |
8
|
return readObject(getSerializedBytes(c)); |
44 |
|
|
45 |
|
} catch (final IOException e) { |
46 |
|
throw new RuntimeException("Failed to instantiate " + c.getName() + "'s mock: " |
47 |
|
+ e.getMessage()); |
48 |
|
} catch (final ClassNotFoundException e) { |
49 |
|
throw new RuntimeException("Failed to instantiate " + c.getName() + "'s mock: " |
50 |
|
+ e.getMessage()); |
51 |
|
} |
52 |
|
|
53 |
|
} |
54 |
|
|
55 |
24
|
final Constructor<?> constructor = getConstructorToUse(c); |
56 |
20
|
final Object[] params = getArgsForTypes(constructor.getParameterTypes()); |
57 |
20
|
try { |
58 |
20
|
return constructor.newInstance(params); |
59 |
|
|
60 |
|
} catch (final IllegalArgumentException e) { |
61 |
|
throw new RuntimeException("Failed to instantiate " + c.getName() + "'s mock: " + e.getMessage()); |
62 |
|
} catch (final IllegalAccessException e) { |
63 |
|
throw new RuntimeException("Failed to instantiate " + c.getName() + "'s mock: " + e.getMessage()); |
64 |
|
|
65 |
|
} catch (final InvocationTargetException e) { |
66 |
2
|
throw new RuntimeException("Failed to instantiate " + c.getName() + "'s mock: " + e.getMessage()); |
67 |
|
} |
68 |
|
} |
69 |
|
|
70 |
|
|
71 |
|
|
72 |
|
|
73 |
|
@param |
74 |
|
|
75 |
|
@return |
76 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
77 |
32
|
private boolean isSerializable(final Class<?> clazz) {... |
78 |
32
|
return Serializable.class.isAssignableFrom(clazz); |
79 |
|
} |
80 |
|
|
81 |
|
|
82 |
|
|
83 |
|
|
84 |
|
|
85 |
|
|
86 |
|
@param |
87 |
|
|
88 |
|
@return |
89 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (7) |
Complexity: 3 |
Complexity Density: 0,6 |
|
90 |
24
|
private Constructor<?> getConstructorToUse(final Class<?> clazz) {... |
91 |
|
|
92 |
24
|
try { |
93 |
24
|
return clazz.getConstructor(new Class[0]); |
94 |
|
} catch (final NoSuchMethodException e) { |
95 |
|
|
96 |
16
|
if (clazz.getConstructors().length == 0) { |
97 |
4
|
throw new IllegalArgumentException("No visible constructors in class " + clazz.getName()); |
98 |
|
} |
99 |
12
|
return clazz.getConstructors()[0]; |
100 |
|
} |
101 |
|
} |
102 |
|
|
103 |
|
|
104 |
|
|
105 |
|
|
106 |
|
@param |
107 |
|
|
108 |
|
@return |
109 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (16) |
Complexity: 4 |
Complexity Density: 0,4 |
|
110 |
20
|
private Object[] getArgsForTypes(final Class<?>[] methodTypes) throws InstantiationException {... |
111 |
20
|
final Object[] methodArgs = new Object[methodTypes.length]; |
112 |
|
|
113 |
32
|
for (int i = 0; i < methodTypes.length; i++) { |
114 |
|
|
115 |
12
|
if (methodTypes[i].isPrimitive()) { |
116 |
|
|
117 |
4
|
methodArgs[i] = RecordState.emptyReturnValueFor(methodTypes[i]); |
118 |
8
|
} else if (Modifier.isFinal(methodTypes[i].getModifiers())) { |
119 |
|
|
120 |
|
|
121 |
|
|
122 |
4
|
methodArgs[i] = newInstance(methodTypes[i]); |
123 |
|
} else { |
124 |
|
|
125 |
4
|
final Object mock = EasyMock.createNiceMock(methodTypes[i]); |
126 |
4
|
EasyMock.replay(mock); |
127 |
4
|
methodArgs[i] = mock; |
128 |
|
} |
129 |
|
} |
130 |
20
|
return methodArgs; |
131 |
|
} |
132 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (14) |
Complexity: 1 |
Complexity Density: 0,07 |
|
133 |
8
|
private static byte[] getSerializedBytes(final Class<?> clazz) throws IOException {... |
134 |
8
|
final ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
135 |
8
|
final DataOutputStream data = new DataOutputStream(baos); |
136 |
8
|
data.writeShort(ObjectStreamConstants.STREAM_MAGIC); |
137 |
8
|
data.writeShort(ObjectStreamConstants.STREAM_VERSION); |
138 |
8
|
data.writeByte(ObjectStreamConstants.TC_OBJECT); |
139 |
8
|
data.writeByte(ObjectStreamConstants.TC_CLASSDESC); |
140 |
8
|
data.writeUTF(clazz.getName()); |
141 |
|
|
142 |
8
|
final Long suid = getSerializableUID(clazz); |
143 |
|
|
144 |
8
|
data.writeLong(suid.longValue()); |
145 |
|
|
146 |
8
|
data.writeByte(2); |
147 |
8
|
data.writeShort(0); |
148 |
8
|
data.writeByte(ObjectStreamConstants.TC_ENDBLOCKDATA); |
149 |
8
|
data.writeByte(ObjectStreamConstants.TC_NULL); |
150 |
8
|
return baos.toByteArray(); |
151 |
|
} |
152 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (8) |
Complexity: 4 |
Complexity Density: 0,67 |
|
153 |
8
|
private static Long getSerializableUID(final Class<?> clazz) {... |
154 |
|
|
155 |
8
|
try { |
156 |
8
|
final Field f = clazz.getDeclaredField("serialVersionUID"); |
157 |
6
|
final int mask = Modifier.STATIC | Modifier.FINAL; |
158 |
6
|
if ((f.getModifiers() & mask) == mask) { |
159 |
4
|
f.setAccessible(true); |
160 |
4
|
return Long.valueOf(f.getLong(null)); |
161 |
|
} |
162 |
|
} catch (final NoSuchFieldException e) { |
163 |
|
|
164 |
|
} catch (final IllegalAccessException e) { |
165 |
|
|
166 |
|
throw new RuntimeException("Should have been able to get serialVersionUID since it's there"); |
167 |
|
|
168 |
|
} |
169 |
|
|
170 |
|
return callLongMethod(clazz, |
171 |
|
ClassInstantiatorFactory.is1_3Specifications() ? "computeSerialVersionUID" |
172 |
|
: "computeDefaultSUID"); |
173 |
|
|
174 |
|
} |
175 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (2) |
Complexity: 1 |
Complexity Density: 0,5 |
|
176 |
4
|
private static Long callLongMethod(final Class<?> clazz, final String methodName) {... |
177 |
|
|
178 |
4
|
Method method; |
179 |
|
|
180 |
|
try { |
181 |
|
method = ObjectStreamClass.class.getDeclaredMethod(methodName, new Class[] { Class.class }); |
182 |
|
} catch (final NoSuchMethodException e) { |
183 |
|
throw new InternalError("ObjectStreamClass." + methodName + " seems to have vanished"); |
184 |
|
} |
185 |
|
final boolean accessible = method.isAccessible(); |
186 |
|
method.setAccessible(true); |
187 |
|
Long suid; |
188 |
|
try { |
189 |
|
suid = (Long) method.invoke(null, new Object[] { clazz }); |
190 |
|
} catch (final IllegalAccessException e) { |
191 |
|
throw new InternalError("ObjectStreamClass." + methodName + " should have been accessible"); |
192 |
|
} catch (final InvocationTargetException e) { |
193 |
|
throw new InternalError("ObjectStreamClass." + methodName + " failled to be called: " |
194 |
|
+ e.getMessage()); |
195 |
|
} |
196 |
|
method.setAccessible(accessible); |
197 |
|
|
198 |
4
|
return suid; |
199 |
|
} |
200 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (2) |
Complexity: 1 |
Complexity Density: 0,5 |
|
201 |
8
|
private static Object readObject(final byte[] bytes) throws IOException, ClassNotFoundException {... |
202 |
8
|
final ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes)); |
203 |
8
|
return in.readObject(); |
204 |
|
} |
205 |
|
|
206 |
|
} |