1 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 ; 14 import java.util.Collections ; 15 import java.util.Map ; 16 17 public class ChangeClassNameRootAdapter extends ChangeClassNameHierarchyAdapter implements Opcodes { 18 private final Collection innerClassesNames; 19 20 private final String srcClassNameSlashes; 21 private final String targetClassNameSlashes; 22 private final String fullClassNameSlashes; 23 private final Map instrumentedContext; 24 private final ChangeContext changeContext; 25 private final Collection methodsToBeRemoved; 26 27 public static String replaceClassName(String className, String srcClassName, String targetClassName) { 28 if (className == null || className.length() == 0) { return className; } 29 30 String returnStr = replaceClassNameInner(className, srcClassName, targetClassName); 31 return returnStr.replace(SLASH_DELIMITER, DOT_DELIMITER); 32 } 33 34 private static String replaceClassNameInner(String classNameDots, String srcClassNameDots, String 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 newClassName = new StringBuffer (); 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 fullClassNameDots, String srcClassNameDots, 58 String targetClassNameDots, Map instrumentedContext, Collection innerClassesHolder) { 59 this(cv, fullClassNameDots, srcClassNameDots, targetClassNameDots, instrumentedContext, innerClassesHolder, 60 Collections.EMPTY_SET); 61 } 62 63 69 public ChangeClassNameRootAdapter(ClassVisitor cv, String fullClassNameDots, String srcClassNameDots, 70 String targetClassNameDots, Map instrumentedContext, Collection innerClassesHolder, 71 Collection 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 name, String signature, String superName, String [] 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 source, String debug) { 93 int lastIndex = srcClassNameSlashes.lastIndexOf(SLASH_DELIMITER); 94 String srcName = srcClassNameSlashes.substring(lastIndex + 1); 95 lastIndex = targetClassNameSlashes.lastIndexOf(SLASH_DELIMITER); 96 String targetName = targetClassNameSlashes.substring(lastIndex + 1); 97 98 source = replaceClassNameInner(source, srcName, targetName); 99 super.visitSource(source, debug); 100 } 101 102 public void visitInnerClass(String name, String outerName, String 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 name, String desc, String signature, Object value) { 112 String convertedDesc = replaceClassNameInner(desc, srcClassNameSlashes, targetClassNameSlashes); 113 String 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 name, String desc, String signature, String [] exceptions) { 121 124 String convertedDesc = replaceClassNameInner(desc, srcClassNameSlashes, targetClassNameSlashes); 125 String 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 owner, String name, String 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 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 owner, String name, String 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 name, String desc, String 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 |