Mixer.java
biz/hammurapi/convert/Mixer.java
Violations
Inspector |
Message |
Severity |
Location |
Java Inspector 048 |
Copyrights information should be present in each file. |
1 |
|
Java Inspector 049 |
Use a Collection instead of arrays Object[] |
2 |
51:22
|
Java Inspector 049 |
Use a Collection instead of arrays Object[] |
2 |
52:22
|
Java Inspector 049 |
Use a Collection instead of arrays Object[] |
2 |
83:55
|
Java Inspector 049 |
Use a Collection instead of arrays Object[] |
2 |
87:62
|
Java Inspector 049 |
Use a Collection instead of arrays Object[] |
2 |
130:27
|
Java Inspector 049 |
Use a Collection instead of arrays Object[] |
2 |
133:31
|
Java Inspector 049 |
Use a Collection instead of arrays Object[] |
2 |
159:22
|
Java Inspector 049 |
Use a Collection instead of arrays Object[] |
2 |
162:31
|
Java Inspector 049 |
Use a Collection instead of arrays Object[] |
2 |
171:70
|
Java Inspector 049 |
Use a Collection instead of arrays Object[] |
2 |
172:70
|
Java Inspector 049 |
Use a Collection instead of arrays Object[] |
2 |
248:23
|
Java Inspector 049 |
Use a Collection instead of arrays Object[] |
2 |
250:17
|
Java Inspector 049 |
Use a Collection instead of arrays Object[] |
2 |
319:30
|
Java Inspector 068 |
Do not use System.out and System.err to output logging messages. Use loggers instead. |
2 |
182:83
|
Java Inspector 070-A |
Cyclomatic complexity is too high: 14, maximum allowed is 12 |
2 |
124:9
|
Java Inspector 085 |
Do not declare runtime exceptions in the throws clause. |
2 |
154:25
|
Java Inspector 089 |
Parameter object is not documented |
2 |
38:9
|
Java Inspector 089 |
Parameter interfaces is not documented |
2 |
38:9
|
Java Inspector 089 |
Method return value is not properly documented |
2 |
38:9
|
Java Inspector 089 |
Undocumented method |
2 |
72:41
|
Java Inspector 089 |
Undocumented method |
2 |
96:41
|
Java Inspector 089 |
Parameter master is not documented |
2 |
124:9
|
Java Inspector 089 |
Parameter interceptors is not documented |
2 |
124:9
|
Java Inspector 089 |
Method return value is not properly documented |
2 |
124:9
|
Java Inspector 089 |
Undocumented method |
2 |
197:41
|
Java Inspector 089 |
Undocumented method |
2 |
206:41
|
Java Inspector 089 |
Undocumented parameter objects |
2 |
222:9
|
Java Inspector 089 |
Parameter interfaces is not documented |
2 |
222:9
|
Java Inspector 089 |
Javadoc contains tag for non-existent parameter object |
2 |
222:9
|
Java Inspector 089 |
Method return value is not properly documented |
2 |
222:9
|
Java Inspector 089 |
Undocumented method |
2 |
269:41
|
Java Inspector 089 |
Parameter objects is not documented |
2 |
300:9
|
Java Inspector 089 |
Method return value is not properly documented |
2 |
300:9
|
Java Inspector 089 |
Undocumented method |
2 |
340:57
|
Java Inspector 026 |
Avoid hardwired string literals. Allowed literals: [] |
3 |
182:84
|
Java Inspector 026 |
Avoid hardwired string literals. Allowed literals: [] |
3 |
182:120
|
1package biz.hammurapi.convert;
2
3import java.lang.reflect.InvocationHandler;
4import java.lang.reflect.InvocationTargetException;
5import java.lang.reflect.Method;
6import java.lang.reflect.Proxy;
7import java.util.ArrayList;
8import java.util.Arrays;
9import java.util.Collection;
10import java.util.HashMap;
11import java.util.Iterator;
12import java.util.List;
13import java.util.Map;
14
15import biz.hammurapi.wrap.WrapperHandler;
16
17
18
19
20
21
22
23public class Mixer {
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 public static Object mixIn(final Object object, Class[] interfaces) {
39 List additional = new ArrayList();
40 for (int i = 0; interfaces!=null && i<interfaces.length; ++i) {
41 if (!interfaces[i].isInstance(object)) {
42 additional.add(interfaces[i]);
43 }
44 }
45
46 if (additional.isEmpty()) {
47 return object;
48 }
49
50 Class objectClass = object.getClass();
51 Class[] objectInterfaces = WrapperHandler.getClassInterfaces(objectClass);
52 Class[] proxyInterfaces = new Class[objectInterfaces.length+additional.size()];
53 ClassLoader classLoader = null;
54 for (int i=0; i<objectInterfaces.length; ++i) {
55 proxyInterfaces[i] = objectInterfaces[i];
56 classLoader = DuckConverterFactory.getChildClassLoader(classLoader, objectInterfaces[i].getClassLoader());
57 }
58
59 final Map methodMap = new HashMap();
60 Iterator it = additional.iterator();
61 for (int i=objectInterfaces.length; it.hasNext(); ++i) {
62 proxyInterfaces[i] = (Class) it.next();
63 classLoader = DuckConverterFactory.getChildClassLoader(classLoader, proxyInterfaces[i].getClassLoader());
64 DuckConverterFactory.duckMap(proxyInterfaces[i], objectClass, methodMap);
65 }
66
67 return Proxy.newProxyInstance(
68 classLoader == null ? objectClass.getClassLoader() : classLoader,
69 proxyInterfaces,
70 new FilterInvocationHandler() {
71
72 public Object invoke(
73 Object proxy,
74 Method method,
75 Object[] args) throws Throwable {
76
77 Method mappedMethod = (Method) methodMap.get(method);
78 if (mappedMethod ==null) {
79 return method.invoke(object, args);
80 }
81
82
83 Object[] convertedArgs;
84 if (args==null) {
85 convertedArgs = null;
86 } else {
87 Class[] parameterTypes = mappedMethod.getParameterTypes();
88 convertedArgs = new Object[args.length];
89 for (int i=0; i<convertedArgs.length; ++i) {
90 convertedArgs[i] = ConvertingService.convert(args[i], parameterTypes[i]);
91 }
92 }
93 return mappedMethod.invoke(object, args);
94 }
95
96 public Object getMaster() {
97 return object;
98 }
99
100 });
101 }
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124 public static Object addInterceptors(final Object master, Object[] interceptors) {
125 if (master == null) {
126 return null;
127 }
128
129
130 Collection[] interceptorMethods = new Collection[interceptors.length];
131 for (int i=0; i<interceptors.length; ++i) {
132 Class interceptorClass = interceptors[i].getClass();
133 Method[] iMethods = interceptorClass.getMethods();
134 interceptorMethods[i] = new ArrayList();
135 for (int m=0; m<iMethods.length; ++m) {
136 Method interceptorMethod = iMethods[m];
137
138 if (!interceptorMethod.getDeclaringClass().equals(Object.class)) {
139 interceptorMethods[i].add(interceptorMethod);
140 }
141 }
142 }
143
144 class InterceptorEntry {
145 Object object;
146 Method method;
147
148 InterceptorEntry(Object object, Method method) {
149 super();
150 this.object = object;
151 this.method = method;
152 }
153
154 Object invoke(Object[] args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
155 return method.invoke(object, args);
156 }
157 }
158
159 Class[] interfaces = WrapperHandler.getClassInterfaces(master.getClass());
160 final Map interceptionMap = new HashMap();
161 for (int interfaceIdx=0; interfaceIdx<interfaces.length; ++interfaceIdx) {
162 Method[] methods = interfaces[interfaceIdx].getMethods();
163 Z: for (int methodIdx = 0; methodIdx < methods.length; ++methodIdx) {
164 Method masterMethod = methods[methodIdx];
165 if (!masterMethod.getDeclaringClass().equals(Object.class)) {
166 for (int interceptorIdx =0; interceptorIdx<interceptors.length; ++interceptorIdx) {
167 Iterator interceptorMethodIterator = interceptorMethods[interceptorIdx].iterator();
168 Y: while (interceptorMethodIterator.hasNext()) {
169 Method interceptorMethod = (Method) interceptorMethodIterator.next();
170 if (masterMethod.getName().equals(interceptorMethod.getName())) {
171 Class[] masterParameterTypes = masterMethod.getParameterTypes();
172 Class[] interceptorParameterTypes = interceptorMethod.getParameterTypes();
173 if (masterParameterTypes.length!=interceptorParameterTypes.length) {
174 continue;
175 }
176 for (int prmIdx = 0; prmIdx<masterParameterTypes.length; ++prmIdx) {
177 if (!masterParameterTypes[prmIdx].equals(interceptorParameterTypes[prmIdx])) {
178 continue Y;
179 }
180 }
181
182 System.out.println("~~~~~ Mapped method "+masterMethod+" to interceptor "+interceptorIdx);
183 interceptionMap.put(masterMethod, new InterceptorEntry(interceptors[interceptorIdx], interceptorMethod));
184 continue Z;
185 }
186 }
187 }
188 }
189 }
190 }
191
192 return Proxy.newProxyInstance(
193 Object.class.getClassLoader(),
194 interfaces,
195 new FilterInvocationHandler() {
196
197 public Object invoke(
198 Object proxy,
199 Method method,
200 Object[] args) throws Throwable {
201
202 InterceptorEntry ie = (InterceptorEntry) interceptionMap.get(method);
203 return ie==null ? method.invoke(master, args) : ie.invoke(args);
204 }
205
206 public Object getMaster() {
207 return master;
208 }
209
210 });
211
212 }
213
214
215
216
217
218
219
220
221
222 public static Object combine(final Object[] objects, Class[] interfaces) {
223 if (objects==null || objects.length==0) {
224 return null;
225 }
226
227 boolean firstDoesIt = true;
228 for (int i=0; i<interfaces.length; ++i) {
229 if (!interfaces[i].isInstance(objects[0])) {
230 firstDoesIt = false;
231 break;
232 }
233 }
234
235 if (firstDoesIt) {
236 return objects[0];
237 }
238
239 if (objects.length==1) {
240 return mixIn(objects[0], interfaces);
241 }
242
243 List allInterfaceMethods = new ArrayList();
244 for (int i=0; i<interfaces.length; ++i) {
245 allInterfaceMethods.addAll(Arrays.asList(interfaces[i].getMethods()));
246 }
247
248 Method[] aim = (Method[]) allInterfaceMethods.toArray(new Method[allInterfaceMethods.size()]);
249
250 final Map[] methodMaps = new Map[objects.length];
251 for (int i=0; i<objects.length; ++i) {
252 methodMaps[i] = new HashMap();
253 DuckConverterFactory.duckMap(aim, objects[i].getClass().getMethods(), methodMaps[i]);
254 }
255
256 ClassLoader classLoader = null;
257 for (int i=0; i<objects.length; ++i) {
258 classLoader = DuckConverterFactory.getChildClassLoader(classLoader, objects[i].getClass().getClassLoader());
259 }
260 for (int i=0; i<interfaces.length; ++i) {
261 classLoader = DuckConverterFactory.getChildClassLoader(classLoader, interfaces[i].getClassLoader());
262 }
263
264 return Proxy.newProxyInstance(
265 classLoader == null ? objects[0].getClass().getClassLoader() : classLoader,
266 interfaces,
267 new InvocationHandler() {
268
269 public Object invoke(
270 Object proxy,
271 Method method,
272 Object[] args) throws Throwable {
273
274 Class declaringClass = method.getDeclaringClass();
275 for (int i=0; i<objects.length; ++i) {
276 if (declaringClass.isInstance(objects[i])) {
277 return method.invoke(objects[i], args);
278 }
279 Method mappedMethod = (Method) methodMaps[i].get(method);
280 if (mappedMethod!=null) {
281 return mappedMethod.invoke(objects[i], args);
282 }
283 }
284
285 return method.invoke(objects[0], args);
286 }
287
288 });
289 }
290
291
292
293
294
295
296
297
298
299
300 public static Object mix(final Object[] objects) {
301 if (objects==null || objects.length==0) {
302 return null;
303 }
304
305 if (objects.length==1) {
306 return objects[0];
307 }
308
309
310
311 final Map interfaceMap = new HashMap();
312 List interfaces = new ArrayList();
313 ClassLoader classLoader = null;
314 boolean onlyFirstInterfaces = false;
315
316 for (int i=0; i<objects.length; ++i) {
317 Class sourceClass = objects[i].getClass();
318 classLoader=DuckConverterFactory.getChildClassLoader(classLoader, sourceClass.getClassLoader());
319 Class[] cia = WrapperHandler.getClassInterfaces(sourceClass);
320 for (int j=0; j<cia.length; ++j) {
321 Class classInterface = cia[j];
322 if (!interfaceMap.containsKey(classInterface)) {
323 onlyFirstInterfaces = i==0;
324 interfaceMap.put(classInterface, objects[i]);
325 interfaces.add(classInterface);
326 }
327 }
328 }
329
330
331 if (onlyFirstInterfaces) {
332 return objects[0];
333 }
334
335 return Proxy.newProxyInstance(
336 classLoader == null ? objects[0].getClass().getClassLoader() : classLoader,
337 (Class[]) interfaces.toArray(new Class[interfaces.size()]),
338 new InvocationHandler() {
339
340 public Object invoke(
341 Object proxy,
342 Method method,
343 Object[] args) throws Throwable {
344
345 Object target = interfaceMap.get(method.getDeclaringClass());
346 return method.invoke(target==null ? objects[0] : target, args);
347 }
348
349 });
350 }
351
352}
353