KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > alt > jiapi > event > FieldEventProducer


1 /*
2  * Copyright(C) 2001 Mika Riekkinen, Joni Suominen
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or(at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but 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 library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */

18
19 package alt.jiapi.event;
20
21 import java.lang.reflect.Method JavaDoc;
22 import java.util.ArrayList JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.List JavaDoc;
25
26 import alt.jiapi.InstrumentationContext;
27 import alt.jiapi.InstrumentationDescriptor;
28
29 import alt.jiapi.instrumentor.ChainInstrumentor;
30 import alt.jiapi.instrumentor.InstrumentorChain;
31
32 import alt.jiapi.instrumentor.FieldAccessStrategy;
33 import alt.jiapi.instrumentor.HeadInstrumentor;
34 import alt.jiapi.instrumentor.Hook;
35 import alt.jiapi.instrumentor.MethodDispatcherInstrumentor;
36 import alt.jiapi.instrumentor.MethodCallInstrumentor;
37 import alt.jiapi.instrumentor.GrepInstrumentor;
38 import alt.jiapi.instrumentor.TailInstrumentor;
39
40 /**
41  * This class registers itself to Jiapi runtime and tracks field
42  * accesses. That is, gets and sets. When either event happens it will
43  * notify each listeners that has been registered.
44  *
45  * @author Mika Riekkinen
46  * @author Joni Suominen
47  * @version $Revision: 1.10 $ $Date: 2004/03/21 12:50:07 $
48  */

49 public class FieldEventProducer extends EventProducer {
50     private List JavaDoc listeners = new ArrayList JavaDoc();
51
52
53     /**
54      * Constructor. Resolution is set to '*', which indicates all field
55      * accesses are trapped.
56      *
57      * @param id Instrumentation decsriptor, that this FieldEventProducer
58      * registers itself to.
59      */

60     public FieldEventProducer(InstrumentationDescriptor id) {
61         this(id, "*");
62     }
63
64     /**
65      * Constructor. Given resolution is compared to name of the field,
66      * and if it matches, a FieldEvent is produced.
67      *
68      * @param id Instrumentation decsriptor, that this FieldEventProducer
69      * registers itself to.
70      * @param resolution Resolution that is used in deciding whether or not
71      * an event should be produced.
72      */

73     public FieldEventProducer(InstrumentationDescriptor id, String JavaDoc resolution) {
74         super(resolution);
75         id.addInstrumentor(new FieldEventInstrumentor(this));
76
77         if (true) {
78             return;
79         }
80
81         try {
82 // InstrumentationContext ctx = new InstrumentationContext();
83
ChainInstrumentor setDispatcher = new MethodDispatcherInstrumentor();
84
85             GrepInstrumentor grepWriteAccess =
86             // Following line fixes bug that we instrument
87
// on field accesses that were synthesized by Jiapi itself.
88
new GrepInstrumentor(new FieldAccessStrategy("*__jiapi_field*", true, FieldAccessStrategy.WRITE_ACCESS));
89
90             grepWriteAccess.setResolutions(getResolutions());
91
92             ChainInstrumentor afterSet = new TailInstrumentor();
93             ChainInstrumentor callFieldSet =
94                 new MethodCallInstrumentor(new FieldSetHook(this));
95             
96             InstrumentorChain setChain = new InstrumentorChain();
97             setChain.add(setDispatcher);
98             setChain.add(grepWriteAccess);
99             setChain.add(afterSet);
100             setChain.add(callFieldSet);
101
102
103             ChainInstrumentor getDispatcher = new MethodDispatcherInstrumentor();
104             GrepInstrumentor grepReadAccess =
105             // Following commented line fixes bug that we instrument
106
// on field accesses that were synthesized by Jiapi itself.
107
new GrepInstrumentor(new FieldAccessStrategy("*__jiapi_field*", true, FieldAccessStrategy.READ_ACCESS));
108
109             grepReadAccess.setResolutions(getResolutions());
110
111             ChainInstrumentor beforeRead = new HeadInstrumentor();
112             ChainInstrumentor callFieldGet =
113                 new MethodCallInstrumentor(new FieldGetHook(this));
114
115             InstrumentorChain getChain = new InstrumentorChain();
116             getChain.add(getDispatcher);
117             getChain.add(grepReadAccess);
118             getChain.add(beforeRead);
119             getChain.add(callFieldGet);
120
121
122             id.addInstrumentor(getChain);
123             id.addInstrumentor(setChain);
124         } catch (Exception JavaDoc e) {
125             // NOTE! Fix exception handling.
126
e.printStackTrace();
127         }
128     }
129
130
131     /**
132      * Adds a FieldListener.
133      * @param fl a FieldListener
134      */

135     public synchronized void addFieldListener(FieldListener fl) {
136         listeners.add(fl);
137     }
138
139     /**
140      * Removes a FieldListener.
141      * @param fl a FieldListener
142      */

143     public synchronized void removeFieldListener(FieldListener fl) {
144         listeners.remove(fl);
145     }
146
147     /**
148      * This method is called by the Jiapi runtime. It should not be called
149      * by others.
150      */

151     public void fieldGet(Object JavaDoc sourceObject, String JavaDoc fieldName) {
152         if (!isProtected(sourceObject)) {
153             fireFieldGetEvent(sourceObject, fieldName);
154         }
155     }
156     
157     /**
158      * This method is called by the Jiapi runtime. It should not be called
159      * by others.
160      */

161     public void fieldSet(Object JavaDoc sourceObject, String JavaDoc fieldName) {
162         if (!isProtected(sourceObject)) {
163             fireFieldSetEvent(sourceObject, fieldName);
164         }
165     }
166
167     /**
168      * Fires an event when a field has been accessed(set).
169      *
170      * @param sourceObject
171      * @param fieldName Name of the field
172      */

173     protected synchronized void fireFieldSetEvent(Object JavaDoc sourceObject,
174                                                   String JavaDoc fieldName) {
175         Iterator JavaDoc i = listeners.iterator();
176         FieldEvent event = new FieldEvent(this, sourceObject, fieldName,
177                                           FieldEvent.FIELD_SET);
178         
179         while (i.hasNext()) {
180             FieldListener fl = (FieldListener)i.next();
181             fl.fieldSet(event);
182         }
183     }
184
185     /**
186      * Fires an event when a field has been accessed(get).
187      *
188      * @param sourceObject
189      * @param fieldName Name of the field
190      */

191     protected synchronized void fireFieldGetEvent(Object JavaDoc sourceObject,
192                                                   String JavaDoc fieldName) {
193         Iterator JavaDoc i = listeners.iterator();
194         FieldEvent event = new FieldEvent(this, sourceObject, fieldName,
195                                           FieldEvent.FIELD_GET);
196
197         while (i.hasNext()) {
198             FieldListener fl = (FieldListener)i.next();
199             fl.fieldGet(event);
200         }
201     }
202 }
203
204
Popular Tags