1 4 package com.tc.aspectwerkz.transform.inlining; 5 6 import java.util.HashSet ; 7 import java.util.Iterator ; 8 import java.util.Set ; 9 10 import com.tc.asm.ClassReader; 11 import com.tc.asm.ClassVisitor; 12 import com.tc.asm.ClassWriter; 13 14 import com.tc.aspectwerkz.definition.SystemDefinition; 15 import com.tc.aspectwerkz.exception.WrappedRuntimeException; 16 import com.tc.aspectwerkz.reflect.impl.asm.AsmClassInfo; 17 import com.tc.aspectwerkz.reflect.ClassInfo; 18 import com.tc.aspectwerkz.transform.InstrumentationContext; 19 import com.tc.aspectwerkz.transform.WeavingStrategy; 20 import com.tc.aspectwerkz.transform.inlining.weaver.AddInterfaceVisitor; 21 import com.tc.aspectwerkz.transform.inlining.weaver.AddMixinMethodsVisitor; 22 import com.tc.aspectwerkz.transform.inlining.weaver.AddWrapperVisitor; 23 import com.tc.aspectwerkz.transform.inlining.weaver.JoinPointInitVisitor; 24 import com.tc.aspectwerkz.transform.inlining.weaver.MethodExecutionVisitor; 25 import com.tc.aspectwerkz.expression.ExpressionContext; 26 import com.tc.aspectwerkz.expression.PointcutType; 27 28 33 public class ProxyWeavingStrategy implements WeavingStrategy { 34 35 41 public void transform(String className, final InstrumentationContext context) { 42 try { 43 final byte[] bytecode = context.getInitialBytecode(); 44 final ClassLoader loader = context.getLoader(); 45 46 ClassInfo classInfo = AsmClassInfo.getClassInfo(className, bytecode, loader); 47 48 final Set definitions = context.getDefinitions(); 49 final ExpressionContext[] ctxs = new ExpressionContext[]{ 50 new ExpressionContext(PointcutType.EXECUTION, classInfo, classInfo) 51 }; 52 53 final boolean isAdvisable = !classFilter(definitions, ctxs, classInfo); 55 56 if (!isAdvisable) { 57 context.setCurrentBytecode(context.getInitialBytecode()); 58 return; 59 } 60 61 final ClassReader crLookahead = new ClassReader(bytecode); 63 64 Set addedMethods = new HashSet (); 65 67 final ClassWriter writerPhase1 = AsmHelper.newClassWriter(true); 70 final ClassReader readerPhase1 = new ClassReader(bytecode); 71 ClassVisitor reversedChainPhase1 = writerPhase1; 72 reversedChainPhase1 = new AddMixinMethodsVisitor(reversedChainPhase1, classInfo, context, addedMethods); 73 reversedChainPhase1 = new AddInterfaceVisitor(reversedChainPhase1, classInfo, context); 74 readerPhase1.accept(reversedChainPhase1, null, false); 75 context.setCurrentBytecode(writerPhase1.toByteArray()); 76 77 classInfo = AsmClassInfo.newClassInfo(context.getCurrentBytecode(), loader); 80 81 final ClassWriter writerPhase2 = AsmHelper.newClassWriter(true); 84 final ClassReader readerPhase2 = new ClassReader(context.getCurrentBytecode()); 85 ClassVisitor reversedChainPhase2 = writerPhase2; 86 reversedChainPhase2 = new MethodExecutionVisitor(reversedChainPhase2, classInfo, context, addedMethods); 88 readerPhase2.accept(reversedChainPhase2, null, false); 90 context.setCurrentBytecode(writerPhase2.toByteArray()); 91 92 if (context.isAdvised()) { 95 final ClassWriter writerPhase3 = AsmHelper.newClassWriter(true); 96 ClassReader readerPhase3 = new ClassReader(context.getCurrentBytecode()); 97 ClassVisitor reversedChainPhase3 = writerPhase3; 98 reversedChainPhase3 = new AddWrapperVisitor(reversedChainPhase3, context, addedMethods); 99 reversedChainPhase3 = new JoinPointInitVisitor(reversedChainPhase3, context); 100 readerPhase3.accept(reversedChainPhase3, null, false); 101 context.setCurrentBytecode(writerPhase3.toByteArray()); 102 } 103 } catch (Throwable t) { 104 t.printStackTrace(); 105 throw new WrappedRuntimeException(t); 106 } 107 } 108 109 117 private static boolean classFilter(final Set definitions, final ExpressionContext[] ctxs, final ClassInfo classInfo) { 118 if (classInfo.isInterface()) { 119 return true; 120 } 121 for (Iterator defs = definitions.iterator(); defs.hasNext();) { 122 if (classFilter((SystemDefinition) defs.next(), ctxs, classInfo)) { 123 continue; 124 } else { 125 return false; 126 } 127 } 128 return true; 129 } 130 131 141 private static boolean classFilter(final SystemDefinition definition, final ExpressionContext[] ctxs, 142 final ClassInfo classInfo) { 143 144 if (classInfo.isInterface()) { 145 return true; 146 } 147 String className = classInfo.getName(); 148 if (definition.inExcludePackage(className)) { 149 return true; 150 } 151 if (!definition.inIncludePackage(className)) { 152 return true; 153 } 154 if (definition.isAdvised(ctxs)) { 155 return false; 156 } 157 if (definition.hasMixin(ctxs)) { 158 return false; 159 } 160 if (definition.hasIntroducedInterface(ctxs)) { 161 return false; 162 } 163 if (definition.inPreparePackage(className)) { 164 return false; 165 } 166 return true; 167 } 168 169 private static boolean classFilterFor(final Set definitions, final ExpressionContext[] ctxs) { 170 for (Iterator defs = definitions.iterator(); defs.hasNext();) { 171 if (classFilterFor((SystemDefinition) defs.next(), ctxs)) { 172 continue; 173 } else { 174 return false; 175 } 176 } 177 return true; 178 } 179 180 private static boolean classFilterFor(final SystemDefinition definition, final ExpressionContext[] ctxs) { 181 if (definition.isAdvised(ctxs)) { 182 return false; 183 } 184 return true; 185 } 186 187 private static boolean hasPointcut(final Set definitions, final ExpressionContext ctx) { 188 for (Iterator defs = definitions.iterator(); defs.hasNext();) { 189 if (hasPointcut((SystemDefinition) defs.next(), ctx)) { 190 return true; 191 } else { 192 continue; 193 } 194 } 195 return false; 196 } 197 198 private static boolean hasPointcut(final SystemDefinition definition, final ExpressionContext ctx) { 199 if (definition.hasPointcut(ctx)) { 200 return true; 201 } 202 return false; 203 } 204 } 205 | Popular Tags |