1 4 package com.tc.aspectwerkz.transform.inlining.weaver; 5 6 import com.tc.asm.ClassAdapter; 7 import com.tc.asm.ClassVisitor; 8 9 import com.tc.aspectwerkz.definition.InterfaceIntroductionDefinition; 10 import com.tc.aspectwerkz.definition.MixinDefinition; 11 import com.tc.aspectwerkz.definition.SystemDefinition; 12 import com.tc.aspectwerkz.transform.InstrumentationContext; 13 import com.tc.aspectwerkz.transform.TransformationConstants; 14 import com.tc.aspectwerkz.reflect.ClassInfo; 15 import com.tc.aspectwerkz.expression.ExpressionContext; 16 import com.tc.aspectwerkz.expression.PointcutType; 17 18 import java.util.HashSet ; 19 import java.util.Iterator ; 20 import java.util.List ; 21 import java.util.Set ; 22 23 29 public class AddInterfaceVisitor extends ClassAdapter implements TransformationConstants { 30 31 private final static String ADVISABLE_MIXIN_IMPL_NAME = "com.tc.aspectwerkz.intercept.AdvisableImpl"; 32 33 private final InstrumentationContext m_ctx; 34 private final ClassInfo m_classInfo; 35 36 43 public AddInterfaceVisitor(final ClassVisitor cv, 44 final ClassInfo classInfo, 45 final InstrumentationContext ctx) { 46 super(cv); 47 m_classInfo = classInfo; 48 m_ctx = (InstrumentationContext) ctx; 49 } 50 51 60 public void visit(final int version, 61 final int access, 62 final String name, 63 final String signature, 64 final String superName, 65 final String [] interfaces) { 66 ExpressionContext ctx = new ExpressionContext(PointcutType.WITHIN, m_classInfo, m_classInfo); 67 if (classFilter(m_classInfo, ctx, m_ctx.getDefinitions())) { 68 super.visit(version, access, name, signature, superName, interfaces); 69 return; 70 } 71 72 final Set interfacesToAdd = new HashSet (); 75 76 for (int i = 0; i < interfaces.length; i++) { 78 interfacesToAdd.add(interfaces[i].replace('/', '.')); 79 } 80 81 final Set systemDefinitions = m_ctx.getDefinitions(); 83 for (Iterator it = systemDefinitions.iterator(); it.hasNext();) { 84 SystemDefinition systemDefinition = (SystemDefinition) it.next(); 85 final List interfaceIntroDefs = systemDefinition.getInterfaceIntroductionDefinitions(ctx); 86 for (Iterator it2 = interfaceIntroDefs.iterator(); it2.hasNext();) { 87 final InterfaceIntroductionDefinition interfaceIntroDef = (InterfaceIntroductionDefinition) it2.next(); 88 interfacesToAdd.addAll(interfaceIntroDef.getInterfaceClassNames()); 89 } 90 final List mixinDefinitions = systemDefinition.getMixinDefinitions(ctx); 91 for (Iterator it2 = mixinDefinitions.iterator(); it2.hasNext();) { 92 final MixinDefinition mixinDef = (MixinDefinition) it2.next(); 93 if (ADVISABLE_MIXIN_IMPL_NAME.equals(mixinDef.getMixinImpl().getName())) { 94 m_ctx.markMadeAdvisable(); 96 } 97 final List interfaceList = mixinDef.getInterfaceClassNames(); 98 for (Iterator it3 = interfaceList.iterator(); it3.hasNext();) { 99 interfacesToAdd.add(it3.next()); 100 } 101 } 102 } 103 104 110 int i = 0; 111 final String [] newInterfaceArray = new String [interfacesToAdd.size()]; 112 for (Iterator it = interfacesToAdd.iterator(); it.hasNext();) { 113 newInterfaceArray[i++] = (String ) it.next(); 114 } 115 116 for (int j = 0; j < newInterfaceArray.length; j++) { 117 newInterfaceArray[j] = newInterfaceArray[j].replace('.', '/'); 118 119 } 120 super.visit(version, access, name, signature, superName, newInterfaceArray); 121 m_ctx.markAsAdvised(); 122 } 123 124 132 public static boolean classFilter(final ClassInfo classInfo, 133 final ExpressionContext ctx, 134 final Set definitions) { 135 for (Iterator it = definitions.iterator(); it.hasNext();) { 136 SystemDefinition systemDef = (SystemDefinition) it.next(); 137 if (classInfo.isInterface()) { 138 return true; 139 } 140 String className = classInfo.getName().replace('/', '.'); 141 if (systemDef.inExcludePackage(className)) { 142 return true; 143 } 144 if (!systemDef.inIncludePackage(className)) { 145 return true; 146 } 147 if (systemDef.hasMixin(ctx) || systemDef.hasIntroducedInterface(ctx)) { 148 return false; 149 } 150 } 151 return true; 152 } 153 } | Popular Tags |