ConvertingService.java
biz/hammurapi/convert/ConvertingService.java
Violations
Inspector |
Message |
Severity |
Location |
Java Inspector 048 |
Copyrights information should be present in each file. |
1 |
|
Java Inspector 086 |
Use equals() instead of == or != to compare objects. |
1 |
112:44
|
Java Inspector 086 |
Use equals() instead of == or != to compare objects. |
1 |
113:47
|
Java Inspector 049 |
Use a Collection instead of arrays Object[] |
2 |
262:39
|
Java Inspector 049 |
Use a Collection instead of arrays Object[] |
2 |
266:54
|
Java Inspector 070-A |
Cyclomatic complexity is too high: 17, maximum allowed is 12 |
2 |
250:17
|
Java Inspector 081 |
Avoid static collections, they can grow in size over time. |
2 |
338:9
|
Java Inspector 082 |
Parenthesis are redundant. |
2 |
105:52
|
Java Inspector 082 |
Parenthesis are redundant. |
2 |
106:52
|
Java Inspector 085 |
Do not declare runtime exceptions in the throws clause. |
2 |
30:17
|
Java Inspector 085 |
Do not declare runtime exceptions in the throws clause. |
2 |
50:9
|
Java Inspector 085 |
Do not declare runtime exceptions in the throws clause. |
2 |
69:9
|
Java Inspector 085 |
Do not declare runtime exceptions in the throws clause. |
2 |
88:9
|
Java Inspector 085 |
Do not declare runtime exceptions in the throws clause. |
2 |
123:25
|
Java Inspector 085 |
Do not declare runtime exceptions in the throws clause. |
2 |
140:25
|
Java Inspector 085 |
Do not declare runtime exceptions in the throws clause. |
2 |
354:9
|
Java Inspector 085 |
Do not declare runtime exceptions in the throws clause. |
2 |
377:9
|
Java Inspector 089 |
Undocumented top level type |
2 |
18:1
|
Java Inspector 089 |
Undocumented method |
2 |
30:17
|
Java Inspector 089 |
Undocumented constructor |
2 |
96:17
|
Java Inspector 089 |
Undocumented method |
2 |
102:17
|
Java Inspector 089 |
Undocumented method |
2 |
110:17
|
Java Inspector 089 |
Undocumented method |
2 |
123:25
|
Java Inspector 089 |
Undocumented method |
2 |
140:25
|
Java Inspector 089 |
Undocumented constructor |
2 |
183:41
|
Java Inspector 089 |
Undocumented method |
2 |
192:41
|
Java Inspector 089 |
Undocumented method |
2 |
220:49
|
Java Inspector 089 |
Undocumented method |
2 |
270:65
|
Java Inspector 089 |
Undocumented method |
2 |
284:65
|
Java Inspector 089 |
Undocumented method |
2 |
299:65
|
Java Inspector 089 |
Undocumented method |
2 |
314:65
|
Java Inspector 089 |
Javadoc contains tag for exception which method doesn't throw ConversionException |
2 |
402:9
|
Java Inspector 089 |
Javadoc contains tag for exception which method doesn't throw ConversionException |
2 |
419:9
|
Java Inspector 089 |
Javadoc contains tag for exception which method doesn't throw ConversionException |
2 |
436:9
|
Java Inspector 089 |
Javadoc contains tag for exception which method doesn't throw ConversionException |
2 |
454:9
|
Java Inspector 089 |
Undocumented method |
2 |
496:25
|
Java Inspector 025 |
Avoid hardwired numeric literals. Allowed literals: [1, -1, 0] |
3 |
103:43
|
Java Inspector 025 |
Avoid hardwired numeric literals. Allowed literals: [1, -1, 0] |
3 |
281:77
|
Java Inspector 025 |
Avoid hardwired numeric literals. Allowed literals: [1, -1, 0] |
3 |
296:77
|
Java Inspector 025 |
Avoid hardwired numeric literals. Allowed literals: [1, -1, 0] |
3 |
311:77
|
Java Inspector 025 |
Avoid hardwired numeric literals. Allowed literals: [1, -1, 0] |
3 |
311:147
|
Java Inspector 026 |
Avoid hardwired string literals. Allowed literals: [] |
3 |
209:92
|
1package biz.hammurapi.convert;
2
3import java.lang.reflect.InvocationTargetException;
4import java.lang.reflect.Method;
5import java.util.ArrayList;
6import java.util.Collection;
7import java.util.Collections;
8import java.util.HashMap;
9import java.util.HashSet;
10import java.util.Iterator;
11import java.util.List;
12import java.util.Map;
13import java.util.Set;
14
15import biz.hammurapi.config.Context;
16import biz.hammurapi.config.DomConfigFactory;
17
18public class ConvertingService {
19
20 private interface ConvertersBucket {
21
22 Object convert(Object source, Context context);
23 }
24
25
26
27
28 public static final Converter CONVERTER = new Converter() {
29
30 public Object convert(Object source, Class targetType, Context context) throws ConversionException {
31 return ConvertingService.convert(source, targetType, context);
32 }
33
34 };
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 public static Object convert(Object source, Class targetType) throws ConversionException {
51 return convert(source, targetType, null, false, null);
52 }
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 public static Object convert(Object source, Class targetType, Context context) throws ConversionException {
70 return convert(source, targetType, context, false, null);
71 }
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88 public static Object convert(Object source, Class targetType, ClassLoader classLoader) throws ConversionException {
89 return convert(source, targetType, null, false, classLoader);
90 }
91
92 private static class ConverterKey {
93 Class sourceType;
94 Class targetType;
95
96 public ConverterKey(Class sourceType, Class targetType) {
97 super();
98 this.sourceType = sourceType;
99 this.targetType = targetType;
100 }
101
102 public int hashCode() {
103 final int prime = 31;
104 int result = 1;
105 result = prime * result + ((sourceType == null) ? 0 : sourceType.hashCode());
106 result = prime * result + ((targetType == null) ? 0 : targetType.hashCode());
107 return result;
108 }
109
110 public boolean equals(Object obj) {
111 return
112 sourceType == ((ConverterKey) obj).sourceType
113 && targetType == ((ConverterKey) obj).targetType;
114 }
115
116 }
117
118 private static class ClassLoaderConvertersEntry {
119 private static final String CONVERT = "convert";
120
121 private Converter master = new Converter() {
122
123 public Object convert(Object source, Class targetType, Context context) throws ConversionException {
124 if (source==null) {
125 return null;
126 }
127
128 if (targetType.isInstance(source)) {
129 return source;
130 }
131
132 final ConvertersBucket bucket = findConverter(source.getClass(), targetType);
133 return bucket==null ? null : bucket.convert(source, context);
134 }
135
136 };
137
138 private Converter chainingMaster = new Converter() {
139
140 public Object convert(Object source, Class targetType, Context context) throws ConversionException {
141 if (source==null) {
142 return null;
143 }
144
145 if (targetType.isInstance(source)) {
146 return source;
147 }
148
149 ConvertersBucket bucket = findChainingConverter(source.getClass(), targetType);
150 return bucket==null ? null : bucket.convert(source, context);
151 }
152
153 };
154
155 Collection atomicConverters = new ArrayList();
156
157
158
159
160 Map converters = new HashMap();
161
162 Set introspectedTargetTypes = new HashSet();
163
164
165
166
167 Map chainingConverters = new HashMap();
168
169 synchronized ConvertersBucket findConverter(Class sourceType, Class targetType) {
170 ConverterKey key = new ConverterKey(sourceType, targetType);
171 Object ret = converters.get(key);
172 if (Boolean.FALSE.equals(ret)) {
173 return null;
174 }
175
176 if (ret == null) {
177 if (!targetType.isInterface() && introspectedTargetTypes.add(targetType)) {
178 atomicConverters.addAll(ReflectionConverter.discoverConstructorConverters(targetType));
179 }
180 final List theConverters = new ArrayList();
181
182 class ConverterEntry implements Comparable {
183 public ConverterEntry(AtomicConverter converter, int affinity, int position) {
184 super();
185 this.converter = converter;
186 this.affinity = affinity;
187 this.position = position;
188 }
189 AtomicConverter converter;
190 int affinity;
191 int position;
192 public int compareTo(Object obj) {
193 int cret = affinity - ((ConverterEntry) obj).affinity;
194 if (cret==0) {
195 return position - ((ConverterEntry) obj).position;
196 }
197 return cret;
198 }
199 }
200
201 Iterator it = atomicConverters.iterator();
202 while (it.hasNext()) {
203 AtomicConverter ac = (AtomicConverter) it.next();
204 int position = 0;
205 if (ac.getSourceType().isAssignableFrom(sourceType) && targetType.isAssignableFrom(ac.getTargetType()) ) {
206 Integer newSourceAffinity = DuckConverterFactory.classAffinity(sourceType, ac.getSourceType());
207 Integer newTargetAffinity = DuckConverterFactory.classAffinity(ac.getTargetType(), targetType);
208 if (newSourceAffinity==null || newTargetAffinity==null) {
209 throw new IllegalArgumentException("kosyak");
210 }
211 theConverters.add(new ConverterEntry(ac, newSourceAffinity.intValue()+newTargetAffinity.intValue(), ++position));
212 }
213 }
214 if (theConverters.isEmpty()) {
215 converters.put(key, Boolean.FALSE);
216 } else {
217 Collections.sort(theConverters);
218 ret = new ConvertersBucket() {
219
220 public Object convert(Object source, Context context) {
221 Iterator it = theConverters.iterator();
222 while (it.hasNext()) {
223 ConverterEntry ce = (ConverterEntry) it.next();
224 Object ret = ce.converter.convert(source, master, context);
225 if (ret!=null) {
226 return ret;
227 }
228 }
229 return null;
230 }
231
232 };
233 converters.put(key, ret);
234 }
235 }
236
237 return (ConvertersBucket) ret;
238 }
239
240 synchronized ConvertersBucket findChainingConverter(Class sourceType, Class targetType) {
241 ConvertersBucket ret = findConverter(sourceType, targetType);
242 if (ret!=null) {
243 return ret;
244 }
245
246
247 return ret;
248 }
249
250 void addConverters(final Object provider) {
251 if (provider instanceof AtomicConverter) {
252 atomicConverters.add(provider);
253 } else if (provider instanceof AtomicConvertersBundle) {
254 atomicConverters.addAll(((AtomicConvertersBundle) provider).getConverters());
255 } else if (provider instanceof Collection) {
256 Iterator it = ((Collection) provider).iterator();
257 while (it.hasNext()) {
258 addConverters(it.next());
259 }
260 } else {
261 Class pClass = provider.getClass();
262 Method[] methods = pClass.getMethods();
263 for (int i=0; i<methods.length; ++i) {
264 final Method method = methods[i];
265 if (CONVERT.equals(method.getName()) && !void.class.equals(method.getReturnType())) {
266 Class[] pTypes = method.getParameterTypes();
267 if (pTypes.length == 1) {
268 atomicConverters.add(new AtomicConverterBase(pTypes[0], method.getReturnType()) {
269
270 public Object convert(Object source, Converter master, Context context) {
271 try {
272 return method.invoke(provider, new Object[] {source});
273 } catch (IllegalAccessException e) {
274 throw new ConversionException(e);
275 } catch (InvocationTargetException e) {
276 throw new ConversionException(e);
277 }
278 }
279
280 });
281 } else if (pTypes.length == 2 && Converter.class.equals(pTypes[1])) {
282 atomicConverters.add(new AtomicConverterBase(pTypes[0], method.getReturnType()) {
283
284 public Object convert(Object source, Converter master, Context context) {
285 try {
286 return method.invoke(provider, new Object[] {source, master});
287 } catch (IllegalAccessException e) {
288 throw new ConversionException(e);
289 } catch (InvocationTargetException e) {
290 throw new ConversionException(e);
291 }
292 }
293
294 });
295
296 } else if (pTypes.length == 2 && Context.class.equals(pTypes[1])) {
297 atomicConverters.add(new AtomicConverterBase(pTypes[0], method.getReturnType()) {
298
299 public Object convert(Object source, Converter master, Context context) {
300 try {
301 return method.invoke(provider, new Object[] {source, context});
302 } catch (IllegalAccessException e) {
303 throw new ConversionException(e);
304 } catch (InvocationTargetException e) {
305 throw new ConversionException(e);
306 }
307 }
308
309 });
310
311 } else if (pTypes.length == 3 && Converter.class.equals(pTypes[1]) && Context.class.equals(pTypes[2])) {
312 atomicConverters.add(new AtomicConverterBase(pTypes[0], method.getReturnType()) {
313
314 public Object convert(Object source, Converter master, Context context) {
315 try {
316 return method.invoke(provider, new Object[] {source, master, context});
317 } catch (IllegalAccessException e) {
318 throw new ConversionException(e);
319 } catch (InvocationTargetException e) {
320 throw new ConversionException(e);
321 }
322 }
323
324 });
325
326 }
327
328 }
329 }
330 }
331 }
332
333 }
334
335
336
337
338 private static Map classLoaderEntries = new HashMap();
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354 public static Object convert(Object source, Class targetType, Context context, ClassLoader classLoader) throws ConversionException {
355 return convert(source, targetType, context, false, classLoader);
356 }
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377 private static Object convert(Object source, Class targetType, Context context, boolean chain, ClassLoader classLoader) throws ConversionException {
378 if (source==null) {
379 return null;
380 }
381
382 if (targetType.isInstance(source)) {
383 return source;
384 }
385
386 ConverterClosure converter = getConverter(source.getClass(), targetType, context, chain, classLoader);
387 return converter==null ? null : converter.convert(source);
388 }
389
390
391
392
393
394
395
396
397
398
399
400
401
402 public static ConverterClosure getConverter(Class sourceType, Class targetType) {
403 return getConverter(sourceType, targetType, null, false, null);
404 }
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419 public static ConverterClosure getConverter(Class sourceType, Class targetType, ClassLoader classLoader) {
420 return getConverter(sourceType, targetType, null, false, classLoader);
421 }
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436 public static ConverterClosure getConverter(Class sourceType, Class targetType, Context context) {
437 return getConverter(sourceType, targetType, context, false, null);
438 }
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454 public static ConverterClosure getConverter(Class sourceType, Class targetType, Context context, ClassLoader classLoader) {
455 return getConverter(sourceType, targetType, context, false, classLoader);
456 }
457
458 private static ClassLoader promote(ClassLoader present, ClassLoader candidate) {
459 ClassLoader ret = DuckConverterFactory.getChildClassLoader(present, candidate);
460 return ret==null ? present : ret;
461 }
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478 private static ConverterClosure getConverter(Class sourceType, Class targetType, final Context context, boolean chain, final ClassLoader pClassLoader) {
479 ClassLoader classLoader = promote(pClassLoader, promote(targetType.getClassLoader(), sourceType.getClassLoader()));
480
481 ClassLoaderConvertersEntry clce;
482 synchronized (classLoaderEntries) {
483 clce = (ClassLoaderConvertersEntry) classLoaderEntries.get(classLoader);
484 if (clce == null) {
485 clce = new ClassLoaderConvertersEntry();
486 Iterator pit = DomConfigFactory.loadProviders(Converter.class, classLoader);
487 while (pit.hasNext()) {
488 clce.addConverters(pit.next());
489 }
490 classLoaderEntries.put(classLoader, clce);
491 }
492 }
493 final ConvertersBucket bucket = chain ? clce.findChainingConverter(sourceType, targetType) : clce.findConverter(sourceType, targetType);
494 return bucket==null ? null : new ConverterClosure() {
495
496 public Object convert(Object source) {
497 return bucket.convert(source, context);
498 }
499
500 };
501 }
502}
503