KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > codehaus > aspectwerkz > definition > MixinDefinition


1 /**************************************************************************************
2  * Copyright (c) Jonas Bonér, Alexandre Vasseur. All rights reserved. *
3  * http://aspectwerkz.codehaus.org *
4  * ---------------------------------------------------------------------------------- *
5  * The software in this package is published under the terms of the LGPL license *
6  * a copy of which has been included with this distribution in the license.txt file. *
7  **************************************************************************************/

8 package org.codehaus.aspectwerkz.definition;
9
10 import org.codehaus.aspectwerkz.expression.ExpressionInfo;
11 import org.codehaus.aspectwerkz.reflect.ClassInfo;
12 import org.codehaus.aspectwerkz.reflect.ClassInfoHelper;
13 import org.codehaus.aspectwerkz.reflect.MethodInfo;
14 import org.codehaus.aspectwerkz.reflect.impl.asm.AsmClassInfo;
15 import org.codehaus.aspectwerkz.DeploymentModel;
16 import org.codehaus.aspectwerkz.aspect.DefaultMixinFactory;
17 import org.codehaus.aspectwerkz.intercept.AdvisableImpl;
18 import org.codehaus.aspectwerkz.intercept.Advisable;
19 import org.codehaus.aspectwerkz.transform.TransformationConstants;
20
21 import java.util.ArrayList JavaDoc;
22 import java.util.Iterator JavaDoc;
23 import java.util.List JavaDoc;
24 import java.util.Map JavaDoc;
25 import java.util.HashMap JavaDoc;
26 import java.lang.ref.WeakReference JavaDoc;
27
28 /**
29  * Definition for the mixin construct.
30  *
31  * @author <a HREF="mailto:jboner@codehaus.org">Jonas Bonér </a>
32  */

33 public class MixinDefinition {
34
35     private final static String JavaDoc DEFAULT_MIXIN_FACTORY = DefaultMixinFactory.class.getName().replace('/', '.');
36     /**
37      * The deployment model for the mixin.
38      */

39     private DeploymentModel m_deploymentModel;
40
41     /**
42      * Flags the mixin as transient.
43      */

44     private boolean m_isTransient;
45
46     /**
47      * The introduced methods info list.
48      */

49     private final List JavaDoc m_methodsToIntroduce = new ArrayList JavaDoc();
50
51     /**
52      * The interface classes name.
53      */

54     private final List JavaDoc m_interfaceClassNames = new ArrayList JavaDoc();
55
56     /**
57      * The class name for the mixin impl.
58      */

59     private final String JavaDoc m_mixinImplClassName;
60
61     /**
62      * The class loader.
63      */

64     private final WeakReference JavaDoc m_loaderRef;
65
66     /**
67      * The mixin expressions.
68      */

69     private ExpressionInfo[] m_expressionInfos = new ExpressionInfo[]{};
70
71     /**
72      * The attribute for the mixin.
73      */

74     private String JavaDoc m_attribute = "";
75
76     /**
77      * The factory class name.
78      */

79     private String JavaDoc m_factoryClassName;
80
81     /**
82      * The system definition.
83      */

84     private SystemDefinition m_systemDefinition;
85
86     /**
87      * The parameters passed to the mixin at definition time.
88      */

89     private Map JavaDoc m_parameters = new HashMap JavaDoc();
90
91     /**
92      * Construct a new definition for mixin.
93      *
94      * @param mixinClass the mixin class
95      * @param deploymentModel mixin deployment model
96      * @param isTransient transient flag
97      * @param systemDef the system definition
98      */

99     public MixinDefinition(ClassInfo mixinClass,
100                            final DeploymentModel deploymentModel,
101                            final boolean isTransient,
102                            final SystemDefinition systemDef) {
103         if (isSystemMixin(mixinClass)) {
104             mixinClass = defineSystemMixin(mixinClass.getClassLoader());
105         } else {
106             List JavaDoc allInterfaces = ClassInfoHelper.collectInterfaces(mixinClass);
107             for (Iterator JavaDoc iterator = allInterfaces.iterator(); iterator.hasNext();) {
108                 ClassInfo interfaceInfo = (ClassInfo) iterator.next();
109                 m_interfaceClassNames.add(interfaceInfo.getName());
110             }
111
112             List JavaDoc interfaceDeclaredMethods = ClassInfoHelper.collectMethodsFromInterfacesImplementedBy(mixinClass);
113             List JavaDoc sortedMethodList = ClassInfoHelper.createInterfaceDefinedMethodList(
114                     mixinClass, interfaceDeclaredMethods
115             );
116             for (Iterator JavaDoc iterator = sortedMethodList.iterator(); iterator.hasNext();) {
117                 MethodInfo methodInfo = (MethodInfo) iterator.next();
118                 m_methodsToIntroduce.add(methodInfo);
119             }
120         }
121
122         m_mixinImplClassName = mixinClass.getName();
123         m_loaderRef = new WeakReference JavaDoc(mixinClass.getClassLoader());
124         m_systemDefinition = systemDef;
125         m_expressionInfos = new ExpressionInfo[]{};
126
127         m_deploymentModel = deploymentModel;
128         m_isTransient = isTransient;
129
130         // default factory
131
setFactoryClassName(DEFAULT_MIXIN_FACTORY);
132     }
133
134     /**
135      * Sets the factory class name.
136      *
137      * @param factoryClassName
138      */

139     public void setFactoryClassName(final String JavaDoc factoryClassName) {
140         m_factoryClassName = factoryClassName;
141     }
142
143     /**
144      * Returns the factory class name.
145      *
146      * @return
147      */

148     public String JavaDoc getFactoryClassName() {
149         return m_factoryClassName;
150     }
151
152     /**
153      * Returns the methods to introduce.
154      *
155      * @return the methods to introduce
156      */

157     public List JavaDoc getMethodsToIntroduce() {
158         return m_methodsToIntroduce;
159     }
160
161     /**
162      * Returns the deployment model.
163      *
164      * @return the deployment model
165      */

166     public DeploymentModel getDeploymentModel() {
167         return m_deploymentModel;
168     }
169
170     /**
171      * Sets the deployment model.
172      *
173      * @param deploymentModel
174      */

175     public void setDeploymentModel(final DeploymentModel deploymentModel) {
176         m_deploymentModel = deploymentModel;
177     }
178
179     /**
180      * Checks if the mixin is transient.
181      *
182      * @return
183      */

184     public boolean isTransient() {
185         return m_isTransient;
186     }
187
188     /**
189      * Sets the mixin as transient.
190      *
191      * @param isTransient
192      */

193     public void setTransient(boolean isTransient) {
194         m_isTransient = isTransient;
195     }
196
197     /**
198      * Returns the class info for the mixin impl.
199      *
200      * @return the class info
201      */

202     public ClassInfo getMixinImpl() {
203         return AsmClassInfo.getClassInfo(m_mixinImplClassName, (ClassLoader JavaDoc) m_loaderRef.get());
204     }
205
206     /**
207      * Returns the expressions.
208      *
209      * @return the expressions array
210      */

211     public ExpressionInfo[] getExpressionInfos() {
212         return m_expressionInfos;
213     }
214
215     /**
216      * Returns the class name of the interface.
217      *
218      * @return the class name of the interface
219      */

220     public List JavaDoc getInterfaceClassNames() {
221         return m_interfaceClassNames;
222     }
223
224     /**
225      * Returns the attribute.
226      *
227      * @return the attribute
228      */

229     public String JavaDoc getAttribute() {
230         return m_attribute;
231     }
232
233     /**
234      * Sets the attribute.
235      *
236      * @param attribute the attribute
237      */

238     public void setAttribute(final String JavaDoc attribute) {
239         m_attribute = attribute;
240     }
241
242     /**
243      * Returns the system definition.
244      *
245      * @return the system definition
246      */

247     public SystemDefinition getSystemDefinition() {
248         return m_systemDefinition;
249     }
250
251     /**
252      * Adds a new expression info.
253      *
254      * @param expression a new expression info
255      */

256     public void addExpressionInfo(final ExpressionInfo expression) {
257         final ExpressionInfo[] tmpExpressions = new ExpressionInfo[m_expressionInfos.length + 1];
258         java.lang.System.arraycopy(m_expressionInfos, 0, tmpExpressions, 0, m_expressionInfos.length);
259         tmpExpressions[m_expressionInfos.length] = expression;
260         m_expressionInfos = new ExpressionInfo[m_expressionInfos.length + 1];
261         java.lang.System.arraycopy(tmpExpressions, 0, m_expressionInfos, 0, tmpExpressions.length);
262     }
263
264     /**
265      * Adds an array with new expression infos.
266      *
267      * @param expressions an array with new expression infos
268      */

269     public void addExpressionInfos(final ExpressionInfo[] expressions) {
270         final ExpressionInfo[] tmpExpressions = new ExpressionInfo[m_expressionInfos.length + expressions.length];
271         java.lang.System.arraycopy(m_expressionInfos, 0, tmpExpressions, 0, m_expressionInfos.length);
272         java.lang.System.arraycopy(expressions, 0, tmpExpressions, m_expressionInfos.length, expressions.length);
273         m_expressionInfos = new ExpressionInfo[m_expressionInfos.length + expressions.length];
274         java.lang.System.arraycopy(tmpExpressions, 0, m_expressionInfos, 0, tmpExpressions.length);
275     }
276
277     /**
278      * Defines system mixins.
279      *
280      * @param loader
281      * @return
282      */

283     private ClassInfo defineSystemMixin(final ClassLoader JavaDoc loader) {
284         // if advisable impl mixin get the class info from the AsmClassInfo to keep the methods starting with aw$
285
ClassInfo mixinClass = AsmClassInfo.getClassInfo(AdvisableImpl.class.getName(), loader);
286         MethodInfo[] methods = mixinClass.getMethods();
287         for (int i = 0; i < methods.length; i++) {
288             MethodInfo method = methods[i];
289             if (method.getName().startsWith(TransformationConstants.SYNTHETIC_MEMBER_PREFIX)
290                 || method.getName().startsWith("aw_")) {//aw$ not reachable in IDEs without AW source code
291
m_methodsToIntroduce.add(method);
292             }
293         }
294         m_interfaceClassNames.add(Advisable.class.getName());
295         return mixinClass;
296     }
297
298     /**
299      * Checks if the mixin is a system mixin.
300      *
301      * @param mixinClass
302      * @return
303      */

304     private boolean isSystemMixin(final ClassInfo mixinClass) {
305         return mixinClass.getName().equals(AdvisableImpl.class.getName());
306     }
307
308     /**
309      * Adds a new parameter to the mixin.
310      *
311      * @param name the name of the parameter
312      * @param value the value for the parameter
313      */

314     public void addParameter(final String JavaDoc name, final String JavaDoc value) {
315         m_parameters.put(name, value);
316     }
317
318     /**
319      * Returns the parameters as a Map.
320      *
321      * @return the parameters
322      */

323     public Map JavaDoc getParameters() {
324         return m_parameters;
325     }
326
327 }
Popular Tags