1 4 package com.tc.aspectwerkz.transform; 5 6 import com.tc.aspectwerkz.expression.SubtypePatternType; 7 import com.tc.aspectwerkz.expression.regexp.Pattern; 8 import com.tc.aspectwerkz.expression.regexp.TypePattern; 9 import com.tc.aspectwerkz.hook.ClassPreProcessor; 10 import com.tc.aspectwerkz.transform.inlining.EmittedJoinPoint; 11 import com.tc.aspectwerkz.util.Util; 12 14 36 public class AspectWerkzPreProcessor implements ClassPreProcessor { 37 38 private final static String AW_TRANSFORM_FILTER = "aspectwerkz.transform.filter"; 39 40 private final static String AW_TRANSFORM_VERBOSE = "aspectwerkz.transform.verbose"; 41 42 private final static String AW_TRANSFORM_DETAILS = "aspectwerkz.transform.details"; 43 44 private final static String AW_TRANSFORM_GENJP = "aspectwerkz.transform.genjp"; 45 46 private final static String AW_TRANSFORM_DUMP = "aspectwerkz.transform.dump"; 47 48 public final static TypePattern DUMP_PATTERN; 49 50 private final static boolean NOFILTER; 52 public final static boolean DUMP_BEFORE; 53 54 public final static boolean DUMP_AFTER; 55 56 public static final String DUMP_DIR_BEFORE; 57 58 public static final String DUMP_DIR_AFTER; 59 60 public final static boolean VERBOSE; 61 62 public final static boolean DETAILS; 63 64 public final static boolean GENJP; 65 66 static { 67 String verbose = System.getProperty(AW_TRANSFORM_VERBOSE, null); 69 VERBOSE = "yes".equalsIgnoreCase(verbose) || "true".equalsIgnoreCase(verbose); 70 String details = System.getProperty(AW_TRANSFORM_DETAILS, null); 71 DETAILS = "yes".equalsIgnoreCase(details) || "true".equalsIgnoreCase(details); 72 String genjp = System.getProperty(AW_TRANSFORM_GENJP, null); 73 GENJP = "yes".equalsIgnoreCase(genjp) || "true".equalsIgnoreCase(genjp); 74 String filter = System.getProperty(AW_TRANSFORM_FILTER, null); 75 NOFILTER = "no".equalsIgnoreCase(filter) || "false".equalsIgnoreCase(filter); 76 String dumpPattern = System.getProperty(AW_TRANSFORM_DUMP, null); 77 if (dumpPattern == null) { 78 DUMP_BEFORE = false; 79 DUMP_AFTER = false; 80 DUMP_PATTERN = null; 81 } else { 82 dumpPattern = dumpPattern.trim(); 83 DUMP_AFTER = true; 84 DUMP_BEFORE = dumpPattern.indexOf(",before") > 0; 85 if (DUMP_BEFORE) { 86 DUMP_PATTERN = Pattern.compileTypePattern(dumpPattern.substring(0, dumpPattern.indexOf(',')), 87 SubtypePatternType.NOT_HIERARCHICAL); 88 } else { 89 DUMP_PATTERN = Pattern.compileTypePattern(dumpPattern, SubtypePatternType.NOT_HIERARCHICAL); 90 } 91 } 92 DUMP_DIR_BEFORE = "_dump/before"; 93 DUMP_DIR_AFTER = AspectWerkzPreProcessor.DUMP_BEFORE ? "_dump/after" : "_dump"; 94 } 95 96 99 private boolean m_initialized = false; 100 101 104 106 109 public void initialize() { 110 throw new RuntimeException ("NOT merged with the changed code yet"); 117 } 118 119 128 public byte[] preProcess(final String name, final byte[] bytecode, final ClassLoader loader) { 129 if (!NOFILTER) { 131 if ((loader == null) || (loader.getParent() == null)) { 132 return bytecode; 133 } 134 } 135 136 final String className = (name != null) ? name.replace('/', '.') : null; 138 139 if (filter(className) || !m_initialized) { 141 return bytecode; 142 } 143 if (VERBOSE) { 144 log(Util.classLoaderToString(loader) + ':' + className + '[' + Thread.currentThread().getName() + ']'); 145 } 146 147 try { 148 InstrumentationContext context = _preProcess(className, bytecode, loader); 149 return context.getCurrentBytecode(); 150 } catch (Exception e) { 151 log("failed " + className); 152 e.printStackTrace(); 153 return bytecode; 154 } 155 } 156 157 165 public InstrumentationContext _preProcess(final String className, final byte[] bytecode, final ClassLoader loader) { 166 167 final InstrumentationContext context = new InstrumentationContext(className, bytecode, loader); 169 170 dumpBefore(className, context); 173 174 final byte[] transformedBytes = bytecode; 177 context.setCurrentBytecode(transformedBytes); 178 179 181 dumpAfter(className, context); 183 184 return context; 186 } 187 188 196 public Output preProcessWithOutput(final String name, final byte[] bytecode, final ClassLoader loader) { 197 final String className = name.replace('/', '.'); 199 200 if (name.endsWith((TransformationConstants.JOIN_POINT_CLASS_SUFFIX))) { 202 Output output = new Output(); 203 output.bytecode = bytecode; 204 output.emittedJoinPoints = null; 205 return output; 206 } 207 208 InstrumentationContext context = _preProcess(className, bytecode, loader); 209 Output output = new Output(); 210 output.bytecode = context.getCurrentBytecode(); 211 output.emittedJoinPoints = (EmittedJoinPoint[]) context.getEmittedJoinPoints() 212 .toArray(new EmittedJoinPoint[0]); 213 214 for (int i = 0; i < output.emittedJoinPoints.length; i++) { 216 EmittedJoinPoint emittedJoinPoint = output.emittedJoinPoints[i]; 217 emittedJoinPoint.resolveLineNumber(context); 218 } 219 return output; 220 } 221 222 227 public static void log(final String msg) { 228 if (VERBOSE) { 229 System.out.println(msg); 230 } 231 } 232 233 238 private static boolean filter(final String klass) { 239 return (klass == null) || klass.endsWith("_AWFactory") || klass.endsWith(TransformationConstants.JOIN_POINT_CLASS_SUFFIX) 241 || klass.startsWith("com.tc.aspectwerkz.") 242 || klass.startsWith("com.tc.asm.") 243 || klass.startsWith("com.tc.jrexx.") 244 || klass.startsWith("com.bluecast.") 245 || klass.startsWith("gnu.trove.") 246 || klass.startsWith("org.dom4j.") 247 || klass.startsWith("org.xml.sax.") 248 || klass.startsWith("javax.xml.parsers.") 249 || klass.startsWith("sun.reflect.Generated") || klass.startsWith("EDU.oswego.cs.dl.util.concurrent"); 251 } 252 253 259 public static void dumpBefore(final String className, final InstrumentationContext context) { 260 if (DUMP_BEFORE) { 261 if (DUMP_PATTERN.matches(className)) { 262 context.dump("_dump/before/"); 263 } 264 } 265 } 266 267 273 public static void dumpAfter(final String className, final InstrumentationContext context) { 274 if (DUMP_AFTER) { 275 if (DUMP_PATTERN.matches(className)) { 276 context.dump("_dump/" + (DUMP_BEFORE ? "after/" : "")); 277 } 278 } 279 } 280 281 284 public static class Output { 285 public byte[] bytecode; 286 public EmittedJoinPoint[] emittedJoinPoints; 287 } 288 } | Popular Tags |