KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > aspectwerkz > definition > MixinDefinition


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

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

36   private DeploymentModel m_deploymentModel;
37
38   /**
39    * Flags the mixin as transient.
40    */

41   private boolean m_isTransient;
42
43   /**
44    * The introduced methods info list.
45    */

46   private final List JavaDoc m_methodsToIntroduce = new ArrayList JavaDoc();
47
48   /**
49    * The interface classes name.
50    */

51   private final List JavaDoc m_interfaceClassNames = new ArrayList JavaDoc();
52
53   /**
54    * The class name for the mixin impl.
55    */

56   private final String JavaDoc m_mixinImplClassName;
57
58   /**
59    * The class loader.
60    */

61   private final WeakReference JavaDoc m_loaderRef;
62
63   /**
64    * The mixin expressions.
65    */

66   private ExpressionInfo[] m_expressionInfos = new ExpressionInfo[]{};
67
68   /**
69    * The attribute for the mixin.
70    */

71   private String JavaDoc m_attribute = "";
72
73   /**
74    * The factory class name.
75    */

76   private String JavaDoc m_factoryClassName;
77
78   /**
79    * The system definition.
80    */

81   private SystemDefinition m_systemDefinition;
82
83   /**
84    * The parameters passed to the mixin at definition time.
85    */

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

320   public Map JavaDoc getParameters() {
321     return m_parameters;
322   }
323
324 }
Popular Tags