KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > alt > jiapi > instrumentor > ChangeReferenceInstrumentor


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.instrumentor;
20
21 import org.apache.log4j.Category;
22
23 import alt.jiapi.Runtime;
24 import alt.jiapi.reflect.JiapiClass;
25 import alt.jiapi.reflect.JiapiField;
26 import alt.jiapi.reflect.JiapiMethod;
27 import alt.jiapi.reflect.Instruction;
28 import alt.jiapi.reflect.InstructionList;
29
30 import alt.jiapi.reflect.instruction.Invocation;
31 import alt.jiapi.reflect.instruction.OpcodeGroups;
32 import alt.jiapi.reflect.instruction.FieldAccess;
33 import alt.jiapi.reflect.instruction.ReferencingInstruction;
34
35 /**
36  *
37  * @author Mika Riekkinen
38  * @author Joni Suominen
39  * @version $Revision: 1.7 $ $Date: 2004/03/15 14:47:53 $
40  */

41 public class ChangeReferenceInstrumentor extends AbstractInstrumentor {
42     private static Category log = Runtime.getLogCategory(ChangeReferenceInstrumentor.class);
43
44     //private String pattern;
45
private String JavaDoc replacement;
46     private int mode;
47     private byte[] bytesToScan;
48 // private RE pattern;
49
private String JavaDoc patternString;
50
51     /**
52      * Mode, that instructs that only field refenreces are searched for
53      */

54     public static final int CHANGE_FIELD_REFERENCES = 1;
55
56     /**
57      * Mode, that instructs that only methodcall refenreces are searched for
58      */

59     public static final int CHANGE_METHODCALL_REFERENCES = 2;
60
61     /**
62      * Mode, that instructs that all references are searched for.
63      * All references here mean all modes, that are defined by this class.
64      */

65     public static final int CHANGE_ALL =
66         CHANGE_FIELD_REFERENCES +
67         CHANGE_METHODCALL_REFERENCES;
68         
69
70     public ChangeReferenceInstrumentor(String JavaDoc pattern, String JavaDoc replacement) {
71         this(CHANGE_ALL, pattern, replacement);
72     }
73
74     public ChangeReferenceInstrumentor(int mode, String JavaDoc pattern,
75                                        String JavaDoc replacement) {
76         this.mode = mode;
77         this.patternString = pattern;
78         try {
79             // first pattern will succeed, no matter what.
80
// if second pattern failes, it will leave pattern so,
81
// that nothing will be matched.
82
// this.pattern = new RE("^.*$");
83
// this.pattern = new RE(pattern);
84
}
85         catch(Exception JavaDoc e) {
86             log.error("Invalid regular expression: " + pattern);
87         }
88
89         this.replacement = replacement;
90
91         int length = 0;
92         if ((mode & CHANGE_FIELD_REFERENCES) == CHANGE_FIELD_REFERENCES) {
93             length = OpcodeGroups.FIELD_ACCESS_INSTRUCTIONS.length;
94         }
95         if ((mode & CHANGE_METHODCALL_REFERENCES) ==
96             CHANGE_METHODCALL_REFERENCES) {
97             length += OpcodeGroups.INVOKE_INSTRUCTIONS.length;
98         }
99
100         this.bytesToScan = new byte[length];
101         int targetPosition = 0;
102         if ((mode & CHANGE_FIELD_REFERENCES) == CHANGE_FIELD_REFERENCES) {
103             System.arraycopy(OpcodeGroups.FIELD_ACCESS_INSTRUCTIONS, 0,
104                              bytesToScan, targetPosition,
105                              OpcodeGroups.FIELD_ACCESS_INSTRUCTIONS.length);
106             targetPosition = OpcodeGroups.FIELD_ACCESS_INSTRUCTIONS.length;
107         }
108         if ((mode & CHANGE_METHODCALL_REFERENCES) ==
109             CHANGE_METHODCALL_REFERENCES) {
110             System.arraycopy(OpcodeGroups.INVOKE_INSTRUCTIONS, 0,
111                              bytesToScan, targetPosition,
112                              OpcodeGroups.INVOKE_INSTRUCTIONS.length);
113
114             // Uncomment, if other references types are added
115
//targetPosition += FIELD_ACCESS_INSTRUCTIONS.length;
116
}
117
118         log.info("Pattern is " + pattern + ", replacement is " + replacement);
119     }
120
121
122     public void instrument(InstructionList il) {
123         int index = 0;
124         String JavaDoc __replacement = null;
125         if (this.replacement == null) {
126             __replacement = getCurrentClass().getName();
127         }
128         else {
129             __replacement = this.replacement;
130         }
131
132         while ((index = il.indexOf(bytesToScan, index)) != -1) {
133             ReferencingInstruction i = (ReferencingInstruction)il.get(index);
134
135             if (((mode & CHANGE_FIELD_REFERENCES) == CHANGE_FIELD_REFERENCES)&&
136                 (i instanceof FieldAccess)) {
137                 changeReference(i, __replacement);
138             }
139             else if (((mode & CHANGE_METHODCALL_REFERENCES) == CHANGE_METHODCALL_REFERENCES) &&
140                 (i instanceof Invocation)) {
141                 changeReference(i, __replacement);
142             }
143
144             index++;
145         }
146
147         forward(il);
148     }
149
150
151     private void changeReference(ReferencingInstruction i,
152                                  String JavaDoc __replacement) {
153         String JavaDoc referencedType = i.getReferencedTypeName();
154
155         if (true /*pattern.match(referencedType)*/) {
156 // String newType = pattern.subst(referencedType,
157
// __replacement);
158

159 // log.debug("Changing type " + referencedType + " to " +
160
// newType);
161
//i.setReferencedTypeName(newType);
162
throw new RuntimeException JavaDoc("NOT IMPLEMENTED");
163         }
164         else {
165             log.debug("Won't change reference to " + referencedType);
166         }
167     }
168 }
169
Popular Tags