001 package railo.transformer.bytecode.util; 002 003 import org.objectweb.asm.ClassReader; 004 import org.objectweb.asm.ClassVisitor; 005 import org.objectweb.asm.ClassWriter; 006 import org.objectweb.asm.MethodVisitor; 007 import org.objectweb.asm.Opcodes; 008 009 import railo.commons.lang.StringUtil; 010 import railo.runtime.type.util.ListUtil; 011 012 public class ClassRenamer extends ClassVisitor implements Opcodes { 013 014 private final String newName; 015 private String oldName; 016 private boolean doNothing; 017 018 ClassRenamer(ClassVisitor cv, String newName) { 019 super(ASM4, cv); 020 newName=ListUtil.trim(newName, "\\/"); 021 this.newName = newName; 022 } 023 024 public void visit(int version, int access, String name, String signature,String superName, String[] interfaces) { 025 oldName=name; 026 doNothing=oldName.equals(newName); 027 028 cv.visit(version, ACC_PUBLIC, newName, signature, superName, interfaces); 029 } 030 031 public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { 032 MethodVisitor mv = cv.visitMethod(access, name, fixDesc(desc),fixSignature(signature), exceptions); 033 if (mv != null && (access & ACC_ABSTRACT) == 0) { 034 mv = new MethodRenamer(mv); 035 } 036 return mv; 037 } 038 039 class MethodRenamer extends MethodVisitor { 040 041 public MethodRenamer(final MethodVisitor mv) { 042 super(ASM4, mv); 043 } 044 045 public void visitTypeInsn(int i, String s) { 046 if (!doNothing && oldName.equals(s)) { 047 s = newName; 048 } 049 mv.visitTypeInsn(i, s); 050 } 051 052 public void visitFieldInsn(int opcode, String owner, String name, 053 String desc) { 054 if (!doNothing && oldName.equals(owner)) { 055 mv.visitFieldInsn(opcode, newName, name, fixDesc(desc)); 056 } else { 057 mv.visitFieldInsn(opcode, owner, name, fixDesc(desc)); 058 } 059 } 060 061 public void visitMethodInsn(int opcode, String owner, String name, 062 String desc) { 063 if (!doNothing && oldName.equals(owner)) { 064 mv.visitMethodInsn(opcode, newName, name, fixDesc(desc)); 065 } else { 066 mv.visitMethodInsn(opcode, owner, name, fixDesc(desc)); 067 } 068 } 069 } 070 071 private String fixDesc(String desc) { 072 //print.e("fixDesc:"+desc); 073 return _fix(desc); 074 } 075 076 private String fixSignature(String signature) { 077 //print.e("fixSignature:"+signature); 078 return _fix(signature); 079 } 080 081 private String _fix(String str) { 082 if (!doNothing && !StringUtil.isEmpty(str)) { 083 if (str.indexOf(oldName) != -1) { 084 str = StringUtil.replace(str, oldName, newName,false); 085 } 086 } 087 return str; 088 } 089 090 public static byte[] rename(byte[] src, String newName){ 091 ClassReader cr = new ClassReader(src); 092 ClassWriter cw = ASMUtil.getClassWriter(); 093 ClassVisitor ca = new ClassRenamer(cw,newName); 094 cr.accept(ca, ClassReader.SKIP_DEBUG); 095 return cw.toByteArray(); 096 } 097 098 /*public static void main(String[] args) throws Throwable { 099 String path = "/Users/mic/Projects/Railo/webroot/WEB-INF/railo/cfclasses/CF_Users_mic_Projects_Railo_webroot_jm4653/jira/test/test_cfm$cf.class"; 100 ResourceProvider frp = ResourcesImpl.getFileResourceProvider(); 101 Resource res = frp.getResource(path); 102 print.e(getClassName(res)); 103 }*/ 104 }