1 15 package org.apache.tapestry.parse; 16 17 import java.io.BufferedInputStream ; 18 import java.io.IOException ; 19 import java.io.InputStream ; 20 import java.net.URL ; 21 import java.util.HashMap ; 22 import java.util.Iterator ; 23 import java.util.Map ; 24 25 import javax.xml.parsers.SAXParser ; 26 import javax.xml.parsers.SAXParserFactory ; 27 28 import org.apache.commons.logging.Log; 29 import org.apache.commons.logging.LogFactory; 30 import org.apache.hivemind.ClassResolver; 31 import org.apache.hivemind.ErrorHandler; 32 import org.apache.hivemind.HiveMind; 33 import org.apache.hivemind.Location; 34 import org.apache.hivemind.Resource; 35 import org.apache.hivemind.impl.DefaultErrorHandler; 36 import org.apache.hivemind.impl.LocationImpl; 37 import org.apache.hivemind.parse.AbstractParser; 38 import org.apache.tapestry.INamespace; 39 import org.apache.tapestry.Tapestry; 40 import org.apache.tapestry.bean.BindingBeanInitializer; 41 import org.apache.tapestry.bean.LightweightBeanInitializer; 42 import org.apache.tapestry.binding.BindingConstants; 43 import org.apache.tapestry.binding.BindingSource; 44 import org.apache.tapestry.coerce.ValueConverter; 45 import org.apache.tapestry.spec.BeanLifecycle; 46 import org.apache.tapestry.spec.BindingType; 47 import org.apache.tapestry.spec.IApplicationSpecification; 48 import org.apache.tapestry.spec.IAssetSpecification; 49 import org.apache.tapestry.spec.IBeanSpecification; 50 import org.apache.tapestry.spec.IBindingSpecification; 51 import org.apache.tapestry.spec.IComponentSpecification; 52 import org.apache.tapestry.spec.IContainedComponent; 53 import org.apache.tapestry.spec.IExtensionSpecification; 54 import org.apache.tapestry.spec.ILibrarySpecification; 55 import org.apache.tapestry.spec.IListenerBindingSpecification; 56 import org.apache.tapestry.spec.IParameterSpecification; 57 import org.apache.tapestry.spec.IPropertySpecification; 58 import org.apache.tapestry.spec.InjectSpecification; 59 import org.apache.tapestry.spec.SpecFactory; 60 import org.apache.tapestry.util.IPropertyHolder; 61 import org.apache.tapestry.util.RegexpMatcher; 62 import org.apache.tapestry.util.xml.DocumentParseException; 63 import org.apache.tapestry.util.xml.InvalidStringException; 64 import org.xml.sax.InputSource ; 65 import org.xml.sax.SAXException ; 66 import org.xml.sax.SAXParseException ; 67 68 75 public class SpecificationParser extends AbstractParser implements ISpecificationParser 76 { 77 private static final String IDENTIFIER_PATTERN = "_?[a-zA-Z]\\w*"; 78 79 private static final String EXTENDED_IDENTIFIER_PATTERN = "_?[a-zA-Z](\\w|-)*"; 80 81 87 88 public static final String ASSET_NAME_PATTERN = "(\\$template)|(" 89 + Tapestry.SIMPLE_PROPERTY_NAME_PATTERN + ")"; 90 91 96 97 public static final String BEAN_NAME_PATTERN = Tapestry.SIMPLE_PROPERTY_NAME_PATTERN; 98 99 105 106 public static final String COMPONENT_ALIAS_PATTERN = Tapestry.SIMPLE_PROPERTY_NAME_PATTERN; 107 108 113 114 public static final String COMPONENT_ID_PATTERN = Tapestry.SIMPLE_PROPERTY_NAME_PATTERN; 115 116 122 123 public static final String COMPONENT_TYPE_PATTERN = "^(" + IDENTIFIER_PATTERN + ":)?" 124 + IDENTIFIER_PATTERN + "$"; 125 126 130 131 private final Map CONVERSION_MAP = new HashMap (); 132 133 140 141 public static final String EXTENDED_PROPERTY_NAME_PATTERN = "^" + EXTENDED_IDENTIFIER_PATTERN 142 + "(\\." + EXTENDED_IDENTIFIER_PATTERN + ")*$"; 143 144 150 151 public static final String EXTENSION_NAME_PATTERN = EXTENDED_PROPERTY_NAME_PATTERN; 152 153 158 159 public static final String LIBRARY_ID_PATTERN = Tapestry.SIMPLE_PROPERTY_NAME_PATTERN; 160 161 162 private final Log _log; 163 164 165 private final ErrorHandler _errorHandler; 166 167 172 173 private boolean _DTD_4_0; 174 175 183 184 public static final String PAGE_NAME_PATTERN = "^" + IDENTIFIER_PATTERN + "(/" 185 + IDENTIFIER_PATTERN + ")*$"; 186 187 193 194 public static final String PARAMETER_NAME_PATTERN = Tapestry.SIMPLE_PROPERTY_NAME_PATTERN; 195 196 202 203 public static final String PROPERTY_NAME_PATTERN = Tapestry.SIMPLE_PROPERTY_NAME_PATTERN; 204 205 213 214 public static final String SERVICE_NAME_PATTERN = EXTENDED_PROPERTY_NAME_PATTERN; 215 216 private static final int STATE_ALLOW_DESCRIPTION = 2000; 217 218 private static final int STATE_ALLOW_PROPERTY = 2001; 219 220 private static final int STATE_APPLICATION_SPECIFICATION_INITIAL = 1002; 221 222 private static final int STATE_BEAN = 4; 223 224 225 226 private static final int STATE_BINDING_3_0 = 7; 227 228 229 230 private static final int STATE_BINDING = 100; 231 232 private static final int STATE_COMPONENT = 6; 233 234 private static final int STATE_COMPONENT_SPECIFICATION = 1; 235 236 private static final int STATE_COMPONENT_SPECIFICATION_INITIAL = 1000; 237 238 private static final int STATE_CONFIGURE = 14; 239 240 private static final int STATE_DESCRIPTION = 2; 241 242 private static final int STATE_EXTENSION = 13; 243 244 private static final int STATE_LIBRARY_SPECIFICATION = 12; 245 246 private static final int STATE_LIBRARY_SPECIFICATION_INITIAL = 1003; 247 248 private static final int STATE_LISTENER_BINDING = 8; 249 250 private static final int STATE_NO_CONTENT = 3000; 251 252 private static final int STATE_PAGE_SPECIFICATION = 11; 253 254 private static final int STATE_PAGE_SPECIFICATION_INITIAL = 1001; 255 256 private static final int STATE_META = 3; 257 258 private static final int STATE_PROPERTY = 10; 259 260 private static final int STATE_SET = 5; 261 262 263 private static final int STATE_STATIC_BINDING = 9; 264 265 266 267 public static final String TAPESTRY_DTD_3_0_PUBLIC_ID = "-//Apache Software Foundation//Tapestry Specification 3.0//EN"; 268 269 270 271 public static final String TAPESTRY_DTD_4_0_PUBLIC_ID = "-//Apache Software Foundation//Tapestry Specification 4.0//EN"; 272 273 276 277 private Map _attributes; 278 279 282 283 private String _elementName; 284 285 286 287 private final SpecFactory _factory; 288 289 private RegexpMatcher _matcher = new RegexpMatcher(); 290 291 private SAXParser _parser; 292 293 private SAXParserFactory _parserFactory = SAXParserFactory.newInstance(); 294 295 298 299 private final ClassResolver _resolver; 300 301 302 303 private BindingSource _bindingSource; 304 305 309 private Object _rootObject; 310 311 312 313 private ValueConverter _valueConverter; 314 315 321 { 322 323 CONVERSION_MAP.put("true", Boolean.TRUE); 324 CONVERSION_MAP.put("t", Boolean.TRUE); 325 CONVERSION_MAP.put("1", Boolean.TRUE); 326 CONVERSION_MAP.put("y", Boolean.TRUE); 327 CONVERSION_MAP.put("yes", Boolean.TRUE); 328 CONVERSION_MAP.put("on", Boolean.TRUE); 329 CONVERSION_MAP.put("aye", Boolean.TRUE); 330 331 CONVERSION_MAP.put("false", Boolean.FALSE); 332 CONVERSION_MAP.put("f", Boolean.FALSE); 333 CONVERSION_MAP.put("0", Boolean.FALSE); 334 CONVERSION_MAP.put("off", Boolean.FALSE); 335 CONVERSION_MAP.put("no", Boolean.FALSE); 336 CONVERSION_MAP.put("n", Boolean.FALSE); 337 CONVERSION_MAP.put("nay", Boolean.FALSE); 338 339 CONVERSION_MAP.put("none", BeanLifecycle.NONE); 340 CONVERSION_MAP.put("request", BeanLifecycle.REQUEST); 341 CONVERSION_MAP.put("page", BeanLifecycle.PAGE); 342 CONVERSION_MAP.put("render", BeanLifecycle.RENDER); 343 344 _parserFactory.setNamespaceAware(false); 345 _parserFactory.setValidating(true); 346 } 347 348 351 public SpecificationParser(ClassResolver resolver) 352 { 353 this(resolver, new SpecFactory()); 354 } 355 356 361 public SpecificationParser(ClassResolver resolver, SpecFactory factory) 362 { 363 this(new DefaultErrorHandler(), LogFactory.getLog(SpecificationParser.class), resolver, 364 factory); 365 } 366 367 370 public SpecificationParser(ErrorHandler errorHandler, Log log, ClassResolver resolver, 371 SpecFactory factory) 372 { 373 _errorHandler = errorHandler; 374 _log = log; 375 _resolver = resolver; 376 _factory = factory; 377 } 378 379 protected void begin(String elementName, Map attributes) 380 { 381 _elementName = elementName; 382 _attributes = attributes; 383 384 switch (getState()) 385 { 386 case STATE_COMPONENT_SPECIFICATION_INITIAL: 387 388 beginComponentSpecificationInitial(); 389 break; 390 391 case STATE_PAGE_SPECIFICATION_INITIAL: 392 393 beginPageSpecificationInitial(); 394 break; 395 396 case STATE_APPLICATION_SPECIFICATION_INITIAL: 397 398 beginApplicationSpecificationInitial(); 399 break; 400 401 case STATE_LIBRARY_SPECIFICATION_INITIAL: 402 403 beginLibrarySpecificationInitial(); 404 break; 405 406 case STATE_COMPONENT_SPECIFICATION: 407 408 beginComponentSpecification(); 409 break; 410 411 case STATE_PAGE_SPECIFICATION: 412 413 beginPageSpecification(); 414 break; 415 416 case STATE_ALLOW_DESCRIPTION: 417 418 beginAllowDescription(); 419 break; 420 421 case STATE_ALLOW_PROPERTY: 422 423 allowMetaData(); 424 break; 425 426 case STATE_BEAN: 427 428 beginBean(); 429 break; 430 431 case STATE_COMPONENT: 432 433 beginComponent(); 434 break; 435 436 case STATE_LIBRARY_SPECIFICATION: 437 438 beginLibrarySpecification(); 439 break; 440 441 case STATE_EXTENSION: 442 443 beginExtension(); 444 break; 445 446 default: 447 448 unexpectedElement(_elementName); 449 } 450 } 451 452 456 457 private void beginAllowDescription() 458 { 459 if (_elementName.equals("description")) 460 { 461 enterDescription(); 462 return; 463 } 464 465 unexpectedElement(_elementName); 466 } 467 468 472 473 private void allowMetaData() 474 { 475 if (_DTD_4_0) 476 { 477 if (_elementName.equals("meta")) 478 { 479 enterMeta(); 480 return; 481 } 482 } 483 else if (_elementName.equals("property")) 484 { 485 enterProperty_3_0(); 486 return; 487 } 488 489 unexpectedElement(_elementName); 490 } 491 492 private void beginApplicationSpecificationInitial() 493 { 494 expectElement("application"); 495 496 String name = getAttribute("name"); 497 String engineClassName = getAttribute("engine-class"); 498 499 IApplicationSpecification as = _factory.createApplicationSpecification(); 500 501 as.setName(name); 502 503 if (HiveMind.isNonBlank(engineClassName)) 504 as.setEngineClassName(engineClassName); 505 506 _rootObject = as; 507 508 push(_elementName, as, STATE_LIBRARY_SPECIFICATION); 509 } 510 511 private void beginBean() 512 { 513 if (_elementName.equals("set")) 514 { 515 enterSet(); 516 return; 517 } 518 519 if (_elementName.equals("set-property")) 520 { 521 enterSetProperty_3_0(); 522 return; 523 } 524 525 if (_elementName.equals("set-message-property")) 526 { 527 enterSetMessage_3_0(); 528 return; 529 } 530 531 if (_elementName.equals("description")) 532 { 533 enterDescription(); 534 return; 535 } 536 537 allowMetaData(); 538 } 539 540 private void beginComponent() 541 { 542 544 if (_elementName.equals("binding")) 545 { 546 enterBinding(); 547 return; 548 } 549 550 if (_elementName.equals("static-binding")) 551 { 552 enterStaticBinding_3_0(); 553 return; 554 } 555 556 if (_elementName.equals("message-binding")) 557 { 558 enterMessageBinding_3_0(); 559 return; 560 } 561 562 if (_elementName.equals("inherited-binding")) 563 { 564 enterInheritedBinding_3_0(); 565 return; 566 } 567 568 if (_elementName.equals("listener-binding")) 569 { 570 enterListenerBinding(); 571 return; 572 } 573 574 allowMetaData(); 575 } 576 577 private void beginComponentSpecification() 578 { 579 if (_elementName.equals("reserved-parameter")) 580 { 581 enterReservedParameter(); 582 return; 583 } 584 585 if (_elementName.equals("parameter")) 586 { 587 enterParameter(); 588 return; 589 } 590 591 594 beginPageSpecification(); 595 } 596 597 private void beginComponentSpecificationInitial() 598 { 599 expectElement("component-specification"); 600 601 IComponentSpecification cs = _factory.createComponentSpecification(); 602 603 cs.setAllowBody(getBooleanAttribute("allow-body", true)); 604 cs.setAllowInformalParameters(getBooleanAttribute("allow-informal-parameters", true)); 605 cs.setDeprecated(getBooleanAttribute("deprecated", false)); 606 607 String className = getAttribute("class"); 608 609 if (className != null) 610 cs.setComponentClassName(className); 611 612 cs.setSpecificationLocation(getResource()); 613 614 _rootObject = cs; 615 616 push(_elementName, cs, STATE_COMPONENT_SPECIFICATION); 617 } 618 619 private void beginExtension() 620 { 621 if (_elementName.equals("configure")) 622 { 623 enterConfigure(); 624 return; 625 } 626 627 allowMetaData(); 628 } 629 630 private void beginLibrarySpecification() 631 { 632 if (_elementName.equals("description")) 633 { 634 enterDescription(); 635 return; 636 } 637 638 if (_elementName.equals("page")) 639 { 640 enterPage(); 641 return; 642 } 643 644 if (_elementName.equals("component-type")) 645 { 646 enterComponentType(); 647 return; 648 } 649 650 652 if (_elementName.equals("service")) 653 { 654 enterService_3_0(); 655 return; 656 } 657 658 if (_elementName.equals("library")) 659 { 660 enterLibrary(); 661 return; 662 } 663 664 if (_elementName.equals("extension")) 665 { 666 enterExtension(); 667 return; 668 } 669 670 allowMetaData(); 671 } 672 673 private void beginLibrarySpecificationInitial() 674 { 675 expectElement("library-specification"); 676 677 ILibrarySpecification ls = _factory.createLibrarySpecification(); 678 679 _rootObject = ls; 680 681 push(_elementName, ls, STATE_LIBRARY_SPECIFICATION); 682 } 683 684 private void beginPageSpecification() 685 { 686 if (_elementName.equals("component")) 687 { 688 enterComponent(); 689 return; 690 } 691 692 if (_elementName.equals("bean")) 693 { 694 enterBean(); 695 return; 696 } 697 698 701 if (_elementName.equals("property-specification") 702 || (_DTD_4_0 && _elementName.equals("property"))) 703 { 704 enterProperty(); 705 return; 706 } 707 708 if (_elementName.equals("inject")) 709 { 710 enterInject(); 711 return; 712 } 713 714 716 if (_elementName.equals("asset")) 717 { 718 enterAsset(); 719 return; 720 } 721 722 726 if (_elementName.equals("context-asset")) 727 { 728 enterContextAsset_3_0(); 729 return; 730 } 731 732 if (_elementName.equals("private-asset")) 733 { 734 enterPrivateAsset_3_0(); 735 return; 736 } 737 738 if (_elementName.equals("external-asset")) 739 { 740 enterExternalAsset_3_0(); 741 return; 742 743 } 744 745 if (_elementName.equals("description")) 746 { 747 enterDescription(); 748 return; 749 } 750 751 allowMetaData(); 752 } 753 754 private void beginPageSpecificationInitial() 755 { 756 expectElement("page-specification"); 757 758 IComponentSpecification cs = _factory.createComponentSpecification(); 759 760 String className = getAttribute("class"); 761 762 if (className != null) 763 cs.setComponentClassName(className); 764 765 cs.setSpecificationLocation(getResource()); 766 cs.setPageSpecification(true); 767 768 _rootObject = cs; 769 770 push(_elementName, cs, STATE_PAGE_SPECIFICATION); 771 } 772 773 776 private void close(InputStream stream) 777 { 778 try 779 { 780 if (stream != null) 781 stream.close(); 782 } 783 catch (IOException ex) 784 { 785 } 787 } 788 789 private void copyBindings(String sourceComponentId, IComponentSpecification cs, 790 IContainedComponent target) 791 { 792 IContainedComponent source = cs.getComponent(sourceComponentId); 793 if (source == null) 794 throw new DocumentParseException(ParseMessages.unableToCopy(sourceComponentId), 795 getLocation(), null); 796 797 Iterator i = source.getBindingNames().iterator(); 798 while (i.hasNext()) 799 { 800 String bindingName = (String ) i.next(); 801 IBindingSpecification binding = source.getBinding(bindingName); 802 target.setBinding(bindingName, binding); 803 } 804 805 target.setType(source.getType()); 806 } 807 808 protected void end(String elementName) 809 { 810 _elementName = elementName; 811 812 switch (getState()) 813 { 814 case STATE_DESCRIPTION: 815 816 endDescription(); 817 break; 818 819 case STATE_META: 820 821 endProperty(); 822 break; 823 824 case STATE_SET: 825 826 endSetProperty(); 827 break; 828 829 case STATE_BINDING_3_0: 830 831 endBinding_3_0(); 832 break; 833 834 case STATE_BINDING: 835 836 endBinding(); 837 break; 838 839 case STATE_LISTENER_BINDING: 840 841 endListenerBinding(); 842 break; 843 844 case STATE_STATIC_BINDING: 845 846 endStaticBinding(); 847 break; 848 849 case STATE_PROPERTY: 850 851 endPropertySpecification(); 852 break; 853 854 case STATE_LIBRARY_SPECIFICATION: 855 856 endLibrarySpecification(); 857 break; 858 859 case STATE_CONFIGURE: 860 861 endConfigure(); 862 break; 863 864 default: 865 break; 866 } 867 868 870 pop(); 871 } 872 873 private void endBinding_3_0() 874 { 875 BindingSetter bs = (BindingSetter) peekObject(); 876 877 String expression = getExtendedValue(bs.getValue(), "expression", true); 878 879 IBindingSpecification spec = _factory.createBindingSpecification(); 880 881 spec.setType(BindingType.PREFIXED); 882 spec.setValue(BindingConstants.OGNL_PREFIX + ":" + expression); 883 884 bs.apply(spec); 885 } 886 887 private void endConfigure() 888 { 889 ExtensionConfigurationSetter setter = (ExtensionConfigurationSetter) peekObject(); 890 891 String finalValue = getExtendedValue(setter.getValue(), "value", true); 892 893 setter.apply(finalValue); 894 } 895 896 private void endDescription() 897 { 898 DescriptionSetter setter = (DescriptionSetter) peekObject(); 899 900 String description = peekContent(); 901 902 setter.apply(description); 903 } 904 905 private void endLibrarySpecification() 906 { 907 ILibrarySpecification spec = (ILibrarySpecification) peekObject(); 908 909 spec.setSpecificationLocation(getResource()); 910 911 spec.instantiateImmediateExtensions(); 912 } 913 914 private void endListenerBinding() 915 { 916 BindingSetter bs = (BindingSetter) peekObject(); 917 918 IListenerBindingSpecification lbs = _factory.createListenerBindingSpecification(); 919 920 lbs.setLanguage(bs.getValue()); 921 922 924 lbs.setValue(peekContent()); 925 lbs.setLocation(getLocation()); 926 927 bs.apply(lbs); 928 } 929 930 private void endProperty() 931 { 932 PropertyValueSetter pvs = (PropertyValueSetter) peekObject(); 933 934 String finalValue = getExtendedValue(pvs.getPropertyValue(), "value", true); 935 936 pvs.applyValue(finalValue); 937 } 938 939 private void endPropertySpecification() 940 { 941 IPropertySpecification ps = (IPropertySpecification) peekObject(); 942 943 String initialValue = getExtendedValue(ps.getInitialValue(), "initial-value", false); 944 945 948 if (initialValue != null && !_DTD_4_0) 949 initialValue = BindingConstants.OGNL_PREFIX + ":" + initialValue; 950 951 ps.setInitialValue(initialValue); 952 } 953 954 private void endSetProperty() 955 { 956 BeanSetPropertySetter bs = (BeanSetPropertySetter) peekObject(); 957 958 String finalValue = getExtendedValue(bs.getBindingReference(), "expression", true); 959 960 bs.applyBindingReference(finalValue); 961 } 962 963 private void endStaticBinding() 964 { 965 BindingSetter bs = (BindingSetter) peekObject(); 966 967 String literalValue = getExtendedValue(bs.getValue(), "value", true); 968 969 IBindingSpecification spec = _factory.createBindingSpecification(); 970 971 spec.setType(BindingType.PREFIXED); 972 spec.setValue(BindingConstants.LITERAL_PREFIX + ":" + literalValue); 973 974 bs.apply(spec); 975 } 976 977 private void enterAsset(String pathAttributeName, String prefix) 978 { 979 String name = getValidatedAttribute("name", ASSET_NAME_PATTERN, "invalid-asset-name"); 980 String path = getAttribute(pathAttributeName); 981 String propertyName = getValidatedAttribute( 982 "property", 983 PROPERTY_NAME_PATTERN, 984 "invalid-property-name"); 985 986 IAssetSpecification ia = _factory.createAssetSpecification(); 987 988 ia.setPath(prefix == null ? path : prefix + path); 989 ia.setPropertyName(propertyName); 990 991 IComponentSpecification cs = (IComponentSpecification) peekObject(); 992 993 cs.addAsset(name, ia); 994 995 push(_elementName, ia, STATE_ALLOW_PROPERTY); 996 } 997 998 private void enterBean() 999 { 1000 String name = getValidatedAttribute("name", BEAN_NAME_PATTERN, "invalid-bean-name"); 1001 1002 String classAttribute = getAttribute("class"); 1003 1004 1006 int commax = classAttribute.indexOf(','); 1007 1008 String className = commax < 0 ? classAttribute : classAttribute.substring(0, commax); 1009 1010 BeanLifecycle lifecycle = (BeanLifecycle) getConvertedAttribute( 1011 "lifecycle", 1012 BeanLifecycle.REQUEST); 1013 String propertyName = getValidatedAttribute( 1014 "property", 1015 PROPERTY_NAME_PATTERN, 1016 "invalid-property-name"); 1017 1018 IBeanSpecification bs = _factory.createBeanSpecification(); 1019 1020 bs.setClassName(className); 1021 bs.setLifecycle(lifecycle); 1022 bs.setPropertyName(propertyName); 1023 1024 if (commax > 0) 1025 { 1026 String initializer = classAttribute.substring(commax + 1); 1027 bs.addInitializer(new LightweightBeanInitializer(initializer)); 1028 } 1029 1030 IComponentSpecification cs = (IComponentSpecification) peekObject(); 1031 1032 cs.addBeanSpecification(name, bs); 1033 1034 push(_elementName, bs, STATE_BEAN); 1035 } 1036 1037 private void enterBinding() 1038 { 1039 if (!_DTD_4_0) 1040 { 1041 enterBinding_3_0(); 1042 return; 1043 } 1044 1045 1047 String name = getValidatedAttribute( 1048 "name", 1049 PARAMETER_NAME_PATTERN, 1050 "invalid-parameter-name"); 1051 String value = getAttribute("value"); 1052 1053 IContainedComponent cc = (IContainedComponent) peekObject(); 1054 1055 BindingSetter bs = new BindingSetter(cc, name, value); 1056 1057 push(_elementName, bs, STATE_BINDING, false); 1058 } 1059 1060 private void endBinding() 1061 { 1062 BindingSetter bs = (BindingSetter) peekObject(); 1063 1064 String value = getExtendedValue(bs.getValue(), "value", true); 1065 1066 IBindingSpecification spec = _factory.createBindingSpecification(); 1067 1068 spec.setType(BindingType.PREFIXED); 1069 spec.setValue(value); 1070 1071 bs.apply(spec); 1072 } 1073 1074 1077 1078 private void enterBinding_3_0() 1079 { 1080 String name = getAttribute("name"); 1081 String expression = getAttribute("expression"); 1082 1083 IContainedComponent cc = (IContainedComponent) peekObject(); 1084 1085 BindingSetter bs = new BindingSetter(cc, name, expression); 1086 1087 push(_elementName, bs, STATE_BINDING_3_0, false); 1088 } 1089 1090 private void enterComponent() 1091 { 1092 String id = getValidatedAttribute("id", COMPONENT_ID_PATTERN, "invalid-component-id"); 1093 1094 String type = getValidatedAttribute( 1095 "type", 1096 COMPONENT_TYPE_PATTERN, 1097 "invalid-component-type"); 1098 String copyOf = getAttribute("copy-of"); 1099 boolean inherit = getBooleanAttribute("inherit-informal-parameters", false); 1100 String propertyName = getValidatedAttribute( 1101 "property", 1102 PROPERTY_NAME_PATTERN, 1103 "invalid-property-name"); 1104 1105 1107 boolean hasCopyOf = HiveMind.isNonBlank(copyOf); 1108 1109 if (hasCopyOf) 1110 { 1111 if (HiveMind.isNonBlank(type)) 1112 throw new DocumentParseException(ParseMessages.bothTypeAndCopyOf(id), 1113 getLocation(), null); 1114 } 1115 else 1116 { 1117 if (HiveMind.isBlank(type)) 1118 throw new DocumentParseException(ParseMessages.missingTypeOrCopyOf(id), 1119 getLocation(), null); 1120 } 1121 1122 IContainedComponent cc = _factory.createContainedComponent(); 1123 cc.setType(type); 1124 cc.setCopyOf(copyOf); 1125 cc.setInheritInformalParameters(inherit); 1126 cc.setPropertyName(propertyName); 1127 1128 IComponentSpecification cs = (IComponentSpecification) peekObject(); 1129 1130 cs.addComponent(id, cc); 1131 1132 if (hasCopyOf) 1133 copyBindings(copyOf, cs, cc); 1134 1135 push(_elementName, cc, STATE_COMPONENT); 1136 } 1137 1138 private void enterComponentType() 1139 { 1140 String type = getValidatedAttribute( 1141 "type", 1142 COMPONENT_ALIAS_PATTERN, 1143 "invalid-component-type"); 1144 String path = getAttribute("specification-path"); 1145 1146 ILibrarySpecification ls = (ILibrarySpecification) peekObject(); 1147 1148 ls.setComponentSpecificationPath(type, path); 1149 1150 push(_elementName, null, STATE_NO_CONTENT); 1151 } 1152 1153 private void enterConfigure() 1154 { 1155 String attributeName = _DTD_4_0 ? "property" : "property-name"; 1156 1157 String propertyName = getValidatedAttribute( 1158 attributeName, 1159 PROPERTY_NAME_PATTERN, 1160 "invalid-property-name"); 1161 1162 String value = getAttribute("value"); 1163 1164 IExtensionSpecification es = (IExtensionSpecification) peekObject(); 1165 1166 ExtensionConfigurationSetter setter = new ExtensionConfigurationSetter(es, propertyName, 1167 value); 1168 1169 push(_elementName, setter, STATE_CONFIGURE, false); 1170 } 1171 1172 private void enterContextAsset_3_0() 1173 { 1174 enterAsset("path", "context:"); 1175 } 1176 1177 1183 1184 private void enterAsset() 1185 { 1186 enterAsset("path", null); 1187 } 1188 1189 private void enterDescription() 1190 { 1191 push(_elementName, new DescriptionSetter(peekObject()), STATE_DESCRIPTION, false); 1192 } 1193 1194 private void enterExtension() 1195 { 1196 String name = getValidatedAttribute( 1197 "name", 1198 EXTENSION_NAME_PATTERN, 1199 "invalid-extension-name"); 1200 1201 boolean immediate = getBooleanAttribute("immediate", false); 1202 String className = getAttribute("class"); 1203 1204 IExtensionSpecification es = _factory.createExtensionSpecification( 1205 _resolver, 1206 _valueConverter); 1207 1208 es.setClassName(className); 1209 es.setImmediate(immediate); 1210 1211 ILibrarySpecification ls = (ILibrarySpecification) peekObject(); 1212 1213 ls.addExtensionSpecification(name, es); 1214 1215 push(_elementName, es, STATE_EXTENSION); 1216 } 1217 1218 private void enterExternalAsset_3_0() 1219 { 1220 1223 enterAsset("URL", null); 1224 } 1225 1226 1227 1228 private void enterInheritedBinding_3_0() 1229 { 1230 String name = getAttribute("name"); 1231 String parameterName = getAttribute("parameter-name"); 1232 1233 IBindingSpecification bs = _factory.createBindingSpecification(); 1234 bs.setType(BindingType.INHERITED); 1235 bs.setValue(parameterName); 1236 1237 IContainedComponent cc = (IContainedComponent) peekObject(); 1238 1239 cc.setBinding(name, bs); 1240 1241 push(_elementName, null, STATE_NO_CONTENT); 1242 } 1243 1244 private void enterLibrary() 1245 { 1246 String libraryId = getValidatedAttribute("id", LIBRARY_ID_PATTERN, "invalid-library-id"); 1247 String path = getAttribute("specification-path"); 1248 1249 if (libraryId.equals(INamespace.FRAMEWORK_NAMESPACE)) 1250 throw new DocumentParseException(ParseMessages 1251 .frameworkLibraryIdIsReserved(INamespace.FRAMEWORK_NAMESPACE), getLocation(), 1252 null); 1253 1254 ILibrarySpecification ls = (ILibrarySpecification) peekObject(); 1255 1256 ls.setLibrarySpecificationPath(libraryId, path); 1257 1258 push(_elementName, null, STATE_NO_CONTENT); 1259 } 1260 1261 private void enterListenerBinding() 1262 { 1263 String name = getAttribute("name"); 1264 String language = getAttribute("language"); 1265 1266 IContainedComponent cc = (IContainedComponent) peekObject(); 1267 BindingSetter bs = new BindingSetter(cc, name, language); 1268 1269 push(_elementName, bs, STATE_LISTENER_BINDING, false); 1270 } 1271 1272 private void enterMessageBinding_3_0() 1273 { 1274 String name = getAttribute("name"); 1275 String key = getAttribute("key"); 1276 1277 IBindingSpecification bs = _factory.createBindingSpecification(); 1278 bs.setType(BindingType.PREFIXED); 1279 bs.setValue(BindingConstants.MESSAGE_PREFIX + ":" + key); 1280 bs.setLocation(getLocation()); 1281 1282 IContainedComponent cc = (IContainedComponent) peekObject(); 1283 1284 cc.setBinding(name, bs); 1285 1286 push(_elementName, null, STATE_NO_CONTENT); 1287 } 1288 1289 private void enterPage() 1290 { 1291 String name = getValidatedAttribute("name", PAGE_NAME_PATTERN, "invalid-page-name"); 1292 String path = getAttribute("specification-path"); 1293 1294 ILibrarySpecification ls = (ILibrarySpecification) peekObject(); 1295 1296 ls.setPageSpecificationPath(name, path); 1297 1298 push(_elementName, null, STATE_NO_CONTENT); 1299 } 1300 1301 private void enterParameter() 1302 { 1303 IParameterSpecification ps = _factory.createParameterSpecification(); 1304 1305 String name = getValidatedAttribute( 1306 "name", 1307 PARAMETER_NAME_PATTERN, 1308 "invalid-parameter-name"); 1309 1310 String attributeName = _DTD_4_0 ? "property" : "property-name"; 1311 1312 String propertyName = getValidatedAttribute( 1313 attributeName, 1314 PROPERTY_NAME_PATTERN, 1315 "invalid-property-name"); 1316 1317 if (propertyName == null) 1318 propertyName = name; 1319 1320 ps.setParameterName(name); 1321 ps.setPropertyName(propertyName); 1322 1323 ps.setRequired(getBooleanAttribute("required", false)); 1324 1325 1329 String defaultValue = getAttribute("default-value"); 1330 1331 if (defaultValue != null && !_DTD_4_0) 1332 defaultValue = BindingConstants.OGNL_PREFIX + ":" + defaultValue; 1333 1334 ps.setDefaultValue(defaultValue); 1335 1336 ps.setDefaultBindingType(getAttribute("default-binding")); 1337 1338 if (!_DTD_4_0) 1339 { 1340 String direction = getAttribute("direction"); 1341 ps.setCache(!"auto".equals(direction)); 1342 } 1343 else 1344 { 1345 boolean cache = getBooleanAttribute("cache", true); 1346 ps.setCache(cache); 1347 } 1348 1349 1351 String type = getAttribute("type"); 1352 1353 if (type != null) 1354 ps.setType(type); 1355 1356 1358 String aliases = getAttribute("aliases"); 1359 1360 ps.setAliases(aliases); 1361 ps.setDeprecated(getBooleanAttribute("deprecated", false)); 1362 1363 IComponentSpecification cs = (IComponentSpecification) peekObject(); 1364 1365 cs.addParameter(ps); 1366 1367 push(_elementName, ps, STATE_ALLOW_DESCRIPTION); 1368 } 1369 1370 private void enterPrivateAsset_3_0() 1371 { 1372 enterAsset("resource-path", "classpath:"); 1373 } 1374 1375 1376 private void enterMeta() 1377 { 1378 String key = getAttribute("key"); 1379 String value = getAttribute("value"); 1380 1381 1383 IPropertyHolder ph = (IPropertyHolder) peekObject(); 1384 1385 push(_elementName, new PropertyValueSetter(ph, key, value), STATE_META, false); 1386 } 1387 1388 private void enterProperty_3_0() 1389 { 1390 String name = getAttribute("name"); 1391 String value = getAttribute("value"); 1392 1393 1395 IPropertyHolder ph = (IPropertyHolder) peekObject(); 1396 1397 push(_elementName, new PropertyValueSetter(ph, name, value), STATE_META, false); 1398 } 1399 1400 1403 1404 private void enterProperty() 1405 { 1406 String name = getValidatedAttribute("name", PROPERTY_NAME_PATTERN, "invalid-property-name"); 1407 String type = getAttribute("type"); 1408 1409 String persistence = null; 1410 1411 if (_DTD_4_0) 1412 persistence = getAttribute("persist"); 1413 else 1414 persistence = getBooleanAttribute("persistent", false) ? "session" : null; 1415 1416 String initialValue = getAttribute("initial-value"); 1417 1418 IPropertySpecification ps = _factory.createPropertySpecification(); 1419 ps.setName(name); 1420 1421 if (HiveMind.isNonBlank(type)) 1422 ps.setType(type); 1423 1424 ps.setPersistence(persistence); 1425 ps.setInitialValue(initialValue); 1426 1427 IComponentSpecification cs = (IComponentSpecification) peekObject(); 1428 cs.addPropertySpecification(ps); 1429 1430 push(_elementName, ps, STATE_PROPERTY, false); 1431 } 1432 1433 1436 1437 private void enterInject() 1438 { 1439 String property = getValidatedAttribute( 1440 "property", 1441 PROPERTY_NAME_PATTERN, 1442 "invalid-property-name"); 1443 String type = getAttribute("type"); 1444 String objectReference = getAttribute("object"); 1445 1446 InjectSpecification spec = _factory.createInjectSpecification(); 1447 1448 spec.setProperty(property); 1449 spec.setType(type); 1450 spec.setObject(objectReference); 1451 IComponentSpecification cs = (IComponentSpecification) peekObject(); 1452 1453 cs.addInjectSpecification(spec); 1454 1455 push(_elementName, spec, STATE_NO_CONTENT); 1456 } 1457 1458 private void enterReservedParameter() 1459 { 1460 String name = getAttribute("name"); 1461 IComponentSpecification cs = (IComponentSpecification) peekObject(); 1462 1463 cs.addReservedParameterName(name); 1464 1465 push(_elementName, null, STATE_NO_CONTENT); 1466 } 1467 1468 private void enterService_3_0() 1469 { 1470 _errorHandler.error(_log, ParseMessages.serviceElementNotSupported(), getLocation(), null); 1471 1472 push(_elementName, null, STATE_NO_CONTENT); 1473 } 1474 1475 private void enterSetMessage_3_0() 1476 { 1477 String name = getAttribute("name"); 1478 String key = getAttribute("key"); 1479 1480 BindingBeanInitializer bi = _factory.createBindingBeanInitializer(_bindingSource); 1481 1482 bi.setPropertyName(name); 1483 bi.setBindingReference(BindingConstants.MESSAGE_PREFIX + ":" + key); 1484 bi.setLocation(getLocation()); 1485 1486 IBeanSpecification bs = (IBeanSpecification) peekObject(); 1487 1488 bs.addInitializer(bi); 1489 1490 push(_elementName, null, STATE_NO_CONTENT); 1491 } 1492 1493 private void enterSet() 1494 { 1495 String name = getAttribute("name"); 1496 String reference = getAttribute("value"); 1497 1498 BindingBeanInitializer bi = _factory.createBindingBeanInitializer(_bindingSource); 1499 1500 bi.setPropertyName(name); 1501 1502 IBeanSpecification bs = (IBeanSpecification) peekObject(); 1503 1504 push(_elementName, new BeanSetPropertySetter(bs, bi, null, reference), STATE_SET, false); 1505 } 1506 1507 private void enterSetProperty_3_0() 1508 { 1509 String name = getAttribute("name"); 1510 String expression = getAttribute("expression"); 1511 1512 BindingBeanInitializer bi = _factory.createBindingBeanInitializer(_bindingSource); 1513 1514 bi.setPropertyName(name); 1515 1516 IBeanSpecification bs = (IBeanSpecification) peekObject(); 1517 1518 push(_elementName, new BeanSetPropertySetter(bs, bi, BindingConstants.OGNL_PREFIX + ":", 1519 expression), STATE_SET, false); 1520 } 1521 1522 private void enterStaticBinding_3_0() 1523 { 1524 String name = getAttribute("name"); 1525 String expression = getAttribute("value"); 1526 1527 IContainedComponent cc = (IContainedComponent) peekObject(); 1528 1529 BindingSetter bs = new BindingSetter(cc, name, expression); 1530 1531 push(_elementName, bs, STATE_STATIC_BINDING, false); 1532 } 1533 1534 private void expectElement(String elementName) 1535 { 1536 if (_elementName.equals(elementName)) 1537 return; 1538 1539 throw new DocumentParseException(ParseMessages.incorrectDocumentType( 1540 _elementName, 1541 elementName), getLocation(), null); 1542 1543 } 1544 1545 private String getAttribute(String name) 1546 { 1547 return (String ) _attributes.get(name); 1548 } 1549 1550 private boolean getBooleanAttribute(String name, boolean defaultValue) 1551 { 1552 String value = getAttribute(name); 1553 1554 if (value == null) 1555 return defaultValue; 1556 1557 Boolean b = (Boolean ) CONVERSION_MAP.get(value); 1558 1559 return b.booleanValue(); 1560 } 1561 1562 private Object getConvertedAttribute(String name, Object defaultValue) 1563 { 1564 String key = getAttribute(name); 1565 1566 if (key == null) 1567 return defaultValue; 1568 1569 return CONVERSION_MAP.get(key); 1570 } 1571 1572 private InputSource getDTDInputSource(String name) 1573 { 1574 InputStream stream = getClass().getResourceAsStream(name); 1575 1576 return new InputSource (stream); 1577 } 1578 1579 private String getExtendedValue(String attributeValue, String attributeName, boolean required) 1580 { 1581 String contentValue = peekContent(); 1582 1583 boolean asAttribute = HiveMind.isNonBlank(attributeValue); 1584 boolean asContent = HiveMind.isNonBlank(contentValue); 1585 1586 if (asAttribute && asContent) 1587 { 1588 throw new DocumentParseException(ParseMessages.noAttributeAndBody( 1589 attributeName, 1590 _elementName), getLocation(), null); 1591 } 1592 1593 if (required && !(asAttribute || asContent)) 1594 { 1595 throw new DocumentParseException(ParseMessages.requiredExtendedAttribute( 1596 _elementName, 1597 attributeName), getLocation(), null); 1598 } 1599 1600 if (asAttribute) 1601 return attributeValue; 1602 1603 return contentValue; 1604 } 1605 1606 private String getValidatedAttribute(String name, String pattern, String errorKey) 1607 { 1608 String value = getAttribute(name); 1609 1610 if (value == null) 1611 return null; 1612 1613 if (_matcher.matches(pattern, value)) 1614 return value; 1615 1616 throw new InvalidStringException(ParseMessages.invalidAttribute(errorKey, value), value, 1617 getLocation()); 1618 } 1619 1620 protected void initializeParser(Resource resource, int startState) 1621 { 1622 super.initializeParser(resource, startState); 1623 1624 _rootObject = null; 1625 _attributes = new HashMap (); 1626 } 1627 1628 public IApplicationSpecification parseApplicationSpecification(Resource resource) 1629 { 1630 initializeParser(resource, STATE_APPLICATION_SPECIFICATION_INITIAL); 1631 1632 try 1633 { 1634 parseDocument(); 1635 1636 return (IApplicationSpecification) _rootObject; 1637 } 1638 finally 1639 { 1640 resetParser(); 1641 } 1642 } 1643 1644 public IComponentSpecification parseComponentSpecification(Resource resource) 1645 { 1646 initializeParser(resource, STATE_COMPONENT_SPECIFICATION_INITIAL); 1647 1648 try 1649 { 1650 parseDocument(); 1651 1652 return (IComponentSpecification) _rootObject; 1653 } 1654 finally 1655 { 1656 resetParser(); 1657 } 1658 } 1659 1660 private void parseDocument() 1661 { 1662 InputStream stream = null; 1663 1664 Resource resource = getResource(); 1665 1666 boolean success = false; 1667 1668 try 1669 { 1670 if (_parser == null) 1671 _parser = _parserFactory.newSAXParser(); 1672 1673 URL resourceURL = resource.getResourceURL(); 1674 1675 if (resourceURL == null) 1676 throw new DocumentParseException(ParseMessages.missingResource(resource), resource, 1677 null); 1678 1679 InputStream rawStream = resourceURL.openStream(); 1680 stream = new BufferedInputStream (rawStream); 1681 1682 _parser.parse(stream, this, resourceURL.toExternalForm()); 1683 1684 stream.close(); 1685 stream = null; 1686 1687 success = true; 1688 } 1689 catch (SAXParseException ex) 1690 { 1691 _parser = null; 1692 1693 Location location = new LocationImpl(resource, ex.getLineNumber(), ex.getColumnNumber()); 1694 1695 throw new DocumentParseException(ParseMessages.errorReadingResource(resource, ex), 1696 location, ex); 1697 } 1698 catch (Exception ex) 1699 { 1700 _parser = null; 1701 1702 throw new DocumentParseException(ParseMessages.errorReadingResource(resource, ex), 1703 resource, ex); 1704 } 1705 finally 1706 { 1707 if (!success) 1708 _parser = null; 1709 1710 close(stream); 1711 } 1712 } 1713 1714 public ILibrarySpecification parseLibrarySpecification(Resource resource) 1715 { 1716 initializeParser(resource, STATE_LIBRARY_SPECIFICATION_INITIAL); 1717 1718 try 1719 { 1720 parseDocument(); 1721 1722 return (ILibrarySpecification) _rootObject; 1723 } 1724 finally 1725 { 1726 resetParser(); 1727 } 1728 } 1729 1730 public IComponentSpecification parsePageSpecification(Resource resource) 1731 { 1732 initializeParser(resource, STATE_PAGE_SPECIFICATION_INITIAL); 1733 1734 try 1735 { 1736 parseDocument(); 1737 1738 return (IComponentSpecification) _rootObject; 1739 } 1740 finally 1741 { 1742 resetParser(); 1743 } 1744 } 1745 1746 protected String peekContent() 1747 { 1748 String content = super.peekContent(); 1749 1750 if (content == null) 1751 return null; 1752 1753 return content.trim(); 1754 } 1755 1756 protected void resetParser() 1757 { 1758 _rootObject = null; 1759 _DTD_4_0 = false; 1760 1761 _attributes.clear(); 1762 } 1763 1764 1768 public InputSource resolveEntity(String publicId, String systemId) throws SAXException 1769 { 1770 if (TAPESTRY_DTD_4_0_PUBLIC_ID.equals(publicId)) 1771 { 1772 _DTD_4_0 = true; 1773 return getDTDInputSource("Tapestry_4_0.dtd"); 1774 } 1775 1776 if (TAPESTRY_DTD_3_0_PUBLIC_ID.equals(publicId)) 1777 return getDTDInputSource("Tapestry_3_0.dtd"); 1778 1779 throw new DocumentParseException(ParseMessages.unknownPublicId(getResource(), publicId), 1780 new LocationImpl(getResource()), null); 1781 } 1782 1783 1784 public void setBindingSource(BindingSource bindingSource) 1785 { 1786 _bindingSource = bindingSource; 1787 } 1788 1789 1790 public void setValueConverter(ValueConverter valueConverter) 1791 { 1792 _valueConverter = valueConverter; 1793 } 1794} | Popular Tags |