| 1 8 package org.codehaus.aspectwerkz.definition; 9 10 import org.codehaus.aspectwerkz.util.Strings; 11 import org.codehaus.aspectwerkz.aspect.AdviceType; 12 import org.codehaus.aspectwerkz.DeploymentModel; 13 import org.codehaus.aspectwerkz.intercept.AdvisableImpl; 14 import org.codehaus.aspectwerkz.reflect.impl.asm.AsmClassInfo; 15 import org.codehaus.aspectwerkz.reflect.impl.java.JavaMethodInfo; 16 import org.codehaus.aspectwerkz.reflect.impl.java.JavaClassInfo; 17 import org.codehaus.aspectwerkz.reflect.ClassInfo; 18 import org.codehaus.aspectwerkz.reflect.ClassInfoHelper; 19 import org.codehaus.aspectwerkz.reflect.MethodInfo; 20 import org.codehaus.aspectwerkz.expression.regexp.Pattern; 21 import org.codehaus.aspectwerkz.expression.ExpressionNamespace; 22 import org.codehaus.aspectwerkz.expression.ExpressionInfo; 23 import org.codehaus.aspectwerkz.annotation.AspectAnnotationParser; 24 import org.codehaus.aspectwerkz.annotation.MixinAnnotationParser; 25 import org.codehaus.aspectwerkz.exception.DefinitionException; 26 import org.codehaus.aspectwerkz.transform.TransformationConstants; 27 import org.codehaus.aspectwerkz.transform.inlining.AspectModelManager; 28 import org.dom4j.Attribute; 29 import org.dom4j.Document; 30 import org.dom4j.Element; 31 32 import java.util.ArrayList ; 33 import java.util.Iterator ; 34 import java.util.List ; 35 import java.util.Set ; 36 import java.util.HashSet ; 37 import java.util.StringTokenizer ; 38 39 45 public class DocumentParser { 46 47 53 public static List parseAspectClassNames(final Document document) { 54 final List aspectClassNames = new ArrayList (); 55 for (Iterator it1 = document.getRootElement().elementIterator("system"); it1.hasNext();) { 56 Element system = (Element) it1.next(); 57 final String basePackage = getBasePackage(system); 58 for (Iterator it11 = system.elementIterator("aspect"); it11.hasNext();) { 59 String className = null; 60 Element aspect = (Element) it11.next(); 61 for (Iterator it2 = aspect.attributeIterator(); it2.hasNext();) { 62 Attribute attribute = (Attribute) it2.next(); 63 final String name = attribute.getName().trim(); 64 final String value = attribute.getValue().trim(); 65 if (name.equalsIgnoreCase("class")) { 66 className = value; 67 } 68 } 69 aspectClassNames.add(basePackage + className); 70 } 71 for (Iterator it11 = system.elementIterator("package"); it11.hasNext();) { 72 final Element packageElement = ((Element) it11.next()); 73 final String packageName = getPackage(packageElement); 74 for (Iterator it12 = packageElement.elementIterator("aspect"); it12.hasNext();) { 75 String className = null; 76 Element aspect = (Element) it12.next(); 77 for (Iterator it2 = aspect.attributeIterator(); it2.hasNext();) { 78 Attribute attribute = (Attribute) it2.next(); 79 final String name = attribute.getName().trim(); 80 final String value = attribute.getValue().trim(); 81 if (name.equalsIgnoreCase("class")) { 82 className = value; 83 } 84 } 85 aspectClassNames.add(packageName + className); 86 } 87 } 88 } 89 aspectClassNames.add(Virtual.class.getName()); 90 91 return aspectClassNames; 92 } 93 94 102 public static AspectDefinition parseAspectDefinition(final Document document, 103 final SystemDefinition systemDef, 104 final Class aspectClass) { 105 106 final Element aspect = document.getRootElement(); 107 108 if (!aspect.getName().equals("aspect")) { 109 throw new DefinitionException("XML definition for aspect is not well-formed: " + document.asXML()); 110 } 111 String specialAspectName = null; 112 String className = null; 113 String deploymentModelAsString = null; 114 String containerClassName = null; 115 for (Iterator it2 = aspect.attributeIterator(); it2.hasNext();) { 116 Attribute attribute = (Attribute) it2.next(); 117 final String name = attribute.getName().trim(); 118 final String value = attribute.getValue().trim(); 119 if (name.equalsIgnoreCase("class")) { 120 className = value; 121 } else if (name.equalsIgnoreCase("deployment-model")) { 122 deploymentModelAsString = value; 123 } else if (name.equalsIgnoreCase("name")) { 124 specialAspectName = value; 125 } else if (name.equalsIgnoreCase("container")) { 126 containerClassName = value; 127 } 128 } 129 if (specialAspectName == null) { 130 specialAspectName = className; 131 } 132 133 final ClassInfo classInfo = JavaClassInfo.getClassInfo(aspectClass); 134 final ClassLoader loader = aspectClass.getClassLoader(); 135 136 final AspectDefinition aspectDef = new AspectDefinition(specialAspectName, classInfo, systemDef); 138 aspectDef.setContainerClassName(containerClassName); 140 aspectDef.setDeploymentModel(DeploymentModel.getDeploymentModelFor(deploymentModelAsString)); 141 142 parsePointcutElements(aspect, aspectDef); 144 AspectModelManager.defineAspect(classInfo, aspectDef, loader); 146 147 parseParameterElements(aspect, aspectDef); 149 parsePointcutElements(aspect, aspectDef); parseAdviceElements(aspect, aspectDef, JavaClassInfo.getClassInfo(aspectClass)); 151 parseIntroduceElements(aspect, aspectDef, "", aspectClass.getClassLoader()); 152 153 systemDef.addAspect(aspectDef); 154 return aspectDef; 155 } 156 157 164 public static Set parse(final ClassLoader loader, final Document document) { 165 final Element root = document.getRootElement(); 166 167 return parseSystemElements(loader, root); 169 } 170 171 177 private static Set parseSystemElements(final ClassLoader loader, final Element root) { 178 final Set systemDefs = new HashSet (); 179 for (Iterator it1 = root.elementIterator("system"); it1.hasNext();) { 180 Element system = (Element) it1.next(); 181 SystemDefinition definition = parseSystemElement(loader, system, getBasePackage(system)); 182 if (definition != null) { 183 systemDefs.add(definition); 184 } 185 } 186 return systemDefs; 187 } 188 189 197 private static SystemDefinition parseSystemElement(final ClassLoader loader, 198 final Element systemElement, 199 final String basePackage) { 200 String uuid = systemElement.attributeValue("id"); 201 if ((uuid == null) || uuid.equals("")) { 202 throw new DefinitionException("system UUID must be specified"); 203 } 204 final SystemDefinition definition = new SystemDefinition(uuid); 205 206 addVirtualAspect(definition); 208 209 List globalPointcuts = parseGlobalPointcutDefs(systemElement); 211 ExpressionNamespace systemNamespace = ExpressionNamespace.getNamespace(definition.getUuid()); 213 for (Iterator iterator = globalPointcuts.iterator(); iterator.hasNext();) { 214 PointcutInfo pointcutInfo = (PointcutInfo) iterator.next(); 215 systemNamespace.addExpressionInfo( 216 pointcutInfo.name, new ExpressionInfo(pointcutInfo.expression, systemNamespace.getName()) 217 ); 218 } 219 220 parseDeploymentScopeDefs(systemElement, definition); 222 223 parseAdvisableDefs(systemElement, definition); 225 226 parseIncludePackageElements(systemElement, definition, basePackage); 228 parseExcludePackageElements(systemElement, definition, basePackage); 229 parsePrepareElements(systemElement, definition, basePackage); 230 231 parseAspectElements(loader, systemElement, definition, basePackage, globalPointcuts); 233 234 parseMixinElements(loader, systemElement, definition, basePackage); 236 237 parsePackageElements(loader, systemElement, definition, basePackage, globalPointcuts); 239 240 DefinitionParserHelper.attachDeploymentScopeDefsToVirtualAdvice(definition); 242 243 return definition; 244 } 245 246 252 private static List parseGlobalPointcutDefs(final Element systemElement) { 253 final List globalPointcuts = new ArrayList (); 254 for (Iterator it11 = systemElement.elementIterator("pointcut"); it11.hasNext();) { 255 PointcutInfo pointcutInfo = new PointcutInfo(); 256 Element globalPointcut = (Element) it11.next(); 257 for (Iterator it2 = globalPointcut.attributeIterator(); it2.hasNext();) { 258 Attribute attribute = (Attribute) it2.next(); 259 final String name = attribute.getName().trim(); 260 final String value = attribute.getValue().trim(); 261 if (name.equalsIgnoreCase("name")) { 262 pointcutInfo.name = value; 263 } else if (name.equalsIgnoreCase("expression")) { 264 pointcutInfo.expression = value; 265 } 266 } 267 if (pointcutInfo.expression == null) { 269 pointcutInfo.expression = globalPointcut.getTextTrim(); 270 } 271 globalPointcuts.add(pointcutInfo); 272 } 273 return globalPointcuts; 274 } 275 276 282 private static void parseDeploymentScopeDefs(final Element systemElement, 283 final SystemDefinition definition) { 284 for (Iterator it11 = systemElement.elementIterator("deployment-scope"); it11.hasNext();) { 285 String expression = null; 286 String name = null; 287 Element globalPointcut = (Element) it11.next(); 288 for (Iterator it2 = globalPointcut.attributeIterator(); it2.hasNext();) { 289 Attribute attribute = (Attribute) it2.next(); 290 final String attrName = attribute.getName().trim(); 291 final String attrValue = attribute.getValue().trim(); 292 if (attrName.equalsIgnoreCase("name")) { 293 name = attrValue; 294 } else if (attrName.equalsIgnoreCase("expression")) { 295 expression = attrValue; 296 } 297 } 298 if (expression == null) { 300 expression = globalPointcut.getTextTrim(); 301 } 302 DefinitionParserHelper.createAndAddDeploymentScopeDef(name, expression, definition); 303 } 304 } 305 306 312 private static void parseAdvisableDefs(final Element systemElement, 313 final SystemDefinition definition) { 314 for (Iterator it11 = systemElement.elementIterator("advisable"); it11.hasNext();) { 315 Element advisableElement = (Element) it11.next(); 316 String expression = ""; 317 String pointcutTypes = "all"; 318 for (Iterator it2 = advisableElement.attributeIterator(); it2.hasNext();) { 319 Attribute attribute = (Attribute) it2.next(); 320 final String name = attribute.getName().trim(); 321 final String value = attribute.getValue().trim(); 322 if (name.equalsIgnoreCase("expression")) { 323 expression = value; 324 } else if (name.equalsIgnoreCase("pointcut-type")) { 325 pointcutTypes = value; 326 } 327 } 328 if (expression == null) { 330 expression = advisableElement.getTextTrim(); 331 } 332 handleAdvisableDefinition(definition, expression, pointcutTypes); 333 } 334 } 335 336 345 private static void parsePackageElements(final ClassLoader loader, 346 final Element systemElement, 347 final SystemDefinition definition, 348 final String basePackage, 349 final List globalPointcuts) { 350 for (Iterator it1 = systemElement.elementIterator("package"); it1.hasNext();) { 351 final Element packageElement = ((Element) it1.next()); 352 final String packageName = basePackage + getPackage(packageElement); 353 parseAspectElements(loader, packageElement, definition, packageName, globalPointcuts); 354 parseMixinElements(loader, packageElement, definition, packageName); 355 parseAdvisableDefs(packageElement, definition); 356 } 357 } 358 359 368 private static void parseAspectElements(final ClassLoader loader, 369 final Element systemElement, 370 final SystemDefinition definition, 371 final String packageName, 372 final List globalPointcuts) { 373 374 for (Iterator it1 = systemElement.elementIterator("aspect"); it1.hasNext();) { 375 String aspectName = null; 376 String className = null; 377 String deploymentModel = null; 378 String containerClassName = null; 379 Element aspect = (Element) it1.next(); 380 for (Iterator it2 = aspect.attributeIterator(); it2.hasNext();) { 381 Attribute attribute = (Attribute) it2.next(); 382 final String name = attribute.getName().trim(); 383 final String value = attribute.getValue().trim(); 384 if (name.equalsIgnoreCase("class")) { 385 className = value; 386 } else if (name.equalsIgnoreCase("deployment-model")) { 387 deploymentModel = value; 388 } else if (name.equalsIgnoreCase("name")) { 389 aspectName = value; 390 } else if (name.equalsIgnoreCase("container")) { 391 containerClassName = value; 392 } 393 } 394 String aspectClassName = packageName + className; 395 if (aspectName == null) { 396 aspectName = aspectClassName; 397 } 398 399 ClassInfo aspectClassInfo; 401 try { 402 aspectClassInfo = AsmClassInfo.getClassInfo(aspectClassName, loader); 403 } catch (Exception e) { 404 System.err.println( 405 "Warning: could not load aspect " 406 + aspectClassName 407 + " from " 408 + loader 409 + "due to: " 410 + e.toString() 411 ); 412 e.printStackTrace(); 413 continue; 414 } 415 416 final AspectDefinition aspectDef = new AspectDefinition(aspectName, aspectClassInfo, definition); 417 418 for (Iterator it = globalPointcuts.iterator(); it.hasNext();) { 420 PointcutInfo pointcutInfo = (PointcutInfo) it.next(); 421 DefinitionParserHelper.createAndAddPointcutDefToAspectDef( 422 pointcutInfo.name, 423 pointcutInfo.expression, 424 aspectDef 425 ); 426 } 427 parsePointcutElements(aspect, aspectDef); 429 AspectModelManager.defineAspect(aspectClassInfo, aspectDef, loader); 431 432 AspectAnnotationParser.parse(aspectClassInfo, aspectDef, loader); 434 435 if (!Strings.isNullOrEmpty(deploymentModel)) { 438 aspectDef.setDeploymentModel(DeploymentModel.getDeploymentModelFor(deploymentModel)); 439 } 440 if (!Strings.isNullOrEmpty(aspectName)) { 441 aspectDef.setName(aspectName); 442 } 443 if (!Strings.isNullOrEmpty(containerClassName)) { 444 aspectDef.setContainerClassName(containerClassName); 445 } 446 447 parseParameterElements(aspect, aspectDef); 449 parsePointcutElements(aspect, aspectDef); parseAdviceElements(aspect, aspectDef, aspectClassInfo); 451 parseIntroduceElements(aspect, aspectDef, packageName, loader); 452 453 definition.addAspect(aspectDef); 454 } 455 } 456 457 465 private static void parseMixinElements(final ClassLoader loader, 466 final Element systemElement, 467 final SystemDefinition systemDefinition, 468 final String packageName) { 469 470 for (Iterator it1 = systemElement.elementIterator("mixin"); it1.hasNext();) { 471 String className = null; 472 String deploymentModelAsString = null; 473 boolean isTransient = false; 474 boolean isTransientSetInXML = false; 475 String factoryClassName = null; 476 String expression = null; 477 Element mixin = (Element) it1.next(); 478 for (Iterator it2 = mixin.attributeIterator(); it2.hasNext();) { 479 Attribute attribute = (Attribute) it2.next(); 480 final String name = attribute.getName().trim(); 481 final String value = attribute.getValue().trim(); 482 if (name.equalsIgnoreCase("class")) { 483 className = value; 484 } else if (name.equalsIgnoreCase("deployment-model") && value != null) { 485 deploymentModelAsString = value; 486 } else if (name.equalsIgnoreCase("transient")) { 487 if (value != null && value.equalsIgnoreCase("true")) { 488 isTransient = true; 489 isTransientSetInXML = true; 490 } 491 } else if (name.equalsIgnoreCase("factory")) { 492 factoryClassName = value; 493 } else if (name.equalsIgnoreCase("bind-to")) { 494 expression = value; 495 } 496 } 497 String mixinClassName = packageName + className; 498 499 ClassInfo mixinClassInfo; 501 try { 502 mixinClassInfo = AsmClassInfo.getClassInfo(mixinClassName, loader); 503 } catch (Exception e) { 504 System.err.println( 505 "Warning: could not load mixin " 506 + mixinClassName 507 + " from " 508 + loader 509 + "due to: " 510 + e.toString() 511 ); 512 e.printStackTrace(); 513 continue; 514 } 515 516 final DeploymentModel deploymentModel = 517 (deploymentModelAsString != null) ? DeploymentModel.getDeploymentModelFor(deploymentModelAsString) 518 : DeploymentModel.PER_INSTANCE; 519 520 final MixinDefinition mixinDefinition = 521 DefinitionParserHelper.createAndAddMixinDefToSystemDef( 522 mixinClassInfo, 523 expression, 524 deploymentModel, 525 isTransient, 526 systemDefinition 527 ); 528 529 MixinAnnotationParser.parse(mixinClassInfo, mixinDefinition); 531 532 if (!Strings.isNullOrEmpty(deploymentModelAsString)) { 534 mixinDefinition.setDeploymentModel(DeploymentModel.getDeploymentModelFor(deploymentModelAsString)); 535 } 536 if (!Strings.isNullOrEmpty(factoryClassName)) { 537 mixinDefinition.setFactoryClassName(factoryClassName); 538 } 539 if (isTransientSetInXML) { 540 mixinDefinition.setTransient(isTransient); 541 } 542 543 parseParameterElements(mixin, mixinDefinition); 544 } 545 } 546 547 552 public static void addVirtualAspect(final SystemDefinition definition) { 553 final Class clazz = Virtual.class; 554 final String aspectName = clazz.getName(); 555 ClassInfo aspectClassInfo = JavaClassInfo.getClassInfo(clazz); 556 final AspectDefinition aspectDef = new AspectDefinition(aspectName, aspectClassInfo, definition); 557 try { 558 MethodInfo methodInfo = JavaMethodInfo.getMethodInfo(clazz.getDeclaredMethod("virtual", new Class []{})); 559 aspectDef.addBeforeAdviceDefinition( 560 new AdviceDefinition( 561 methodInfo.getName(), 562 AdviceType.BEFORE, 563 null, 564 aspectName, 565 aspectName, 566 null, 567 methodInfo, 568 aspectDef 569 ) 570 ); 571 } catch (NoSuchMethodException e) { 572 throw new Error ("virtual aspect [" + aspectName + "] does not have expected method: " + e.toString()); 573 } 574 definition.addAspect(aspectDef); 575 } 576 577 583 private static void parseParameterElements(final Element aspectElement, 584 final AspectDefinition aspectDef) { 585 for (Iterator it2 = aspectElement.elementIterator(); it2.hasNext();) { 586 Element parameterElement = (Element) it2.next(); 587 if (parameterElement.getName().trim().equals("param")) { 588 aspectDef.addParameter( 589 parameterElement.attributeValue("name"), 590 parameterElement.attributeValue("value") 591 ); 592 } 593 } 594 } 595 596 602 private static void parseParameterElements(final Element mixinElement, 603 final MixinDefinition mixinDef) { 604 for (Iterator it2 = mixinElement.elementIterator(); it2.hasNext();) { 605 Element parameterElement = (Element) it2.next(); 606 if (parameterElement.getName().trim().equals("param")) { 607 mixinDef.addParameter( 608 parameterElement.attributeValue("name"), 609 parameterElement.attributeValue("value") 610 ); 611 } 612 } 613 } 614 615 621 private static void parsePointcutElements(final Element aspectElement, final AspectDefinition aspectDef) { 622 for (Iterator it2 = aspectElement.elementIterator(); it2.hasNext();) { 623 Element pointcutElement = (Element) it2.next(); 624 if (pointcutElement.getName().trim().equals("pointcut")) { 625 String name = pointcutElement.attributeValue("name"); 626 String expression = pointcutElement.attributeValue("expression"); 627 if (expression == null) { 629 expression = pointcutElement.getTextTrim(); 630 } 631 DefinitionParserHelper.createAndAddPointcutDefToAspectDef(name, expression, aspectDef); 632 } else if (pointcutElement.getName().trim().equals("deployment-scope")) { 633 String name = pointcutElement.attributeValue("name"); 634 String expression = pointcutElement.attributeValue("expression"); 635 if (expression == null) { 637 expression = pointcutElement.getTextTrim(); 638 } 639 DefinitionParserHelper.createAndAddDeploymentScopeDef( 640 name, expression, aspectDef.getSystemDefinition() 641 ); 642 &n
|