ContextConverterFactory.java
biz/hammurapi/convert/ContextConverterFactory.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 |
175:58
|
Java Inspector 086 |
Use equals() instead of == or != to compare objects. |
1 |
180:58
|
Java Inspector 049 |
Use a Collection instead of arrays Object[] |
2 |
48:17
|
Java Inspector 049 |
Use a Collection instead of arrays Object[] |
2 |
127:39
|
Java Inspector 070-A |
Cyclomatic complexity is too high: 14, maximum allowed is 12 |
2 |
89:9
|
Java Inspector 081 |
Avoid static collections, they can grow in size over time. |
2 |
37:9
|
Java Inspector 089 |
Undocumented method |
2 |
28:17
|
Java Inspector 089 |
Undocumented constructor |
2 |
52:17
|
Java Inspector 089 |
Undocumented method |
2 |
58:17
|
Java Inspector 089 |
Undocumented method |
2 |
62:33
|
Java Inspector 089 |
Method is not properly documented |
2 |
89:9
|
Java Inspector 089 |
Parameter sourceClass is not documented |
2 |
89:9
|
Java Inspector 089 |
Parameter targetInterface is not documented |
2 |
89:9
|
Java Inspector 005 |
Classes, interfaces, methods, and variables should be named according to Sun's naming conventions. |
3 |
26:9
|
Java Inspector 026 |
Avoid hardwired string literals. Allowed literals: [] |
3 |
68:73
|
Java Inspector 026 |
Avoid hardwired string literals. Allowed literals: [] |
3 |
69:131
|
Java Inspector 026 |
Avoid hardwired string literals. Allowed literals: [] |
3 |
73:117
|
Java Inspector 026 |
Avoid hardwired string literals. Allowed literals: [] |
3 |
110:66
|
Java Inspector 026 |
Avoid hardwired string literals. Allowed literals: [] |
3 |
119:126
|
Java Inspector 026 |
Avoid hardwired string literals. Allowed literals: [] |
3 |
137:79
|
Java Inspector 026 |
Avoid hardwired string literals. Allowed literals: [] |
3 |
140:86
|
Java Inspector 051 |
It is good practice to call in any case super() in a constructor. |
3 |
52:17
|
1package biz.hammurapi.convert;
2
3import java.lang.reflect.InvocationHandler;
4import java.lang.reflect.Method;
5import java.lang.reflect.Proxy;
6import java.util.ArrayList;
7import java.util.Collection;
8import java.util.HashMap;
9import java.util.Map;
10
11import biz.hammurapi.config.Context;
12import biz.hammurapi.config.MutableContext;
13import biz.hammurapi.config.RuntimeConfigurationException;
14
15
16
17
18
19
20
21public class ContextConverterFactory {
22
23
24
25
26 private static ConverterClosure ZERO_CONVERTER = new ConverterClosure() {
27
28 public Object convert(Object source) {
29 return source;
30 }
31
32 };
33
34
35
36
37 private static Map converterMap = new HashMap();
38
39 private static class ProxyConverter implements ConverterClosure {
40
41
42
43
44
45
46 private Map methodMap;
47
48 private Class[] targetInterfaces;
49
50 private ClassLoader classLoader;
51
52 public ProxyConverter(Class targetInterface, Map methodMap, ClassLoader classLoader) {
53 this.methodMap = methodMap;
54 this.targetInterfaces = new Class[] {targetInterface};
55 this.classLoader = classLoader;
56 }
57
58 public Object convert(final Object source) {
59
60 InvocationHandler ih = new InvocationHandler() {
61
62 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
63 Method sourceMethod = (Method) (methodMap==null ? null : methodMap.get(method));
64 if (sourceMethod==null) {
65 return method.invoke(source, args);
66 }
67
68 if (method.getName().startsWith("get")) {
69 Object ret = sourceMethod.invoke(source, new Object[] {method.getName().substring("get".length())});
70 return ConvertingService.convert(ret, method.getReturnType());
71 }
72
73 return sourceMethod.invoke(source, new Object[] {method.getName().substring("set".length()), args[0]});
74 }
75
76 };
77
78 return Proxy.newProxyInstance(classLoader, targetInterfaces, ih);
79 }
80
81 }
82
83
84
85
86
87
88
89 public static ConverterClosure getConverter(Class sourceClass, Class targetInterface) {
90 if (targetInterface.isAssignableFrom(sourceClass)) {
91 return ZERO_CONVERTER;
92 }
93
94 Collection key=new ArrayList();
95 key.add(sourceClass);
96 key.add(targetInterface);
97 synchronized (converterMap) {
98 Object value = converterMap.get(key);
99 if (Boolean.FALSE.equals(value)) {
100 return null;
101 }
102
103 if (!Context.class.isAssignableFrom(sourceClass)) {
104 converterMap.put(key, Boolean.FALSE);
105 return null;
106 }
107
108 Method getter;
109 try {
110 getter = Context.class.getMethod("get", new Class[] {String.class});
111 } catch (SecurityException e) {
112 throw new RuntimeConfigurationException(e);
113 } catch (NoSuchMethodException e) {
114 throw new RuntimeConfigurationException(e);
115 }
116
117 Method setter;
118 try {
119 setter = MutableContext.class.isAssignableFrom(sourceClass) ? MutableContext.class.getMethod("set", new Class[] {String.class, Object.class}) : null;
120 } catch (SecurityException e) {
121 throw new RuntimeConfigurationException(e);
122 } catch (NoSuchMethodException e) {
123 throw new RuntimeConfigurationException(e);
124 }
125
126 if (value==null) {
127 Method[] targetMethods = targetInterface.getMethods();
128
129 Map methodMap = new HashMap();
130
131 for (int i=0, l=targetMethods.length; i<l; ++i) {
132 if (Object.class.equals(targetMethods[i].getDeclaringClass())) {
133 continue;
134 }
135
136 Method targetMethod = targetMethods[i];
137 if (targetMethod.getName().startsWith("get")
138 && targetMethod.getParameterTypes().length==0) {
139 methodMap.put(targetMethod, getter);
140 } else if (targetMethod.getName().startsWith("set")
141 && targetMethod.getParameterTypes().length==1
142 && setter!=null) {
143 methodMap.put(targetMethod, setter);
144 } else {
145 converterMap.put(key, Boolean.FALSE);
146 return null;
147 }
148 }
149
150 ClassLoader cl = getChildClassLoader(sourceClass.getClassLoader(), targetInterface.getClassLoader());
151 if (cl==null) {
152 converterMap.put(key, Boolean.FALSE);
153 return null;
154 }
155
156 value = new ProxyConverter(targetInterface, methodMap.isEmpty() ? null : methodMap, cl);
157 converterMap.put(key, value);
158 }
159 return (ConverterClosure) value;
160 }
161 }
162
163
164
165
166
167
168 private static ClassLoader getChildClassLoader(ClassLoader cl1, ClassLoader cl2) {
169 if (cl1==null) {
170 return cl2;
171 }
172 if (cl2==null) {
173 return cl1;
174 }
175 for (ClassLoader cl = cl1; cl!=null && cl!=cl.getParent(); cl=cl.getParent()) {
176 if (cl2.equals(cl)) {
177 return cl1;
178 }
179 }
180 for (ClassLoader cl = cl2; cl!=null && cl!=cl.getParent(); cl=cl.getParent()) {
181 if (cl1.equals(cl)) {
182 return cl2;
183 }
184 }
185 return null;
186 }
187}
188