SoftCachingProxyFactory.java
biz/hammurapi/cache/SoftCachingProxyFactory.java
Violations
Inspector |
Message |
Severity |
Location |
Java Inspector 048 |
Copyrights information should be present in each file. |
1 |
|
Java Inspector 043 |
Call 'wait ()' only inside a "while" loop |
2 |
136:37
|
Java Inspector 049 |
Use a Collection instead of arrays Object[] |
2 |
44:22
|
Java Inspector 049 |
Use a Collection instead of arrays Object[] |
2 |
70:38
|
Java Inspector 077 |
To reduce probability of NullPointerException, use "string literal".equals(variable) instead of variable.equals("string literal"). |
2 |
58:80
|
Java Inspector 089 |
Undocumented parameter master |
2 |
39:9
|
Java Inspector 089 |
Undocumented method |
2 |
53:25
|
Java Inspector 089 |
Undocumented method |
2 |
57:25
|
Java Inspector 089 |
Undocumented exception Throwable |
2 |
134:17
|
Java Inspector 026 |
Avoid hardwired string literals. Allowed literals: [] |
3 |
58:81
|
1package biz.hammurapi.cache;
2
3import java.lang.ref.SoftReference;
4import java.lang.reflect.Method;
5import java.lang.reflect.Proxy;
6import java.util.ArrayList;
7import java.util.List;
8import java.util.Map;
9import java.util.concurrent.ConcurrentHashMap;
10
11import biz.hammurapi.convert.FilterInvocationHandler;
12import biz.hammurapi.wrap.WrapperHandler;
13
14
15
16
17
18
19
20public class SoftCachingProxyFactory {
21
22 private static final String GET = "get";
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 public static Object createCachingProxy(final Object master) {
40 if (master==null) {
41 return null;
42 }
43
44 Class[] interfaces = WrapperHandler.getClassInterfaces(master.getClass());
45 if (interfaces.length==0) {
46 return master;
47 }
48
49 final Map getMap = new ConcurrentHashMap();
50
51 FilterInvocationHandler ih = new FilterInvocationHandler() {
52
53 public Object getMaster() {
54 return master;
55 }
56
57 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
58 if (method.getDeclaringClass().getName().equals("java.lang.Object")) {
59 return method.invoke(master, args);
60 }
61
62 if (!method.getName().startsWith(GET) || void.class.equals(method.getReturnType())) {
63 getMap.clear();
64 return method.invoke(master, args);
65 }
66
67 List invocationKey = new ArrayList();
68 invocationKey.add(method.getDeclaringClass().getName());
69 invocationKey.add(method.getName());
70 Class[] pTypes = method.getParameterTypes();
71 for (int i=0; pTypes!=null && i<pTypes.length; ++i) {
72 invocationKey.add(pTypes[i].getName());
73 }
74 for (int i=0; args!=null && i<args.length; ++i) {
75 invocationKey.add(args[i]);
76 }
77
78 ReturnValueEntry rve = (ReturnValueEntry) getMap.get(invocationKey);
79 if (rve!=null) {
80 return rve.get();
81 }
82
83 rve = new ReturnValueEntry();
84 getMap.put(invocationKey, rve);
85
86 try {
87 Object ret = method.invoke(master, args);
88 rve.set(ret);
89 return ret;
90 } catch (Throwable th) {
91 rve.setProblem(th);
92 throw th;
93 }
94 }
95
96 };
97
98
99 return Proxy.newProxyInstance(master.getClass().getClassLoader(), interfaces, ih);
100 }
101
102 private static class ReturnValueEntry {
103
104 private boolean initialized;
105
106 private SoftReference ref;
107
108 private Throwable problem;
109
110
111
112
113
114 synchronized void set(Object obj) {
115 this.ref = new SoftReference(obj);
116 initialized = true;
117 notifyAll();
118 }
119
120
121
122
123
124 synchronized void setProblem(Throwable th) {
125 problem = th;
126 initialized = true;
127 notifyAll();
128 }
129
130
131
132
133
134 public synchronized Object get() throws Throwable {
135 if (!initialized) {
136 wait();
137 }
138
139 if (problem!=null) {
140 throw problem;
141 }
142
143 return ref==null ? null : ref.get();
144 }
145
146 }
147
148}
149