KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > aspectwerkz > transform > inlining > weaver > AddInterfaceVisitor


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

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 JavaDoc;
19 import java.util.Iterator JavaDoc;
20 import java.util.List JavaDoc;
21 import java.util.Set JavaDoc;
22
23 /**
24  * Adds an interface to the target class.
25  *
26  * @author <a HREF="mailto:jboner@codehaus.org">Jonas BonŽr </a>
27  * @author <a HREF="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
28  */

29 public class AddInterfaceVisitor extends ClassAdapter implements TransformationConstants {
30
31   private final static String JavaDoc ADVISABLE_MIXIN_IMPL_NAME = "com.tc.aspectwerkz.intercept.AdvisableImpl";
32
33   private final InstrumentationContext m_ctx;
34   private final ClassInfo m_classInfo;
35
36   /**
37    * Creates a new add interface class adapter.
38    *
39    * @param cv
40    * @param classInfo
41    * @param ctx
42    */

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   /**
52    * Visits the class.
53    *
54    * @param access
55    * @param name
56    * @param signature
57    * @param superName
58    * @param interfaces
59    */

60   public void visit(final int version,
61                     final int access,
62                     final String JavaDoc name,
63                     final String JavaDoc signature,
64                     final String JavaDoc superName,
65                     final String JavaDoc[] 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     // javaclass names of interface to have
73
// use a Set to avoid doublons
74
final Set JavaDoc interfacesToAdd = new HashSet JavaDoc();
75
76     // already there interface javaclass names
77
for (int i = 0; i < interfaces.length; i++) {
78       interfacesToAdd.add(interfaces[i].replace('/', '.'));
79     }
80
81     // add new ones
82
final Set JavaDoc systemDefinitions = m_ctx.getDefinitions();
83     for (Iterator JavaDoc it = systemDefinitions.iterator(); it.hasNext();) {
84       SystemDefinition systemDefinition = (SystemDefinition) it.next();
85       final List JavaDoc interfaceIntroDefs = systemDefinition.getInterfaceIntroductionDefinitions(ctx);
86       for (Iterator JavaDoc it2 = interfaceIntroDefs.iterator(); it2.hasNext();) {
87         final InterfaceIntroductionDefinition interfaceIntroDef = (InterfaceIntroductionDefinition) it2.next();
88         interfacesToAdd.addAll(interfaceIntroDef.getInterfaceClassNames());
89       }
90       final List JavaDoc mixinDefinitions = systemDefinition.getMixinDefinitions(ctx);
91       for (Iterator JavaDoc it2 = mixinDefinitions.iterator(); it2.hasNext();) {
92         final MixinDefinition mixinDef = (MixinDefinition) it2.next();
93         if (ADVISABLE_MIXIN_IMPL_NAME.equals(mixinDef.getMixinImpl().getName())) {
94           // mark it as made advisable
95
m_ctx.markMadeAdvisable();
96         }
97         final List JavaDoc interfaceList = mixinDef.getInterfaceClassNames();
98         for (Iterator JavaDoc it3 = interfaceList.iterator(); it3.hasNext();) {
99           interfacesToAdd.add(it3.next());
100         }
101       }
102     }
103
104     //TODO refactor to handle precedence injection
105
// if (ClassInfoHelper.hasMethodClash(interfacesToAdd, m_ctx.getLoader())) {
106
// super.visit(version, access, name, superName, interfaces, sourceFile);
107
// return;
108
// }
109

110     int i = 0;
111     final String JavaDoc[] newInterfaceArray = new String JavaDoc[interfacesToAdd.size()];
112     for (Iterator JavaDoc it = interfacesToAdd.iterator(); it.hasNext();) {
113       newInterfaceArray[i++] = (String JavaDoc) 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   /**
125    * Filters the classes to be transformed.
126    *
127    * @param classInfo the class to filter
128    * @param ctx the context
129    * @param definitions a set with the definitions
130    * @return boolean true if the method should be filtered away
131    */

132   public static boolean classFilter(final ClassInfo classInfo,
133                                     final ExpressionContext ctx,
134                                     final Set JavaDoc definitions) {
135     for (Iterator JavaDoc it = definitions.iterator(); it.hasNext();) {
136       SystemDefinition systemDef = (SystemDefinition) it.next();
137       if (classInfo.isInterface()) {
138         return true;
139       }
140       String JavaDoc 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