1 |
| package org.jboss.cache.pojo.impl; |
2 |
| |
3 |
| import org.jboss.aop.Advisor; |
4 |
| import org.jboss.aop.joinpoint.FieldInvocation; |
5 |
| import org.jboss.cache.pojo.interceptors.PojoBeginInterceptor; |
6 |
| import org.jboss.cache.pojo.memory.FieldPersistentReference; |
7 |
| import org.jboss.cache.pojo.memory.PersistentReference; |
8 |
| |
9 |
| import java.lang.ref.WeakReference; |
10 |
| import java.lang.reflect.Field; |
11 |
| import java.lang.reflect.Method; |
12 |
| import java.lang.reflect.Modifier; |
13 |
| import java.util.ArrayList; |
14 |
| import java.util.Arrays; |
15 |
| import java.util.HashMap; |
16 |
| import java.util.HashSet; |
17 |
| import java.util.Iterator; |
18 |
| import java.util.List; |
19 |
| import java.util.Map; |
20 |
| import java.util.Set; |
21 |
| import java.util.WeakHashMap; |
22 |
| |
23 |
| |
24 |
| |
25 |
| |
26 |
| |
27 |
| |
28 |
| |
29 |
| |
30 |
| |
31 |
| public class CachedType |
32 |
| { |
33 |
| |
34 |
| private static final Set immediates = |
35 |
| new HashSet(Arrays.asList(new Object[]{ |
36 |
| String.class, |
37 |
| Boolean.class, |
38 |
| Double.class, |
39 |
| Float.class, |
40 |
| Integer.class, |
41 |
| Long.class, |
42 |
| Short.class, |
43 |
| Character.class, |
44 |
| Byte.class, |
45 |
| Boolean.TYPE, |
46 |
| Double.TYPE, |
47 |
| Float.TYPE, |
48 |
| Integer.TYPE, |
49 |
| Long.TYPE, |
50 |
| Short.TYPE, |
51 |
| Character.TYPE, |
52 |
| Byte.TYPE, |
53 |
| Class.class})); |
54 |
| |
55 |
| private WeakReference<Class> type; |
56 |
| private boolean immutable; |
57 |
| private boolean immediate; |
58 |
| |
59 |
| private static Map CachedClassWithNoAnnotation_ = new WeakHashMap(); |
60 |
| private static Map CachedClassWithAnnotation_ = new WeakHashMap(); |
61 |
| |
62 |
| |
63 |
| private List fields = new ArrayList(); |
64 |
| private Map fieldMap = new HashMap(); |
65 |
| |
66 |
0
| public CachedType()
|
67 |
| { |
68 |
| } |
69 |
| |
70 |
2012
| public CachedType(Class type)
|
71 |
| { |
72 |
2012
| this.type = new WeakReference<Class>(type);
|
73 |
2012
| analyze();
|
74 |
| } |
75 |
| |
76 |
15596
| public Class getType()
|
77 |
| { |
78 |
15596
| return type.get();
|
79 |
| } |
80 |
| |
81 |
| |
82 |
24807
| public boolean isImmediate()
|
83 |
| { |
84 |
24807
| return immediate;
|
85 |
| } |
86 |
| |
87 |
2012
| private static boolean isImmediate(Class clazz)
|
88 |
| { |
89 |
2012
| return immediates.contains(clazz);
|
90 |
| } |
91 |
| |
92 |
0
| public boolean isImmutable()
|
93 |
| { |
94 |
0
| return immutable;
|
95 |
| } |
96 |
| |
97 |
4266
| public List getFields()
|
98 |
| { |
99 |
4266
| return fields;
|
100 |
| } |
101 |
| |
102 |
0
| public Field getField(String name)
|
103 |
| { |
104 |
0
| FieldPersistentReference ref = (FieldPersistentReference) fieldMap.get(name);
|
105 |
0
| if (ref == null) return null;
|
106 |
0
| return (Field) ref.get();
|
107 |
| } |
108 |
| |
109 |
| |
110 |
| |
111 |
| |
112 |
| |
113 |
| |
114 |
| |
115 |
| |
116 |
| |
117 |
| |
118 |
| |
119 |
| |
120 |
| |
121 |
| |
122 |
| |
123 |
| |
124 |
| |
125 |
| |
126 |
| |
127 |
| |
128 |
| |
129 |
| |
130 |
| |
131 |
| |
132 |
| |
133 |
| |
134 |
| |
135 |
| |
136 |
| |
137 |
| |
138 |
| |
139 |
| |
140 |
| |
141 |
| |
142 |
0
| public String toString()
|
143 |
| { |
144 |
0
| StringBuffer sb = new StringBuffer();
|
145 |
0
| sb.append(getType().getName()).append(" {\n");
|
146 |
| |
147 |
| |
148 |
| |
149 |
| |
150 |
| |
151 |
| |
152 |
| |
153 |
| |
154 |
| |
155 |
| |
156 |
| |
157 |
| |
158 |
| |
159 |
| |
160 |
| |
161 |
| |
162 |
| |
163 |
| |
164 |
| |
165 |
0
| sb.append("}, immutable =").append(immutable);
|
166 |
0
| return sb.toString();
|
167 |
| } |
168 |
| |
169 |
| |
170 |
| |
171 |
2012
| private void analyze()
|
172 |
| { |
173 |
| |
174 |
| |
175 |
| |
176 |
| |
177 |
| |
178 |
| |
179 |
| |
180 |
| |
181 |
| |
182 |
| |
183 |
| |
184 |
| |
185 |
| |
186 |
| |
187 |
| |
188 |
| |
189 |
| |
190 |
| |
191 |
| |
192 |
| |
193 |
| |
194 |
| |
195 |
2012
| analyzeFields(getType());
|
196 |
| |
197 |
2012
| immediate = isImmediate(getType());
|
198 |
| |
199 |
| } |
200 |
| |
201 |
5761
| private void analyzeFields(Class clazz)
|
202 |
| { |
203 |
5761
| if (clazz == null)
|
204 |
| { |
205 |
2012
| return;
|
206 |
| } |
207 |
| |
208 |
3749
| analyzeFields(clazz.getSuperclass());
|
209 |
| |
210 |
3749
| Field[] classFields = clazz.getDeclaredFields();
|
211 |
3749
| for (int i = 0; i < classFields.length; i++)
|
212 |
| { |
213 |
14519
| Field f = classFields[i];
|
214 |
10166
| if (isPrimitiveNonReplicatable(f)) continue;
|
215 |
| |
216 |
4353
| f.setAccessible(true);
|
217 |
| |
218 |
4353
| FieldPersistentReference persistentRef = new FieldPersistentReference(f, PersistentReference.REFERENCE_SOFT);
|
219 |
| |
220 |
4353
| fields.add(persistentRef);
|
221 |
4353
| fieldMap.put(f.getName(), persistentRef);
|
222 |
| } |
223 |
| } |
224 |
| |
225 |
| |
226 |
| |
227 |
| |
228 |
| |
229 |
5935
| public static boolean hasAnnotation(Class clazz, Advisor advisor, CachedType type)
|
230 |
| { |
231 |
| |
232 |
5935
| if (CachedClassWithNoAnnotation_.get(clazz) != null)
|
233 |
| { |
234 |
5818
| return false;
|
235 |
| } |
236 |
117
| else if (CachedClassWithAnnotation_.get(clazz) != null)
|
237 |
| { |
238 |
15
| return true;
|
239 |
| } |
240 |
| |
241 |
102
| for (Iterator i = type.getFields().iterator(); i.hasNext();)
|
242 |
| { |
243 |
521
| Field field = (Field) (((FieldPersistentReference) i.next())).get();
|
244 |
| |
245 |
521
| if (CachedType.hasFieldAnnotation(field, advisor))
|
246 |
| { |
247 |
1
| synchronized (CachedClassWithAnnotation_)
|
248 |
| { |
249 |
1
| CachedClassWithAnnotation_.put(clazz, clazz.getName());
|
250 |
| } |
251 |
1
| return true;
|
252 |
| } |
253 |
| } |
254 |
| |
255 |
| |
256 |
| |
257 |
101
| synchronized (CachedClassWithNoAnnotation_)
|
258 |
| { |
259 |
101
| CachedClassWithNoAnnotation_.put(clazz, clazz.getName());
|
260 |
| } |
261 |
101
| return false;
|
262 |
| } |
263 |
| |
264 |
29050
| public static boolean isPrimitiveNonReplicatable(Field f)
|
265 |
| { |
266 |
29050
| int mods = f.getModifiers();
|
267 |
| |
268 |
| |
269 |
| |
270 |
| |
271 |
29050
| if (Modifier.isStatic(mods)
|
272 |
| || Modifier.isTransient(mods)) |
273 |
| { |
274 |
10190
| return true;
|
275 |
| } |
276 |
| |
277 |
18860
| if (!PojoBeginInterceptor.getReplicateFinalField() && Modifier.isFinal(mods))
|
278 |
| { |
279 |
17
| return true;
|
280 |
| } |
281 |
| |
282 |
18843
| return false;
|
283 |
| } |
284 |
| |
285 |
| |
286 |
| |
287 |
| |
288 |
| |
289 |
| |
290 |
| |
291 |
| |
292 |
0
| private static boolean hasTransientAnnotation(FieldInvocation invocation)
|
293 |
| { |
294 |
0
| Object obj = invocation.resolveAnnotation(org.jboss.cache.pojo.annotation.Transient.class);
|
295 |
0
| if (obj != null)
|
296 |
| { |
297 |
0
| return true;
|
298 |
| } |
299 |
0
| return false;
|
300 |
| } |
301 |
| |
302 |
521
| private static boolean hasFieldAnnotation(Field field, Advisor advisor)
|
303 |
| { |
304 |
521
| return hasTransientAnnotation(field, advisor) || hasSerializableAnnotation(field, advisor);
|
305 |
| } |
306 |
| |
307 |
537
| public static boolean hasTransientAnnotation(Field field, Advisor advisor)
|
308 |
| { |
309 |
537
| Object obj = advisor.resolveAnnotation(field, org.jboss.cache.pojo.annotation.Transient.class);
|
310 |
537
| if (obj != null)
|
311 |
| { |
312 |
5
| return true;
|
313 |
| } |
314 |
532
| return false;
|
315 |
| } |
316 |
| |
317 |
526
| public static boolean hasSerializableAnnotation(Field field, Advisor advisor)
|
318 |
| { |
319 |
526
| Object obj = advisor.resolveAnnotation(field, org.jboss.cache.pojo.annotation.Serializable.class);
|
320 |
526
| if (obj != null)
|
321 |
| { |
322 |
6
| return true;
|
323 |
| } |
324 |
520
| return false;
|
325 |
| } |
326 |
| |
327 |
0
| public static boolean hasSerializableAnnotation(FieldInvocation invocation)
|
328 |
| { |
329 |
0
| Object obj = invocation.resolveAnnotation(org.jboss.cache.pojo.annotation.Serializable.class);
|
330 |
0
| if (obj != null)
|
331 |
| { |
332 |
0
| return true;
|
333 |
| } |
334 |
0
| return false;
|
335 |
| } |
336 |
| |
337 |
| |
338 |
| |
339 |
| |
340 |
0
| protected static String attributeName(String methodName)
|
341 |
| { |
342 |
0
| return methodName.substring(3, 4).toLowerCase()
|
343 |
| + methodName.substring(4); |
344 |
| } |
345 |
| |
346 |
0
| protected static boolean isGet(Method method)
|
347 |
| { |
348 |
0
| return method.getName().startsWith("get")
|
349 |
| && method.getParameterTypes().length == 0 |
350 |
| && method.getReturnType() != Void.TYPE; |
351 |
| } |
352 |
| |
353 |
0
| protected static boolean isSet(Method method)
|
354 |
| { |
355 |
0
| return method.getName().startsWith("set")
|
356 |
| && method.getParameterTypes().length == 1 |
357 |
| && method.getReturnType() == Void.TYPE; |
358 |
| } |
359 |
| |
360 |
| } |