1 package org.neo.swarm.core.aop.silc.comp;
2
3 import java.io.Serializable;
4 import java.lang.reflect.AccessibleObject;
5 import java.lang.reflect.Method;
6 import java.util.Arrays;
7 import java.util.Collections;
8 import java.util.Iterator;
9 import java.util.List;
10 import java.util.ListIterator;
11 import java.util.Map;
12
13 import org.neo.swarm.core.aop.AspectComponent;
14
15
16 import net.sf.cglib.proxy.CallbackFilter;
17 import net.sf.cglib.proxy.Enhancer;
18 import net.sf.cglib.proxy.MethodProxy;
19
20 public class CGLibProxyFactory implements ProxyFactory {
21 public Object createProxy(Perspective perspective, Object key, Class[] interfaces, AspectComponent aspectedComponent) {
22 return null;
23 }
24
25 public Object createProxy(Object key, Class[] interfaces, AspectComponent aspectComponent, Map methodInterceptorMap) {
26 Enhancer e = new Enhancer();
27 e.setInterfaces(interfaces);
28 CustomCallback [] cb = createCallBacks(methodInterceptorMap, aspectComponent.getTarget());
29 e.setCallbacks(cb);
30 e.setCallbackFilter(createCallBackFilter(cb));
31 return e.create();
32 }
33
34 private CallbackFilter createCallBackFilter(CustomCallback [] callBacks) {
35 CallbackFilter filter = new CustomCallbackFilter(callBacks);
36 return filter;
37 }
38
39 private CustomCallback[] createCallBacks(Map methodInterceptorMap, Object target) {
40 int mapSize = methodInterceptorMap.size();
41 CustomCallback[] callBacks = new CustomCallback[mapSize+1];
42 List[] interceptors = new List[methodInterceptorMap.size()];
43 String[] methods = new String[methodInterceptorMap.size()];
44
45 int i = 0;
46 for (Iterator keys = methodInterceptorMap.keySet().iterator(); keys.hasNext(); i++) {
47 String key = (String) keys.next();
48 methods[i] = key;
49 interceptors[i] = (List) methodInterceptorMap.get(key);
50 }
51
52 int j;
53 for (j = 0; j < callBacks.length - 1; j++) {
54 callBacks[j] = new CustomCallback(methods[j], interceptors[j], target);
55 }
56 callBacks[j] = new OtherCustomCallback("hashCode", Collections.EMPTY_LIST, target);
57
58
59 return callBacks;
60
61 }
62
63 static class CustomCallbackFilter implements CallbackFilter {
64 private CustomCallback[] callBacks;
65
66 public CustomCallbackFilter(CustomCallback [] callBacks) {
67 this.callBacks = callBacks;
68 }
69
70 public int accept(Method method) {
71 for (int i = 0; i < callBacks.length; i++) {
72 CustomCallback callBack = callBacks[i];
73 if (callBack.isForMethod(method)) {
74 return i;
75 }
76 }
77 return 0;
78 }
79
80 public boolean equals(Object o) {
81 if (this == o) return true;
82 if (!(o instanceof CustomCallbackFilter)) return false;
83
84 final CustomCallbackFilter customCallbackFilter = (CustomCallbackFilter) o;
85
86 if (!Arrays.equals(callBacks, customCallbackFilter.callBacks)) return false;
87
88 return true;
89 }
90
91 public int hashCode() {
92 int hashCode = callBacks.hashCode();
93
94 for (int i = 0; i < callBacks.length; i++) {
95 CustomCallback callBack = callBacks[i];
96 hashCode = 29 * hashCode + callBack.hashCode();
97 }
98 return hashCode;
99 }
100
101 }
102
103 static class OtherCustomCallback extends CustomCallback {
104 Object mytarget;
105 public OtherCustomCallback(String method, List interceptors, Object target) {
106 super(method, interceptors, target);
107 this.mytarget = target;
108 }
109
110 public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
111 return methodProxy.invoke(mytarget, objects);
112 }
113
114 public boolean isForMethod(Method method) {
115 return true;
116 }
117 }
118
119 static class CustomCallback implements net.sf.cglib.proxy.MethodInterceptor {
120 private String method;
121 private List interceptors;
122 private Object target;
123
124
125 public CustomCallback(String method, List interceptors, Object target) {
126 this.method = method;
127 this.interceptors = interceptors;
128 this.target = target;
129 }
130
131 public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
132 Invocation invocation = new CGLibAspectInvocation("", methodProxy, objects, interceptors.listIterator(), target);
133 return invocation.proceed();
134 }
135
136 public boolean isForMethod(Method oMethod) {
137 return method.equals(oMethod.getDeclaringClass().getName() + "." + oMethod.getName());
138 }
139
140 public boolean equals(Object o) {
141 if (this == o) return true;
142 if (!(o instanceof CustomCallback)) return false;
143
144 final CustomCallback customCallback = (CustomCallback) o;
145
146 if (!interceptors.equals(customCallback.interceptors)) return false;
147 if (!method.equals(customCallback.method)) return false;
148 if (!target.equals(customCallback.target)) return false;
149
150 return true;
151 }
152
153 public int hashCode() {
154 int result;
155 result = method.hashCode();
156 result = 29 * result + interceptors.hashCode();
157 result = 29 * result + target.hashCode();
158 return result;
159 }
160
161 }
162
163 static class CGLibAspectInvocation implements Invocation, Serializable {
164 private Object key;
165 private MethodProxy method;
166 private Object[] args;
167 private ListIterator interceptors;
168 private Object target;
169
170 public CGLibAspectInvocation(Object key, MethodProxy method, Object[] args, ListIterator interceptors, Object target) {
171 this.key = key;
172 this.method = method;
173 this.args = args;
174 this.interceptors = interceptors;
175 this.target = target;
176 }
177
178 public Object proceed() throws Throwable {
179 if (interceptors.hasNext()) {
180 return ((MethodInterceptor) interceptors.next()).invoke(this);
181 }
182
183 return method.invoke(target, args);
184 }
185
186 public Object[] getArguments() {
187 return this.args;
188 }
189
190 public void setArguments(Object[] args) {
191 this.args = new Object[args.length];
192 System.arraycopy(args, 0, this.args, 0, args.length);
193 }
194
195 public Method getMethod() {
196 return null;
197 }
198
199 public void setMethod(Method method) {
200 }
201
202 public Object getThis() {
203 return target;
204 }
205
206 public void setTarget(Object o) {
207 this.target = o;
208 }
209
210 public AccessibleObject getStaticPart() {
211 return null;
212 }
213 public Object getKey() {
214 return key;
215 }
216 }
217 }