KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > object > bytecode > ChangeClassNameRootAdapter


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package com.tc.object.bytecode;
5
6 import com.tc.asm.ClassVisitor;
7 import com.tc.asm.FieldVisitor;
8 import com.tc.asm.Label;
9 import com.tc.asm.MethodAdapter;
10 import com.tc.asm.MethodVisitor;
11 import com.tc.asm.Opcodes;
12
13 import java.util.Collection JavaDoc;
14 import java.util.Collections JavaDoc;
15 import java.util.Map JavaDoc;
16
17 public class ChangeClassNameRootAdapter extends ChangeClassNameHierarchyAdapter implements Opcodes {
18   private final Collection JavaDoc innerClassesNames;
19
20   private final String JavaDoc srcClassNameSlashes;
21   private final String JavaDoc targetClassNameSlashes;
22   private final String JavaDoc fullClassNameSlashes;
23   private final Map JavaDoc instrumentedContext;
24   private final ChangeContext changeContext;
25   private final Collection JavaDoc methodsToBeRemoved;
26
27   public static String JavaDoc replaceClassName(String JavaDoc className, String JavaDoc srcClassName, String JavaDoc targetClassName) {
28     if (className == null || className.length() == 0) { return className; }
29
30     String JavaDoc returnStr = replaceClassNameInner(className, srcClassName, targetClassName);
31     return returnStr.replace(SLASH_DELIMITER, DOT_DELIMITER);
32   }
33
34   private static String JavaDoc replaceClassNameInner(String JavaDoc classNameDots, String JavaDoc srcClassNameDots, String JavaDoc targetClassNameDots) {
35     if (classNameDots == null || classNameDots.length() == 0) { return classNameDots; }
36
37     classNameDots = classNameDots.replace(DOT_DELIMITER, SLASH_DELIMITER);
38     srcClassNameDots = srcClassNameDots.replace(DOT_DELIMITER, SLASH_DELIMITER);
39     targetClassNameDots = targetClassNameDots.replace(DOT_DELIMITER, SLASH_DELIMITER);
40
41     int index = classNameDots.indexOf(srcClassNameDots);
42     if (index == -1) { return classNameDots; }
43
44     StringBuffer JavaDoc newClassName = new StringBuffer JavaDoc();
45     while (index != -1) {
46       if (index > 0) {
47         newClassName.append(classNameDots.substring(0, index));
48       }
49       newClassName.append(targetClassNameDots);
50       classNameDots = classNameDots.substring(index + srcClassNameDots.length());
51       index = classNameDots.indexOf(srcClassNameDots);
52     }
53     newClassName.append(classNameDots);
54     return newClassName.toString();
55   }
56
57   public ChangeClassNameRootAdapter(ClassVisitor cv, String JavaDoc fullClassNameDots, String JavaDoc srcClassNameDots,
58                                     String JavaDoc targetClassNameDots, Map JavaDoc instrumentedContext, Collection JavaDoc innerClassesHolder) {
59     this(cv, fullClassNameDots, srcClassNameDots, targetClassNameDots, instrumentedContext, innerClassesHolder,
60          Collections.EMPTY_SET);
61   }
62
63   /**
64    * @param fullClassNameDots The fully qualified class name that this class adapter is working on, e.g.,
65    * java.util.LinkedHashMap.
66    * @param srcClassNameSlashes The fully qualified class name that needs to be changed, e.g., java.util.HashMap$Entry.
67    * @param targetClassNameSlashes The fully qualified new class name, e.g., java.util.HashMap_J$Entry.
68    */

69   public ChangeClassNameRootAdapter(ClassVisitor cv, String JavaDoc fullClassNameDots, String JavaDoc srcClassNameDots,
70                                     String JavaDoc targetClassNameDots, Map JavaDoc instrumentedContext, Collection JavaDoc innerClassesHolder,
71                                     Collection JavaDoc methodsToBeRemoved) {
72     super(cv);
73     this.srcClassNameSlashes = srcClassNameDots.replace(DOT_DELIMITER, SLASH_DELIMITER);
74     this.targetClassNameSlashes = targetClassNameDots.replace(DOT_DELIMITER, SLASH_DELIMITER);
75     this.fullClassNameSlashes = fullClassNameDots.replace(DOT_DELIMITER, SLASH_DELIMITER);
76     this.innerClassesNames = innerClassesHolder;
77     this.methodsToBeRemoved = methodsToBeRemoved;
78     this.instrumentedContext = instrumentedContext;
79     this.changeContext = addNewContextIfNotExist(fullClassNameSlashes, replaceClassNameInner(fullClassNameSlashes,
80                                                                                              srcClassNameSlashes,
81                                                                                              targetClassNameSlashes),
82                                                  instrumentedContext);
83   }
84
85   public void visit(int version, int access, String JavaDoc name, String JavaDoc signature, String JavaDoc superName, String JavaDoc[] interfaces) {
86     this.changeContext.setOriginalSuperClass(superName);
87     name = replaceClassNameInner(name, srcClassNameSlashes, targetClassNameSlashes);
88     superName = replaceClassNameInner(superName, srcClassNameSlashes, targetClassNameSlashes);
89     super.visit(version, access & ~ACC_ABSTRACT, name, signature, superName, interfaces);
90   }
91
92   public void visitSource(String JavaDoc source, String JavaDoc debug) {
93     int lastIndex = srcClassNameSlashes.lastIndexOf(SLASH_DELIMITER);
94     String JavaDoc srcName = srcClassNameSlashes.substring(lastIndex + 1);
95     lastIndex = targetClassNameSlashes.lastIndexOf(SLASH_DELIMITER);
96     String JavaDoc targetName = targetClassNameSlashes.substring(lastIndex + 1);
97
98     source = replaceClassNameInner(source, srcName, targetName);
99     super.visitSource(source, debug);
100   }
101
102   public void visitInnerClass(String JavaDoc name, String JavaDoc outerName, String JavaDoc innerName, int access) {
103     if (innerClassesNames != null && !innerClassesNames.contains(name) && fullClassNameSlashes.equals(outerName)) {
104       innerClassesNames.add(name);
105     }
106     name = replaceClassNameInner(name, srcClassNameSlashes, targetClassNameSlashes);
107     outerName = replaceClassNameInner(outerName, srcClassNameSlashes, targetClassNameSlashes);
108     super.visitInnerClass(name, outerName, innerName, access);
109   }
110
111   public FieldVisitor visitField(int access, String JavaDoc name, String JavaDoc desc, String JavaDoc signature, Object JavaDoc value) {
112     String JavaDoc convertedDesc = replaceClassNameInner(desc, srcClassNameSlashes, targetClassNameSlashes);
113     String JavaDoc convertedSign = replaceClassName(signature, srcClassNameSlashes, targetClassNameSlashes);
114     if (!convertedDesc.equals(desc) || (convertedSign != null && !convertedSign.equals(signature))) {
115       changeContext.addModifiedFieldInfo(name, desc, convertedDesc, signature, convertedSign);
116     }
117     return super.visitField(access, name, convertedDesc, convertedSign, value);
118   }
119
120   public MethodVisitor visitMethod(int access, String JavaDoc name, String JavaDoc desc, String JavaDoc signature, String JavaDoc[] exceptions) {
121     // if (methodsToBeRemoved.contains(name+desc)) { return invokeSuperVisitMethod(access, name, desc, signature,
122
// exceptions, instrumentedContext, fullClassNameSlashes); }
123

124     String JavaDoc convertedDesc = replaceClassNameInner(desc, srcClassNameSlashes, targetClassNameSlashes);
125     String JavaDoc convertedSign = replaceClassNameInner(signature, srcClassNameSlashes, targetClassNameSlashes);
126
127     if (!convertedDesc.equals(desc) || (convertedSign != null && !convertedSign.equals(signature))) {
128       changeContext.addModifiedMethodInfo(name, desc, convertedDesc, signature, convertedSign);
129     }
130     return new ChangeClassNameMethodAdapter(super.visitMethod(access, name, convertedDesc, convertedSign, exceptions));
131   }
132
133   private class ChangeClassNameMethodAdapter extends MethodAdapter implements Opcodes {
134     public ChangeClassNameMethodAdapter(MethodVisitor mv) {
135       super(mv);
136     }
137
138     public void visitFieldInsn(int opcode, String JavaDoc owner, String JavaDoc name, String JavaDoc desc) {
139       owner = replaceClassNameInner(owner, srcClassNameSlashes, targetClassNameSlashes);
140       desc = replaceClassNameInner(desc, srcClassNameSlashes, targetClassNameSlashes);
141       super.visitFieldInsn(opcode, owner, name, desc);
142     }
143
144     public void visitTypeInsn(int opcode, String JavaDoc desc) {
145       ChangeContext context = (ChangeContext) instrumentedContext.get(desc);
146       if (context != null) {
147         desc = context.convertedClassNameSlashes;
148       } else {
149         desc = replaceClassNameInner(desc, srcClassNameSlashes, targetClassNameSlashes);
150       }
151       super.visitTypeInsn(opcode, desc);
152     }
153
154     public void visitMethodInsn(int opcode, String JavaDoc owner, String JavaDoc name, String JavaDoc desc) {
155       ChangeContext context = (ChangeContext) instrumentedContext.get(owner);
156       if (context != null) {
157         owner = context.convertedClassNameSlashes;
158       } else {
159         owner = replaceClassNameInner(owner, srcClassNameSlashes, targetClassNameSlashes);
160       }
161
162       desc = replaceClassNameInner(desc, srcClassNameSlashes, targetClassNameSlashes);
163
164       super.visitMethodInsn(opcode, owner, name, desc);
165     }
166
167     public void visitLocalVariable(String JavaDoc name, String JavaDoc desc, String JavaDoc signature, Label start, Label end, int index) {
168       desc = replaceClassNameInner(desc, srcClassNameSlashes, targetClassNameSlashes);
169       super.visitLocalVariable(name, desc, signature, start, end, index);
170     }
171   }
172 }
173
Popular Tags