KickJava   Java API By Example, From Geeks To Geeks.

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


1 package alt.jiapi.event;
2
3 import java.lang.reflect.Modifier JavaDoc;
4
5 import alt.jiapi.InstrumentationException;
6 import alt.jiapi.Instrumentor;
7
8 import alt.jiapi.reflect.FieldExistsException;
9 import alt.jiapi.reflect.Instruction;
10 import alt.jiapi.reflect.InstructionFactory;
11 import alt.jiapi.reflect.InstructionList;
12 import alt.jiapi.reflect.JiapiClass;
13 import alt.jiapi.reflect.JiapiField;
14 import alt.jiapi.reflect.JiapiMethod;
15 import alt.jiapi.reflect.Loader;
16 import alt.jiapi.reflect.MethodExistsException;
17 import alt.jiapi.reflect.Signature;
18
19 /**
20  * Class EventInstrumentor.
21  *
22  * @author Mika Riekkinen
23  */

24 public abstract class EventInstrumentor implements Instrumentor {
25     private EventProducer ep;
26     private JiapiField eventProducerField;
27     private JiapiClass currentClass;
28
29     protected EventInstrumentor(EventProducer ep) {
30         this.ep = ep;
31     }
32
33     /**
34      * Matches given String to resolutions set to event-producer.
35      */

36     public boolean match(String JavaDoc s) {
37         return ep.match(s);
38     }
39
40     /**
41      * Called by Jiapi insturmentation process.
42      */

43     public void instrument(JiapiClass jc) {
44         this.currentClass = jc;
45
46         if (jc.isInterface()) {
47             return;
48         }
49
50
51         // Instrument all the methods
52
JiapiMethod[] dMethods = jc.getDeclaredMethods();
53         for (int i = 0; i < dMethods.length; i++) {
54             // Do not instrument methods syntesized by jiapi
55
if (!dMethods[i].isSynthetic()) {
56                 // Abstract methods do not have instruction list
57
if (dMethods[i].getInstructionList() != null) {
58                     int su1 = dMethods[i].getInstructionList().stackUsage();
59                     instrument(dMethods[i]);
60                     int su2 = dMethods[i].getInstructionList().stackUsage();
61
62                     if (su1 != su2) {
63                         System.out.println("ERROR: " + "Instrumentation of " + jc.getName() + ": " + dMethods[i] + " changes stack usage from " + su1 + " to " + su2);
64                         //throw new InstrumentationException("Instrumentation of " + jc.getName() + ": " + dMethods[i] + " changes stack usage from " + su1 + " to " + su2);
65
}
66                 }
67             }
68         }
69     }
70
71     protected JiapiClass getEventProducer() {
72         JiapiClass jc = null;
73         try {
74             jc = new Loader().loadClass(ep.getClass().getName());
75         }
76         catch(Exception JavaDoc e) {
77             System.out.println("ERROR: " + e);
78         }
79
80         return jc;
81     }
82
83     protected JiapiField getEventProducerField() {
84         String JavaDoc fieldName = "__jiapi_field_" +
85             EventRuntime.nextFieldNameIndex();
86
87         // Store EventProducer in EventRuntime,
88
// so that it can be retrieved later by instrumented class
89
// when they are instantiated.
90
EventRuntime.setFieldValue(fieldName, ep);
91
92         // First add a field to hold event producer
93
eventProducerField = null;
94         try {
95             eventProducerField =
96                 currentClass.addField(Modifier.PRIVATE +Modifier.STATIC,
97                                       ep.getClass().getName(), fieldName);
98         }
99         catch(FieldExistsException fee) {
100             // ERROR
101
}
102         
103
104         // Next, create static initializer, that initializes
105
// field created above.
106
JiapiMethod clinit = null;
107         try {
108             clinit = currentClass.getDeclaredMethod("<clinit>",new String JavaDoc[]{});
109         }
110         catch(NoSuchMethodException JavaDoc nsme) {
111             // It did not exists, so create one
112
try {
113                 clinit =
114                     currentClass.addMethod(Modifier.STATIC, "<clinit>",
115                                            new Signature("void",
116                                                          new String JavaDoc[0]));
117                 // create 'return' from <clinit>
118
clinit.getInstructionList().add(clinit.getInstructionList().getInstructionFactory().returnMethod(clinit));
119             }
120             catch(MethodExistsException mee) {
121                 mee.printStackTrace();
122             }
123         }
124
125         InstructionList il = clinit.getInstructionList();
126         InstructionFactory factory = il.getInstructionFactory();
127         InstructionList initializer = il.createEmptyList();
128
129         try {
130             JiapiClass er = currentClass.getLoader().loadClass("alt.jiapi.event.EventRuntime");
131             JiapiMethod gfv =
132                 er.getDeclaredMethod("getFieldValue",
133                                      new String JavaDoc[] {"java.lang.String"});
134
135             // Get the field value from runtime
136
initializer.add(factory.pushConstant(fieldName));
137             initializer.add(factory.invoke(gfv));
138
139
140             // put the returned event producer to __jiapi_field
141
initializer.add(factory.cast(ep.getClass().getName()));
142             initializer.add(factory.setField(eventProducerField));
143         }
144         catch(NoSuchMethodException JavaDoc nsme) {
145             nsme.printStackTrace();
146         }
147         catch(ClassNotFoundException JavaDoc cnfe) {
148             cnfe.printStackTrace();
149         }
150         catch(java.io.IOException JavaDoc ioe) {
151             ioe.printStackTrace();
152         }
153
154         // Insert initializer code before 'return'
155
il.insert(0, initializer);
156
157
158         return eventProducerField;
159     }
160
161     public JiapiClass getCurrentClass() {
162         return currentClass;
163     }
164
165
166     public abstract void instrument(JiapiMethod jm);
167 }
168
Popular Tags