KickJava   Java API By Example, From Geeks To Geeks.

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


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.expression.ExpressionNamespace;
12 import org.codehaus.aspectwerkz.expression.regexp.Pattern;
13 import org.codehaus.aspectwerkz.util.Strings;
14 import org.codehaus.aspectwerkz.aspect.AdviceType;
15 import org.codehaus.aspectwerkz.DeploymentModel;
16 import org.codehaus.aspectwerkz.reflect.MethodInfo;
17 import org.codehaus.aspectwerkz.reflect.ClassInfo;
18 import org.codehaus.aspectwerkz.exception.DefinitionException;
19
20 import java.util.Iterator JavaDoc;
21 import java.util.Collection JavaDoc;
22
23 /**
24  * Helper class for the attribute and the XML definition parsers.
25  *
26  * @author <a HREF="mailto:jboner@codehaus.org">Jonas Bonér </a>
27  * @author <a HREF="mailto:alex@gnilux.com">Alexandre Vasseur </a>
28  */

29 public class DefinitionParserHelper {
30     public static final String JavaDoc EXPRESSION_PREFIX = "AW_";
31
32     /**
33      * Creates and adds pointcut definition to aspect definition.
34      *
35      * @param name
36      * @param expression
37      * @param aspectDef
38      */

39     public static void createAndAddPointcutDefToAspectDef(final String JavaDoc name,
40                                                           final String JavaDoc expression,
41                                                           final AspectDefinition aspectDef) {
42         PointcutDefinition pointcutDef = new PointcutDefinition(expression);
43         aspectDef.addPointcutDefinition(pointcutDef);
44
45         // name can be the "pcName(paramType paramName)"
46
// extract the parameter name to type map
47
// and register the pointcut using its name
48
//TODO: support for same pc name and different signature
49
String JavaDoc pointcutName = name;
50         String JavaDoc pointcutCallSignature = null;
51         if (name.indexOf("(") > 0) {
52             pointcutName = name.substring(0, name.indexOf("("));
53             pointcutCallSignature = name.substring(name.indexOf("(") + 1, name.lastIndexOf(")"));
54         }
55
56         // do a lookup first to avoid infinite recursion when:
57
// <pointcut name="pc" ...> [will be registered as pc]
58
// <advice bind-to="pc" ...> [will be registered as pc and should not override previous one !]
59
ExpressionNamespace namespace = ExpressionNamespace.getNamespace(aspectDef.getQualifiedName());
60         ExpressionInfo info = namespace.getExpressionInfoOrNull(pointcutName);
61         if (info == null) {
62             info = new ExpressionInfo(expression, aspectDef.getQualifiedName());
63             // extract the pointcut signature map
64
if (pointcutCallSignature != null) {
65                 String JavaDoc[] parameters = Strings.splitString(pointcutCallSignature, ",");
66                 for (int i = 0; i < parameters.length; i++) {
67                     String JavaDoc[] parameterInfo = Strings.splitString(
68                             Strings.replaceSubString(parameters[i].trim(), " ", " "),
69                             " "
70                     );
71                     info.addArgument(parameterInfo[1], parameterInfo[0], aspectDef.getClassInfo().getClassLoader());
72                 }
73             }
74         }
75         ExpressionNamespace.getNamespace(aspectDef.getQualifiedName()).addExpressionInfo(pointcutName, info);
76     }
77
78     /**
79      * Creates and adds a prepared pointcut definition to virtual aspect definition.
80      *
81      * @param name
82      * @param expression
83      * @param systemDef
84      */

85     public static void createAndAddDeploymentScopeDef(final String JavaDoc name,
86                                                       final String JavaDoc expression,
87                                                       final SystemDefinition systemDef) {
88         AspectDefinition aspectDef = systemDef.getAspectDefinition(Virtual.class.getName());
89         aspectDef.addPointcutDefinition(new PointcutDefinition(expression));
90         systemDef.addDeploymentScope(new DeploymentScope(name, expression));
91     }
92
93     /**
94      * Creates and adds an advisable definition to virtual aspect definition.
95      *
96      * @param expression
97      * @param systemDef
98      */

99     public static void createAndAddAdvisableDef(final String JavaDoc expression, final SystemDefinition systemDef) {
100         AspectDefinition virtualAspectDef = systemDef.getAspectDefinition(Virtual.class.getName());
101         virtualAspectDef.addPointcutDefinition(new PointcutDefinition(expression));
102
103         AdviceDefinition virtualAdviceDef = (AdviceDefinition) virtualAspectDef.getBeforeAdviceDefinitions().get(0);
104         ExpressionInfo oldExpressionInfo = virtualAdviceDef.getExpressionInfo();
105         String JavaDoc newExpression;
106         if (oldExpressionInfo != null) {
107             String JavaDoc oldExpression = oldExpressionInfo.toString();
108             newExpression = oldExpression + " || " + expression;
109         } else {
110             newExpression = expression;
111         }
112
113         virtualAdviceDef.setExpressionInfo(
114                 new ExpressionInfo(
115                         newExpression,
116                         virtualAspectDef.getQualifiedName()
117                 )
118         );
119     }
120
121     /**
122      * Attaches all deployment scopes in a system to the virtual advice.
123      *
124      * @param systemDef the system definition
125      */

126     public static void attachDeploymentScopeDefsToVirtualAdvice(final SystemDefinition systemDef) {
127         final AspectDefinition virtualAspectDef = systemDef.getAspectDefinition(Virtual.class.getName());
128         final AdviceDefinition virtualAdviceDef = (AdviceDefinition) virtualAspectDef.getBeforeAdviceDefinitions().get(
129                 0
130         );
131
132         final StringBuffer JavaDoc newExpression = new StringBuffer JavaDoc();
133         final ExpressionInfo oldExpressionInfo = virtualAdviceDef.getExpressionInfo();
134         if (oldExpressionInfo != null) {
135             String JavaDoc oldExpression = oldExpressionInfo.toString();
136             newExpression.append(oldExpression);
137         }
138         final Collection JavaDoc deploymentScopes = systemDef.getDeploymentScopes();
139         if (deploymentScopes.size() != 0 && oldExpressionInfo != null) {
140             newExpression.append(" || ");
141         }
142         for (Iterator JavaDoc it = deploymentScopes.iterator(); it.hasNext();) {
143             DeploymentScope deploymentScope = (DeploymentScope) it.next();
144             newExpression.append(deploymentScope.getExpression());
145             if (it.hasNext()) {
146                 newExpression.append(" || ");
147             }
148         }
149         if (newExpression.length() != 0) {
150             virtualAdviceDef.setExpressionInfo(
151                     new ExpressionInfo(
152                             newExpression.toString(),
153                             virtualAspectDef.getQualifiedName()
154                     )
155             );
156         }
157     }
158
159     /**
160      * Creates and add mixin definition to system definition.
161      *
162      * @param mixinClassInfo
163      * @param expression
164      * @param deploymentModel
165      * @param isTransient
166      * @param systemDef
167      * @return the mixin definition
168      */

169     public static MixinDefinition createAndAddMixinDefToSystemDef(final ClassInfo mixinClassInfo,
170                                                                   final String JavaDoc expression,
171                                                                   final DeploymentModel deploymentModel,
172                                                                   final boolean isTransient,
173                                                                   final SystemDefinition systemDef) {
174         final MixinDefinition mixinDef = createMixinDefinition(
175                 mixinClassInfo,
176                 expression,
177                 deploymentModel,
178                 isTransient,
179                 systemDef
180         );
181
182         // check doublons - TODO change ArrayList to HashMap since NAME is a key
183
MixinDefinition doublon = null;
184         for (Iterator JavaDoc intros = systemDef.getMixinDefinitions().iterator(); intros.hasNext();) {
185             MixinDefinition intro = (MixinDefinition) intros.next();
186             if (intro.getMixinImpl().getName().equals(mixinDef.getMixinImpl().getName())) {
187                 doublon = intro;
188                 intro.addExpressionInfos(mixinDef.getExpressionInfos());
189                 break;
190             }
191         }
192         if (doublon == null) {
193             systemDef.addMixinDefinition(mixinDef);
194         }
195         return mixinDef;
196     }
197
198     /**
199      * Creates and add interface introduction definition to aspect definition.
200      *
201      * @param expression
202      * @param introductionName
203      * @param interfaceClassName
204      * @param aspectDef
205      */

206     public static void createAndAddInterfaceIntroductionDefToAspectDef(final String JavaDoc expression,
207                                                                        final String JavaDoc introductionName,
208                                                                        final String JavaDoc interfaceClassName,
209                                                                        final AspectDefinition aspectDef) {
210         // Introduction name is unique within an aspectDef only
211
InterfaceIntroductionDefinition introDef = createInterfaceIntroductionDefinition(
212                 introductionName,
213                 expression,
214                 interfaceClassName,
215                 aspectDef
216         );
217         aspectDef.addInterfaceIntroductionDefinition(introDef);
218     }
219
220     /**
221      * Creates a new advice definition.
222      *
223      * @param adviceName the advice name
224      * @param adviceType the advice type
225      * @param expression the advice expression
226      * @param specialArgumentType the arg
227      * @param aspectName the aspect name
228      * @param aspectClassName the aspect class name
229      * @param methodInfo the advice methodInfo
230      * @param aspectDef the aspect definition
231      * @return the new advice definition
232      */

233     public static AdviceDefinition createAdviceDefinition(final String JavaDoc adviceName,
234                                                           final AdviceType adviceType,
235                                                           final String JavaDoc expression,
236                                                           final String JavaDoc specialArgumentType,
237                                                           final String JavaDoc aspectName,
238                                                           final String JavaDoc aspectClassName,
239                                                           final MethodInfo methodInfo,
240                                                           final AspectDefinition aspectDef) {
241         ExpressionInfo expressionInfo = new ExpressionInfo(
242                 expression,
243                 aspectDef.getQualifiedName()
244         );
245
246         // support for pointcut signature
247
String JavaDoc adviceCallSignature = null;
248         String JavaDoc resolvedSpecialArgumentType = specialArgumentType;
249         if (adviceName.indexOf('(') > 0) {
250             adviceCallSignature = adviceName.substring(adviceName.indexOf('(') + 1, adviceName.lastIndexOf(')'));
251             String JavaDoc[] parameters = Strings.splitString(adviceCallSignature, ",");
252             for (int i = 0; i < parameters.length; i++) {
253                 String JavaDoc[] parameterInfo = Strings.splitString(
254                         Strings.replaceSubString(parameters[i].trim(), " ", " "),
255                         " "
256                 );
257                 // Note: for XML defined aspect, we support anonymous parameters like
258
// advice(JoinPoint, Rtti) as well as abbreviations, so we have to assign
259
// them a name here, as well as their real type
260
String JavaDoc paramName, paramType = null;
261                 if (parameterInfo.length == 2) {
262                     paramName = parameterInfo[1];
263                     paramType = parameterInfo[0];
264                 } else {
265                     paramName = "anonymous_" + i;
266                     paramType = (String JavaDoc) Pattern.ABBREVIATIONS.get(parameterInfo[0]);
267                 }
268                 // skip the parameter if this ones is a after returning / throwing binding
269
if (paramName.equals(specialArgumentType)) {
270                     resolvedSpecialArgumentType = paramType;
271                     expressionInfo.setSpecialArgumentName(paramName);
272                 } else {
273                     expressionInfo.addArgument(paramName, paramType, aspectDef.getClassInfo().getClassLoader());
274                 }
275             }
276         }
277
278         // check that around advice return Object else the compiler will fail
279
if (adviceType.equals(AdviceType.AROUND)) {
280             if (!"java.lang.Object".equals(methodInfo.getReturnType().getName())) {
281                 throw new DefinitionException(
282                         "around advice must return java.lang.Object : " + aspectClassName + "." + methodInfo.getName()
283                 );
284             }
285         }
286
287         final AdviceDefinition adviceDef = new AdviceDefinition(
288                 adviceName,
289                 adviceType,
290                 resolvedSpecialArgumentType,
291                 aspectName,
292                 aspectClassName,
293                 expressionInfo,
294                 methodInfo,
295                 aspectDef
296         );
297         return adviceDef;
298     }
299
300     /**
301      * Creates an introduction definition.
302      *
303      * @param mixinClassInfo
304      * @param expression
305      * @param deploymentModel
306      * @param isTransient
307      * @param systemDef
308      * @return
309      */

310     public static MixinDefinition createMixinDefinition(final ClassInfo mixinClassInfo,
311                                                         final String JavaDoc expression,
312                                                         final DeploymentModel deploymentModel,
313                                                         final boolean isTransient,
314                                                         final SystemDefinition systemDef) {
315         final MixinDefinition mixinDef = new MixinDefinition(mixinClassInfo, deploymentModel, isTransient, systemDef);
316         if (expression != null) {
317             ExpressionInfo expressionInfo = new ExpressionInfo(expression, systemDef.getUuid());
318
319             // auto-name the pointcut which is anonymous for introduction
320
ExpressionNamespace.getNamespace(systemDef.getUuid()).addExpressionInfo(
321                     EXPRESSION_PREFIX + expression.hashCode(),
322                     expressionInfo
323             );
324             mixinDef.addExpressionInfo(expressionInfo);
325         }
326         return mixinDef;
327     }
328
329     /**
330      * Creates a new interface introduction definition.
331      *
332      * @param introductionName the introduction name
333      * @param expression the pointcut expression
334      * @param interfaceClassName the class name of the interface
335      * @param aspectDef the aspect definition
336      * @return the new introduction definition
337      */

338     public static InterfaceIntroductionDefinition createInterfaceIntroductionDefinition(final String JavaDoc introductionName,
339                                                                                         final String JavaDoc expression,
340                                                                                         final String JavaDoc interfaceClassName,
341                                                                                         final AspectDefinition aspectDef) {
342         final InterfaceIntroductionDefinition introDef = new InterfaceIntroductionDefinition(
343                 introductionName, interfaceClassName
344         );
345         if (expression != null) {
346             ExpressionInfo expressionInfo = new ExpressionInfo(expression, aspectDef.getQualifiedName());
347
348             // auto-name the pointcut which is anonymous for introduction
349
ExpressionNamespace.getNamespace(aspectDef.getQualifiedName()).addExpressionInfo(
350                     EXPRESSION_PREFIX + expression.hashCode(),
351                     expressionInfo
352             );
353             introDef.addExpressionInfo(expressionInfo);
354         }
355         return introDef;
356     }
357
358 }
Popular Tags