1 |
| |
2 |
| |
3 |
| |
4 |
| |
5 |
| |
6 |
| |
7 |
| package org.jboss.cache.pojo.collection; |
8 |
| |
9 |
| import java.lang.reflect.InvocationTargetException; |
10 |
| import java.lang.reflect.Method; |
11 |
| import java.util.HashMap; |
12 |
| import java.util.List; |
13 |
| import java.util.Map; |
14 |
| import java.util.Set; |
15 |
| |
16 |
| import org.apache.commons.logging.Log; |
17 |
| import org.apache.commons.logging.LogFactory; |
18 |
| import org.jboss.aop.AspectManager; |
19 |
| import org.jboss.aop.InstanceAdvisor; |
20 |
| import org.jboss.aop.advice.AdviceBinding; |
21 |
| import org.jboss.aop.joinpoint.Invocation; |
22 |
| import org.jboss.aop.joinpoint.MethodInvocation; |
23 |
| import org.jboss.aop.pointcut.ast.ParseException; |
24 |
| import org.jboss.aop.proxy.ClassProxy; |
25 |
| import org.jboss.aop.proxy.ClassProxyFactory; |
26 |
| import org.jboss.aop.util.MethodHashing; |
27 |
| import org.jboss.cache.Fqn; |
28 |
| import org.jboss.cache.pojo.PojoCacheException; |
29 |
| import org.jboss.cache.pojo.impl.PojoCacheImpl; |
30 |
| import org.jboss.cache.pojo.interceptors.dynamic.AbstractCollectionInterceptor; |
31 |
| import org.jboss.cache.pojo.interceptors.dynamic.CachedListInterceptor; |
32 |
| import org.jboss.cache.pojo.interceptors.dynamic.CachedMapInterceptor; |
33 |
| import org.jboss.cache.pojo.interceptors.dynamic.CachedSetInterceptor; |
34 |
| import org.jboss.cache.pojo.util.AopUtil; |
35 |
| |
36 |
| |
37 |
| |
38 |
| |
39 |
| |
40 |
| |
41 |
| |
42 |
| |
43 |
| public class CollectionInterceptorUtil |
44 |
| { |
45 |
| private static Log log = LogFactory.getLog(CollectionInterceptorUtil.class.getName()); |
46 |
| |
47 |
1748
| private static ClassProxy createProxy(Class clazz, AbstractCollectionInterceptor interceptor)
|
48 |
| throws Exception |
49 |
| { |
50 |
1748
| ClassProxy result = ClassProxyFactory.newInstance(clazz);
|
51 |
1748
| InstanceAdvisor advisor = result._getInstanceAdvisor();
|
52 |
1748
| advisor.appendInterceptor(interceptor);
|
53 |
| |
54 |
| |
55 |
1748
| try
|
56 |
| { |
57 |
1748
| String bindName = clazz.getName() + ".toString";
|
58 |
1748
| HashMap<String, AdviceBinding> bindings = AspectManager.instance().getBindings();
|
59 |
1748
| if (bindings.get(bindName) == null)
|
60 |
| { |
61 |
74
| String bind = null;
|
62 |
74
| if (interceptor instanceof CachedListInterceptor)
|
63 |
| { |
64 |
44
| bind = "execution(public String " + CachedListAbstract.class.getName() + "->toString())";
|
65 |
30
| } else if (interceptor instanceof CachedSetInterceptor)
|
66 |
| { |
67 |
12
| bind = "execution(public String " + CachedSetImpl.class.getName() + "->toString())";
|
68 |
18
| } else if (interceptor instanceof CachedMapInterceptor)
|
69 |
| { |
70 |
18
| bind = "execution(public String " + CachedMapImpl.class.getName() + "->toString())";
|
71 |
| } else |
72 |
| { |
73 |
0
| throw new IllegalStateException("CollectionInterceptorUtil.createProxy(). Non Collection interceptor"
|
74 |
| + interceptor); |
75 |
| } |
76 |
| |
77 |
74
| AdviceBinding bindingm = new AdviceBinding(bindName, bind, null);
|
78 |
74
| AspectManager.instance().addBinding(bindingm);
|
79 |
| } |
80 |
| } |
81 |
| catch (ParseException e) |
82 |
| { |
83 |
0
| throw new PojoCacheException("PojoUtil._attachInterceptor(): can't parse the field binding: "
|
84 |
| + e); |
85 |
| } |
86 |
| |
87 |
1748
| return result;
|
88 |
| } |
89 |
| |
90 |
110
| public static ClassProxy createMapProxy(PojoCacheImpl cache, Fqn fqn, Class clazz, Map obj) throws Exception
|
91 |
| { |
92 |
110
| return CollectionInterceptorUtil.createProxy(clazz, new CachedMapInterceptor(cache, fqn, clazz, obj));
|
93 |
| } |
94 |
| |
95 |
1572
| public static ClassProxy createListProxy(PojoCacheImpl cache, Fqn fqn, Class clazz, List obj) throws Exception
|
96 |
| { |
97 |
1572
| return CollectionInterceptorUtil.createProxy(clazz, new CachedListInterceptor(cache, fqn, clazz, obj));
|
98 |
| } |
99 |
| |
100 |
66
| public static ClassProxy createSetProxy(PojoCacheImpl cache, Fqn fqn, Class clazz, Set obj) throws Exception
|
101 |
| { |
102 |
66
| return CollectionInterceptorUtil.createProxy(clazz, new CachedSetInterceptor(cache, fqn, clazz, obj));
|
103 |
| } |
104 |
| |
105 |
3066
| public static AbstractCollectionInterceptor getInterceptor(ClassProxy proxy)
|
106 |
| { |
107 |
3066
| InstanceAdvisor advisor = proxy._getInstanceAdvisor();
|
108 |
3066
| return (AbstractCollectionInterceptor) AopUtil.findCollectionInterceptor(advisor);
|
109 |
| } |
110 |
| |
111 |
1748
| public static Map getMethodMap(Class clazz)
|
112 |
| { |
113 |
1748
| Map result = ClassProxyFactory.getMethodMap(clazz.getName());
|
114 |
1748
| if (result == null)
|
115 |
| { |
116 |
73
| try
|
117 |
| { |
118 |
73
| ClassProxyFactory.newInstance(clazz);
|
119 |
| } |
120 |
| catch (Exception e) |
121 |
| { |
122 |
0
| throw new PojoCacheException(e);
|
123 |
| } |
124 |
73
| result = ClassProxyFactory.getMethodMap(clazz.getName());
|
125 |
| } |
126 |
1748
| return result;
|
127 |
| } |
128 |
| |
129 |
73
| public static Map getManagedMethods(Class clazz)
|
130 |
| { |
131 |
73
| Method tostring = null;
|
132 |
73
| try
|
133 |
| { |
134 |
73
| tostring = Object.class.getDeclaredMethod("toString", new Class[0]);
|
135 |
| } |
136 |
| catch (NoSuchMethodException e) |
137 |
| { |
138 |
0
| throw new PojoCacheException(e);
|
139 |
| } |
140 |
| |
141 |
73
| Map managedMethods = new HashMap();
|
142 |
73
| try
|
143 |
| { |
144 |
73
| Method[] methods = clazz.getDeclaredMethods();
|
145 |
73
| for (int i = 0; i < methods.length; i++)
|
146 |
| { |
147 |
1507
| long hash = MethodHashing.methodHash(methods[i]);
|
148 |
1507
| managedMethods.put(hash, methods[i]);
|
149 |
| } |
150 |
| |
151 |
73
| long hash = MethodHashing.methodHash(tostring);
|
152 |
73
| managedMethods.put(hash, tostring);
|
153 |
| } |
154 |
| catch (Exception ignored) |
155 |
| { |
156 |
0
| log.trace(ignored, ignored);
|
157 |
| } |
158 |
73
| return managedMethods;
|
159 |
| } |
160 |
| |
161 |
5154
| private static boolean skipVerify(Method method)
|
162 |
| { |
163 |
5154
| String name = method.getName();
|
164 |
5154
| Class<?>[] types = method.getParameterTypes();
|
165 |
5154
| if ("toString".equals(name) && types.length == 0)
|
166 |
38
| return true;
|
167 |
| |
168 |
5116
| return false;
|
169 |
| } |
170 |
| |
171 |
5154
| public static Object invoke(Invocation invocation,
|
172 |
| AbstractCollectionInterceptor interceptor, |
173 |
| Object impl, |
174 |
| Map methodMap, Map managedMethods) |
175 |
| throws Throwable |
176 |
| { |
177 |
| |
178 |
5154
| try
|
179 |
| { |
180 |
5154
| if (invocation instanceof MethodInvocation)
|
181 |
| { |
182 |
5154
| MethodInvocation methodInvocation = (MethodInvocation) invocation;
|
183 |
5154
| Long methodHash = methodInvocation.getMethodHash();
|
184 |
5154
| Method method = (Method) managedMethods.get(methodHash);
|
185 |
5154
| if (log.isTraceEnabled() && method != null)
|
186 |
| { |
187 |
0
| log.trace("invoke(): method intercepted " + method.getName());
|
188 |
| } |
189 |
5154
| Object[] args = methodInvocation.getArguments();
|
190 |
5154
| if (method != null)
|
191 |
| { |
192 |
5154
| if (!skipVerify(method))
|
193 |
5116
| interceptor.verifyAttached(impl);
|
194 |
| |
195 |
5153
| return method.invoke(impl, args);
|
196 |
| } else |
197 |
| { |
198 |
0
| method = methodInvocation.getMethod();
|
199 |
0
| if (method == null)
|
200 |
| { |
201 |
0
| method = (Method) methodMap.get(methodHash);
|
202 |
| } |
203 |
| |
204 |
0
| if (log.isTraceEnabled())
|
205 |
0
| log.trace("invoke(): non-managed method: " + method.toString());
|
206 |
0
| Object target = methodInvocation.getTargetObject();
|
207 |
0
| if (target == null)
|
208 |
| { |
209 |
0
| throw new PojoCacheException("CollectionInterceptorUtil.invoke(): targetObject is null." +
|
210 |
| " Can't invoke " + method.toString()); |
211 |
| } |
212 |
0
| return method.invoke(target, args);
|
213 |
| |
214 |
| } |
215 |
| } |
216 |
| } |
217 |
| catch (InvocationTargetException e) |
218 |
| { |
219 |
2
| if (e.getCause() != null)
|
220 |
2
| throw e.getCause();
|
221 |
0
| else if (e.getTargetException() != null)
|
222 |
0
| throw e.getTargetException();
|
223 |
0
| throw e;
|
224 |
| } |
225 |
| |
226 |
0
| return invocation.invokeNext();
|
227 |
| } |
228 |
| |
229 |
| } |