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.DeploymentModel;
11 import org.codehaus.aspectwerkz.util.Strings;
12 import org.codehaus.aspectwerkz.aspect.AdviceType;
13 import org.codehaus.aspectwerkz.reflect.impl.java.JavaClassInfo;
14 import org.codehaus.aspectwerkz.expression.regexp.Pattern;
15 import org.codehaus.aspectwerkz.joinpoint.JoinPoint;
16 import org.codehaus.aspectwerkz.annotation.AspectAnnotationParser;
17 import org.codehaus.aspectwerkz.exception.DefinitionException;
18 import org.codehaus.aspectwerkz.exception.WrappedRuntimeException;
19 import org.codehaus.aspectwerkz.transform.ReflectHelper;
20 import org.dom4j.Attribute;
21 import org.dom4j.Document;
22 import org.dom4j.Element;
23
24 import java.lang.reflect.Method;
25 import java.util.ArrayList;
26 import java.util.Iterator;
27 import java.util.List;
28
29 /***
30 * Parses the XML definition using <tt>dom4j</tt>.
31 *
32 * @author <a href="mailto:jboner@codehaus.org">Jonas Bonér </a>
33 * @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur </a>
34 */
35 public class DocumentParser {
36
37 /***
38 * Parses aspect class names.
39 *
40 * @param document the defintion as a document
41 * @return the aspect class names
42 */
43 public static List parseAspectClassNames(final Document document) {
44 final List aspectClassNames = new ArrayList();
45 for (Iterator it1 = document.getRootElement().elementIterator("system"); it1.hasNext();) {
46 Element system = (Element) it1.next();
47 final String packageName = getBasePackage(system);
48 for (Iterator it11 = system.elementIterator("aspect"); it11.hasNext();) {
49 String className = null;
50 Element aspect = (Element) it11.next();
51 for (Iterator it2 = aspect.attributeIterator(); it2.hasNext();) {
52 Attribute attribute = (Attribute) it2.next();
53 final String name = attribute.getName().trim();
54 final String value = attribute.getValue().trim();
55 if (name.equalsIgnoreCase("class")) {
56 className = value;
57 }
58 }
59 String aspectClassName = packageName + className;
60 aspectClassNames.add(aspectClassName);
61 }
62 for (Iterator it11 = system.elementIterator("package"); it11.hasNext();) {
63 g>final Element packageElement = ((Element) it11.next());
64 g>final String packageName1 = getPackage(packageElement);
65 ong>for (Iterator it12 = packageElement.elementIterator("aspect"); it12.hasNext();) {
66 String className = null;
67 Element aspect = (Element) it12.next();
68 for (Iterator it2 = aspect.attributeIterator(); it2.hasNext();) {
69 Attribute attribute = (Attribute) it2.next();
70 final String name = attribute.getName().trim();
71 final String value = attribute.getValue().trim();
72 if (name.equalsIgnoreCase("class")) {
73 className = value;
74 }
75 }
76 String aspectClassName = packageName1 + className;
77 aspectClassNames.add(aspectClassName);
78 }
79 }
80 }
81 return aspectClassNames;
82 }
83
84 /***
85 * Parses the definition DOM document.
86 *
87 * @param loader the current class loader
88 * @param document the defintion as a document
89 * @return the definitions
90 */
91 public static List parse(final ClassLoader loader, final Document document) {
92 final Element root = document.getRootElement();
93
94
95 return parseSystemElements(loader, root);
96 }
97
98 /***
99 * Parses the <tt>system</tt> elements.
100 *
101 * @param loader the current class loader
102 * @param root the root element
103 */
104 private static List parseSystemElements(final ClassLoader loader, final Element root) {
105 final List systemDefs = new ArrayList();
106 for (Iterator it1 = root.elementIterator("system"); it1.hasNext();) {
107 Element system = (Element) it1.next();
108 SystemDefinition definition = parseSystemElement(loader, system, getBasePackage(system));
109 if (definition != null) {
110 systemDefs.add(definition);
111 }
112 }
113 return systemDefs;
114 }
115
116 /***
117 * Parses the <tt>system</tt> elements.
118 *
119 * @param loader the current class loader
120 * @param systemElement the system element
121 * @param basePackage the base package
122 * @return the definition for the system
123 */
124 private static SystemDefinition parseSystemElement(final ClassLoader loader,
125 final Element systemElement,
126 final String basePackage) {
127 String uuid = systemElement.attributeValue("id");
128 if ((uuid == null) || uuid.equals("")) {
129 throw new DefinitionException("system UUID must be specified");
130 }
131 final SystemDefinition definition = new SystemDefinition(uuid);
132
133
134 List globalPointcuts = parseGlobalPointcuts(systemElement);
135
136
137 parseIncludePackageElements(systemElement, definition, basePackage);
138 parseExcludePackageElements(systemElement, definition, basePackage);
139 parsePrepareElements(systemElement, definition, basePackage);
140
141
142 parseAspectElements(loader, systemElement, definition, basePackage, globalPointcuts);
143
144
145 parsePackageElements(loader, systemElement, definition, basePackage, globalPointcuts);
146 return definition;
147 }
148
149 /***
150 * Parses the global pointcuts.
151 *
152 * @param systemElement the system element
153 * @return a list with the pointcuts
154 */
155 private static List parseGlobalPointcuts(final Element systemElement) {
156 final List globalPointcuts = new ArrayList();
157 for (Iterator it11 = systemElement.elementIterator("pointcut"); it11.hasNext();) {
158 PointcutInfo pointcutInfo = new PointcutInfo();
159 Element globalPointcut = (Element) it11.next();
160 for (Iterator it2 = globalPointcut.attributeIterator(); it2.hasNext();) {
161 Attribute attribute = (Attribute) it2.next();
162 final String name = attribute.getName().trim();
163 final String value = attribute.getValue().trim();
164 if (name.equalsIgnoreCase("name")) {
165 pointcutInfo.name = value;
166 } else if (name.equalsIgnoreCase("expression")) {
167 pointcutInfo.expression = value;
168 }
169 }
170
171 if (pointcutInfo.expression == null) {
172 pointcutInfo.expression = globalPointcut.getTextTrim();
173 }
174 globalPointcuts.add(pointcutInfo);
175 }
176 return globalPointcuts;
177 }
178
179 /***
180 * Parses the definition DOM document.
181 *
182 * @param loader the current class loader
183 * @param systemElement the system element
184 * @param definition the definition
185 * @param basePackage the base package
186 * @param globalPointcuts the global pointcuts
187 */
188 private static void parsePackageElements(final ClassLoader loader,
189 final Element systemElement,
190 final SystemDefinition definition,
191 final String basePackage,
192 final List globalPointcuts) {
193 for (Iterator it1 = systemElement.elementIterator("package"); it1.hasNext();) {
194 final Element packageElement = ((Element) it1.next());
195 final String packageName = basePackage + getPackage(packageElement);
196 parseAspectElements(loader, packageElement, definition, packageName, globalPointcuts);
197 }
198 }
199
200 /***
201 * Parses the <tt>aspect</tt> elements.
202 *
203 * @param loader the current class loader
204 * @param systemElement the system element
205 * @param definition the definition object
206 * @param packageName the package name
207 * @param globalPointcuts the global pointcuts
208 */
209 private static void parseAspectElements(final ClassLoader loader,
210 final Element systemElement,
211 final SystemDefinition definition,
212 final String packageName,
213 final List globalPointcuts) {
214 for (Iterator it1 = systemElement.elementIterator("aspect"); it1.hasNext();) {
215 String aspectName = null;
216 String className = null;
217 String deploymentModel = null;
218 String containerClassName = null;
219 Element aspect = (Element) it1.next();
220 for (Iterator it2 = aspect.attributeIterator(); it2.hasNext();) {
221 Attribute attribute = (Attribute) it2.next();
222 final String name = attribute.getName().trim();
223 final String value = attribute.getValue().trim();
224 if (name.equalsIgnoreCase("class")) {
225 className = value;
226 } else if (name.equalsIgnoreCase("deployment-model")) {
227 deploymentModel = value;
228 } else if (name.equalsIgnoreCase("name")) {
229 aspectName = value;
230 } else if (name.equalsIgnoreCase("container")) {
231 containerClassName = value;
232 }
233 }
234 String aspectClassName = packageName + className;
235 if (aspectName == null) {
236 aspectName = aspectClassName;
237 }
238
239
240 AspectDefinition aspectDef = new AspectDefinition(aspectName, aspectClassName, definition.getUuid());
241 Class aspectClass;
242 try {
243 aspectClass = loadAspectClass(loader, aspectClassName);
244 } catch (Exception e) {
245 System.out.println("loader: " + loader);
246 System.out.println("aspectClassName: " + aspectClassName);
247 System.err.println(
248 "Warning: could not load aspect "
249 + aspectClassName
250 + " from "
251 + loader
252 + "due to: "
253 + e.toString()
254 );
255 e.printStackTrace();
256 continue;
257 }
258
259
260 for (Iterator it = globalPointcuts.iterator(); it.hasNext();) {
261 PointcutInfo pointcutInfo = (PointcutInfo) it.next();
262 DefinitionParserHelper.createAndAddPointcutDefToAspectDef(
263 pointcutInfo.name,
264 pointcutInfo.expression,
265 aspectDef
266 );
267 }
268 parsePointcutElements(aspect, aspectDef);
269
270 AspectAnnotationParser.parse(aspectClass, aspectDef, definition);
271
272
273 aspectDef.setDeploymentModel(deploymentModel);
274 aspectDef.setName(aspectName);
275 aspectDef.setContainerClassName(containerClassName);
276
277
278 parseParameterElements(aspect, definition, aspectDef);
279 parsePointcutElements(aspect, aspectDef);
280 parseAdviceElements(aspect, aspectDef, aspectClass);
281 parseIntroductionElements(aspect, aspectDef, aspectClass, packageName);
282
283
284 for (Iterator mixins = aspectDef.getInterfaceIntroductions().iterator(); mixins.hasNext();) {
285 definition.addInterfaceIntroductionDefinition((InterfaceIntroductionDefinition) mixins.next());
286 }
287 for (Iterator mixins = aspectDef.getIntroductions().iterator(); mixins.hasNext();) {
288 definition.addIntroductionDefinition((IntroductionDefinition) mixins.next());
289 }
290 definition.addAspect(aspectDef);
291 }
292 }
293
294 /***
295 * Loads the aspect class.
296 *
297 * @param loader the class loader
298 * @param aspectClassName the name of the class implementing the aspect
299 * @return the class
300 */
301 private static Class loadAspectClass(final ClassLoader loader, final String aspectClassName) {
302 Class aspectClass;
303 try {
304 aspectClass = loader.loadClass(aspectClassName);
305 } catch (Exception e) {
306 e.printStackTrace();
307 throw new WrappedRuntimeException(e);
308 }
309 return aspectClass;
310 }
311
312 /***
313 * Parses the aspectElement parameters. <p/>TODO: should perhaps move the parameters to the aspect def instead of
314 * the system def
315 *
316 * @param aspectElement the aspect element
317 * @param def the system definition
318 * @param aspectDef the aspect def
319 */
320 private static void parseParameterElements(final Element aspectElement,
321 final SystemDefinition def,
322 final AspectDefinition aspectDef) {
323 for (Iterator it2 = aspectElement.elementIterator(); it2.hasNext();) {
324 Element parameterElement = (Element) it2.next();
325 if (parameterElement.getName().trim().equals("param")) {
326 def.addParameter(
327 aspectDef.getName(), parameterElement.attributeValue("name"), parameterElement
328 .attributeValue("value")
329 );
330 }
331 }
332 }
333
334 /***
335 * Parses the pointcuts.
336 *
337 * @param aspectElement the aspect element
338 * @param aspectDef the system definition
339 */
340 private static void parsePointcutElements(final Element aspectElement, final AspectDefinition aspectDef) {
341 for (Iterator it2 = aspectElement.elementIterator(); it2.hasNext();) {
342 Element pointcutElement = (Element) it2.next();
343 if (pointcutElement.getName().trim().equals("pointcut")) {
344 String name = pointcutElement.attributeValue("name");
345 String expression = pointcutElement.attributeValue("expression");
346
347 if (expression == null) {
348 expression = pointcutElement.getTextTrim();
349 }
350 DefinitionParserHelper.createAndAddPointcutDefToAspectDef(name, expression, aspectDef);
351 }
352 }
353 }
354
355 /***
356 * Parses the advices.
357 *
358 * @param aspectElement the aspect element
359 * @param aspectDef the system definition
360 * @param aspectClass the aspect class
361 */
362 private static void parseAdviceElements(final Element aspectElement,
363 final AspectDefinition aspectDef,
364 final Class aspectClass) {
365 List methodList = ReflectHelper.createCompleteSortedMethodList(aspectClass);
366 for (Iterator it2 = aspectElement.elementIterator(); it2.hasNext();) {
367 Element adviceElement = (Element) it2.next();
368 if (adviceElement.getName().trim().equals("advice")) {
369 String name = adviceElement.attributeValue("name");
370 String type = adviceElement.attributeValue("type");
371 String bindTo = adviceElement.attributeValue("bind-to");
372 String adviceName =
373 int methodIndex = 0;
374 Method method = null;
375 for (Iterator it3 = methodList.iterator(); it3.hasNext(); methodIndex++) {
376 Method methodCurrent = (Method) it3.next();
377
378 if (matchMethodAsAdvice(methodCurrent, name)) {
379 method = methodCurrent;
380 break;
381 }
382 }
383 if (method == null) {
384 throw new DefinitionException(
385 "Could not find advice method " + name + " in " + aspectClass.getName()
386 );
387 }
388 createAndAddAdviceDefsToAspectDef(type, bindTo, adviceName, method, methodIndex, aspectDef);
389 for (Iterator it1 = adviceElement.elementIterator("bind-to"); it1.hasNext();) {
390 Element bindToElement = (Element) it1.next();
391 String pointcut = bindToElement.attributeValue("pointcut");
392 createAndAddAdviceDefsToAspectDef(type, pointcut, adviceName, method, methodIndex, aspectDef);
393 }
394 }
395 }
396 }
397
398 /***
399 * Parses the introduction.
400 *
401 * @param aspectElement the aspect element
402 * @param aspectDef the system definition
403 * @param aspectClass the aspect class
404 * @param packageName
405 */
406 private static void parseIntroductionElements(final Element aspectElement,
407 final AspectDefinition aspectDef,
408 final Class aspectClass,
409 final String packageName) {
410 for (Iterator it2 = aspectElement.elementIterator(); it2.hasNext();) {
411 Element introduceElement = (Element) it2.next();
412 if (introduceElement.getName().trim().equals("introduce")) {
413 String klass = introduceElement.attributeValue("class");
414 String name = introduceElement.attributeValue("name");
415 String bindTo = introduceElement.attributeValue("bind-to");
416 String deploymentModel = introduceElement.attributeValue("deployment-model");
417
418
419 if ((deploymentModel == null) || (deploymentModel.length() <= 0)) {
420 deploymentModel = DeploymentModel.getDeploymentModelAsString(DeploymentModel.PER_JVM);
421 }
422
423
424 if ((name == null) || (name.length() <= 0)) {
425 name = packageName + klass;
426 }
427
428
429 Class mixin;
430 try {
431 mixin = aspectClass.getClassLoader().loadClass(packageName + klass);
432 } catch (ClassNotFoundException e) {
433 throw new DefinitionException(
434 "could not find mixin implementation: "
435 + packageName
436 + klass
437 + " "
438 + e.getMessage()
439 );
440 }
441
442
443 if (mixin.isInterface()) {
444 DefinitionParserHelper.createAndAddInterfaceIntroductionDefToAspectDef(
445 bindTo, name, packageName
446 + klass, aspectDef
447 );
448
449
450 for (Iterator it1 = introduceElement.elementIterator("bind-to"); it1.hasNext();) {
451 Element bindToElement = (Element) it1.next();
452 String pointcut = bindToElement.attributeValue("pointcut");
453 DefinitionParserHelper.createAndAddInterfaceIntroductionDefToAspectDef(
454 pointcut,
455 name,
456 packageName + klass,
457 aspectDef
458 );
459 }
460 } else {
461
462 Class[] introduced = mixin.getInterfaces();
463 String[] introducedInterfaceNames = new String[introduced.length];
464 for (int i = 0; i < introduced.length; i++) {
465 introducedInterfaceNames[i] = introduced[i].getName();
466 }
467 DefinitionParserHelper.createAndAddIntroductionDefToAspectDef(
468 mixin,
469 bindTo,
470 deploymentModel,
471 aspectDef
472 );
473
474
475 for (Iterator it1 = introduceElement.elementIterator("bind-to"); it1.hasNext();) {
476 Element bindToElement = (Element) it1.next();
477 String pointcut = bindToElement.attributeValue("pointcut");
478 DefinitionParserHelper.createAndAddIntroductionDefToAspectDef(
479 mixin,
480 pointcut,
481 deploymentModel,
482 aspectDef
483 );
484 }
485 }
486 }
487 }
488 }
489
490 /***
491 * Creates the advice definitions and adds them to the aspect definition.
492 *
493 * @param type the type of advice
494 * @param bindTo the pointcut expresion
495 * @param name the name of the advice
496 * @param method the method implementing the advice
497 * @param methodIndex the method index
498 * @param aspectDef the aspect definition
499 */
500 private static void createAndAddAdviceDefsToAspectDef(final String type,
501 final String bindTo,
502 final String name,
503 final Method method,
504 final int methodIndex,
505 final AspectDefinition aspectDef) {
506 try {
507 if (type.equalsIgnoreCase("around")) {
508 final String aspectName = aspectDef.getName();
509 AdviceDefinition adviceDef = DefinitionParserHelper.createAdviceDefinition(
510 name,
511 AdviceType.AROUND,
512 bindTo,
513 null,
514 aspectName,
515 aspectDef.getClassName(),
516 method,
517 methodIndex,
518 aspectDef
519 );
520 aspectDef.addAroundAdvice(adviceDef);
521
522 } else if (type.equalsIgnoreCase("before")) {
523 final String aspectName = aspectDef.getName();
524 AdviceDefinition adviceDef = DefinitionParserHelper.createAdviceDefinition(
525 name,
526 AdviceType.BEFORE,
527 bindTo,
528 null,
529 aspectName,
530 aspectDef.getClassName(),
531 method,
532 methodIndex,
533 aspectDef
534 );
535 aspectDef.addBeforeAdvice(adviceDef);
536
537 } else if (type.startsWith("after")) {
538 String specialArgumentType = null;
539 AdviceType adviceType = AdviceType.AFTER;
540 if (type.startsWith("after returning(")) {
541 adviceType = AdviceType.AFTER_RETURNING;
542 int start = type.indexOf('(');
543 int end = type.indexOf(')');
544 specialArgumentType = type.substring(start + 1, end).trim();
545 } else if (type.startsWith("after throwing(")) {
546 adviceType = AdviceType.AFTER_THROWING;
547 int start = type.indexOf('(');
548 int end = type.indexOf(')');
549 specialArgumentType = type.substring(start + 1, end).trim();
550 } else if (type.startsWith("after finally")) {
551 adviceType = AdviceType.AFTER_FINALLY;
552 }
553 if (specialArgumentType != null && specialArgumentType.indexOf(' ') > 0) {
554 throw new DefinitionException(
555 "argument to after (returning/throwing) can only be a type (parameter name binding should be done using args(..))"
556 );
557 }
558 final String aspectName = aspectDef.getName();
559 AdviceDefinition adviceDef = DefinitionParserHelper.createAdviceDefinition(
560 name,
561 adviceType,
562 bindTo,
563 specialArgumentType,
564 aspectName,
565 aspectDef.getClassName(),
566 method,
567 methodIndex,
568 aspectDef
569 );
570
571 aspectDef.addAfterAdvice(adviceDef);
572 }
573 } catch (DefinitionException e) {
574 System.err.println(
575 "WARNING: unable to register advice "
576 + aspectDef.getName()
577 + "."
578 + name
579 + " at pointcut \""
580 + bindTo
581 + "\" due to: "
582 + e.getMessage()
583 );
584
585 }
586 }
587
588 /***
589 * Retrieves and returns the package.
590 *
591 * @param packageElement the package element
592 * @return the package as a string ending with DOT, or empty string
593 */
594 private static String getPackage(final Element packageElement) {/package-summary.html">ong> static String getPackage(final Element packageElement) {
595 String packageName = "";
596 for (Iterator it2 = packageElement.attributeIterator(); it2.hasNext();) {
597 Attribute attribute = (Attribute) it2.next();
598 if (attribute.getName().trim().equalsIgnoreCase("name")) {
599 packageName = attribute.getValue().trim();
600 rong>if (packageName.endsWith(".*")) {
601 packageName = packageName.substring(0, packageName.length() - 1);
602 } else if (packageName.endsWith(".")) {
603 ;
604 } else {
605 packageName += ".";
606 }
607 break;
608 } else {
609 continue;
610 }
611 }
612 return</strong> packageName;
613 }
614
615 /***
616 * Parses the <tt>include</tt> elements.
617 *
618 * @param root the root element
619 * @param definition the definition object
620 * @param packageName the package name
621 */
622 private static void parseIncludePackageElements(final Element root,
623 final SystemDefinition definition,
624 final String packageName) {
625 for (Iterator it1 = root.elementIterator("include"); it1.hasNext();) {
626 String includePackage = "";
627 Element includeElement = (Element) it1.next();
628 for (Iterator it2 = includeElement.attributeIterator(); it2.hasNext();) {
629 Attribute attribute = (Attribute) it2.next();
630 if (attribute.getName().trim().equalsIgnoreCase("package")) {
631
632 if (packageName.endsWith(".*")) {
633 includePackage = packageName.substring(0, packageName.length() - 2);
634 } else if (packageName.endsWith(".")) {
635 includePackage = packageName.substring(0, packageName.length() - 1);
636 }
637
638
639 includePackage = packageName + attribute.getValue().trim();
640 if (includePackage.endsWith(".*")) {
641 includePackage = includePackage.substring(0, includePackage.length() - 2);
642 } else if (includePackage.endsWith(".")) {
643 includePackage = includePackage.substring(0, includePackage.length() - 1);
644 }
645 break;
646 } else {
647 continue;
648 }
649 }
650 if (includePackage.length() != 0) {
651 definition.addIncludePackage(includePackage);
652 }
653 }
654 }
655
656 /***
657 * Parses the <tt>exclude</tt> elements.
658 *
659 * @param root the root element
660 * @param definition the definition object
661 * @param packageName the package name
662 */
663 private static void parseExcludePackageElements(final Element root,
664 final SystemDefinition definition,
665 final String packageName) {
666 for (Iterator it1 = root.elementIterator("exclude"); it1.hasNext();) {
667 String excludePackage = "";
668 Element excludeElement = (Element) it1.next();
669 for (Iterator it2 = excludeElement.attributeIterator(); it2.hasNext();) {
670 Attribute attribute = (Attribute) it2.next();
671 if (attribute.getName().trim().equalsIgnoreCase("package")) {
672
673 if (packageName.endsWith(".*")) {
674 excludePackage = packageName.substring(0, packageName.length() - 2);
675 } else if (packageName.endsWith(".")) {
676 excludePackage = packageName.substring(0, packageName.length() - 1);
677 }
678
679
680 excludePackage = packageName + attribute.getValue().trim();
681 if (excludePackage.endsWith(".*")) {
682 excludePackage = excludePackage.substring(0, excludePackage.length() - 2);
683 } else if (excludePackage.endsWith(".")) {
684 excludePackage = excludePackage.substring(0, excludePackage.length() - 1);
685 }
686 break;
687 } else {
688 continue;
689 }
690 }
691 if (excludePackage.length() != 0) {
692 definition.addExcludePackage(excludePackage);
693 }
694 }
695 }
696
697 /***
698 * Parses the <tt>prepare</tt> elements.
699 *
700 * @param root the root element
701 * @param definition the definition object
702 * @param packageName the base package name
703 */
704 public static void parsePrepareElements(final Element root,
705 final SystemDefinition definition,
706 final String packageName) {
707 for (Iterator it1 = root.elementIterator("prepare"); it1.hasNext();) {
708 String preparePackage = "";
709 Element prepareElement = (Element) it1.next();
710 for (Iterator it2 = prepareElement.attributeIterator(); it2.hasNext();) {
711 Attribute attribute = (Attribute) it2.next();
712 if (attribute.getName().trim().equals("package")) {
713
714 if (packageName.endsWith(".*")) {
715 preparePackage = packageName.substring(0, packageName.length() - 2);
716 } else if (packageName.endsWith(".")) {
717 preparePackage = packageName.substring(0, packageName.length() - 1);
718 }
719
720
721 preparePackage = packageName + attribute.getValue().trim();
722 if (preparePackage.endsWith(".*")) {
723 preparePackage = preparePackage.substring(0, preparePackage.length() - 2);
724 } else if (preparePackage.endsWith(".")) {
725 preparePackage = preparePackage.substring(0, preparePackage.length() - 1);
726 }
727 break;
728 } else {
729 continue;
730 }
731 }
732 if (preparePackage.length() != 0) {
733 definition.addPreparePackage(preparePackage);
734 }
735 }
736 }
737
738 /***
739 * Retrieves and returns the base package for a system element
740 *
741 * @param system a system element
742 * @return the base package
743 */
744 private static String getBasePackage(final Element system) {
745 String basePackage = "";
746 for (Iterator it2 = system.attributeIterator(); it2.hasNext();) {
747 Attribute attribute = (Attribute) it2.next();
748 if (attribute.getName().trim().equalsIgnoreCase("base-package")) {
749 basePackage = attribute.getValue().trim();
750 if (basePackage.endsWith(".*")) {
751 basePackage = basePackage.substring(0, basePackage.length() - 1);
752 } else if (basePackage.endsWith(".")) {
753 ;
754 } else {
755 basePackage += ".";
756 }
757 break;
758 } else {
759 continue;
760 }
761 }
762 return basePackage;
763 }
764
765 /***
766 * Struct with pointcut info.
767 */
768 private static class PointcutInfo {
769 public String name;
770
771 public String expression;
772 }
773
774 /***
775 * Check if a method from an aspect class match a given advice signature.
776 * <br/>
777 * If the signature is just a method name, then we have a match even if JoinPoint is sole method parameter.
778 * Else we match both method name and parameters type, with abbreviation support (java.lang.* and JoinPoint)
779 *
780 * @param method
781 * @param adviceSignature
782 * @return
783 */
784 private static boolean matchMethodAsAdvice(Method method, String adviceSignature) {
785
786
787 String[] signatureElements = Strings.extractMethodSignature(adviceSignature);
788
789 if (!method.getName().equals(signatureElements[0])) {
790 return false;
791 }
792
793 if (method.getParameterTypes().length * 2 != signatureElements.length - 1) {
794
795
796 if (signatureElements.length == 1
797 && method.getParameterTypes().length == 1
798 && method.getParameterTypes()[0].getName().equals(JoinPoint.class.getName())) {
799 return true;
800 } else {
801 return false;
802 }
803 }
804 int argIndex = 0;
805 for (int i = 1; i < signatureElements.length; i++) {
806 String paramType = signatureElements[i++];
807 String paramName = signatureElements[i];
808 String methodParamType = JavaClassInfo.convertJavaArrayTypeNameToHumanTypeName(
809 method.getParameterTypes()[argIndex++].getName().replace('/', '.')
810 );
811
812 String paramTypeResolved = (String) Pattern.ABBREVIATIONS.get(paramType);
813 if (methodParamType.equals(paramType) || methodParamType.equals(paramTypeResolved)) {
814 continue;
815 } else {
816 return false;
817 }
818 }
819 return true;
820 }
821 }