1 22 package org.jboss.aop; 23 24 import java.io.IOException ; 25 import java.io.InputStream ; 26 import java.io.StringReader ; 27 import java.net.URL ; 28 import java.util.ArrayList ; 29 import java.util.Iterator ; 30 import java.util.StringTokenizer ; 31 import javax.xml.parsers.DocumentBuilder ; 32 import javax.xml.parsers.DocumentBuilderFactory ; 33 import javax.xml.parsers.ParserConfigurationException ; 34 35 import org.jboss.aop.advice.AdviceBinding; 36 import org.jboss.aop.advice.AdviceFactory; 37 import org.jboss.aop.advice.AdviceStack; 38 import org.jboss.aop.advice.AfterFactory; 39 import org.jboss.aop.advice.AspectDefinition; 40 import org.jboss.aop.advice.AspectFactory; 41 import org.jboss.aop.advice.AspectFactoryDelegator; 42 import org.jboss.aop.advice.AspectFactoryWithClassLoader; 43 import org.jboss.aop.advice.BeforeFactory; 44 import org.jboss.aop.advice.DynamicCFlowDefinition; 45 import org.jboss.aop.advice.GenericAspectFactory; 46 import org.jboss.aop.advice.InterceptorFactory; 47 import org.jboss.aop.advice.PrecedenceDef; 48 import org.jboss.aop.advice.PrecedenceDefEntry; 49 import org.jboss.aop.advice.Scope; 50 import org.jboss.aop.advice.ScopeUtil; 51 import org.jboss.aop.advice.ScopedInterceptorFactory; 52 import org.jboss.aop.advice.ThrowingFactory; 53 import org.jboss.aop.introduction.AnnotationIntroduction; 54 import org.jboss.aop.introduction.InterfaceIntroduction; 55 import org.jboss.aop.metadata.ClassMetaDataBinding; 56 import org.jboss.aop.metadata.ClassMetaDataLoader; 57 import org.jboss.aop.pointcut.CFlow; 58 import org.jboss.aop.pointcut.CFlowStack; 59 import org.jboss.aop.pointcut.DeclareDef; 60 import org.jboss.aop.pointcut.Pointcut; 61 import org.jboss.aop.pointcut.PointcutExpression; 62 import org.jboss.aop.pointcut.Typedef; 63 import org.jboss.aop.pointcut.TypedefExpression; 64 import org.jboss.aop.pointcut.ast.ASTCFlowExpression; 65 import org.jboss.aop.pointcut.ast.ASTStart; 66 import org.jboss.aop.pointcut.ast.ParseException; 67 import org.jboss.aop.pointcut.ast.PointcutExpressionParser; 68 import org.jboss.aop.pointcut.ast.TypeExpressionParser; 69 import org.jboss.aop.util.XmlHelper; 70 import org.jboss.util.xml.XmlLoadable; 71 import org.w3c.dom.Document ; 72 import org.w3c.dom.Element ; 73 import org.w3c.dom.Node ; 74 import org.w3c.dom.NodeList ; 75 import org.xml.sax.EntityResolver ; 76 import org.xml.sax.InputSource ; 77 import org.xml.sax.SAXException ; 78 79 83 public class AspectXmlLoader implements XmlLoader 84 { 85 87 protected int counter; 88 protected String defaultBaseName; 89 protected AspectManager manager; 90 protected ArrayList bindings = new ArrayList (); 91 protected ArrayList factories = new ArrayList (); 92 protected ArrayList aspects = new ArrayList (); 93 94 public AspectXmlLoader() 95 { 96 } 97 98 public void setManager(AspectManager manager) 99 { 100 if (AspectManager.verbose) System.out.println("AspectXMLLoader using manager" + manager); 101 this.manager = manager; 102 } 103 104 private ClassLoader cl; 105 106 public void setClassLoader(ClassLoader cl) 107 { 108 this.cl = cl; 109 } 110 111 public ClassLoader getClassLoader() 112 { 113 if (cl == null) 114 { 115 return Thread.currentThread().getContextClassLoader(); 116 } 117 return cl; 118 } 119 120 123 private String getName(Element element, String errorHeader) 124 { 125 String name = element.getAttribute("name"); 126 if (name != null && !name.equals("")) 127 { 128 return name; 129 } 130 131 return getName(errorHeader); 132 133 } 134 135 private String getName(String errorHeader) 136 { 137 return defaultBaseName + counter++; 138 } 139 140 public void undeployInterceptor(Element element) throws Exception 141 { 142 String name = element.getAttribute("name"); 143 if (name != null && name.trim().equals("")) name = null; 144 145 String clazz = element.getAttribute("class"); 146 if (clazz != null && clazz.trim().equals("")) clazz = null; 147 String factory = element.getAttribute("factory"); 148 if (factory != null && factory.trim().equals("")) factory = null; 149 if (name == null) name = (clazz == null) ? factory : clazz; 150 aspects.add(name); 152 String factoryName = name; 153 factories.add(factoryName); 155 } 156 157 public InterceptorFactory deployInterceptor(Element element) throws Exception 158 { 159 String name = element.getAttribute("name"); 160 if (name != null && name.trim().equals("")) name = null; 161 162 String clazz = element.getAttribute("class"); 163 if (clazz != null && clazz.trim().equals("")) clazz = null; 164 String factory1 = element.getAttribute("factory"); 165 if (factory1 != null && factory1.trim().equals("")) factory1 = null; 166 if (clazz == null && factory1 == null) throw new RuntimeException ("Interceptor" + " " + name + " must have a class or factory associated with it."); 167 if (clazz != null && factory1 != null) throw new RuntimeException ("Interceptor" + " " + name + " cannot have both the class and factory attribute set."); 168 if (name == null) name = (clazz == null) ? factory1 : clazz; 169 170 String s = element.getAttribute("scope"); 171 if (s != null && s.trim().equals("")) s = null; 172 173 Scope scope = null; 174 if (s != null) 175 { 176 scope = ScopeUtil.parse(s); 177 if (scope == null) throw new RuntimeException ("Illegal scope attribute value: " + s); 178 } 179 AspectDefinition def = (AspectDefinition) manager.getAspectDefinition(name); 180 181 if (def != null) 184 { 185 if (scope == null) scope = Scope.PER_VM; 186 if (scope != def.getScope()) throw new RuntimeException ("multiple definitions of <interceptor> " + name + " with different scopes is illegal"); 187 } 188 else 189 { 190 AspectFactory aspectFactory; 191 if (clazz != null) 192 { 193 aspectFactory = new GenericAspectFactory(clazz, element); 194 ((AspectFactoryWithClassLoader)aspectFactory).setClassLoader(cl); 195 } 196 else 197 { 198 aspectFactory = new AspectFactoryDelegator(factory1, element); 199 ((AspectFactoryWithClassLoader)aspectFactory).setClassLoader(cl); 200 } 201 202 def = new AspectDefinition(name, scope, aspectFactory); 203 manager.addAspectDefinition(def); 204 } 205 ScopedInterceptorFactory factory = new ScopedInterceptorFactory(def); 206 manager.addInterceptorFactory(factory.getName(), factory); 207 return factory; 208 } 209 210 211 public void undeployAdvice(Element element) throws Exception 212 { 213 String name = element.getAttribute("name"); 214 String aspect = element.getAttribute("aspect"); 215 String factory = aspect + "." + name; 216 factories.add(factory); 218 } 219 220 public InterceptorFactory deployAdvice(Element element) throws Exception 221 { 222 String name = element.getAttribute("name"); 223 String aspect = element.getAttribute("aspect"); 224 AspectDefinition def = manager.getAspectDefinition(aspect); 225 if (def == null) throw new RuntimeException ("advice " + name + " cannot find aspect " + aspect); 226 227 String tagName = element.getTagName(); 228 229 AdviceFactory factory = null; 230 if (tagName.equals("advice")) 231 { 232 factory = new AdviceFactory(def, name); 233 } 234 else if (tagName.equals("before")) 235 { 236 factory = new BeforeFactory(def, name); 237 } 238 else if (tagName.equals("after")) 239 { 240 factory = new AfterFactory(def, name); 241 } 242 else if (tagName.equals("throwing")) 243 { 244 factory = new ThrowingFactory(def, name); 245 } 246 manager.addInterceptorFactory(factory.getName(), factory); 247 return factory; 248 } 249 250 251 public void deployBinding(Element element) throws Exception 252 { 253 String name = getName(element, "binding"); 254 String pointcut = element.getAttribute("pointcut"); 255 if (pointcut == null || pointcut.trim().equals("")) 256 { 257 throw new RuntimeException ("Binding must have a pointcut element associated with it."); 258 } 259 String cflow = element.getAttribute("cflow"); 260 if (cflow != null && cflow.trim().equals("")) 261 { 262 cflow = null; 263 } 264 ASTCFlowExpression cflowExpression = null; 265 if (cflow != null) 266 { 267 try 268 { 269 cflowExpression = new PointcutExpressionParser(new StringReader (cflow)).CFlowExpression(); 270 } 271 catch (ParseException e) 272 { 273 throw new RuntimeException (cflow, e); } 275 } 276 ArrayList interceptors = loadInterceptors(element); 277 InterceptorFactory[] inters = (InterceptorFactory[]) interceptors.toArray(new InterceptorFactory[interceptors.size()]); 278 Pointcut p = null; 279 try 280 { 281 p = new PointcutExpression(getName("binding pointcut "), pointcut); 282 } 283 catch (ParseException ex) 284 { 285 throw new RuntimeException ("<bind> pointcut expression failed: " + pointcut, ex); 286 } 287 AdviceBinding binding = new AdviceBinding(name, p, cflowExpression, cflow, inters); 288 manager.addBinding(binding); 289 } 290 291 public void undeployBinding(Element element) throws Exception 292 { 293 String binding = getName(element, "binding"); 294 if (binding == null) throw new RuntimeException ("undeploying Binding that is null!"); 295 bindings.add(binding); 297 unloadInterceptors(element); 298 String pointcut = getName("pointcut"); 299 manager.removePointcut(pointcut); 300 } 301 302 private void deployPrecedence(Element element) throws Exception 303 { 304 String name = getName(element, "precedence"); 305 306 ArrayList precedenceEntries = new ArrayList (); 307 NodeList children2 = element.getChildNodes(); 308 for (int j = 0; j < children2.getLength(); j++) 309 { 310 if (children2.item(j).getNodeType() == Node.ELEMENT_NODE) 311 { 312 Element interceptorElement = (Element ) children2.item(j); 313 String tag2 = interceptorElement.getTagName(); 314 if (tag2.equals("interceptor-ref")) 315 { 316 String iname = interceptorElement.getAttribute("name"); 317 if (iname == null || iname.length() == 0) 318 { 319 throw new RuntimeException ("name must be specified for interceptor-ref in precedence declaration"); 320 } 321 precedenceEntries.add(new PrecedenceDefEntry(iname, null)); 322 } 323 else if (tag2.equals("advice")) 324 { 325 String method = interceptorElement.getAttribute("name"); 326 String aspect = interceptorElement.getAttribute("aspect"); 327 328 if (method == null || method.length() == 0) 329 { 330 throw new RuntimeException ("name must be specified for advice in precedence declaration"); 331 } 332 333 if (aspect == null || aspect.length() == 0) 334 { 335 throw new RuntimeException ("aspect must be specified for advice in precedence declaration"); 336 } 337 338 precedenceEntries.add(new PrecedenceDefEntry(aspect, method)); 339 } 340 else 341 { 342 throw new RuntimeException ("Invalid child element of precedence : " + tag2); 343 } 344 } 345 } 346 347 PrecedenceDefEntry[] entries = (PrecedenceDefEntry[]) precedenceEntries.toArray(new PrecedenceDefEntry[precedenceEntries.size()]); 348 manager.addPrecedence(new PrecedenceDef(name, entries)); 349 } 350 351 352 private ArrayList loadInterceptors(Element element) throws Exception 353 { 354 ArrayList interceptors = new ArrayList (); 355 NodeList children2 = element.getChildNodes(); 356 for (int j = 0; j < children2.getLength(); j++) 357 { 358 if (children2.item(j).getNodeType() == Node.ELEMENT_NODE) 359 { 360 Element interceptorElement = (Element ) children2.item(j); 361 String tag2 = interceptorElement.getTagName(); 362 if (tag2.equals("interceptor")) 363 { 364 InterceptorFactory factory = deployInterceptor(interceptorElement); 365 interceptors.add(factory); 366 } 367 else if (tag2.equals("interceptor-ref")) 368 { 369 String iname = interceptorElement.getAttribute("name"); 370 if (iname == null) throw new RuntimeException ("interceptor-ref has null name attribute"); 371 InterceptorFactory factory = manager.getInterceptorFactory(iname); 372 if (factory == null) throw new RuntimeException ("unable to resolve interceptor-ref: " + iname); 373 interceptors.add(factory); 374 } 375 else if (tag2.equals("stack-ref")) 376 { 377 String name = interceptorElement.getAttribute("name"); 378 AdviceStack stack = manager.getAdviceStack(name); 379 if (stack == null) throw new Exception ("there is no <stack> defined for name: " + name); 380 interceptors.addAll(stack.getInterceptorFactories()); 381 } 382 else if (tag2.equals("advice") || tag2.equals("before") || tag2.equals("after") || tag2.equals("throwing")) 383 { 384 InterceptorFactory factory = deployAdvice(interceptorElement); 385 interceptors.add(factory); 386 } 387 } 388 } 389 return interceptors; 390 } 391 392 private void unloadInterceptors(Element element) throws Exception 393 { 394 NodeList children2 = element.getChildNodes(); 395 for (int j = 0; j < children2.getLength(); j++) 396 { 397 if (children2.item(j).getNodeType() == Node.ELEMENT_NODE) 398 { 399 Element interceptorElement = (Element ) children2.item(j); 400 String tag2 = interceptorElement.getTagName(); 401 if (tag2.equals("interceptor")) 402 { 403 undeployInterceptor(interceptorElement); 404 } 405 if (tag2.equals("advice")) 406 { 407 undeployAdvice(interceptorElement); 408 } 409 } 410 } 411 } 412 413 public void undeployAspect(Element pointcut) throws Exception 414 { 415 String clazz = pointcut.getAttribute("class"); 416 if (clazz == null || clazz.trim().equals("")) clazz = null; 417 String name = pointcut.getAttribute("name"); 418 if (name == null || name.trim().equals("")) name = clazz; 419 if (name == null) return; 420 aspects.add(name); 422 } 423 424 public AspectDefinition deployAspect(Element element, String type) throws Exception 425 { 426 String name = element.getAttribute("name"); 427 if (name != null && name.trim().equals("")) name = null; 428 429 String clazz = element.getAttribute("class"); 430 if (clazz != null && clazz.trim().equals("")) clazz = null; 431 String factory = element.getAttribute("factory"); 432 if (factory != null && factory.trim().equals("")) factory = null; 433 if (clazz == null && factory == null) throw new RuntimeException (type + " " + name + " must have a class or factory associated with it."); 434 if (clazz != null && factory != null) throw new RuntimeException (type + " " + name + " cannot have both the class and factory attribute set."); 435 if (name == null) name = (clazz == null) ? factory : clazz; 436 437 String s = element.getAttribute("scope"); 438 if (s != null && s.trim().equals("")) s = null; 439 440 Scope scope = null; 441 if (s != null) 442 { 443 scope = ScopeUtil.parse(s); 444 if (scope == null) throw new RuntimeException ("Illegal scope attribute value: " + s); 445 } 446 AspectFactory aspectFactory; 447 if (clazz != null) 448 { 449 aspectFactory = new GenericAspectFactory(clazz, element); 450 ((AspectFactoryWithClassLoader)aspectFactory).setClassLoader(cl); 451 } 452 else 453 { 454 aspectFactory = new AspectFactoryDelegator(factory, element); 455 ((AspectFactoryWithClassLoader)aspectFactory).setClassLoader(cl); 456 } 457 458 AspectDefinition def = new AspectDefinition(name, scope, aspectFactory); 459 manager.addAspectDefinition(def); 460 return def; 461 } 462 463 public void undeployCFlowStack(Element pointcut) throws Exception 464 { 465 String name = pointcut.getAttribute("name"); 466 manager.removeCFlowStack(name); 467 } 468 469 public void deployCFlowStack(Element pointcut) throws Exception 470 { 471 String name = pointcut.getAttribute("name"); 472 if (name != null && name.trim().equals("")) name = null; 473 if (name == null) throw new RuntimeException ("name required for a cflow-stack"); 474 CFlowStack stack = new CFlowStack(name); 475 NodeList children2 = pointcut.getChildNodes(); 476 for (int j = 0; j < children2.getLength(); j++) 477 { 478 if (children2.item(j).getNodeType() == Node.ELEMENT_NODE) 479 { 480 Element cflowElement = (Element ) children2.item(j); 481 String tag2 = cflowElement.getTagName(); 482 String expr = cflowElement.getAttribute("expr"); 483 if (expr != null && expr.trim().equals("")) 484 { 485 throw new RuntimeException (tag2 + " requires an expr attribute to be defined"); 486 } 487 if (tag2.equals("called")) 488 { 489 stack.addCFlow(new CFlow(expr, false)); 490 } 491 if (tag2.equals("not-called")) 492 { 493 stack.addCFlow(new CFlow(expr, true)); 494 } 495 } 496 } 497 498 manager.addCFlowStack(stack); 499 } 500 501 502 public void undeployInterceptorStack(Element element) throws Exception 503 { 504 String name = element.getAttribute("name"); 505 unloadInterceptors(element); 506 manager.removeInterceptorStack(name); 507 } 508 509 public void deployInterceptorStack(Element element) throws Exception 510 { 511 ArrayList interceptors = loadInterceptors(element); 512 String name = element.getAttribute("name"); 513 AdviceStack stack = new AdviceStack(name, interceptors); 514 manager.addAdviceStack(stack); 515 } 516 517 private ClassMetaDataBinding loadMetaData(Element element) 518 throws Exception 519 { 520 String classExpr = element.getAttribute("class"); 521 String tag = element.getAttribute("tag"); 522 String name = getName(element, "metadata: " + tag + " " + classExpr); 523 ClassMetaDataLoader loader = manager.findClassMetaDataLoader(tag); 524 return loader.importMetaData(element, name, tag, classExpr); 525 } 526 527 public void undeployMetaDataLoader(Element element) throws Exception 528 { 529 String tag = element.getAttribute("tag"); 530 manager.removeClassMetaDataLoader(tag); 531 } 532 533 public void deployMetaDataLoader(Element element) throws Exception 534 { 535 String tag = element.getAttribute("tag"); 536 String classname = element.getAttribute("class"); 537 Class clazz = getClassLoader().loadClass(classname); 538 ClassMetaDataLoader loader = (ClassMetaDataLoader) clazz.newInstance(); 539 if (loader instanceof XmlLoadable) 540 { 541 ((XmlLoadable) loader).importXml(element); 542 } 543 manager.addClassMetaDataLoader(tag, loader); 544 } 545 546 public void deployClassMetaData(Element element) throws Exception 547 { 548 ClassMetaDataBinding data = loadMetaData(element); 549 manager.addClassMetaData(data); 550 } 551 552 public void undeployClassMetaData(Element element) throws Exception 553 { 554 String classExpr = element.getAttribute("class"); 555 String tag = element.getAttribute("tag"); 556 String name = getName(element, "metadata: " + tag + " " + classExpr); 557 manager.removeClassMetaData(name); 558 } 559 560 public void undeployPointcut(Element pointcut) throws Exception 561 { 562 String name = pointcut.getAttribute("name"); 563 manager.removePointcut(name); 564 } 565 566 public void undeployPluggablePointcut(Element pointcut) throws Exception 567 { 568 String name = pointcut.getAttribute("name"); 569 manager.removePointcut(name); 570 } 571 572 public void deployPluggablePointcut(Element pointcut) throws Exception 573 { 574 String name = pointcut.getAttribute("name"); 575 if (name == null || name.trim().equals("")) 576 { 577 throw new RuntimeException ("pluggable pointcut declaration must have a name associated with it"); 578 } 579 String clazz = pointcut.getAttribute("class"); 580 if (clazz != null && clazz.trim().equals("")) 581 { 582 throw new RuntimeException ("pluggable pointcut declaration must have an expr associated with it"); 583 } 584 585 Pointcut p = null; 586 587 Class pClass = null; 588 try 589 { 590 pClass = getClassLoader().loadClass(clazz); 591 } 592 catch (ClassNotFoundException e) 593 { 594 throw new RuntimeException ("pluggable pointcut class not found: " + clazz); 595 } 596 p = (Pointcut) pClass.newInstance(); 597 if (p instanceof XmlLoadable) 598 { 599 ((XmlLoadable) p).importXml(pointcut); 600 } 601 manager.addPointcut(p); 602 } 603 604 public void undeployDynamicCFlow(Element pointcut) throws Exception 605 { 606 String name = pointcut.getAttribute("name"); 607 manager.removeDynamicCFlow(name); 608 } 609 610 public void deployDynamicCFlow(Element pointcut) throws Exception 611 { 612 String name = pointcut.getAttribute("name"); 613 if (name == null || name.trim().equals("")) 614 { 615 throw new RuntimeException ("dynamic cflow declaration must have a name associated with it"); 616 } 617 String clazz = pointcut.getAttribute("class"); 618 if (clazz != null && clazz.trim().equals("")) 619 { 620 throw new RuntimeException ("dynamic cflow declaration must have an expr associated with it"); 621 } 622 623 manager.addDynamicCFlow(name, new DynamicCFlowDefinition(pointcut, clazz, name)); 624 } 625 626 public void deployPointcut(Element pointcut) throws Exception 627 { 628 String name = pointcut.getAttribute("name"); 629 if (name == null || name.trim().equals("")) 630 { 631 throw new RuntimeException ("pointcut declaration must have a name associated with it"); 632 } 633 String expr = pointcut.getAttribute("expr"); 634 if (expr == null || expr.trim().equals("")) 635 { 636 throw new RuntimeException ("pointcut declaration must have an expr associated with it"); 637 } 638 Pointcut p = null; 639 try 640 { 641 p = new PointcutExpression(name, expr); 642 } 643 catch (ParseException ex) 644 { 645 throw new RuntimeException ("<pointcut name='" + name + "' expr='" + expr + "'/> failed", ex); 646 } 647 manager.addPointcut(p); 648 } 649 650 public void undeployPrepare(Element pointcut) throws Exception 651 { 652 String name = getName(pointcut, "prepare"); 653 manager.removePointcut(name); 654 } 655 656 public void deployPrepare(Element pointcut) throws Exception 657 { 658 String name = getName(pointcut, "prepare"); 659 String expr = pointcut.getAttribute("expr"); 660 if (expr != null && expr.trim().equals("")) 661 { 662 throw new RuntimeException ("pointcut declaration must have an expr associated with it"); 663 } 664 Pointcut p = null; 665 try 666 { 667 p = new PointcutExpression(name, expr); 668 } 669 catch (ParseException ex) 670 { 671 throw new RuntimeException ("<prepare> failed: " + expr, ex); 672 } 673 manager.addPointcut(p); 674 } 675 676 public void deployAnnotationIntroduction(Element pointcut) throws Exception 677 { 678 manager.addAnnotationIntroduction(loadAnnotationIntroduction(pointcut)); 679 } 680 681 public void deployAnnotationOverride(Element pointcut) throws Exception 682 { 683 manager.addAnnotationOverride(loadAnnotationIntroduction(pointcut)); 684 } 685 686 public void undeployAnnotationIntroduction(Element pointcut) throws Exception 687 { 688 manager.removeAnnotationIntroduction(loadAnnotationIntroduction(pointcut)); 689 } 690 691 public void undeployAnnotationOverride(Element pointcut) throws Exception 692 { 693 manager.removeAnnotationOverride(loadAnnotationIntroduction(pointcut)); 694 } 695 696 public AnnotationIntroduction loadAnnotationIntroduction(Element pointcut) throws Exception 697 { 698 String expr = pointcut.getAttribute("expr"); 699 if (expr != null && expr.trim().equals("")) 700 { 701 throw new RuntimeException ("annotation introduction must have an expr attribute"); 702 } 703 704 String invisible = pointcut.getAttribute("invisible"); 705 if (invisible != null && expr.trim().equals("")) 706 { 707 throw new RuntimeException ("annotation introduction must have an invisible attribute"); 708 } 709 710 boolean isInvisble = new Boolean (invisible).booleanValue(); 711 712 String annotation = XmlHelper.getElementContent(pointcut); 713 714 return AnnotationIntroduction.createComplexAnnotationIntroduction(expr, annotation, isInvisble); 715 } 716 717 public void undeployIntroductionPointcut(Element pointcut) throws Exception 718 { 719 String name = getName(pointcut, "introduction-pointcut"); 720 721 manager.removeInterfaceIntroduction(name); 722 } 723 724 public void deployIntroductionPointcut(Element pointcut) throws Exception 725 { 726 String name = getName(pointcut, "introduction"); 727 String classExpr = pointcut.getAttribute("class"); 728 if (classExpr != null && classExpr.trim().equals("")) 729 { 730 classExpr = null; 731 } 732 733 String ast = pointcut.getAttribute("expr"); 734 if (ast != null && ast.trim().equals("")) 735 { 736 ast = null; 737 } 738 739 740 if (classExpr == null && ast == null) 741 { 742 throw new RuntimeException ("A class nor a expr attribute is defined for this <introduction>"); 743 } 744 745 if (classExpr != null && ast != null) 746 { 747 throw new RuntimeException ("You cannot define both a class and expr attribute in the same <introduction>"); 748 } 749 750 String intfs = XmlHelper.getOptionalChildContent(pointcut, "interfaces"); 751 String [] ifaces = null; 752 if (intfs != null) 753 { 754 StringTokenizer tokenizer = new StringTokenizer (intfs, ","); 755 ArrayList interfaces = new ArrayList (); 756 while (tokenizer.hasMoreTokens()) 757 { 758 String intf = tokenizer.nextToken().trim(); 759 if (!intf.equals("")) interfaces.add(intf); 760 } 761 ifaces = (String []) interfaces.toArray(new String [interfaces.size()]); 762 } 763 764 InterfaceIntroduction pcut = null; 765 if (classExpr != null) 766 { 767 pcut = new InterfaceIntroduction(name, classExpr, ifaces); 768 } 769 else 770 { 771 ASTStart start = new TypeExpressionParser(new StringReader (ast)).Start(); 772 pcut = new InterfaceIntroduction(name, start, ifaces); 773 } 774 Iterator it = XmlHelper.getChildrenByTagName(pointcut, "mixin"); 775 while (it.hasNext()) 776 { 777 Element mixin = (Element ) it.next(); 778 if (mixin != null) 779 { 780 String construction = XmlHelper.getOptionalChildContent(mixin, "construction"); 781 String classname = XmlHelper.getUniqueChildContent(mixin, "class"); 782 String isTransientString = mixin.getAttribute("transient"); 783 boolean isTransient = true; 784 if (isTransientString == null || isTransientString.trim().equals("")) 785 { 786 isTransient = true; 787 } 788 else 789 { 790 isTransient = new Boolean (isTransientString).booleanValue(); 791 } 792 793 intfs = XmlHelper.getUniqueChildContent(mixin, "interfaces"); 794 StringTokenizer tokenizer = new StringTokenizer (intfs, ","); 795 ArrayList interfaces = new ArrayList (); 796 while (tokenizer.hasMoreTokens()) 797 { 798 String intf = tokenizer.nextToken().trim(); 799 if (!intf.equals("")) interfaces.add(intf); 800 } 801 ifaces = (String []) interfaces.toArray(new String [interfaces.size()]); 802 pcut.getMixins().add(new InterfaceIntroduction.Mixin(classname, ifaces, construction, isTransient)); 803 } 804 } 805 manager.addInterfaceIntroduction(pcut); 806 } 807 808 public void deployTypedef(Element pointcut) throws Exception 809 { 810 String name = pointcut.getAttribute("name"); 811 if (name == null || name.trim().equals("")) 812 { 813 throw new RuntimeException ("typedef declaration must have a name associated with it"); 814 } 815 String expr = pointcut.getAttribute("expr"); 816 if (expr == null || expr.trim().equals("")) 817 { 818 throw new RuntimeException ("typedef declaration must have an expr associated with it"); 819 } 820 821 try 822 { 823 Typedef typedef = new TypedefExpression(name, expr); 824 manager.addTypedef(typedef); 825 } 826 catch (ParseException ex) 827 { 828 throw new RuntimeException ("<typedef name='" + name + "' expr='" + expr + "'/> failed", ex); 829 } 830 } 831 832 public void undeployTypedef(Element pointcut) throws Exception 833 { 834 String name = pointcut.getAttribute("name"); 835 manager.removeTypedef(name); 836 } 837 838 public void deployDeclare(Element pointcut, String tagName) throws Exception 839 { 840 String name = getName(pointcut, "declare"); 841 String expr = pointcut.getAttribute("expr"); 842 if (expr == null || expr.trim().equals("")) 843 { 844 throw new RuntimeException ("declare declaration must have an expr associated with it"); 845 } 846 847 boolean warning = (tagName.equals("declare-warning")); 848 String msg = XmlHelper.getElementContent(pointcut); 849 850 851 try 852 { 853 DeclareDef declare = new DeclareDef(name, expr, warning, msg); 854 manager.addDeclare(declare); 855 } 856 catch (ParseException ex) 857 { 858 throw new RuntimeException ("<declare name='" + name + "' expr='" + expr + "'/> failed", ex); 859 } 860 } 861 862 public void undeployDeclare(Element pointcut) throws Exception 863 { 864 String name = getName(pointcut, "declare"); 865 manager.removeDeclare(name); 866 } 867 868 869 private void setupDefaultName(URL url) throws Exception 870 { 871 if (url == null) return; 872 counter = 0; 873 defaultBaseName = url.toString(); 874 } 875 876 public void deployXML(Document doc, URL url, ClassLoader cl) throws Exception 877 { 878 setClassLoader(cl); 879 deployXML(doc, url); 880 } 881 882 public void deployXML(Document doc, URL url) throws Exception 883 { 884 setupDefaultName(url); 885 Element top = doc.getDocumentElement(); 886 try 887 { 888 deployTopElements(top); 889 } 890 catch (Exception e) 891 { 892 System.err.println("[error] " + e.getMessage() + " " + url); 893 if (AspectManager.verbose) e.printStackTrace(); 894 throw new RuntimeException (e); 895 } 896 } 897 898 public void deployDomain(Element element) throws Exception 899 { 900 String name = element.getAttribute("name"); 901 if (name == null || name.trim().equals("")) 902 { 903 throw new RuntimeException ("domain declaration must have a name associated with it"); 904 } 905 906 boolean parentFirst = false; 907 String parentFirstString = element.getAttribute("parentFirst"); 908 if (parentFirstString == null || parentFirstString.trim().equals("")) 909 { 910 parentFirst = false; 911 } 912 else 913 { 914 parentFirst = new Boolean (parentFirstString).booleanValue(); 915 } 916 917 boolean inheritDefs = true; 918 String inheritDefsString = element.getAttribute("inheritDefinitions"); 919 if (inheritDefsString == null || inheritDefsString.trim().equals("")) 920 { 921 inheritDefs = true; 922 } 923 else 924 { 925 inheritDefs = new Boolean (inheritDefsString).booleanValue(); 926 } 927 928 boolean inheritBindings = false; 929 String inheritBindingsString = element.getAttribute("inheritBindings"); 930 if (inheritBindingsString == null || inheritBindingsString.trim().equals("")) 931 { 932 inheritBindings = false; 933 } 934 else 935 { 936 inheritBindings = new Boolean (inheritBindingsString).booleanValue(); 937 } 938 939 AspectManager parent = manager; 940 String extend = element.getAttribute("extends"); 941 if (extend != null && !extend.trim().equals("")) 942 { 943 extend = extend.trim(); 944 DomainDefinition parentDef = manager.getContainer(extend); 945 if (parentDef == null) throw new RuntimeException ("unable to find parent Domain: " + extend); 946 parent = parentDef.getManager(); 947 } 948 949 DomainDefinition def = new DomainDefinition(name, parent, parentFirst, inheritDefs, inheritBindings); 950 AspectManager push = manager; 951 try 952 { 953 manager = def.getManager(); 954 deployTopElements(element); 955 } 956 finally 957 { 958 manager = push; 959 } 960 push.addContainer(def); 961 } 962 963 public void undeployDomain(Element element) throws Exception 964 { 965 String name = element.getAttribute("name"); 966 if (name == null || name.trim().equals("")) 967 { 968 throw new RuntimeException ("container declaration must have a name associated with it"); 969 } 970 971 DomainDefinition def = manager.getContainer(name); 972 if (def == null) throw new RuntimeException ("Unable to undeploy container: " + name); 973 AspectManager push = manager; 974 ArrayList oldFactories = factories; 975 ArrayList oldAspects = aspects; 976 ArrayList oldBindings = bindings; 977 try 978 { 979 factories = new ArrayList (); 980 aspects = new ArrayList (); 981 bindings = new ArrayList (); 982 manager = def.getManager(); 983 undeployTopElements(element); 984 bulkUndeploy(); 985 } 986 finally 987 { 988 manager = push; 989 } 990 push.removeContainer(name); 991 factories = oldFactories; 992 aspects = oldAspects; 993 bindings = oldBindings; 994 } 995 996 private void deployTopElements(Element top) 997 throws Exception 998 { 999 NodeList children = top.getChildNodes(); 1000 for (int i = 0; i < children.getLength(); i++) 1001 { 1002 if (children.item(i).getNodeType() == Node.ELEMENT_NODE) 1003 { 1004 Element element = (Element ) children.item(i); 1005 String tag = element.getTagName(); 1006 if (tag.equals("interceptor")) 1007 { 1008 deployInterceptor(element); 1009 } 1010 else if (tag.equals("introduction")) 1011 { 1012 deployIntroductionPointcut(element); 1013 } 1014 else if (tag.equals("metadata-loader")) 1015 { 1016 deployMetaDataLoader(element); 1017 } 1018 else if (tag.equals("metadata")) 1019 { 1020 deployClassMetaData(element); 1021 } 1022 else if (tag.equals("stack")) 1023 { 1024 deployInterceptorStack(element); 1025 } 1026 else if (tag.equals("aspect")) 1027 { 1028 deployAspect(element, "Aspect"); 1029 } 1030 else if (tag.equals("pointcut")) 1031 { 1032 deployPointcut(element); 1033 } 1034 else if (tag.equals("pluggable-pointcut")) 1035 { 1036 deployPluggablePointcut(element); 1037 } 1038 else if (tag.equals("bind")) 1039 { 1040 deployBinding(element); 1041 } 1042 else if (tag.equals("prepare")) 1043 { 1044 deployPrepare(element); 1045 } 1046 else if (tag.equals("cflow-stack")) 1047 { 1048 deployCFlowStack(element); 1049 } 1050 else if (tag.equals("dynamic-cflow")) 1051 { 1052 deployDynamicCFlow(element); 1053 } 1054 else if (tag.equals("annotation-introduction")) 1055 { 1056 deployAnnotationIntroduction(element); 1057 } 1058 else if (tag.equals("annotation")) 1059 { 1060 deployAnnotationOverride(element); 1061 } 1062 else if (tag.equals("typedef")) 1063 { 1064 deployTypedef(element); 1065 } 1066 else if (tag.equals("domain")) 1067 { 1068 deployDomain(element); 1069 } 1070 else if (tag.equals("precedence")) 1071 { 1072 deployPrecedence(element); 1073 } 1074 else if (tag.equals("declare-error") || tag.equals("declare-warning")) 1075 { 1076 deployDeclare(element, tag); 1077 } 1078 else 1079 { 1080 throw new IllegalArgumentException ("Unknown AOP tag: " + tag); 1081 } 1082 } 1083 } 1084 } 1085 1086 public void undeployXML(Document doc, URL url) throws Exception 1087 { 1088 setupDefaultName(url); 1090 undeployTopElements(doc.getDocumentElement()); 1091 1092 bulkUndeploy(); 1093 1094 1095 } 1096 1097 private void bulkUndeploy() 1098 { 1099 manager.removeBindings(bindings); 1102 for (int i = 0; i < factories.size(); i++) 1103 { 1104 String factory = (String ) factories.get(i); 1105 manager.removeInterceptorFactory(factory); 1106 } 1107 for (int i = 0; i < aspects.size(); i++) 1108 { 1109 String aspect = (String ) aspects.get(i); 1110 manager.removeAspectDefinition(aspect); 1111 } 1112 } 1113 1114 private void undeployTopElements(Element top) 1115 throws Exception 1116 { 1117 NodeList children = top.getChildNodes(); 1118 for (int i = 0; i < children.getLength(); i++) 1119 { 1120 if (children.item(i).getNodeType() == Node.ELEMENT_NODE) 1121 { 1122 Element element = (Element ) children.item(i); 1123 String tag = element.getTagName(); 1124 if (tag.equals("interceptor")) 1125 { 1126 undeployInterceptor(element); 1127 } 1128 else if (tag.equals("introduction")) 1129 { 1130 undeployIntroductionPointcut(element); 1131 } 1132 else if (tag.equals("metadata-loader")) 1133 { 1134 undeployMetaDataLoader(element); 1135 } 1136 else if (tag.equals("metadata")) 1137 { 1138 undeployClassMetaData(element); 1139 } 1140 else if (tag.equals("stack")) 1141 { 1142 undeployInterceptorStack(element); 1143 } 1144 else if (tag.equals("aspect")) 1145 { 1146 undeployAspect(element); 1147 } 1148 else if (tag.equals("pointcut")) 1149 { 1150 undeployPointcut(element); 1151 } 1152 else if (tag.equals("bind")) 1153 { 1154 undeployBinding(element); 1155 } 1156 else if (tag.equals("prepare")) 1157 { 1158 undeployPrepare(element); 1159 } 1160 else if (tag.equals("cflow-stack")) 1161 { 1162 undeployCFlowStack(element); 1163 } 1164 else if (tag.equals("pluggable-pointcut")) 1165 { 1166 undeployPluggablePointcut(element); 1167 } 1168 else if (tag.equals("dynamic-cflow")) 1169 { 1170 undeployDynamicCFlow(element); 1171 } 1172 else if (tag.equals("typedef")) 1173 { 1174 undeployTypedef(element); 1175 } 1176 else if (tag.equals("annotation-introduction")) 1177 { 1178 undeployAnnotationIntroduction(element); 1179 } 1180 else if (tag.equals("annotation")) 1181 { 1182 undeployAnnotationOverride(element); 1183 } 1184 else if (tag.equals("domain")) 1185 { 1186 undeployDomain(element); 1187 } 1188 else if (tag.equals("declare-error") || tag.equals("declare-warning")) 1189 { 1190 undeployDeclare(element); 1191 } 1192 } 1193 } 1194 } 1195 1196 public static XmlLoaderFactory factory = null; 1197 1198 1199 public void deploy(URL url, AspectManager manager, ClassLoader cl) throws Exception 1200 { 1201 setClassLoader(cl); 1202 deploy(url, manager); 1203 } 1204 1205 public void deploy(URL url, AspectManager manager) throws Exception 1206 { 1207 setManager(manager); 1208 deployXML(loadURL(url), url); 1209 } 1210 1211 public void undeploy(URL url, AspectManager manager) throws Exception 1212 { 1213 setManager(manager); 1214 undeployXML(loadURL(url), url); 1215 } 1216 1217 public static void deployXML(URL url) throws Exception 1218 { 1219 deployXML(url, null); 1220 } 1221 1222 public static void deployXML(URL url, ClassLoader cl) throws Exception 1223 { 1224 XmlLoader loader = null; 1225 if (factory == null) 1226 { 1227 loader = new AspectXmlLoader(); 1228 } 1229 else 1230 { 1231 loader = factory.create(); 1232 } 1233 loader.setClassLoader(cl); 1234 loader.deploy(url, AspectManager.instance()); 1235 1236 } 1237 1238 public static void undeployXML(URL url) throws Exception 1239 { 1240 XmlLoader loader = null; 1241 if (factory == null) 1242 { 1243 loader = new AspectXmlLoader(); 1244 } 1245 else 1246 { 1247 loader = factory.create(); 1248 } 1249 loader.undeploy(url, AspectManager.instance()); 1250 } 1251 1252 private static class Resolver implements EntityResolver 1253 { 1254 public InputSource resolveEntity(String publicId, String systemId) throws SAXException , IOException 1255 { 1256 if (systemId.endsWith("jboss-aop_1_0.dtd")) 1257 { 1258 try 1259 { 1260 URL url = AspectXmlLoader.class.getResource("/jboss-aop_1_0.dtd"); 1261 InputStream is = url.openStream(); 1262 return new InputSource (is); 1263 } 1264 catch (IOException e) 1265 { 1266 e.printStackTrace(); 1267 return null; 1268 } 1269 } 1270 return null; 1271 } 1272 } 1273 1274 public static Document loadURL(URL configURL) throws Exception 1275 { 1276 InputStream is = configURL != null ? configURL.openStream() : null; 1277 if (is == null) 1278 throw new IOException ("Failed to obtain InputStream from url: " + configURL); 1279 1280 return loadDocument(is); 1281 } 1282 1283 public static Document loadDocument(InputStream is) 1284 throws ParserConfigurationException , SAXException , IOException 1285 { 1286 DocumentBuilderFactory docBuilderFactory = null; 1287 docBuilderFactory = DocumentBuilderFactory.newInstance(); 1288 docBuilderFactory.setValidating(false); 1289 InputSource source = new InputSource (is); 1290 URL url = AspectXmlLoader.class.getResource("/jboss-aop_1_0.dtd"); 1291 source.setSystemId(url.toString()); 1292 DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); 1293 docBuilder.setEntityResolver(new Resolver ()); 1294 Document doc = docBuilder.parse(source); 1296 return doc; 1297 } 1298 1299} 1300 | Popular Tags |