View Javadoc

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 }