1 2 package org.quilt.cl; 3 4 import java.util.Hashtable ; 5 import java.util.List ; 6 7 import org.apache.bcel.classfile.JavaClass; 8 import org.apache.bcel.classfile.Method; 9 import org.apache.bcel.generic.ClassGen; 10 import org.apache.bcel.generic.InstructionList; 11 import org.apache.bcel.generic.MethodGen; 12 13 20 public class ClassTransformer { 21 22 23 private Hashtable classHash = new Hashtable (); 24 25 26 private List cxf; 27 28 private List mxf; 29 30 private List gxf; 31 32 private MethodTransformer xformer; 33 34 35 boolean aborted_ = false; 36 37 46 public ClassTransformer (List cxf, List mxf, List gxf ) { 47 this.cxf = cxf; 48 this.mxf = mxf; 49 this.gxf = gxf; 50 xformer = new MethodTransformer (mxf, gxf); 51 } 52 53 public Hashtable getClassHash() { 54 return classHash; 55 } 56 private void zapClassXformer ( ClassXformer cxf, Exception e) { 57 System.err.println("WARNING: exception in " 58 + cxf.getName() + ": transformation will not be applied" ); 59 e.printStackTrace(); 60 cxf = null; 61 } 62 public JavaClass xform (JavaClass jc) { 63 if ( jc == null || ! jc.isClass() ) { 64 throw new IllegalArgumentException ("null or corrupt JavaClass"); 65 } 66 ClassGen clazz = new ClassGen(jc); 67 68 makePublic(clazz); 72 aborted_ = false; 74 ClassXformer[] xf = new ClassXformer[ cxf.size() ]; 75 for (int i = 0; i < xf.length; i++) { 76 try { 77 xf[i] = (ClassXformer) ( 78 (cxf.get(i)).getClass().newInstance() ); 79 xf[i].setClassTransformer(this); 80 } catch (IllegalAccessException e) { 81 zapClassXformer (xf[i], e); 82 } catch (InstantiationException e) { 83 zapClassXformer (xf[i], e); 84 } 85 if ( xf[i] != null && !aborted_) { 86 xf[i].preMethods(clazz); 87 } 88 } 89 90 if ( mxf.size() > 0 || gxf.size() > 0 && !aborted_) { 93 Method [] methods = clazz.getMethods(); 95 for (int i = 0; i < methods.length; i++) { 96 String methodName = methods[i].getName(); 97 if (methods[i].getCode() != null 98 && ! methodName.startsWith("q$$q") ) { 99 MethodGen result = xformer.xform ( clazz, methods[i] ); 101 if (result != null) { 103 clazz.replaceMethod(methods[i], result.getMethod()); 104 InstructionList ilist = result.getInstructionList(); 106 ilist.dispose(); 107 result = null; 108 } 109 } 110 } 111 } 112 for (int i = xf.length - 1; i >= 0; i--) { 114 if (xf[i] != null && !aborted_) { 115 xf[i].postMethods(clazz); 116 } 117 } 118 if (clazz == null || aborted_) { 119 System.out.println( 120 "ClassTransformer WARNING could not transform class"); 121 return jc; 122 } else { 123 return clazz.getJavaClass(); 124 } 125 } 126 127 132 protected static void makePublic (ClassGen cg) { 133 int flags = cg.getAccessFlags(); 134 flags &= ~ (org.apache.bcel.Constants.ACC_PRIVATE 135 | org.apache.bcel.Constants.ACC_PROTECTED); 136 flags |= org.apache.bcel.Constants.ACC_PUBLIC; 137 cg.setAccessFlags(flags); 138 if (!cg.isPublic()) { 139 System.out.println("WARNING: makePublic for " 140 + cg.getClassName() + " failed"); 141 } 142 } 143 144 public void abort() { 145 aborted_= true; 146 } 147 } 148 | Popular Tags |