1 4 package com.tc.object.bytecode; 5 6 import com.tc.asm.ClassAdapter; 7 import com.tc.asm.ClassVisitor; 8 import com.tc.asm.FieldVisitor; 9 import com.tc.asm.Label; 10 import com.tc.asm.MethodAdapter; 11 import com.tc.asm.MethodVisitor; 12 import com.tc.asm.Opcodes; 13 14 import java.util.Collection ; 15 16 public class ChangePackageClassAdapter extends ClassAdapter implements Opcodes { 17 private final static char DOT_DELIMITER = '.'; 18 private final static char SLASH_DELIMITER = '/'; 19 20 private final String newName; 21 private final String targetName; 22 private final String newType; 23 private final String targetType; 24 25 private final Collection innerClassNames; 26 27 public static String replaceClassName(String name, String targetPackage, String newPackage) { 28 name = name.replace(SLASH_DELIMITER, DOT_DELIMITER); 29 int index = name.indexOf(targetPackage); 30 if (index == -1) { return name; } 31 return newPackage+DOT_DELIMITER+name.substring(targetPackage.length()+1); 32 } 33 34 41 public ChangePackageClassAdapter(ClassVisitor cv, String targetClassName, String targetPackage, String newPackage, 42 Collection innerClassesHolder) { 43 super(cv); 44 this.targetName = targetPackage.replace(DOT_DELIMITER, SLASH_DELIMITER) + SLASH_DELIMITER + targetClassName; 45 this.newName = newPackage.replace(DOT_DELIMITER, SLASH_DELIMITER) + SLASH_DELIMITER + targetClassName; 46 this.targetType = "L"+targetName+";"; 47 this.newType = "L"+newName+";"; 48 this.innerClassNames = innerClassesHolder; 49 } 50 51 public void visit(int version, int access, String name, String signature, String superName, String [] interfaces) { 52 name = replaceName(name); 53 superName = replaceName(superName); 54 super.visit(version, access, name, signature, superName, interfaces); 55 } 56 57 public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { 58 desc = replaceName(desc); 59 return super.visitField(access, name, desc, signature, value); 60 } 61 62 public void visitInnerClass(String name, String outerName, String innerName, int access) { 63 if (innerClassNames != null && !innerClassNames.contains(name) && targetName.equals(outerName)) { 64 innerClassNames.add(name); 65 } 66 67 name = replaceName(name); 68 outerName = replaceName(outerName); 69 super.visitInnerClass(name, outerName, innerName, access); 70 } 71 72 public MethodVisitor visitMethod(int access, String name, String desc, String signature, String [] exceptions) { 73 desc = replaceName(desc); 74 MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); 75 return new ChangePackageMethodVisitor(mv); 76 } 77 78 private String replaceName(String name) { 79 if (targetName.equals(name)) { 80 return newName; 81 } 82 int index = name.indexOf(targetName); 83 while (index != -1) { 84 name = name.substring(0, index)+newName+name.substring(index+targetName.length()); 85 index = name.indexOf(targetName); 86 } 87 return name; 88 } 89 90 private String replaceDesc(String desc) { 91 if (targetType.equals(desc)) { 92 return newType; 93 } 94 int index = desc.indexOf(targetType); 95 while (index != -1) { 96 desc = desc.substring(0, index)+newType+desc.substring(index+targetType.length()); 97 index = desc.indexOf(targetType); 98 } 99 return desc; 100 } 101 102 private class ChangePackageMethodVisitor extends MethodAdapter implements Opcodes { 103 public ChangePackageMethodVisitor(MethodVisitor mv) { 104 super(mv); 105 } 106 107 public void visitFieldInsn(int opcode, String owner, String name, String desc) { 108 owner = replaceName(owner); 109 desc = replaceName(desc); 110 super.visitFieldInsn(opcode, owner, name, desc); 111 } 112 113 public void visitMethodInsn(int opcode, String owner, String name, String desc) { 114 owner = replaceName(owner); 115 desc = replaceDesc(desc); 116 super.visitMethodInsn(opcode, owner, name, desc); 117 } 118 119 public void visitTypeInsn(int opcode, String desc) { 120 desc = replaceName(desc); 121 super.visitTypeInsn(opcode, desc); 122 } 123 124 public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) { 125 desc = replaceName(desc); 126 super.visitLocalVariable(name, desc, signature, start, end, index); 127 } 128 } 129 } | Popular Tags |