1 8 package org.codehaus.aspectwerkz.transform.inlining.weaver; 9 10 import java.util.Iterator ; 11 import java.util.Set ; 12 import java.util.HashSet ; 13 import java.util.List ; 14 15 import org.objectweb.asm.*; 16 import org.codehaus.aspectwerkz.transform.Context; 17 import org.codehaus.aspectwerkz.transform.TransformationConstants; 18 import org.codehaus.aspectwerkz.transform.TransformationUtil; 19 import org.codehaus.aspectwerkz.transform.inlining.ContextImpl; 20 import org.codehaus.aspectwerkz.definition.SystemDefinition; 21 import org.codehaus.aspectwerkz.definition.InterfaceIntroductionDefinition; 22 import org.codehaus.aspectwerkz.definition.MixinDefinition; 23 import org.codehaus.aspectwerkz.expression.ExpressionContext; 24 import org.codehaus.aspectwerkz.expression.PointcutType; 25 import org.codehaus.aspectwerkz.reflect.ClassInfo; 26 import org.codehaus.aspectwerkz.reflect.ClassInfoHelper; 27 28 34 public class AddInterfaceVisitor extends ClassAdapter implements TransformationConstants { 35 36 private final static String ADVISABLE_MIXIN_IMPL_NAME = "org.codehaus.aspectwerkz.intercept.AdvisableImpl"; 37 38 private final ContextImpl m_ctx; 39 private final ClassInfo m_classInfo; 40 41 48 public AddInterfaceVisitor(final ClassVisitor cv, 49 final ClassInfo classInfo, 50 final Context ctx) { 51 super(cv); 52 m_classInfo = classInfo; 53 m_ctx = (ContextImpl) ctx; 54 } 55 56 65 public void visit(final int version, 66 final int access, 67 final String name, 68 final String superName, 69 final String [] interfaces, 70 final String sourceFile) { 71 ExpressionContext ctx = new ExpressionContext(PointcutType.WITHIN, m_classInfo, m_classInfo); 72 if (classFilter(m_classInfo, ctx, m_ctx.getDefinitions())) { 73 super.visit(version, access, name, superName, interfaces, sourceFile); 74 return; 75 } 76 77 final Set interfacesToAdd = new HashSet (); 80 81 for (int i = 0; i < interfaces.length; i++) { 83 interfacesToAdd.add(interfaces[i].replace('/', '.')); 84 } 85 86 final Set systemDefinitions = m_ctx.getDefinitions(); 88 for (Iterator it = systemDefinitions.iterator(); it.hasNext();) { 89 SystemDefinition systemDefinition = (SystemDefinition) it.next(); 90 final List interfaceIntroDefs = systemDefinition.getInterfaceIntroductionDefinitions(ctx); 91 for (Iterator it2 = interfaceIntroDefs.iterator(); it2.hasNext();) { 92 final InterfaceIntroductionDefinition interfaceIntroDef = (InterfaceIntroductionDefinition) it2.next(); 93 interfacesToAdd.addAll(interfaceIntroDef.getInterfaceClassNames()); 94 } 95 final List mixinDefinitions = systemDefinition.getMixinDefinitions(ctx); 96 for (Iterator it2 = mixinDefinitions.iterator(); it2.hasNext();) { 97 final MixinDefinition mixinDef = (MixinDefinition) it2.next(); 98 if (ADVISABLE_MIXIN_IMPL_NAME.equals(mixinDef.getMixinImpl().getName())) { 99 m_ctx.markMadeAdvisable(); 101 } 102 final List interfaceList = mixinDef.getInterfaceClassNames(); 103 for (Iterator it3 = interfaceList.iterator(); it3.hasNext();) { 104 interfacesToAdd.add(((String ) it3.next())); 105 } 106 } 107 } 108 109 if (ClassInfoHelper.hasMethodClash(interfacesToAdd, m_ctx.getLoader())) { 110 super.visit(version, access, name, superName, interfaces, sourceFile); 111 return; 112 } 113 114 int i = 0; 115 final String [] newInterfaceArray = new String [interfacesToAdd.size()]; 116 for (Iterator it = interfacesToAdd.iterator(); it.hasNext();) { 117 newInterfaceArray[i++] = (String ) it.next(); 118 } 119 120 for (int j = 0; j < newInterfaceArray.length; j++) { 121 newInterfaceArray[j] = newInterfaceArray[j].replace('.', '/'); 122 123 } 124 super.visit(version, access, name, superName, newInterfaceArray, sourceFile); 125 m_ctx.markAsAdvised(); 126 } 127 128 136 public static boolean classFilter(final ClassInfo classInfo, 137 final ExpressionContext ctx, 138 final Set definitions) { 139 for (Iterator it = definitions.iterator(); it.hasNext();) { 140 SystemDefinition systemDef = (SystemDefinition) it.next(); 141 if (classInfo.isInterface()) { 142 return true; 143 } 144 String className = classInfo.getName().replace('/', '.'); 145 if (systemDef.inExcludePackage(className)) { 146 return true; 147 } 148 if (!systemDef.inIncludePackage(className)) { 149 return true; 150 } 151 if (systemDef.hasMixin(ctx) || systemDef.hasIntroducedInterface(ctx)) { 152 return false; 153 } 154 } 155 return true; 156 } 157 } | Popular Tags |