KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jac > core > Wrapper


1 /*
2   Copyright (C) 2001-2002 Renaud Pawlak <renaud@aopsys.com>
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU Lesser General Public License as
6   published by the Free Software Foundation; either version 2 of the
7   License, or (at your option) any later version.
8
9   This program is distributed in the hope that it will be useful, but
10   WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12   Lesser General Public License for more details.
13
14   You should have received a copy of the GNU Lesser General Public
15   License along with this program; if not, write to the Free Software
16   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17   USA */

18
19 package org.objectweb.jac.core;
20
21
22 import java.io.Serializable JavaDoc;
23 import java.lang.reflect.Method JavaDoc;
24 import java.util.Vector JavaDoc;
25 import org.aopalliance.intercept.ConstructorInterceptor;
26 import org.aopalliance.intercept.ConstructorInvocation;
27 import org.aopalliance.intercept.Invocation;
28 import org.aopalliance.intercept.MethodInterceptor;
29 import org.aopalliance.intercept.MethodInvocation;
30 import org.objectweb.jac.core.rtti.ClassRepository;
31
32 /**
33  * This class is the root class for all the wrappers. A wrapper is
34  * part of a collaboration point when one or several of its methods
35  * wrap a base program object (a wrappee). The set of wrappers
36  * (methods) that wrap a wrappee (method) it called a wrapping
37  * (method) chain.
38  *
39  * <p>When a method call occurs on a wrappee, the system creates a new
40  * collaboration point in the current collaboration and all the
41  * wrappers are sequentially called.
42  *
43  * <p>A given wrapper passes the hand to the next wrapper (or to the
44  * wrappee if last) by explicitly calling the <code>proceed()</code>
45  * method.
46  *
47  * <p>For futher details about wrapping semantics, see the
48  * <code>Wrapper.proceed()</code> method and the
49  * <code>Wrappee.wrap()</code> methods.
50  *
51  * @author <a HREF="http://cedric.cnam.fr/~pawlak/index-english.html">Renaud Pawlak</a> */

52
53 public abstract class Wrapper
54     implements Serializable JavaDoc, MethodInterceptor, ConstructorInterceptor
55 {
56
57     protected static final ClassRepository cr = ClassRepository.get();
58
59     /**
60      * The constructor sets the aspect component that owns the wrapper
61      * from the context. */

62
63     public Wrapper(AspectComponent ac) {
64         // this.ac = ACManager.get().getName(ac);
65
this.ac = ac;
66         if (ac != null) {
67             //Log.trace("wrapper","new wrapper for "+ac);
68
ac.addWrapper(this);
69             //Log.trace("wrapper","wrappers= "+ac.getWrappers());
70
}
71     }
72
73     /** The AC of the wrapper. */
74     // protected transient String acName;
75
protected final transient AspectComponent ac;
76
77     /**
78      * Returns true if the method is defined in the wrapper class.
79      *
80      * @param methodName the method to test
81      * @return true if wrapper method
82      */

83
84     public static boolean defines(String JavaDoc methodName) {
85         if (ClassRepository.getDirectMethodAccess(Wrapper.class, methodName)[0]
86             != null)
87             return true;
88         return false;
89     }
90
91     /**
92      * Returns the exception handlers of the given wrapper class. Are
93      * considered as exception handlers all methods whose first
94      * argument is an Exception.
95      *
96      * @param wrapperClass the wrapper class
97      * @return a vector containing the methods names */

98
99     public static Vector JavaDoc getExceptionHandlers(Class JavaDoc wrapperClass) {
100         Method JavaDoc[] methods = wrapperClass.getMethods();
101         Vector JavaDoc ret = new Vector JavaDoc();
102         for (int i = 0; i < methods.length; i++) {
103             Class JavaDoc[] pts = methods[i].getParameterTypes();
104             if (pts.length > 0) {
105                 Class JavaDoc cl = pts[0];
106                 boolean ok = false;
107                 if (cl != null) {
108                     while (cl != null
109                         && (!cl.isPrimitive())
110                         && cl != Object JavaDoc.class) {
111                         if (cl == Exception JavaDoc.class) {
112                             ok = true;
113                         }
114                         cl = cl.getSuperclass();
115                     }
116                 }
117                 if (ok) {
118                     ret.add(methods[i].getName());
119                 }
120             }
121         }
122         return ret;
123     }
124
125     /**
126      * Returns the Aspect Component the wrapper belongs to by resolving
127      * the name.
128      *
129      * @see #getAspectComponentName() */

130
131     public AspectComponent getAspectComponent() {
132         return ac;
133         /*
134         if (ac==null) return null;
135         return (AspectComponent)ACManager.get().getObject(ac);
136         */

137     }
138
139     /**
140      * Returns the Aspect Component name the wrapper belongs to. By
141      * default, this name is set by the system when an aspect component
142      * wraps a given wrappee.
143      *
144      * @see Wrappee */

145
146     public String JavaDoc getAspectComponentName() {
147         return ACManager.get().getName(ac);
148     }
149
150     /**
151      * Set the aspect component name that owns the wrapper. The name of
152      * the aspect component is the one registered in
153      * <code>ACManager</code> (see <code>ACManager.get()</code>). This
154      * method should not be called directly since the aspect component
155      * is automatically set by the system when the wrap method is
156      * called on a wrappee.
157      *
158      * @param ac the name of the aspect component
159      * @see Wrappee
160      */

161     /*
162     public void setAspectComponent(AspectComponent ac) {
163         this.ac = ac;
164     }
165     */

166     /**
167      * String representation of a wrapper (eg <code>{wrapper
168      * className owned by aspectComponentName}</code>). */

169
170     public String JavaDoc toString() {
171         if (ac == null) {
172             return super.toString() + "(nobody)";
173         }
174         return super.toString() + "(" + getAspectComponentName() + ")";
175     }
176
177     /**
178      * Run the next wrapper of the collaboration point.
179      *
180      * <p>A new collaboration point is initiated by the system when a
181      * method call occurs on a base program object (a wrappee). If the
182      * called method is wrapped by one or several wrapping methods
183      * (wrappers methods - see <code>Wrappee.wrap()</code>), then the
184      * system first upcalls all the wrapping methods.
185      *
186      * <p>A wrapping method is a regular Java method that takes no
187      * argument and returns an object. It can access the currently
188      * called method runtime caracteristics by using the
189      * <code>CollaborationParticipant</code> interface methods
190      * implemented by the wrapper (see <code>method()</code> or
191      * <code>args</code>).
192      *
193      * <p>The set of wrapping methods that wraps a wrappee method is
194      * called a wrapping method chain. The wrapping methods of a
195      * wrapping chain are sequentially called. A given wrapping method
196      * of the wrapping chain passes the hand to the next wrapping
197      * method of this chain by calling <code>proceed()</code>.
198      *
199      * <p>A wrapper should ALWAYS call the proceed method except if it
200      * delibaratly wants to replace all the upcoming wrappers and base
201      * method functionalities (e.g. the
202      * <code>org.objectweb.jac.aspects.binding.ForwardingWrapper</code>).
203      *
204      * <p>The wrapping methods are called in a well-defined order. A
205      * wrapper cannot change this order by himself since it is the
206      * composition aspect that is responsible for setting this order
207      * (see <code>Wrappee.wrap()</code> and
208      * <code>CompositionAspect.getWeaveTimeRank()</code>).
209      *
210      * <p>Within a clean aspect-oriented design, the wrapper can be
211      * shortcutted by its aspect component if needed (see
212      * <code>AspectComponent.beforeRunningWrapper()</code>).
213      *
214      * <p>In a wrapping method, proceed returns the value returned by
215      * the wrappee method. A wrapper can modify this return value if
216      * needed. The wrapping method code that is placed before the
217      * <code>proceed()</code> call is called <i>before</i> code (since
218      * it is executed before the wrapped method execution), and the
219      * code that is placed after the proceed call is called
220      * <i>after</i> code (since it is executed after).
221      *
222      * <p>A typical wrapping method looks like the following:
223      *
224      * <ul><pre>
225      * public class MyWrapper extends Wrapper {
226      * public MyWrapper(AspectComponent ac) { super(ac); }
227      * public Object invoke(MethodInvocation mi) {
228      * // before code (can access the called method infos)
229      * ...
230      * Object result = proceed(mi);
231      * // after code (can modify the returned value)
232      * ...
233      * // must return a value (most of the time the proceed() value)
234      * return result;
235      * }
236      * public Object construct(ConstructorInvocation ci) {
237      * return proceed(ci);
238      * }
239      * }
240      * </pre></ul>
241      *
242      * @return the final value returned by the current method call
243      * @see Wrapping#wrap(Wrappee,Wrapper,AbstractMethodItem)
244      * @see CollaborationParticipant
245      * @see CompositionAspect#getWeaveTimeRank(WrappingChain,Wrapper)
246      * @see AspectComponent#beforeRunningWrapper(Wrapper,String)
247      */

248     public final Object JavaDoc proceed(Invocation invocation) {
249         // The AOP Alliance Invocation interface is implemented by the Interaction class
250
Interaction interaction = (Interaction) invocation;
251         interaction.rank += 1;
252         return Wrapping.nextWrapper(interaction);
253     }
254
255     // following methods implement the CollaborationParticipant interface
256

257     public final void attrdef(String JavaDoc name, Object JavaDoc value) {
258         Collaboration.get().addAttribute(name, value);
259     }
260
261     public final Object JavaDoc attr(String JavaDoc name) {
262         return Collaboration.get().getAttribute(name);
263     }
264
265     public Object JavaDoc invoke(MethodInvocation invocation) throws Throwable JavaDoc {
266         throw new Exception JavaDoc("Wrapper "+this+" does not support method interception.");
267     }
268     
269     public Object JavaDoc construct(ConstructorInvocation invocation) throws Throwable JavaDoc
270     {
271         throw new Exception JavaDoc("Wrapper "+this+" does not support construction interception.");
272     }
273
274 }
275
Popular Tags