KickJava   Java API By Example, From Geeks To Geeks.

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


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.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 JavaDoc;
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 JavaDoc newName;
21   private final String JavaDoc targetName;
22   private final String JavaDoc newType;
23   private final String JavaDoc targetType;
24   
25   private final Collection JavaDoc innerClassNames;
26   
27   public static String JavaDoc replaceClassName(String JavaDoc name, String JavaDoc targetPackage, String JavaDoc 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   /**
35    * @param targetClassName The class name at which package needs to be changed, e.g., HashMap.
36    * @param targetPackageName The package name at which package needs to be changed, e.g., com.tc.bootjar.java.util.
37    * @param newPackage The new package name, e.g., java.util.
38    * @param innerClassesHolder A collection which contains the inner class names of this class.
39    * It could be null if the inner class can be ignored.
40    */

41   public ChangePackageClassAdapter(ClassVisitor cv, String JavaDoc targetClassName, String JavaDoc targetPackage, String JavaDoc newPackage,
42                                    Collection JavaDoc 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 JavaDoc name, String JavaDoc signature, String JavaDoc superName, String JavaDoc[] 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 JavaDoc name, String JavaDoc desc, String JavaDoc signature, Object JavaDoc value) {
58     desc = replaceName(desc);
59     return super.visitField(access, name, desc, signature, value);
60   }
61   
62   public void visitInnerClass(String JavaDoc name, String JavaDoc outerName, String JavaDoc 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 JavaDoc name, String JavaDoc desc, String JavaDoc signature, String JavaDoc[] 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 JavaDoc replaceName(String JavaDoc 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 JavaDoc replaceDesc(String JavaDoc 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 JavaDoc owner, String JavaDoc name, String JavaDoc 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 JavaDoc owner, String JavaDoc name, String JavaDoc 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 JavaDoc desc) {
120       desc = replaceName(desc);
121       super.visitTypeInsn(opcode, desc);
122     }
123     
124     public void visitLocalVariable(String JavaDoc name, String JavaDoc desc, String JavaDoc 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