1 2 package SOFA.Tools.Resolver; 3 4 import org.objectweb.asm.ClassAdapter; 5 import org.objectweb.asm.ClassReader; 6 import org.objectweb.asm.ClassVisitor; 7 import org.objectweb.asm.ClassWriter; 8 import org.objectweb.asm.CodeAdapter; 9 import org.objectweb.asm.CodeVisitor; 10 import org.objectweb.asm.Constants; 11 import org.objectweb.asm.Label; 12 13 17 public class Resolver { 18 19 private java.util.Hashtable trTable; 20 21 25 public Resolver(java.util.Hashtable table) { 26 trTable = table; 27 } 28 29 35 public byte[] process(java.io.InputStream is) throws java.io.IOException { 36 ClassReader cr = new ClassReader(is); 37 ClassWriter cw = new ClassWriter(false); 38 ClassVisitor cv = new SOFAClassAdapter(cw, trTable); 39 cr.accept(cv, false); 40 return cw.toByteArray(); 41 } 42 43 49 public static String classNameToVMClassName(String className) { 50 StringBuffer ret = new StringBuffer (); 51 for (int i=0; i<className.length(); i++) { 52 if (className.charAt(i) == '.') 53 ret.append('/'); 54 else 55 ret.append(className.charAt(i)); 56 } 57 return ret.toString(); 58 } 59 60 68 public static String cdlClassNameToVMClassName(String cdlClassName, String version) { 69 StringBuffer ret = new StringBuffer (); 70 for (int i=0; i<cdlClassName.length(); i++) { 71 if (cdlClassName.charAt(i) == '.') 72 ret.append('/'); 73 else 74 ret.append(cdlClassName.charAt(i)); 75 } 76 ret.append("_Q_"); 77 for (int i=0; i<version.length(); i++) { 78 switch (version.charAt(i)) { 79 case '.': 80 ret.append('_'); 81 break; 82 case '!': 83 ret.append("_E_"); 84 break; 85 default: 86 ret.append(version.charAt(i)); 87 } 88 } 89 return ret.toString(); 90 } 91 } 92 93 97 class SOFAClassAdapter extends ClassAdapter implements Constants { 98 99 private java.util.Hashtable trTable; 100 101 103 public SOFAClassAdapter (ClassVisitor cv, java.util.Hashtable table) { 104 super(cv); 105 trTable = table; 106 } 107 108 public void visit ( final int access, final String name, final String superName, final String [] interfaces, final String sourceFile) { 109 String newName = (String ) trTable.get(name); 110 if (newName == null) { 111 newName = name; 113 } 114 String newSuperName = (String ) trTable.get(superName); 115 newSuperName = (newSuperName != null) ? newSuperName : superName; 116 String [] newInterfaces = new String [interfaces.length]; 117 for (int i=0; i<interfaces.length; i++) { 118 newInterfaces[i] = (String ) trTable.get(interfaces[i]); 119 newInterfaces[i] = (newInterfaces[i] != null) ? newInterfaces[i] : interfaces[i]; 120 } 121 cv.visit(access, newName, newSuperName, newInterfaces, sourceFile); 122 } 123 124 public void visitField(final int access, final String name, final String desc, final Object value) { 125 String newDesc = augmentSimpleDesc(desc, trTable); 126 cv.visitField(access, name, newDesc, value); 127 } 128 129 public CodeVisitor visitMethod(final int access, final String name, final String desc, final String [] exceptions) { 130 String [] newExceptions = null; 131 if (exceptions != null) { newExceptions = new String [exceptions.length]; 133 for (int i=0; i<exceptions.length; i++) { 134 newExceptions[i] = (String ) trTable.get(exceptions[i]); 135 newExceptions[i] = (newExceptions[i] != null) ? newExceptions[i] : exceptions[i]; 136 } 137 } 138 String paramTypes = desc.substring(1,desc.indexOf(')')); 141 String retType = desc.substring(desc.indexOf(')')+1); 142 String newRetType = augmentSimpleDesc(retType, trTable); 143 String newParamTypes = augmentListOfDescs(paramTypes, trTable); 144 String newDesc = "(" + newParamTypes + ")" + newRetType; 145 CodeVisitor mv = cv.visitMethod(access, name, newDesc, newExceptions); 146 return mv == null ? null : new TraceFieldCodeAdapter(mv, trTable); 147 } 148 149 155 public static String augmentSimpleDesc(String desc, java.util.Hashtable trTable) { 156 StringBuffer type = new StringBuffer (); 157 StringBuffer prefix = new StringBuffer (); 158 int i=0; 159 while (desc.charAt(i) == '[') { prefix.append('['); 161 i++; 162 } 163 if (desc.charAt(i) == 'L') { 164 i++; while (desc.charAt(i) != ';') { type.append(desc.charAt(i++)); 167 } 168 String newType = (String ) trTable.get(type.toString()); 169 newType = (newType != null) ? newType : type.toString(); 170 return prefix.toString() + "L" + newType + ";"; 171 } else { 172 return desc; 173 } 174 } 175 176 182 public static String augmentListOfDescs(String descs, java.util.Hashtable trTable) { 183 StringBuffer ret = new StringBuffer (); 184 StringBuffer cur = new StringBuffer (); 185 boolean typeNow = false; 186 for (int i=0; i<descs.length(); i++) { 187 if (typeNow) { 188 if (descs.charAt(i) != ';') { 189 cur.append(descs.charAt(i)); 190 } else { 191 String newType = (String ) trTable.get(cur.toString()); 192 newType = (newType != null) ? newType : cur.toString(); 193 ret.append(newType); 194 ret.append(';'); 195 cur = new StringBuffer (); 196 typeNow = false; 197 } 198 } else { 199 if (descs.charAt(i) == 'L') { 200 typeNow = true; 201 } 202 ret.append(descs.charAt(i)); 203 } 204 } 205 return ret.toString(); 206 } 207 } 208 209 213 class TraceFieldCodeAdapter extends CodeAdapter implements Constants { 214 private java.util.Hashtable trTable; 215 public TraceFieldCodeAdapter (CodeVisitor cv, java.util.Hashtable table) { 216 super(cv); 217 trTable = table; 218 } 219 220 public void visitFieldInsn(final int opcode, final String owner, final String name, final String desc) { 221 String newOwner = (String ) trTable.get(owner); 222 newOwner = (newOwner != null) ? newOwner : owner; 223 String newDesc = SOFAClassAdapter.augmentSimpleDesc(desc, trTable); 224 cv.visitFieldInsn(opcode, newOwner, name, newDesc); 225 } 226 227 public void visitMethodInsn(int opcode, String owner, String name, String desc) { 228 String paramTypes = desc.substring(1,desc.indexOf(')')); 229 String retType = desc.substring(desc.indexOf(')')+1); 230 String newRetType = SOFAClassAdapter.augmentSimpleDesc(retType, trTable); 231 String newParamTypes = SOFAClassAdapter.augmentListOfDescs(paramTypes, trTable); 232 String newDesc = "(" + newParamTypes + ")" + newRetType; 233 String newOwner = (String ) trTable.get(owner); 234 newOwner = (newOwner != null) ? newOwner : owner; 235 cv.visitMethodInsn(opcode, newOwner, name, newDesc); 236 } 237 238 public void visitTypeInsn(int opcode, String desc) { 239 String newDesc = (String ) trTable.get(desc); 240 newDesc = (newDesc != null) ? newDesc : desc; 241 cv.visitTypeInsn(opcode, newDesc); 242 } 243 244 public void visitLocalVariable(String name, String desc, Label start, Label end, int index) { 245 String newDesc = SOFAClassAdapter.augmentSimpleDesc(desc, trTable); 246 cv.visitLocalVariable(name, newDesc, start, end, index); 247 } 248 249 public void visitMultiANewArrayInsn(String desc, int dims) { 250 String newDesc = SOFAClassAdapter.augmentSimpleDesc(desc, trTable); 251 cv.visitMultiANewArrayInsn(newDesc, dims); 252 } 253 254 public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { 255 String newType = null; 256 if (type != null) { 257 newType = (String ) trTable.get(type); 258 newType = (newType != null) ? newType : type; 259 } 260 cv.visitTryCatchBlock(start, end, handler, newType); 261 } 262 } 263 | Popular Tags |