1 19 20 package org.netbeans.tax.io; 21 22 import java.io.*; 23 import java.net.URL ; 24 import java.util.*; 25 import java.text.MessageFormat ; 26 import java.lang.reflect.*; 27 28 import org.xml.sax.*; 29 import org.xml.sax.helpers.LocatorImpl ; 30 31 import org.apache.xerces.xni.*; 32 import org.apache.xerces.xni.parser.XMLDTDSource; 33 import org.apache.xerces.xni.parser.XMLDTDContentModelSource; 34 import org.apache.xerces.xni.parser.XMLDocumentSource; 35 import org.apache.xerces.parsers.*; 36 37 import org.netbeans.tax.*; 38 import org.netbeans.tax.io.*; 39 import org.netbeans.tax.decl.*; 40 import java.util.List ; 41 42 56 public final class XNIBuilder implements TreeBuilder { 57 58 private static final boolean ASSERT = false; 59 60 62 private static final String DTD_WRAPPER = "<!DOCTYPE DTD PUBLIC \"{0}\" \"{1}\">"; 64 private Class buildClass; 67 private InputSource inputSource; 68 69 private TreeStreamBuilderErrorHandler errorHandler; 71 72 private EntityResolver entityResolver; 74 75 76 77 public XNIBuilder (Class buildClass, InputSource inputSource, EntityResolver entityResolver, TreeStreamBuilderErrorHandler errorHandler) { 78 init (buildClass, inputSource, entityResolver, errorHandler); 79 } 80 81 82 private void init (Class buildClass, InputSource inputSource, EntityResolver entityResolver, TreeStreamBuilderErrorHandler errorHandler) { 83 this.inputSource = inputSource; 84 this.buildClass = buildClass; 85 this.errorHandler = errorHandler; 86 this.entityResolver = entityResolver; 87 } 88 89 93 public TreeDocumentRoot buildDocument () throws TreeException { 94 95 boolean buildXML = true; 96 InputSource builderSource = inputSource; 97 EntityResolver builderResolver = entityResolver; 98 99 103 if (buildClass == TreeDTD.class) { 104 105 String src = MessageFormat.format (DTD_WRAPPER, new Object [] { 106 DTDEntityResolver.DTD_ID, 107 inputSource.getSystemId () 108 }); 109 110 builderSource = new InputSource (inputSource.getSystemId ()); 111 builderSource.setCharacterStream (new StringReader (src)); 112 113 builderResolver = new DTDEntityResolver (); 114 buildXML = false; 115 } 116 117 XMLBuilder builder = this.new XMLBuilder (buildXML); 118 119 try { 120 final String SAX_FEATURE = "http://xml.org/sax/features/"; final String XERCES_FEATURE = "http://apache.org/xml/features/"; 123 builder.setFeature (SAX_FEATURE + "namespaces", false); builder.setFeature (SAX_FEATURE + "validation", false); builder.setFeature (SAX_FEATURE + "external-general-entities", true); builder.setFeature (SAX_FEATURE + "external-parameter-entities", true); builder.setFeature (XERCES_FEATURE + "validation/warn-on-duplicate-attdef", true); builder.setFeature (XERCES_FEATURE + "allow-java-encodings", true); builder.setFeature (XERCES_FEATURE + "scanner/notify-char-refs", true); builder.setFeature (XERCES_FEATURE + "scanner/notify-builtin-refs", true); 134 137 builder.setEntityResolver (builderResolver); 138 139 142 builder.setErrorHandler (new ErrorHandler () { 143 public void error (org.xml.sax.SAXParseException e) {} 144 public void warning (org.xml.sax.SAXParseException e) {} 145 public void fatalError (org.xml.sax.SAXParseException e) {} 146 }); 147 builder.parse (builderSource); 148 149 } catch (DTDStopException stop) { 150 151 153 } catch (SAXException sax) { 154 155 158 Exception exception = sax.getException (); 159 160 if ((exception instanceof DTDStopException) == false ) { 161 162 if ( Util.THIS.isLoggable() ) Util.THIS.debug ("sax", sax); if ( Util.THIS.isLoggable() ) Util.THIS.debug ("exception", exception); 165 if (exception instanceof XNIException) { 166 exception = ((XNIException)exception).getException (); 167 } 168 if (exception != null) { 169 if (!!! (exception instanceof TreeException)) { 170 exception = new TreeException (sax); 171 } 172 } else { 173 exception = new TreeException (sax); 174 } 175 throw (TreeException) exception; 176 } 177 178 } catch (IOException exc) { 179 if ( Util.THIS.isLoggable() ) Util.THIS.debug ("exc", exc); 181 throw new TreeException (exc); 182 } 183 184 return builder.getDocumentRoot (); 185 } 186 187 188 192 private class DTDEntityResolver implements EntityResolver { 193 194 static final String DTD_ID = "PRIVATE//AUXILIARY DTD ID//PRIVATE"; 196 public InputSource resolveEntity (String publicId, String systemId) throws SAXException, IOException { 197 198 if (DTD_ID.equals (publicId)) { 199 return inputSource; 200 } else { 201 return entityResolver.resolveEntity (publicId, systemId); 202 } 203 } 204 205 } 206 207 211 private class DTDStopException extends XNIException { 212 213 214 private static final long serialVersionUID =4994054007367982021L; 215 216 public DTDStopException () { 217 super ("This exception is used to signal end of DTD."); }; 219 220 public Exception getException () { 225 return this; 226 } 227 228 public Throwable fillInStackTrace () { 229 return this; 230 } 231 } 232 233 235 242 243 244 249 private class XMLBuilder extends SAXParser implements XMLDTDContentModelHandler, XMLDocumentHandler, XMLDTDHandler { 250 251 private TreeDocumentRoot returnDocument; private TreeDocumentRoot document; 254 private TreeDocumentType doctype; private TreeNode tempNode; 257 private Stack parentObjectListStack; private TreeObjectList parentObjectList; private Stack parentNodeStack; 261 private Stack elementStack; private int entityCounter; 264 private boolean isXMLDocument; private boolean inCDATASection; private boolean inDTD; private boolean isCorrect; private boolean inCharacterRef; 270 private StringBuffer cdataSectionBuffer; private QName tmpQName = new QName (); private TreeAttlistDecl attlistDecl = null; 274 private int errors = 0; 276 private final String XML_ENTITY = "[xml]"; private final String DTD_ENTITY = "[dtd]"; 279 private XMLLocator locator; 280 281 private boolean hasExternalDTD = false; 282 283 private RememberingReader rememberingReader; 284 285 private XMLDTDSource xmldtdSource; 287 private XMLDTDContentModelSource xmldtdContentModelSource; 289 private XMLDocumentSource xmlDocumentSource; 291 295 public XMLBuilder (boolean xmlDocument) { 296 isXMLDocument = xmlDocument; 297 entityCounter = 0; 298 isCorrect = false; 299 inCDATASection = false; 300 inDTD = false; 301 parentObjectListStack = new Stack (); 302 parentNodeStack = new Stack (); 303 elementStack = new Stack (); cdataSectionBuffer = new StringBuffer (); 305 inCharacterRef = false; 306 } 307 308 309 313 public void parse (InputSource in) throws IOException, SAXException { 314 Reader reader = in.getCharacterStream (); 315 if (reader != null) { 316 rememberingReader = new RememberingReader (reader); 317 in.setCharacterStream (rememberingReader); 318 rememberingReader.startRemembering (); } 320 321 super.parse (in); 322 } 323 324 325 329 public XMLDocumentSource getDocumentSource() { 330 return xmlDocumentSource; 331 } 332 333 public void setDocumentSource(XMLDocumentSource src) { 334 xmlDocumentSource = src; 335 } 336 337 public void startDocument (XMLLocator locator, String encoding, NamespaceContext nsCtx, Augmentations a) { 339 startDocument(locator, encoding, a); 340 } 341 342 347 public void startDocument (XMLLocator locator, String encoding, Augmentations a) { 349 350 trace ("startDocument()"); 352 this.locator = locator; 353 try { 354 returnDocument = document = new TreeDocument (null,null,null); 355 pushParentNode ((TreeDocument)document); 356 } catch (TreeException exc) { 357 throw new XNIException (exc); 358 } 359 } 361 373 public void xmlDecl (String version, String encoding, String standalone, Augmentations a) { 374 375 trace ("xmlDecl()"); 377 try { 378 ((TreeDocument)document).setHeader (version, encoding, standalone); 379 } catch (TreeException exc) { 380 throw new XNIException (exc); 381 } 382 } 384 385 public void textDecl (String version, String encoding, Augmentations a) { 387 388 trace ("textDecl()"); 390 if (isXMLDocument == false && inDTD && inEntity () == false) { 392 try { 393 ((TreeDTD)document).setHeader (version, encoding); 394 } catch (TreeException ex) { 395 throw new XNIException (ex); 396 } 397 } 398 } 399 400 public void textDecl (String version, String encoding) { 402 textDecl(version, encoding, null); 403 } 404 405 408 public void doctypeDecl (String rootElement, String publicId, String systemId, Augmentations a) { 409 410 trace ("doctypeDecl(" + rootElement + "," + publicId + ")"); 412 try { 413 TreeDocumentType _doctype = 414 new TreeDocumentType (rootElement, publicId, systemId); 415 setBeginPosition (_doctype); 416 ((TreeDocument)document).setDocumentType (_doctype); 417 418 doctype = _doctype; 419 } catch (TreeException exc) { 420 throw new XNIException (exc); 421 } 422 } 424 425 428 public void startElement (QName element, XMLAttributes attributes, Augmentations a) { 429 430 trace ("startElement(" + element + ")"); 432 try { 433 tempNode = new TreeElement (element.rawname); 434 startElementImpl ((TreeElement) tempNode, attributes); 435 436 pushParentNode ((TreeElement)tempNode); 437 elementStack.push (tempNode); 438 439 } catch (TreeException exc) { 440 throw new XNIException (exc); 441 } 442 } 444 447 public void emptyElement (QName qName, XMLAttributes attributes, Augmentations a) { 448 449 trace ("emptyElement(" + qName + ")"); 451 try { 452 tempNode = new TreeElement (qName.rawname, true); 453 startElementImpl ((TreeElement) tempNode, attributes); 454 } catch (TreeException exc) { 455 throw new XNIException (exc); 456 } 457 } 458 459 462 private void startElementImpl (TreeElement elem, XMLAttributes attributes) throws TreeException { 463 464 setBeginPosition (elem); 465 466 if (currentParentNode () instanceof TreeDocument) { 468 ((TreeDocument)currentParentNode ()).setDocumentElement (elem); 469 } else { 470 appendChild (elem); 471 } 472 473 475 int attrCount = attributes.getLength (); 476 for (int i = 0; i < attrCount; i++) { 477 boolean specified = attributes.isSpecified (i); 478 479 if ( specified == true ) { 481 attributes.getName (i, tmpQName); String val = attributes.getNonNormalizedValue (i); 484 TreeAttribute attr; 486 if (val.indexOf ('&') < 0) { 487 488 attr = new TreeAttribute (tmpQName.rawname, val, specified); 489 490 } else { 491 492 attr = new TreeAttribute (tmpQName.rawname, "", specified); List list = attr.getValueList (); 494 list.clear (); 495 496 498 int lastOffset = 0; for (int offset = val.indexOf ('&'); offset >= 0; offset = val.indexOf ('&', offset + 1)) { 500 501 int endOffset = val.indexOf (';', offset); 502 String name = val.substring (offset + 1, endOffset); 503 504 if (offset > lastOffset) { 505 TreeText text = 507 new TreeText (val.substring (lastOffset, offset)); 508 list.add (text); 509 } 510 511 512 if (name.startsWith ("#")) { TreeCharacterReference chref = 514 new TreeCharacterReference (name); 515 list.add (chref); 516 } else { 517 TreeGeneralEntityReference gref = 518 new TreeGeneralEntityReference (name); 519 list.add (gref); 520 } 521 522 lastOffset = endOffset + 1; 523 } 524 525 if (val.length () > lastOffset) { 526 String lastText = val.substring (lastOffset); 527 list.add (new TreeText (lastText)); 528 } 529 } 530 531 if ( !!! specified ) { 532 setReadOnly (attr); 533 } 534 elem.addAttribute (attr); 535 536 } } 538 539 541 if (rememberingReader == null) { 542 return; 543 } 544 StringBuffer mem = rememberingReader.stopRemembering (); 545 if (mem == null) return; 546 547 String idtd = mem.toString (); 548 int start = -1, end = -1; int now, last = -1; char delimiter; 551 552 if ( Util.THIS.isLoggable() ) Util.THIS.debug ("TreeStreamBuilderXercesImpl: going to inspect:\n" + idtd); 553 554 557 final String DOCTYPE = "<!DOCTYPE"; int pos = -1; 559 DOCTYPE_LOOP: 560 while (true) { 561 pos = idtd.indexOf (DOCTYPE, ++pos); 562 if (pos == -1) { 563 Util.THIS.debug ("XNIBuilder: no DOCTYPE detected."); return; 565 } else { 566 int comment = -1; 567 while (true) { 568 comment = idtd.indexOf("<!--", ++comment); if (comment != -1 && comment < pos) { 570 if (idtd.indexOf("-->", comment) > pos) { break; 573 } else { 574 continue; 576 } 577 } else { 578 break DOCTYPE_LOOP; 579 } 580 } 581 } 582 } 583 584 if ( Util.THIS.isLoggable() ) Util.THIS.debug ("\nlast index = " + pos); 585 586 588 pos += DOCTYPE.length (); 589 for (; StringUtil.isWS (idtd.charAt (pos)); pos ++); 590 for (; StringUtil.isWS (idtd.charAt (pos)) == false; pos ++); 591 for (; StringUtil.isWS (idtd.charAt (pos)); pos ++); 592 593 594 if ( Util.THIS.isLoggable() ) Util.THIS.debug ("\nafter process index = " + pos); 595 596 598 if ( Util.THIS.isLoggable() ) Util.THIS.debug ("\nTesting DOCTYPE kind-----\n" + idtd.substring (pos)); 599 600 if (idtd.charAt (pos) == '[') { start = ++pos; 602 } else if (idtd.charAt (pos) == 'S') { for (; StringUtil.isWS (idtd.charAt (pos)) == false; pos ++); 604 for (; StringUtil.isWS (idtd.charAt (pos)); pos ++); 605 delimiter = idtd.charAt (pos++); 606 for (; idtd.charAt (pos) != delimiter; pos ++); 607 pos++; 608 for (; StringUtil.isWS (idtd.charAt (pos)); pos ++); 609 if (idtd.charAt (pos) == '[') { 610 start = ++pos; 611 } 612 } else if (idtd.charAt (pos) == 'P') { for (; StringUtil.isWS (idtd.charAt (pos)) == false; pos ++); 614 for (; StringUtil.isWS (idtd.charAt (pos)); pos ++); 615 delimiter = idtd.charAt (pos++); 616 for (; idtd.charAt (pos) != delimiter; pos ++); 617 pos++; 618 for (; StringUtil.isWS (idtd.charAt (pos)); pos ++); 619 delimiter = idtd.charAt (pos++); 620 for (; idtd.charAt (pos) != delimiter; pos ++); 621 pos++; 622 for (; StringUtil.isWS (idtd.charAt (pos)); pos ++); 623 if (idtd.charAt (pos) == '[') { 624 start = ++pos; 625 } 626 } 627 628 if (start == -1) { 629 if ( Util.THIS.isLoggable() ) Util.THIS.debug ("TreeStreamBuilderXercesImpl: it does not have internal DTD."); 630 631 return; 632 } else { 633 if ( Util.THIS.isLoggable() ) Util.THIS.debug ("\n---Analyzing internal DTD:\n" + idtd.substring (start)); 634 } 635 636 638 for (last = pos-1; idtd.startsWith ("]>", pos) == false && last < pos;) { 639 640 last = pos; 641 642 for (; StringUtil.isWS (idtd.charAt (pos)); pos ++); 644 645 now = StringUtil.skipDelimited (idtd, pos, "<!--", "-->"); 646 if (now != -1) { 647 pos = now; 648 continue; 649 } 650 651 now = StringUtil.skipDelimited (idtd, pos, "<?", "?>"); 653 if (now != -1) { 654 pos = now; 655 continue; 656 } 657 658 now = StringUtil.skipDelimited (idtd, pos, '<', '>' , "\"'"); 660 if (now != -1) { 661 pos = now; 662 continue; 663 } 664 665 now = StringUtil.skipDelimited (idtd, pos, '%', ';' , ""); 667 if (now != -1) { 668 pos = now; 669 continue; 670 } 671 672 } 673 674 if (last == pos) { 675 if ( Util.THIS.isLoggable() ) Util.THIS.debug ("TreeStreamBuilderXercesImpl: end not reached"); 676 677 return; 678 } 679 680 String internalDTDText = idtd.substring (start, pos); 681 682 if ( Util.THIS.isLoggable() ) Util.THIS.debug ("Internal DTD:" + internalDTDText + "\n--"); 683 684 686 try { 687 if (doctype == null) return; 688 Class klass = doctype.getClass (); 689 Field field = klass.getDeclaredField ("internalDTDText"); 690 field.setAccessible (true); 691 field.set (doctype, internalDTDText); 692 } catch (RuntimeException ex) { 693 throw ex; 694 } catch (Exception ex) { 695 if ( Util.THIS.isLoggable() ) Util.THIS.debug ("TreeStreamBuilderXercesImpl.settingInternaDTDText", ex); 697 } 698 699 } 700 701 702 705 public void characters (XMLString text, Augmentations a) { 706 707 try { 708 if (inCharacterRef == true) return; 710 if (inDTD) { 711 if (currentParentNode () instanceof TreeConditionalSection) { 712 if ( Util.THIS.isLoggable() ) Util.THIS.debug ("\n*** TreeStreamBuilderXercesImpl::characters: XMLString = '" + text + "'"); 714 ((TreeConditionalSection)currentParentNode ()).setIgnoredContent ( 715 text.toString () 716 ); 717 } 718 } else if (inCDATASection) { 719 cdataSectionBuffer.append (text.toString ()); 720 } else { 721 tempNode = new TreeText (text.toString ()); 722 setBeginPosition (tempNode); 723 appendChild ((TreeText)tempNode); 724 } 725 } catch (TreeException exc) { 726 throw new XNIException (exc); 727 } 728 } 730 731 public void ignoredCharacters (XMLString text, Augmentations a) { 733 characters( text, null); 734 } 735 736 public void characters (XMLString text) { 738 characters( text, null); 739 } 740 741 744 public void ignorableWhitespace (XMLString text, Augmentations a) { 745 try { 746 tempNode = new TreeText (text.toString ()); setBeginPosition (tempNode); 748 appendChild ((TreeText)tempNode); 749 } catch (TreeException exc) { 750 throw new XNIException (exc); 751 } 752 } 754 757 public void endElement (QName element, Augmentations a) { 758 trace ("endElement(" + element + ")"); 760 try { 761 TreeElement el = (TreeElement) elementStack.pop (); 762 el.normalize (); popParentNode (); 764 } catch (TreeException exc) { 765 throw new XNIException (exc); 766 } 767 } 769 772 public void startCDATA (Augmentations a) { 773 inCDATASection = true; 774 cdataSectionBuffer.delete (0, cdataSectionBuffer.length ()); 775 } 778 781 public void endCDATA (Augmentations a) { 782 783 inCDATASection = false; 784 785 try { 786 tempNode = new TreeCDATASection (cdataSectionBuffer.toString ()); 787 setBeginPosition (tempNode); appendChild ((TreeCDATASection)tempNode); 789 } catch (TreeException exc) { 790 throw new XNIException (exc); 791 } 792 } 794 797 public void endDocument (Augmentations a) { 798 trace ("endDocument()"); 800 if (parentObjectListStack.isEmpty () == false) { 801 if ( Util.THIS.isLoggable() ) Util.THIS.debug ("Inconsistency at parentStack: " + parentObjectListStack ); } else if (elementStack.isEmpty () == false) { 803 if ( Util.THIS.isLoggable() ) Util.THIS.debug ("Inconsistency at elementStack: " + parentObjectListStack ); } else { 805 isCorrect = true; 806 } 807 } 809 813 public void endPrefixMapping (String prefix, Augmentations a) { 814 } 816 817 public void startPrefixMapping (String prefix, String uri, Augmentations a) { 818 } 820 821 public void startExternalSubset(XMLResourceIdentifier entity, Augmentations a) { 823 startEntity( 824 "[dtd]", entity.getPublicId(), entity.getLiteralSystemId(), 825 entity.getBaseSystemId(), null, a 826 ); 827 } 828 829 public void startGeneralEntity(String name, XMLResourceIdentifier entity, String encoding, Augmentations a) { 830 startEntity( 831 name, entity.getPublicId(), entity.getLiteralSystemId(), 832 entity.getBaseSystemId(), encoding, a 833 ); 834 } 835 836 845 private void startEntity (String name, String publicId, String systemId, 846 String baseSystemId, String encoding, Augmentations a) { 847 848 trace ("startEntity(" + name + ")"); 850 try { 851 852 855 if (XML_ENTITY.equals (name)) return; 856 if (isXMLDocument == false && DTD_ENTITY.equals (name)) return; 857 858 859 if (DTD_ENTITY.equals (name) && isXMLDocument) { 860 861 hasExternalDTD = true; 862 863 TreeObjectList external = doctype.getExternalDTD (); 868 if (external == null) { 869 TreeDTDFragment entity = new TreeDTDFragment(); 870 TreeObjectList holder = entity.getChildNodes(); 871 pushParentObjectList (holder); 872 doctype.setExternalDTD(entity); 873 } else { 874 pushParentObjectList(null); 876 } 877 878 } else if (name.startsWith ("#")) { 880 tempNode = new TreeCharacterReference (name); 881 appendChild (tempNode); 882 setBeginPosition (tempNode); 883 inCharacterRef = true; 884 885 } else if ( "lt".equals (name) || "gt".equals (name) || "amp".equals (name) || "apos".equals (name) || "quot".equals (name)) { 888 tempNode = new TreeGeneralEntityReference (name); 889 appendChild (tempNode); 890 setBeginPosition (tempNode); 891 inCharacterRef = true; 892 893 } else if (name.startsWith ("%")) { 895 if ("IGNORE".equals (encoding)) { name = name.substring (1); 898 pushParentNode (new TreeParameterEntityReference (name)); 899 900 } else { 901 name = name.substring (1); 902 tempNode = new TreeParameterEntityReference (name); appendChild ((TreeParameterEntityReference)tempNode); 904 setBeginPosition (tempNode); 905 pushParentNode ((TreeEntityReference)tempNode); 906 } 907 908 } else { 909 910 tempNode = new TreeGeneralEntityReference (name); appendChild ((TreeGeneralEntityReference)tempNode); 912 setBeginPosition (tempNode); 913 pushParentNode ((TreeEntityReference)tempNode); 914 915 } 916 917 enterEntity (); 918 919 } catch (TreeException exc) { 920 throw new XNIException (exc); 921 } 922 } 924 925 public void startEntity (String name, String publicId, String systemId, 927 String baseSystemId, String encoding) { 928 startEntity(name, publicId, systemId, baseSystemId, encoding, null); 929 } 930 931 public void startParameterEntity(String name, XMLResourceIdentifier entity, String encoding, Augmentations a) { 933 String pname = name; 934 if (false == name.startsWith("%")) { 935 pname = "%" + name; 936 } 937 startEntity( 938 pname, entity.getPublicId(), entity.getLiteralSystemId(), 939 entity.getBaseSystemId(), encoding, a 940 ); 941 } 942 943 946 public void comment (XMLString text, Augmentations a) { 948 949 trace ("comment()"); 951 try { 952 tempNode = new TreeComment (text.toString ()); 953 setBeginPosition (tempNode); 954 appendChild ((TreeComment)tempNode); 955 } catch (TreeException exc) { 956 throw new XNIException (exc); 957 } 958 } 960 public void comment (XMLString text) { 962 comment(text, null); 963 } 964 965 970 public void processingInstruction (String target, XMLString data, Augmentations a) { 972 973 trace ("processingInstruction(" + target + ")"); 975 try { 976 tempNode = new TreeProcessingInstruction (target, data.toString ()); 977 setBeginPosition (tempNode); 978 appendChild ((TreeProcessingInstruction)tempNode); 979 } catch (TreeException exc) { 980 throw new XNIException (exc); 981 } 982 } 984 public void processingInstruction (String target, XMLString data) { 986 processingInstruction( target, data, null); 987 } 988 989 public void endExternalSubset(Augmentations a) { 991 endEntity("[dtd]", a); 992 } 993 994 public void endParameterEntity(String name, Augmentations a) { 996 String pname = name; 997 if (false == name.startsWith("%")) { 998 pname = "%" + name; 999 } 1000 endEntity(pname, a); 1001 } 1002 1003 public void endGeneralEntity(String name, Augmentations a) { 1004 endEntity(name, a); 1005 } 1006 1007 1013 private void endEntity (String name, Augmentations a) { 1014 trace ("endEntity(" + name + ")"); 1016 1019 if (XML_ENTITY.equals (name)) return; 1020 if (isXMLDocument == false && DTD_ENTITY.equals (name)) return; 1021 1022 exitEntity (); 1023 1024 if (inCharacterRef == true) { 1025 inCharacterRef = false; 1026 return; 1027 } 1028 1029 if (isXMLDocument && DTD_ENTITY.equals (name)) { 1030 popParentObjectList (); } else { 1032 popParentNode (); 1033 } 1034 1035 } 1037 1038 public void endEntity (String name) { 1040 endEntity(name, null); 1041 } 1042 1043 1045 public XMLDTDSource getDTDSource() { 1047 return xmldtdSource; 1048 } 1049 1050 public void setDTDSource( XMLDTDSource src) { 1052 xmldtdSource = src; 1053 } 1054 1055 public void startDTD ( XMLLocator locator, Augmentations a) { 1057 startDTD(locator); 1058 } 1059 1060 1063 public void startDTD ( XMLLocator locator) { 1065 trace ("startDTD()"); 1067 try { 1068 inDTD = true; 1069 1070 if (isXMLDocument) { 1071 1072 pushParentNode (doctype); 1073 1074 } else { 1075 1076 returnDocument = document = new TreeDTD (null,null); 1078 pushParentNode ((TreeDTD)document); 1079 } 1080 } catch (TreeException exc) { 1081 throw new XNIException (exc); 1082 } 1083 } 1085 public void elementDecl (String name, String contentModel, Augmentations a) { 1087 elementDecl(name, contentModel); 1088 } 1089 1090 1093 public void elementDecl (String name, String cM) { 1095 trace ("elementDecl(" + name + ")"); if (ASSERT) 1097 doAssert (inDTD); 1098 1099 try { 1100 appendChild (new TreeElementDecl (name, this.contentModel)); 1101 this.contentModel = null; 1102 } catch (TreeException exc) { 1103 throw new XNIException (exc); 1104 } 1105 1106 } 1108 public void startAttlist (String elementName, Augmentations a) { 1110 startAttlist(elementName); 1111 } 1112 1113 1116 public void startAttlist (String elementName) { 1118 1119 trace ("startAttlist(" + elementName + ")"); 1121 try { 1122 tempNode = new TreeAttlistDecl (elementName); 1123 attlistDecl = (TreeAttlistDecl) tempNode; 1124 appendChild (attlistDecl); 1125 } catch (TreeException exc) { 1126 throw new XNIException (exc); 1127 } 1128 } 1130 public void attributeDecl(String elementName, String attributeName, 1132 String type, String [] enumeration, 1133 String defaultType, XMLString defaultValue, 1134 XMLString nonNormalizedDefaultValue, Augmentations a) { 1135 attributeDecl( 1136 elementName, attributeName, type, 1137 enumeration, defaultType, defaultValue 1138 ); 1139 } 1140 1141 1144 public void attributeDecl (String elementName, String attributeName, 1146 String type, String [] enumeration, 1147 String defaultType, XMLString defaultValue) { 1148 1149 trace ("attributeDecl(" + attributeName + ")"); 1151 try { 1152 TreeAttlistDecl list; 1153 1154 if (attlistDecl != null) { 1155 list = attlistDecl; 1156 } else { 1157 list = new TreeAttlistDecl (elementName); 1158 } 1159 if ( type.equals ("ENUMERATION") ) { type = null; 1161 } 1162 1163 short shortDefaultType = TreeAttlistDeclAttributeDef.findDefaultType (defaultType); 1164 String newDefaultValue = null; 1165 if ( ( shortDefaultType == TreeAttlistDeclAttributeDef.DEFAULT_TYPE_NULL ) || 1166 ( shortDefaultType == TreeAttlistDeclAttributeDef.DEFAULT_TYPE_FIXED ) ) { 1167 newDefaultValue = defaultValue.toString (); 1168 } 1169 TreeAttlistDeclAttributeDef decl = 1170 new TreeAttlistDeclAttributeDef (attributeName, TreeAttlistDeclAttributeDef.findType (type), 1171 enumeration, shortDefaultType, newDefaultValue); 1172 1173 list.setAttributeDef (decl); 1174 } catch (TreeException exc) { 1175 throw new XNIException (exc); 1177 } 1178 } 1180 public void endAttlist (Augmentations a) { 1182 endAttlist(); 1183 } 1184 1185 1188 public void endAttlist () { 1190 1191 trace ("endAttlist()"); 1193 attlistDecl = null; 1194 } 1196 public void internalEntityDecl (String name, XMLString text, XMLString nonNormalizedText, Augmentations a) { 1198 internalEntityDecl(name, text, nonNormalizedText); 1199 } 1200 1201 1208 public void internalEntityDecl (String name, XMLString text, XMLString nonNormalizedText) { 1210 1211 trace ("internalEntityDecl(" + name + ")"); 1213 try { 1214 boolean par = name.startsWith ("%"); if (par) { 1216 name = name.substring (1); 1217 } 1218 appendChild (new TreeEntityDecl (par, name, text.toString ())); 1219 } catch (TreeException exc) { 1220 throw new XNIException (exc); 1221 } 1222 } 1224 public void externalEntityDecl (String name, String publicId, 1226 String systemId, String baseSystemId, Augmentations a) { 1227 externalEntityDecl( name, publicId, systemId, baseSystemId); 1228 } 1229 1230 1237 public void externalEntityDecl (String name, String publicId, 1239 String systemId, String baseSystemId) { 1240 1241 trace ("externalEntityDecl(" + name + ")"); 1243 try { 1244 boolean par = name.startsWith ("%"); if (par) { 1246 name = name.substring (1); 1247 } 1248 1249 appendChild (new TreeEntityDecl (par, name, publicId, systemId)); 1250 } catch (TreeException exc) { 1251 throw new XNIException (exc); 1252 } 1253 } 1255 public void unparsedEntityDecl (String name, 1257 String publicId, String systemId, 1258 String notation, Augmentations a) { 1259 unparsedEntityDecl(name, publicId, systemId, notation); 1260 } 1261 1262 1265 public void unparsedEntityDecl (String name, 1267 String publicId, String systemId, 1268 String notation) { 1269 1270 trace ("unparsedEntityDecl(" + name + ")"); 1272 try { 1273 appendChild (new TreeEntityDecl (name, publicId, systemId, notation)); 1274 } catch (TreeException exc) { 1275 throw new XNIException (exc); 1276 } 1277 } 1279 public void notationDecl (String name, String publicId, String systemId, Augmentations a) { 1281 notationDecl(name, publicId, systemId); 1282 } 1283 1284 1287 public void notationDecl (String name, String publicId, String systemId) { 1289 1290 trace ("notationDecl(" + name + ")"); 1292 try { 1293 appendChild (new TreeNotationDecl (name, publicId, systemId)); 1294 } catch (TreeException exc) { 1295 throw new XNIException (exc); 1296 } 1297 } 1299 public void startConditional (short type, Augmentations a) { 1301 startConditional(type); 1302 } 1303 1304 1310 public void startConditional (short type) { 1312 trace ("startConditional(" + type + ")"); if (ASSERT) 1314 doAssert (inDTD); 1315 1316 if (type == CONDITIONAL_INCLUDE) { 1317 tempNode = new TreeConditionalSection (true); 1318 } else { 1319 tempNode = new TreeConditionalSection (false); 1320 } 1321 1322 appendChild ((TreeConditionalSection) tempNode); 1323 setBeginPosition (tempNode); 1324 pushParentNode ((TreeConditionalSection) tempNode); 1325 1326 } 1328 public void endConditional (Augmentations a) { 1330 endConditional(); 1331 } 1332 1333 1336 public void endConditional () { 1338 trace ("endConditional()"); 1340 popParentNode (); 1341 } 1343 public void endDTD (Augmentations a) { 1345 endDTD(); 1346 } 1347 1348 1353 public void endDTD () { 1355 trace ("endDTD()"); 1357 if (isXMLDocument) { 1358 1359 popParentNode (); 1360 1361 } else { 1362 1363 popParentNode (); 1364 1365 1368 isCorrect = errors == 0; 1369 throw new DTDStopException (); 1370 1371 } 1372 1373 inDTD = false; 1374 } 1376 1377 1379 private TreeElementDecl.ContentType lastType; private TreeElementDecl.ContentType contentModel; private Stack contentModelMembersStack; 1383 public XMLDTDContentModelSource getDTDContentModelSource() { 1384 return xmldtdContentModelSource; 1385 } 1386 1387 public void setDTDContentModelSource(XMLDTDContentModelSource src) { 1388 xmldtdContentModelSource = src; 1389 } 1390 1391 public void startContentModel (String elementName, Augmentations a) { 1392 1393 if ( Util.THIS.isLoggable() ) Util.THIS.debug ("startContentModel(" + elementName + ")"); 1395 lastType = null; 1396 contentModelMembersStack = new Stack (); 1397 1398 } 1399 1400 public void any (Augmentations a) { 1401 contentModel = new ANYType (); 1402 } 1403 1404 public void empty (Augmentations a) { 1405 contentModel = new EMPTYType (); 1406 } 1407 1408 public void pcdata (Augmentations a) { 1409 setMembersType (new MixedType ()); 1410 } 1411 1412 1413 public void startGroup (Augmentations a) { 1415 if ( Util.THIS.isLoggable() ) Util.THIS.debug ("startGroup()"); 1417 startMembers (); 1418 } 1419 1420 public void element (String elementName, Augmentations a) { 1421 1422 if ( Util.THIS.isLoggable() ) Util.THIS.debug ("element(" + elementName + ")"); 1424 lastType = new NameType (elementName); 1425 addMember (lastType); 1426 } 1427 1428 public void separator (short separator, Augmentations a) { 1430 if ( Util.THIS.isLoggable() ) Util.THIS.debug ("childrenSeparator()"); 1432 switch (separator) { 1433 case SEPARATOR_SEQUENCE: 1434 setMembersType (new SequenceType ()); 1435 break; 1436 case SEPARATOR_CHOICE: 1437 setMembersType (new ChoiceType ()); 1438 break; 1439 default: 1440 doAssert (false); 1441 } 1442 } 1443 1444 public void occurrence (short occurrence, Augmentations a) { 1448 if ( Util.THIS.isLoggable() ) Util.THIS.debug ("childrenOccurrence()"); 1450 switch (occurrence) { 1451 case OCCURS_ZERO_OR_ONE: 1452 lastType.setMultiplicity ('?'); 1453 break; 1454 case OCCURS_ZERO_OR_MORE: 1455 lastType.setMultiplicity ('*'); 1456 break; 1457 case OCCURS_ONE_OR_MORE: 1458 lastType.setMultiplicity ('+'); 1459 break; 1460 default: 1461 doAssert (false); 1462 } 1463 1464 } 1465 1466 public void endGroup (Augmentations a) { 1467 if ( Util.THIS.isLoggable() ) Util.THIS.debug ("childrenEndGroup()"); 1469 ChildrenType group = getMembersType (); 1470 group.addTypes (endMembers ()); 1471 lastType = group; 1472 addMember (lastType); 1473 } 1474 1475 public void endContentModel (Augmentations a) { 1476 if ( Util.THIS.isLoggable() ) Util.THIS.debug ("endContentModel()"); 1478 if (contentModel == null && lastType == null) { contentModel = new MixedType (); 1480 } else if (contentModel == null) { contentModel = lastType; 1482 if (contentModel instanceof MixedType) { 1483 contentModel.setMultiplicity ('*'); 1484 } 1485 } 1486 } 1487 1488 1489 1490 private void startMembers () { 1491 contentModelMembersStack.push (new Members (13)); 1492 } 1493 1494 private void addMember (TreeElementDecl.ContentType child) { 1495 1496 if (contentModelMembersStack.isEmpty ()) return; 1498 1499 Collection members = (Collection) contentModelMembersStack.peek (); 1500 members.add (child); 1501 } 1502 1503 private Collection endMembers () { 1504 return (Collection) contentModelMembersStack.pop (); 1505 } 1506 1507 private void setMembersType (ChildrenType group) { 1509 1510 if (contentModelMembersStack.isEmpty ()) return; 1512 1513 Members members = (Members) contentModelMembersStack.peek (); 1514 if (members.group == null) members.group = group; 1515 } 1516 1517 private ChildrenType getMembersType () { 1518 Members members = (Members) contentModelMembersStack.peek (); 1519 if (members.group == null) { 1520 return new ChoiceType (); 1521 } else { 1522 return members.group; 1523 } 1524 } 1525 1526 private class Members extends ArrayList { 1530 1531 private ChildrenType group; 1532 1533 private static final long serialVersionUID =4614355994187952965L; 1534 1535 public Members (int initSize) { 1536 super (initSize); 1537 group = null; 1538 } 1539 } 1540 1541 1543 1544 public void error (org.xml.sax.SAXParseException e) { 1545 trace (e.getMessage ()); 1546 1547 errorHandler.message (TreeStreamBuilderErrorHandler.ERROR_ERROR, e); 1548 } 1549 1550 public void warning (org.xml.sax.SAXParseException e) { 1551 trace (e.getMessage ()); 1552 1553 errorHandler.message (TreeStreamBuilderErrorHandler.ERROR_WARNING, e); 1554 } 1555 1556 public void fatalError (org.xml.sax.SAXParseException e) { 1557 trace (e.getMessage ()); 1558 1559 errors++; 1560 errorHandler.message (TreeStreamBuilderErrorHandler.ERROR_FATAL_ERROR, e); 1561 } 1562 1563 1565 1567 private void setReadOnly (TreeObject treeObject) { 1568 setReadOnly (treeObject, true); 1569 } 1570 1571 1572 private void setReadOnly (TreeObject treeObject, boolean value) { 1573 try { 1574 Method setReadOnlyMethod = TreeObject.class.getDeclaredMethod ("setReadOnly", new Class [] { Boolean.TYPE }); setReadOnlyMethod.setAccessible (true); 1576 setReadOnlyMethod.invoke (treeObject, new Object [] { value == true ? Boolean.TRUE : Boolean.FALSE}); 1577 } catch (NoSuchMethodException exc) { 1578 } catch (IllegalAccessException exc) { 1579 } catch (InvocationTargetException exc) { 1580 } 1581 } 1582 1583 1586 private void setBeginPosition (TreeNode n) { 1587 } 1589 1590 1591 1594 private TreeDocumentRoot getDocumentRoot () { 1595 TreeDocumentRoot doc = (TreeDocumentRoot) (errors > 0 ? null : returnDocument); 1596 1597 if ( Util.THIS.isLoggable() ) Util.THIS.debug ("TreeStreamBuilderXercesImpl returns: " + doc); 1599 return doc; 1600 } 1601 1602 1603 1606 private void pushParentNode (TreeParentNode parent) { 1607 parentNodeStack.push (parent); 1608 pushParentObjectList (parent.getChildNodes ()); 1609 } 1610 1611 1614 private void pushParentObjectList (TreeObjectList parentList) { 1615 parentObjectListStack.push (parentObjectList); 1616 1617 if (parentObjectList != null || parentObjectListStack.size() == 1) { 1619 parentObjectList = parentList; 1620 } else { 1621 parentObjectList = null; 1622 } 1623 } 1624 1625 1628 private void popParentObjectList () { 1629 parentObjectList = (TreeObjectList) parentObjectListStack.pop (); 1630 } 1631 1632 1635 private void popParentNode () { 1636 popParentObjectList (); 1637 TreeParentNode parentNode = (TreeParentNode) parentNodeStack.pop (); 1638 1639 1641 if ( parentNode instanceof TreeGeneralEntityReference ) { 1643 setReadOnly (parentNode.getChildNodes ()); 1644 1645 } else if ( parentNode instanceof TreeDTD ) { 1647 setReadOnly (parentNode); 1648 1649 } else if ( parentNode instanceof TreeDocumentType ) { 1650 1651 setReadOnly (parentNode.getChildNodes ()); 1652 1653 TreeObjectList externalDTD = ((TreeDocumentType)parentNode).getExternalDTD (); 1655 if (externalDTD != null) { 1656 setReadOnly (externalDTD); 1657 } 1658 } 1659 } 1660 1661 private TreeParentNode currentParentNode () { 1662 return (TreeParentNode) parentNodeStack.peek (); 1663 } 1664 1665 1668 private void appendChild (TreeObject child) { 1669 if (parentObjectList != null) parentObjectList.add (child); 1670 } 1671 1672 1675 private void enterEntity () { 1676 entityCounter++; 1677 } 1678 1679 1682 private void exitEntity () { 1683 entityCounter--; 1684 } 1685 1686 1689 private boolean inEntity () { 1690 return entityCounter > 0; 1691 } 1692 1693 private void trace (String msg) { 1694 if ( Util.THIS.isLoggable() ) { 1695 String location = ""; 1696 if (locator != null) { 1697 String entity = locator.getExpandedSystemId (); 1698 int index = entity.lastIndexOf ('/'); 1699 entity = entity.substring (index > 0 ? index : 0); 1700 location = entity + "/" + locator.getLineNumber () + ":" + locator.getColumnNumber () ; 1701 } 1702 Util.THIS.debug ("X2T " + location + " " + msg); } 1704 } 1705 1706 private void doAssert (boolean asrt) { 1707 if (asrt == false) { 1708 throw new IllegalStateException ("ASSERT"); } 1710 } 1711 1712 } 1713 1714 1715 1716} 1717 | Popular Tags |