KickJava   Java API By Example, From Geeks To Geeks.

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


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 org.apache.log4j.Category;
27
28 import alt.jiapi.InstrumentationContext;
29 import alt.jiapi.InstrumentationDescriptor;
30 import alt.jiapi.Runtime;
31
32 import alt.jiapi.instrumentor.ChainInstrumentor;
33 import alt.jiapi.instrumentor.InstrumentorChain;
34 import alt.jiapi.instrumentor.HeadInstrumentor;
35 import alt.jiapi.instrumentor.Hook;
36 import alt.jiapi.instrumentor.MethodCallInstrumentor;
37 import alt.jiapi.instrumentor.MethodDispatcherInstrumentor;
38 import alt.jiapi.instrumentor.MethodEntryStrategy;
39 import alt.jiapi.instrumentor.MethodReturnStrategy;
40 import alt.jiapi.instrumentor.GrepInstrumentor;
41
42 /**
43  * This class registers itself to Jiapi runtime and tracks method
44  * entries and exits. When either event happens it will notify each
45  * listeners that has been registered.<p>
46  *
47  * If an exception is thrown from a method, the exit event is not produced.
48  * That is, exit events are produced only for the normal exits from
49  * methods.
50  *
51  * @author Mika Riekkinen
52  * @author Joni Suominen
53  * @version $Revision: 1.23 $ $Date: 2004/03/21 12:50:07 $
54  */

55 public class MethodEventProducer extends EventProducer {
56 // private static Category log =
57
// Runtime.getLogCategory(MethodEventProducer.class);
58

59     private List JavaDoc listeners = new ArrayList JavaDoc();
60
61
62     /**
63      * Constructor. Resolution is set to '*', which indicates all the
64      * MethodEvents are produced.
65      *
66      * @param id Instrumentation decsriptor, that this MethodEventProducer
67      * registers itself to.
68      */

69     public MethodEventProducer(InstrumentationDescriptor id) {
70         this(id, "*");
71     }
72
73
74     /**
75      * Creates new MethodEventProducer.
76      * Only MethodEvents, that match with given resolution,
77      * are produced. Resolution is compared against the name of the
78      * method during instrumentation.
79      *
80      * @param id Instrumentation decsriptor, that this MethodEventProducer
81      * registers itself to.
82      * @param resolution Resolution, that is used further to select which
83      * methods will trigger events to be produced.
84      */

85     public MethodEventProducer(InstrumentationDescriptor id, String JavaDoc resolution) {
86         super(resolution);
87         if (true) {
88             id.addInstrumentor(new MethodEventInstrumentor(this));
89             return;
90         }
91
92         try {
93 // InstrumentationContext ctx = new InstrumentationContext();
94

95             // For method entry traps :
96
ChainInstrumentor entryDispatcher = new MethodDispatcherInstrumentor();
97             GrepInstrumentor grepEntry =
98                 new GrepInstrumentor(new MethodEntryStrategy());
99
100 // Instrumentor head0 = new HeadInstrumentor(); // ---
101

102             grepEntry.setResolutions(getResolutions());
103
104             ChainInstrumentor entryCall
105                 = new MethodCallInstrumentor(new MethodEntryHook(this));
106
107             InstrumentorChain entryChain = new InstrumentorChain();
108             entryChain.add(entryDispatcher);
109             entryChain.add(grepEntry);
110 // entryChain.add(head0); // ---
111
entryChain.add(entryCall);
112
113
114             // For method exit traps :
115
ChainInstrumentor exitDispatcher = new MethodDispatcherInstrumentor();
116             GrepInstrumentor grepExit
117                 = new GrepInstrumentor(new MethodReturnStrategy());
118             
119             grepExit.setResolutions(getResolutions());
120             
121             ChainInstrumentor head = new HeadInstrumentor();
122             ChainInstrumentor exitCall =
123                 new MethodCallInstrumentor(new MethodExitHook(this));
124             
125             InstrumentorChain exitChain = new InstrumentorChain();
126             exitChain.add(exitDispatcher);
127             exitChain.add(grepExit);
128             exitChain.add(head);
129             exitChain.add(exitCall);
130                 
131             // Add chains created
132
id.addInstrumentor(entryChain);
133             id.addInstrumentor(exitChain);
134         }
135         catch (Exception JavaDoc e) {
136             // NOTE! Fix exception handling.
137
e.printStackTrace();
138         }
139     }
140
141
142     /**
143      * Adds a MethodListener.
144      * @param mel a MethodListener
145      */

146     public synchronized void addMethodListener(MethodListener mel) {
147         listeners.add(mel);
148     }
149
150     /**
151      * Removes a MethodListener.
152      * @param mel a MethodListener
153      */

154     public synchronized void removeMethodListener(MethodListener mel) {
155         listeners.remove(mel);
156     }
157
158     /**
159      * This method is called by the Jiapi runtime. It should not be called
160      * by others.
161      */

162     public void methodEntered(Object JavaDoc sourceObject, String JavaDoc methodName) {
163         if (!isProtected(sourceObject)) {
164             fireMethodEnterEvent(sourceObject, methodName);
165         }
166         else {
167 // log.debug("sourceObject " + sourceObject +
168
// " was protected. Not firing JiapiEvent.");
169
}
170     }
171     
172     /**
173      * This method is called by the Jiapi runtime. It should not be called
174      * by others.
175      */

176     public void methodExited(Object JavaDoc sourceObject, String JavaDoc methodName) {
177         if (!isProtected(sourceObject)) {
178             fireMethodExitEvent(sourceObject, methodName);
179         }
180         else {
181 // log.debug("sourceObject " + sourceObject +
182
// " was protected. Not firing JiapiEvent.");
183
}
184     }
185
186     /**
187      * Fires an event on method entry.
188      * @param sourceObject Source Object
189      * @param methodName Name of the method
190      */

191     protected synchronized void fireMethodEnterEvent(Object JavaDoc sourceObject,
192                                                      String JavaDoc methodName) {
193         Iterator JavaDoc i = listeners.iterator();
194         MethodEvent event = new MethodEvent(this, sourceObject, methodName,
195                                             MethodEvent.METHOD_ENTERED);
196         
197         while (i.hasNext()) {
198             MethodListener ml = (MethodListener)i.next();
199             ml.methodEntered(event);
200         }
201     }
202
203     /**
204      * Fires an event on method exit.
205      * @param sourceObject Source Object
206      * @param methodName Name of the method
207      */

208     protected synchronized void fireMethodExitEvent(Object JavaDoc sourceObject,
209                                                     String JavaDoc methodName) {
210         Iterator JavaDoc i = listeners.iterator();
211         MethodEvent event = new MethodEvent(this, sourceObject, methodName,
212                                             MethodEvent.METHOD_EXITED);
213
214         while (i.hasNext()) {
215             MethodListener ml = (MethodListener)i.next();
216             ml.methodExited(event);
217         }
218     }
219 }
220
221
Popular Tags