KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > sapia > soto > aop > Invoker


1 package org.sapia.soto.aop;
2
3 import org.sapia.soto.ConfigurationException;
4
5 import java.util.ArrayList JavaDoc;
6 import java.util.Iterator JavaDoc;
7 import java.util.List JavaDoc;
8
9
10 /**
11  * An instance of this class encapsulates the advices that are to be called
12  * in the context of a given method.
13  *
14  * @author Yanick Duchesne
15  * <dl>
16  * <dt><b>Copyright:</b><dd>Copyright &#169; 2002-2003 <a HREF="http://www.sapia-oss.org">Sapia Open Source Software</a>. All Rights Reserved.</dd></dt>
17  * <dt><b>License:</b><dd>Read the license.txt file of the jar or visit the
18  * <a HREF="http://www.sapia-oss.org/license.html">license page</a> at the Sapia OSS web site</dd></dt>
19  * </dl>
20  */

21 public class Invoker {
22   private List JavaDoc _around = new ArrayList JavaDoc();
23   private List JavaDoc _before = new ArrayList JavaDoc();
24   private List JavaDoc _after = new ArrayList JavaDoc();
25   private List JavaDoc _throws = new ArrayList JavaDoc();
26   private List JavaDoc _returns = new ArrayList JavaDoc();
27   private boolean _hasBefore;
28   private boolean _hasAfter;
29   private boolean _hasThrows;
30   private boolean _hasReturns;
31
32   /**
33    * Constructor for MethodInterceptor.
34    *
35    * @param advices a <code>List</code> of <code>Advice</code>
36    * instance.
37    */

38   public Invoker(List JavaDoc advices) throws ConfigurationException {
39     Advice adv;
40
41     for (int i = 0; i < advices.size(); i++) {
42       adv = (Advice) advices.get(i);
43
44       if (adv instanceof BeforeAdvice) {
45         _before.add(adv);
46       }
47
48       if (adv instanceof AfterAdvice) {
49         _after.add(adv);
50       }
51
52       if (adv instanceof ThrowsAdvice) {
53         _throws.add(adv);
54       }
55
56       if (adv instanceof ReturnAdvice) {
57         _returns.add(adv);
58       }
59     }
60
61     _hasBefore = _before.size() > 0;
62     _hasAfter = _after.size() > 0;
63     _hasThrows = _throws.size() > 0;
64     _hasReturns = _returns.size() > 0;
65   }
66
67   /**
68    * Dispatches a method call to the approriate advices that are
69    * kept within this instance.
70    *
71    * @param instance the object on which the method call is to occur.
72    * @param method the <code>Method</code> object representing the method
73    * to be called.
74    * @param the <code>MethodProxy</code> object with which the actual dynamic
75    * method invocation is to be performed.
76    */

77   public Object JavaDoc invoke(Invocation invocation, Iterator JavaDoc itr)
78     throws Throwable JavaDoc {
79     if (_hasBefore) {
80       for (int i = 0; (i < _before.size()) && !invocation.wasInvoked(); i++) {
81         ((BeforeAdvice) _before.get(i)).preInvoke(invocation);
82       }
83     }
84
85     if (_hasAfter) {
86       Object JavaDoc toReturn;
87
88       if (itr.hasNext()) {
89         toReturn = ((Invoker) itr.next()).invoke(invocation, itr);
90       } else {
91         if (_hasThrows) {
92           try {
93             if (invocation.wasInvoked()) {
94               toReturn = invocation.getReturnValue();
95             } else {
96               toReturn = invocation.invoke();
97             }
98           } catch (Throwable JavaDoc t) {
99             for (int i = 0; i < _throws.size(); i++) {
100               ((ThrowsAdvice) _throws.get(i)).onThrows(invocation, t);
101             }
102
103             throw t;
104           }
105         } else {
106           if (invocation.wasInvoked()) {
107             toReturn = invocation.getReturnValue();
108           } else {
109             toReturn = invocation.invoke();
110           }
111         }
112       }
113
114       if (_hasAfter) {
115         for (int i = 0; i < _after.size(); i++) {
116           ((AfterAdvice) _after.get(i)).postInvoke(invocation);
117         }
118       }
119
120       if (_hasReturns &&
121             !invocation.getMethod().getReturnType().equals(void.class)) {
122         for (int i = 0; i < _returns.size(); i++) {
123           invocation.setReturnValue(((ReturnAdvice) _returns.get(i)).onReturn(
124               invocation));
125         }
126       }
127
128       return toReturn;
129     } else {
130       if (itr.hasNext()) {
131         return ((Invoker) itr.next()).invoke(invocation, itr);
132       } else {
133         Object JavaDoc toReturn;
134
135         if (_hasThrows) {
136           try {
137             if (invocation.wasInvoked()) {
138               toReturn = invocation.getReturnValue();
139             } else {
140               toReturn = invocation.invoke();
141             }
142           } catch (Throwable JavaDoc t) {
143             for (int i = 0; i < _throws.size(); i++) {
144               ((ThrowsAdvice) _throws.get(i)).onThrows(invocation, t);
145             }
146
147             throw t;
148           }
149         } else {
150           if (invocation.wasInvoked()) {
151             toReturn = invocation.getReturnValue();
152           } else {
153             toReturn = invocation.invoke();
154           }
155         }
156
157         if (_hasReturns &&
158               !invocation.getMethod().getReturnType().equals(void.class)) {
159           for (int i = 0; i < _returns.size(); i++) {
160             toReturn = ((ReturnAdvice) _returns.get(i)).onReturn(invocation);
161           }
162         }
163
164         return toReturn;
165       }
166     }
167   }
168
169   /**
170    * Return true if this instance contains "before" advices.
171    *
172    * @return <code>true</code> if this instance contains <code>BeforeAdvice</code>s.
173    */

174   public boolean hasBefore() {
175     return _hasBefore;
176   }
177
178   /**
179    * Return true if this instance contains "after" advices.
180    *
181    * @return <code>true</code> if this instance contains <code>AfterAdvice</code>s.
182    */

183   public boolean hasAfter() {
184     return _hasAfter;
185   }
186 }
187
Popular Tags