1 package org.neo.swarm.core.aop.silc.comp;
2 import java.io.Externalizable;
3 import java.io.IOException;
4 import java.io.ObjectInput;
5 import java.io.ObjectOutput;
6 import java.lang.reflect.AccessibleObject;
7 import java.lang.reflect.InvocationTargetException;
8 import java.lang.reflect.Method;
9
10
11 /***
12 * Represents a particular invocation chain
13 * @author damiang
14 * @author navery
15 */
16 public class AspectInvocation extends AccessibleObject implements Externalizable, Invocation {
17 private static final long serialVersionUID = 1;
18 transient protected AccessibleObject staticPart;
19 private int current;
20 private Object key;
21
22 String methodName;
23 int methodIndex;
24 private MethodInterceptor[] interceptors;
25
26 private transient Object target;
27 String targetClassString;
28 private Object[] args;
29 transient private Method method;
30
31 public AspectInvocation() {};
32
33 public AspectInvocation(AccessibleObject staticPart, Object key, Object target, Method method, Object[] args, MethodInterceptor[] interceptors) {
34 this.key = key;
35 setMethod(method);
36 this.target = target;
37 this.targetClassString = target.getClass().getInterfaces()[0].getName();
38 this.args = args == null ? new Object[0] : args;
39 this.interceptors = interceptors;
40 this.staticPart = staticPart;
41 current = 0;
42 setAccessible(true);
43 }
44 public Object proceed() throws Throwable {
45 if (hasNext()) {
46 return next().invoke(this);
47 }
48 reset();
49 try {
50 return method.invoke(target, args);
51 } catch (InvocationTargetException ex) {
52 ex.printStackTrace();
53 System.out.println(ex + " exception on method:" + method.getName() + " args:" + args);
54 throw ex;
55 } catch (Exception ex) {
56 ex.printStackTrace();
57 System.out.println(ex + " exception on method:" + method.getName() + " args:" + args);
58 throw ex;
59 }
60 }
61 private void reset() {
62 current = 0;
63 }
64 private MethodInterceptor next() {
65 return interceptors[current++];
66 }
67 private boolean hasNext() {
68 return current < interceptors.length;
69 }
70 public Object[] getArguments() {
71 return this.args;
72 }
73 public void setArguments(Object[] args) {
74 this.args = args;
75 }
76 public Method getMethod() {
77 if (method == null) {
78 try {
79 method = Class.forName(targetClassString).getMethods()[methodIndex];
80 if (method.getParameterTypes().length != this.args.length) {
81 throw new Exception("Invalid number of arguments - failed to match method");
82 }
83 } catch (ClassNotFoundException e) {
84 System.err.println("Potentially invalid interface assignment! - Class not found:" + targetClassString + " Failed to locate method for index:"+ methodIndex);
85 e.printStackTrace();
86 } catch (NullPointerException ex) {
87 System.err.println("AspectInvocation unravelling failed - Null pointer thrown for Class:" + targetClassString + " methodIndex:"+ methodIndex);
88 } catch (Exception ex) {
89 ex.printStackTrace();
90 }
91 }
92 return this.method;
93 }
94 public void setMethod(Method method) {
95 this.method = method;
96 this.methodName = this.method.getName();
97 Method[] m = method.getDeclaringClass().getDeclaredMethods();
98 for (int i = 0; i < m.length; i++) {
99 if (method.equals(m[i])) {
100 this.methodIndex = i;
101 return;
102 }
103 }
104
105 throw new RuntimeException("Failed to match method index for method:"+method);
106 }
107 public Object getThis() {
108 return target;
109 }
110 public void setTarget(Object o) {
111 this.target = o;
112 }
113 /***
114 * @return Returns the key.
115 */
116 public Object getKey() {
117 return key;
118 }
119 /***
120 * Native Java Serialization through externalization
121 * (non-Javadoc)
122 *
123 * @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
124 */
125 public void writeExternal(ObjectOutput s) throws IOException {
126 s.writeInt(current);
127 s.writeObject(key);
128 s.writeUTF(targetClassString);
129 s.writeObject(args);
130 s.writeObject(interceptors);
131 s.writeInt(methodIndex);
132
133 }
134 /***
135 * Native Java Serialization through externalization
136 * (non-Javadoc)
137 *
138 * @see java.io.Externalizable#readExternal(java.io.ObjectInput)
139 */
140 public void readExternal(ObjectInput s) throws IOException, ClassNotFoundException {
141 current = s.readInt();
142 key = (String) s.readObject();
143 targetClassString = s.readUTF();
144 args = (Object[]) s.readObject();
145 interceptors = (MethodInterceptor[]) s.readObject();
146 this.methodIndex = s.readInt();
147
148 }
149 public String toString() {
150 return this.getMethod() + " args:" + this.getArguments();
151 }
152
153
154
155
156
157 public AccessibleObject getStaticPart() {
158 return this.staticPart;
159 }
160 }