KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > ch > ethz > prose > crosscut > SetCut


1 //
2
// This file is part of the prose package.
3
//
4
// The contents of this file are subject to the Mozilla Public License
5
// Version 1.1 (the "License"); you may not use this file except in
6
// compliance with the License. You may obtain a copy of the License at
7
// http://www.mozilla.org/MPL/
8
//
9
// Software distributed under the License is distributed on an "AS IS" basis,
10
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11
// for the specific language governing rights and limitations under the
12
// License.
13
//
14
// The Original Code is prose.
15
//
16
// The Initial Developer of the Original Code is Andrei Popovici. Portions
17
// created by Andrei Popovici are Copyright (C) 2002 Andrei Popovici.
18
// All Rights Reserved.
19
//
20
// Contributor(s):
21
// $Id: SetCut.java,v 1.3 2003/11/07 22:32:37 anicoara Exp $
22
// =====================================================================
23
//
24
// (history at end)
25
//
26

27 package ch.ethz.prose.crosscut;
28
29 // used packages
30
import java.lang.reflect.Field JavaDoc;
31 import java.util.HashMap JavaDoc;
32
33 import ch.ethz.jvmai.ExceptionJoinPoint;
34 import ch.ethz.jvmai.FieldAccessJoinPoint;
35 import ch.ethz.jvmai.FieldModificationJoinPoint;
36 import ch.ethz.jvmai.JoinPoint;
37 import ch.ethz.jvmai.MethodEntryJoinPoint;
38 import ch.ethz.jvmai.MethodExitJoinPoint;
39 import ch.ethz.prose.engine.FieldModificationRequest;
40
41
42
43 /**
44  * Class SetCut is a crosscut which cuts field sets.
45  *
46  *
47  *
48  * The advice method is <code>SET_ARGS</code>. The join-point
49  * where the advice method is executted depend on:
50  * <ol>
51  * <li> the signature of <code>SET_ARGS</code>
52  * <li> the value returned by <code>pointCutter</code>.
53  * </ol>
54  *
55  * Within an advice method, the <code>thisJoinPoint()</code> method
56  * can be called to obtain a reference to the currently executing
57  * join-point.
58  *
59  * @version $Revision: 1.3 $
60  * @author Andrei Popovici
61  */

62 public abstract class SetCut extends AbstractCrosscut {
63
64
65   private static class SetGetArgs
66   {
67
68     Object JavaDoc[] cc;
69     Object JavaDoc[] cw;
70     Object JavaDoc[] wc;
71     Object JavaDoc[] ww;
72     SetGetArgs()
73       {
74     cc = new Object JavaDoc[2];
75     cw = new Object JavaDoc[2]; cw[1]=new ANY();
76     wc = new Object JavaDoc[2]; wc[0]=new ANY();
77     ww = new Object JavaDoc[2]; ww[0]=new ANY(); ww[1]=new ANY();
78       }
79   }
80
81   private ThreadLocal JavaDoc threadLocalArgs;
82   private transient SetGetSignaturePattern advicePattern;
83
84   protected void SET_ARGS() {}
85
86   static class SetGetThreadLocal extends ThreadLocal JavaDoc implements java.io.Serializable JavaDoc
87   {
88     protected Object JavaDoc initialValue()
89       {
90     return new SetGetArgs();
91       }
92   };
93
94   protected SetCut()
95     {
96       initState();
97       threadLocalArgs = new SetGetThreadLocal();
98     }
99
100
101
102   public void insertionAction(boolean isBeforeInsertion)
103     {
104       if (isBeforeInsertion)
105     initState();
106     }
107
108   String JavaDoc toStringSignature;
109   private void initState()
110     {
111       if (advicePattern == null)
112     {
113       advicePattern= new SetGetSignaturePattern(this);
114       toStringSignature = advicePattern.toString();
115     }
116     }
117
118   /**
119    * Note that Field f does <em>not</em> contain the current (old)
120    * value of the field. If you want to retrieve the old value, do
121    * it by invoking <code>f.get(owner)</code>. The old value is
122    * only accessible at the moment this method is called. After that,
123    * invokation of <code>f.get(owner)</code> returns the new value.
124    *
125    */

126
127
128
129
130   /** Extracts the field owner and passes this to <code>fieldAccessAdvice</code>
131    */

132   protected void joinPointAction(FieldModificationJoinPoint ev)
133     {
134
135       Object JavaDoc[] args = null;
136       SetGetArgs setGetArgs=(SetGetArgs)threadLocalArgs.get();
137
138       switch (advicePattern.signatureCathegory)
139       {
140       case SignaturePattern.SIGNATURE__EMPTY: //SET_ARGS(); //BUGFIX: the advice method is executed twice
141
break;
142       case SignaturePattern.SIGNATURE__CONCRETE__CONCRETE:
143           args = setGetArgs.cc;
144           args[0]= ev.getTarget();
145           args[1] = ev.getValue();
146           break;
147       case SignaturePattern.SIGNATURE__WILDCARD__CONCRETE:
148           args=setGetArgs.wc;
149           ((ANY)args[0]).setObject(ev.getTarget());
150           args[1]=ev.getValue();
151           break;
152       case SignaturePattern.SIGNATURE__CONCRETE__WILDCARD:
153           args=setGetArgs.cw;
154           args[0]=ev.getTarget();
155           ((ANY)args[1]).setObject(ev.getValue());
156           break;
157       case SignaturePattern.SIGNATURE__WILDCARD__WILDCARD:
158           args=setGetArgs.ww;
159           ((ANY)args[0]).setObject(ev.getTarget());
160           ((ANY)args[1]).setObject(ev.getValue());
161           break;
162       default:
163           throw new Error JavaDoc("Wrong pattern signature in " + this);
164       }
165       try
166       {
167           advicePattern.methodObj.invoke(this,args);
168       }
169       catch (IllegalAccessException JavaDoc e)
170       {
171           throw new RuntimeException JavaDoc();
172       }
173       catch (java.lang.reflect.InvocationTargetException JavaDoc e)
174       {
175           throw new RuntimeException JavaDoc();
176       }
177
178     }
179
180
181   /**
182    * Create a new CrosscutRequest consisting of FieldAccessRequests
183    * and FieldModificationRequests for every field (public, protected,
184    * private or package-scoped) declared in class <code>c</code>. (No
185    * request is generated for inherited fields!)
186    */

187   protected CrosscutRequest doCreateRequest(Class JavaDoc c)
188     throws SecurityException JavaDoc
189   {
190       // retrieve all fields of this class and install
191
// a field access and a field modification watch.
192
Field JavaDoc[] declaredFields = null;
193       CrosscutRequest result = new CrosscutRequest();
194
195       try
196     { declaredFields = c.getDeclaredFields(); }
197       catch (NoClassDefFoundError JavaDoc e)
198     { return result; }
199
200
201       for ( int i = 0; i < declaredFields.length; i++ )
202       {
203           if (advicePattern.matchesOperationOnField(declaredFields[i]))
204           result.add(requestFactory.createJoinPointRequest(FieldModificationJoinPoint.KIND,declaredFields[i]));
205       }
206
207       return result;
208   }
209
210   /**
211    *
212    */

213   public String JavaDoc toString()
214     {
215        return " Crosscut: 'SetCut' \n" +
216          " Advice:" + toStringSignature + "\n" +
217          " PointCutter: " + getSpecializer() + "\n";
218    }
219
220 }
221
222
223 //======================================================================
224
//
225
// $Log: SetCut.java,v $
226
// Revision 1.3 2003/11/07 22:32:37 anicoara
227
// SetCut bugfixes: threadLocalArgs has been transient, the advice method was executed twice
228
//
229
// Revision 1.2 2003/07/11 12:27:43 apopovic
230
// Bug fix for rare cases. Some classed loaded late may throw a 'NoClassDefError' when
231
// trying to retrieve the declared methods; The crosscut for such cases is now an empty listt
232
//
233
// Revision 1.1.1.1 2003/07/02 15:30:51 apopovic
234
// Imported from ETH Zurich
235
//
236
// Revision 1.3 2003/05/26 13:28:53 popovici
237
// Documentation Improvements
238
//
239
// Revision 1.2 2003/05/25 11:46:45 popovici
240
// Improved 'toString' presentation of aspects
241
//
242
// Revision 1.1 2003/05/05 13:58:16 popovici
243
// renaming from runes to prose
244
//
245
// Revision 1.8 2002/06/06 12:01:50 popovici
246
// fieldAccessAdvice removed from SetCut; tests and usage of SetCut's
247
// ability to intercept gets moved to 'GetCut'
248
// Minor bug fixes;
249
//
250
// Revision 1.7 2002/06/05 12:03:49 popovici
251
// thisJoinPoint() updated everywhere. The 'fieldModificationAdvice is now parameterless'; older implemnentations now
252
// use 'thisJoinPoint()'
253
//
254
// Revision 1.6 2002/06/05 09:27:58 popovici
255
// thisJoinPoint() introduced in Abstract Crosscut and subclasses;
256
//
257
// Revision 1.5 2002/03/28 13:48:41 popovici
258
// Mozilla-ified
259
//
260
// Revision 1.4 2002/03/06 13:48:37 popovici
261
// joinPointAction now in 4 flavours, depending on the join point type
262
//
263
// Revision 1.3 2002/02/21 12:39:20 popovici
264
// Crosscut efficiency issues:
265
// - joinPointAction dispatch based on static optimization
266
// (->doesEventSpecialization, 'setSpecializer' modified)
267
// (->calculation of 'adviceMethodOptimization', in Func.Crossc)
268
// - joinPointAction now uses JoinPoints (not Events)
269
// - JoinPointListeners (including crosscuts) now use joinPointReached(XXXJoinPoint) to avoid casting
270
// Crosscut architectural issues:
271
// - AbstractCrosscut now insertable.
272
// - AbstractCrosscuts owns referecnces to JVMAI
273
//
274
// Revision 1.2 2002/02/05 09:47:12 smarkwal
275
// JVMDI-specific code replaced by JVMAI. Prose-implementation classes and reflection package removed.
276
//
277
// Revision 1.1.1.1 2001/11/29 18:13:17 popovici
278
// Sources from runes
279
//
280
// Revision 1.1.2.1 2000/11/28 16:39:38 groos
281
// Initial revision.
282
//
283
Popular Tags