View Javadoc

1   /*************************************************
2    * Copyright (c) Shen Li. All rights reserved.  *
3    * http://joyaop.sourceforge.net                *
4    * -------------------------------------------- *
5    * Distributable under LGPL license.            *
6    * See terms of license at gnu.org.             *
7    ************************************************/
8   package net.sf.joyaop.impl;
9   
10  import net.sf.cglib.proxy.MethodProxy;
11  import net.sf.joyaop.AbstractInterceptor;
12  import net.sf.joyaop.AspectRuntimeException;
13  import org.aopalliance.intercept.MethodInvocation;
14  
15  import java.lang.reflect.AccessibleObject;
16  import java.lang.reflect.Method;
17  import java.util.List;
18  
19  /***
20   * @author Shen Li
21   */
22  public class InvocationImpl implements AbstractInterceptor, MethodInvocation {
23      // If always using per-method InvocationHandler,
24      // the Invocation could just contain 3 states: handler, arguments, currentInterceptorIndex
25  
26      // the target instance and interceptor instances are not in the same list
27      // because i want reuse the interceptor list when it contains no instance-scope interceptor
28  
29      private static final ThreadLocal invocationHolder = new ThreadLocal();
30      private static final short INITIAL_INDEX = -1;
31  
32      private Object[] arguments;
33      private short currentInterceptorIndex = INITIAL_INDEX;
34      private List interceptorAspectInstances;
35      private RuntimeInstance targetInstance;
36      private Method method;
37      private MethodProxy methodProxy;
38      private Object proxy;
39  
40      public static InvocationImpl getCurrentInvocation() {
41          return (InvocationImpl) invocationHolder.get();
42      }
43  
44      public static void setCurrentInvocation(InvocationImpl invocation) {
45          invocationHolder.set(invocation);
46      }
47  
48      public Object proceed() throws Throwable {
49          currentInterceptorIndex++;
50          try {
51              return getCurrentRuntimeInstance().invoke(this);
52          } finally {
53              currentInterceptorIndex--;
54          }
55      }
56  
57      public Object execute() throws Throwable {
58          throw new AspectRuntimeException(
59                  "Method execute() of interface "
60                  + AbstractInterceptor.class.getName()
61                  + " has not been implemented.");
62      }
63  
64      public boolean isDirty() {
65          return (currentInterceptorIndex != INITIAL_INDEX);
66      }
67  
68      private RuntimeInstance getCurrentRuntimeInstance() {
69  //        if (!isDirty()) {
70  //            throw new AspectRuntimeException("The invocation has not been used.");
71  //        }
72          if (currentInterceptorIndex < interceptorAspectInstances.size()) {
73              return (RuntimeInstance) interceptorAspectInstances.get(currentInterceptorIndex);
74          }
75          return targetInstance;
76      }
77  
78      public Object getParameter(String name) {
79          return getCurrentRuntimeInstance().getParameter(name);
80      }
81  
82      public boolean isOnInterceptor() {
83          return (currentInterceptorIndex < interceptorAspectInstances.size());
84      }
85  
86      public boolean allowRecursion() {
87          return getCurrentRuntimeInstance().allowRecursiveInvocation();
88      }
89  
90      public Object[] getArguments() {
91          return arguments;
92      }
93  
94      public short getCurrentInterceptorIndex() {
95          return currentInterceptorIndex;
96      }
97  
98      public List getInterceptorAspectInstances() {
99          return interceptorAspectInstances;
100     }
101 
102     public RuntimeInstance getTargetInstance() {
103         return targetInstance;
104     }
105 
106     public Method getMethod() {
107         return method;
108     }
109 
110     public MethodProxy getMethodProxy() {
111         return methodProxy;
112     }
113 
114     public Object getProxy() {
115         return proxy;
116     }
117 
118     public Object getThis() {
119         return getProxy();
120     }
121 
122     public AccessibleObject getStaticPart() {
123         return getMethod();
124     }
125 
126     public void setArguments(Object[] arguments) {
127         this.arguments = arguments;
128     }
129 
130     public void setCurrentInterceptorIndex(short currentInterceptorIndex) {
131         this.currentInterceptorIndex = currentInterceptorIndex;
132     }
133 
134     public void resetCurrentInterceptorIndex() {
135         this.currentInterceptorIndex = INITIAL_INDEX;
136     }
137 
138     public void setInterceptorAspectInstances(List interceptorAspectInstances) {
139         this.interceptorAspectInstances = interceptorAspectInstances;
140     }
141 
142     public void setTargetInstance(RuntimeInstance targetInstance) {
143         this.targetInstance = targetInstance;
144     }
145 
146     public void setMethod(Method method) {
147         this.method = method;
148     }
149 
150     public void setMethodProxy(MethodProxy methodProxy) {
151         this.methodProxy = methodProxy;
152     }
153 
154     public void setProxy(Object proxy) {
155         this.proxy = proxy;
156     }
157 }
158