1 8 package org.codehaus.aspectwerkz.transform; 9 10 import org.codehaus.aspectwerkz.util.Util; 11 import org.codehaus.aspectwerkz.expression.SubtypePatternType; 12 import org.codehaus.aspectwerkz.expression.regexp.Pattern; 13 import org.codehaus.aspectwerkz.expression.regexp.TypePattern; 14 import org.codehaus.aspectwerkz.hook.ClassPreProcessor; 15 import org.codehaus.aspectwerkz.transform.inlining.InliningWeavingStrategy; 16 import org.codehaus.aspectwerkz.transform.inlining.EmittedJoinPoint; 17 import org.codehaus.aspectwerkz.transform.inlining.ContextImpl; 18 19 import java.util.Collection ; 20 import java.util.HashMap ; 21 import java.util.Map ; 22 23 45 public class AspectWerkzPreProcessor implements ClassPreProcessor { 46 47 private final static String AW_TRANSFORM_FILTER = "aspectwerkz.transform.filter"; 48 49 private final static String AW_TRANSFORM_VERBOSE = "aspectwerkz.transform.verbose"; 50 51 private final static String AW_TRANSFORM_DETAILS = "aspectwerkz.transform.details"; 52 53 private final static String AW_TRANSFORM_GENJP = "aspectwerkz.transform.genjp"; 54 55 private final static String AW_TRANSFORM_DUMP = "aspectwerkz.transform.dump"; 56 57 private final static TypePattern DUMP_PATTERN; 58 59 private final static boolean NOFILTER; 61 private final static boolean DUMP_BEFORE; 62 63 private final static boolean DUMP_AFTER; 64 65 public final static boolean VERBOSE; 66 67 public final static boolean DETAILS; 68 69 public final static boolean GENJP; 70 71 static { 72 String verbose = System.getProperty(AW_TRANSFORM_VERBOSE, null); 74 VERBOSE = "yes".equalsIgnoreCase(verbose) || "true".equalsIgnoreCase(verbose); 75 String details = System.getProperty(AW_TRANSFORM_DETAILS, null); 76 DETAILS = "yes".equalsIgnoreCase(details) || "true".equalsIgnoreCase(details); 77 String genjp = System.getProperty(AW_TRANSFORM_GENJP, null); 78 GENJP = "yes".equalsIgnoreCase(genjp) || "true".equalsIgnoreCase(genjp); 79 String filter = System.getProperty(AW_TRANSFORM_FILTER, null); 80 NOFILTER = "no".equalsIgnoreCase(filter) || "false".equalsIgnoreCase(filter); 81 String dumpPattern = System.getProperty(AW_TRANSFORM_DUMP, null); 82 if (dumpPattern == null) { 83 DUMP_BEFORE = false; 84 DUMP_AFTER = false; 85 DUMP_PATTERN = null; 86 } else { 87 dumpPattern = dumpPattern.trim(); 88 DUMP_AFTER = true; 89 DUMP_BEFORE = dumpPattern.indexOf(",before") > 0; 90 if (DUMP_BEFORE) { 91 DUMP_PATTERN = Pattern.compileTypePattern( 92 dumpPattern.substring(0, dumpPattern.indexOf(',')), 93 SubtypePatternType.NOT_HIERARCHICAL 94 ); 95 } else { 96 DUMP_PATTERN = Pattern.compileTypePattern(dumpPattern, SubtypePatternType.NOT_HIERARCHICAL); 97 } 98 } 99 } 100 101 104 private boolean m_initialized = false; 105 106 109 private WeavingStrategy m_weavingStrategy; 110 111 114 public void initialize() { 115 m_weavingStrategy = new InliningWeavingStrategy(); 116 m_initialized = true; 117 } 118 119 129 public byte[] preProcess(final String name, final byte[] bytecode, final ClassLoader loader) { 130 if (!NOFILTER) { 132 if ((loader == null) || (loader.getParent() == null)) { 133 return bytecode; 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 Context 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 Context _preProcess(final String className, final byte[] bytecode, final ClassLoader loader) { 166 final Context context = m_weavingStrategy.newContext(className, bytecode, loader); 167 168 dumpBefore(className, context); 171 172 m_weavingStrategy.transform(className, context); 174 175 dumpAfter(className, context); 177 178 return context; 180 } 181 182 190 public Output preProcessWithOutput(final String name, final byte[] bytecode, final ClassLoader loader) { 191 final String className = name.replace('/', '.'); 193 194 if (name.endsWith((TransformationConstants.JOIN_POINT_CLASS_SUFFIX))) { 196 Output output = new Output(); 197 output.bytecode = bytecode; 198 output.emittedJoinPoints = null; 199 return output; 200 } 201 202 Context context = _preProcess(className, bytecode, loader); 203 Output output = new Output(); 204 output.bytecode = context.getCurrentBytecode(); 205 output.emittedJoinPoints = 206 (EmittedJoinPoint[]) ((ContextImpl) context).getEmittedJoinPoints().toArray(new EmittedJoinPoint[0]); 207 208 for (int i = 0; i < output.emittedJoinPoints.length; i++) { 210 EmittedJoinPoint emittedJoinPoint = output.emittedJoinPoints[i]; 211 emittedJoinPoint.resolveLineNumber(context); 212 } 213 return output; 214 } 215 216 221 public static void log(final String msg) { 222 if (VERBOSE) { 223 System.out.println(msg); 224 } 225 } 226 227 232 private static boolean filter(final String klass) { 233 return (klass == null) 234 || klass.endsWith(TransformationConstants.JOIN_POINT_CLASS_SUFFIX) 235 || klass.startsWith("org.codehaus.aspectwerkz.") 236 || klass.startsWith("org.objectweb.asm.") 237 || klass.startsWith("com.karneim.") 238 || klass.startsWith("com.bluecast.") 239 || klass.startsWith("gnu.trove.") 240 || klass.startsWith("org.dom4j.") 241 || klass.startsWith("org.xml.sax.") 242 || klass.startsWith("javax.xml.parsers.") 243 || klass.startsWith("sun.reflect.Generated") || klass.startsWith("EDU.oswego.cs.dl.util.concurrent") 245 ; 246 } 247 248 254 public static void dumpBefore(final String className, final Context context) { 255 if (DUMP_BEFORE) { 256 if (DUMP_PATTERN.matches(className)) { 257 context.dump("_dump/before/"); 258 } 259 } 260 } 261 262 268 public static void dumpAfter(final String className, final Context context) { 269 if (DUMP_AFTER) { 270 if (DUMP_PATTERN.matches(className)) { 271 context.dump("_dump/" + (DUMP_BEFORE ? "after/" : "")); 272 } 273 } 274 } 275 276 279 public static class Output { 280 public byte[] bytecode; 281 public EmittedJoinPoint[] emittedJoinPoints; 282 } 283 284 } | Popular Tags |