1 16 19 20 package org.apache.xalan.xsltc.dom; 21 22 import java.net.URL ; 23 import java.net.MalformedURLException ; 24 import java.util.Enumeration ; 25 26 import javax.xml.transform.Source ; 27 import javax.xml.transform.dom.DOMSource ; 28 29 import org.apache.xalan.xsltc.DOM; 30 import org.apache.xalan.xsltc.DOMEnhancedForDTM; 31 import org.apache.xalan.xsltc.StripFilter; 32 import org.apache.xalan.xsltc.TransletException; 33 import org.apache.xalan.xsltc.runtime.BasisLibrary; 34 import org.apache.xalan.xsltc.runtime.Hashtable; 35 import org.apache.xml.dtm.DTM; 36 import org.apache.xml.dtm.DTMAxisIterator; 37 import org.apache.xml.dtm.DTMManager; 38 import org.apache.xml.dtm.DTMWSFilter; 39 import org.apache.xml.dtm.ref.DTMAxisIterNodeList; 40 import org.apache.xml.dtm.ref.DTMDefaultBase; 41 import org.apache.xml.dtm.ref.EmptyIterator; 42 import org.apache.xml.dtm.ref.DTMNodeProxy; 43 import org.apache.xml.dtm.ref.sax2dtm.SAX2DTM2; 44 import org.apache.xml.serializer.SerializationHandler; 45 import org.apache.xml.serializer.ToXMLSAXHandler; 46 import org.apache.xml.utils.XMLStringFactory; 47 import org.apache.xml.utils.SystemIDResolver; 48 import org.w3c.dom.Node ; 49 import org.w3c.dom.NodeList ; 50 import org.w3c.dom.Document ; 51 import org.w3c.dom.DocumentType ; 52 import org.w3c.dom.NamedNodeMap ; 53 import org.w3c.dom.Entity ; 54 55 import org.xml.sax.Attributes ; 56 import org.xml.sax.SAXException ; 57 58 59 75 public final class SAXImpl extends SAX2DTM2 76 implements DOMEnhancedForDTM, DOMBuilder 77 { 78 79 80 81 82 83 private int _uriCount = 0; 85 private int _prefixCount = 0; 86 87 private int[] _xmlSpaceStack; 90 private int _idx = 1; 91 private boolean _preserve = false; 92 93 private static final String XML_STRING = "xml:"; 94 private static final String XML_PREFIX = "xml"; 95 private static final String XMLSPACE_STRING = "xml:space"; 96 private static final String PRESERVE_STRING = "preserve"; 97 private static final String XMLNS_PREFIX = "xmlns"; 98 private static final String XML_URI = "http://www.w3.org/XML/1998/namespace"; 99 100 private boolean _escaping = true; 101 private boolean _disableEscaping = false; 102 private int _textNodeToProcess = DTM.NULL; 103 104 105 106 107 108 private final static String EMPTYSTRING = ""; 110 111 private final static DTMAxisIterator EMPTYITERATOR = EmptyIterator.getInstance(); 113 private int _namesSize = -1; 115 116 private Hashtable _nsIndex = new Hashtable(); 118 119 private int _size = 0; 121 122 private BitArray _dontEscape = null; 124 125 private String _documentURI = null; 127 static private int _documentURIIndex = 0; 128 129 private Document _document; 131 132 private Hashtable _node2Ids = null; 136 137 private boolean _hasDOMSource = false; 139 140 private XSLTCDTMManager _dtmManager; 142 143 private Node [] _nodes; 145 private NodeList[] _nodeLists; 146 private final static String XML_LANG_ATTRIBUTE = 147 "http://www.w3.org/XML/1998/namespace:@lang"; 148 149 152 public void setDocumentURI(String uri) { 153 if (uri != null) { 154 setDocumentBaseURI(SystemIDResolver.getAbsoluteURI(uri)); 155 } 156 } 157 158 161 public String getDocumentURI() { 162 String baseURI = getDocumentBaseURI(); 163 return (baseURI != null) ? baseURI : "rtf" + _documentURIIndex++; 164 } 165 166 public String getDocumentURI(int node) { 167 return getDocumentURI(); 168 } 169 170 public void setupMapping(String [] names, String [] urisArray, 171 int[] typesArray, String [] namespaces) { 172 } 174 175 180 public String lookupNamespace(int node, String prefix) 181 throws TransletException 182 { 183 int anode, nsnode; 184 final AncestorIterator ancestors = new AncestorIterator(); 185 186 if (isElement(node)) { 187 ancestors.includeSelf(); 188 } 189 190 ancestors.setStartNode(node); 191 while ((anode = ancestors.next()) != DTM.NULL) { 192 final NamespaceIterator namespaces = new NamespaceIterator(); 193 194 namespaces.setStartNode(anode); 195 while ((nsnode = namespaces.next()) != DTM.NULL) { 196 if (getLocalName(nsnode).equals(prefix)) { 197 return getNodeValue(nsnode); 198 } 199 } 200 } 201 202 BasisLibrary.runTimeError(BasisLibrary.NAMESPACE_PREFIX_ERR, prefix); 203 return null; 204 } 205 206 209 public boolean isElement(final int node) { 210 return getNodeType(node) == DTM.ELEMENT_NODE; 211 } 212 213 216 public boolean isAttribute(final int node) { 217 return getNodeType(node) == DTM.ATTRIBUTE_NODE; 218 } 219 220 223 public int getSize() { 224 return getNumberOfNodes(); 225 } 226 227 230 public void setFilter(StripFilter filter) { 231 } 232 233 234 237 public boolean lessThan(int node1, int node2) { 238 if (node1 == DTM.NULL) { 239 return false; 240 } 241 242 if (node2 == DTM.NULL) { 243 return true; 244 } 245 246 return (node1 < node2); 247 } 248 249 252 public Node makeNode(int index) { 253 if (_nodes == null) { 254 _nodes = new Node [_namesSize]; 255 } 256 257 int nodeID = makeNodeIdentity(index); 258 if (nodeID < 0) { 259 return null; 260 } 261 else if (nodeID < _nodes.length) { 262 return (_nodes[nodeID] != null) ? _nodes[nodeID] 263 : (_nodes[nodeID] = new DTMNodeProxy((DTM)this, index)); 264 } 265 else { 266 return new DTMNodeProxy((DTM)this, index); 267 } 268 } 269 270 274 public Node makeNode(DTMAxisIterator iter) { 275 return makeNode(iter.next()); 276 } 277 278 281 public NodeList makeNodeList(int index) { 282 if (_nodeLists == null) { 283 _nodeLists = new NodeList[_namesSize]; 284 } 285 286 int nodeID = makeNodeIdentity(index); 287 if (nodeID < 0) { 288 return null; 289 } 290 else if (nodeID < _nodeLists.length) { 291 return (_nodeLists[nodeID] != null) ? _nodeLists[nodeID] 292 : (_nodeLists[nodeID] = new DTMAxisIterNodeList(this, 293 new SingletonIterator(index))); 294 } 295 else { 296 return new DTMAxisIterNodeList(this, new SingletonIterator(index)); 297 } 298 } 299 300 304 public NodeList makeNodeList(DTMAxisIterator iter) { 305 return new DTMAxisIterNodeList(this, iter); 306 } 307 308 312 public class TypedNamespaceIterator extends NamespaceIterator { 313 314 private String _nsPrefix; 315 316 322 public TypedNamespaceIterator(int nodeType) { 323 super(); 324 if(m_expandedNameTable != null){ 325 _nsPrefix = m_expandedNameTable.getLocalName(nodeType); 326 } 327 } 328 329 334 public int next() { 335 if ((_nsPrefix == null) ||(_nsPrefix.length() == 0) ){ 336 return (END); 337 } 338 int node = END; 339 for (node = super.next(); node != END; node = super.next()) { 340 if (_nsPrefix.compareTo(getLocalName(node))== 0) { 341 return returnNode(node); 342 } 343 } 344 return (END); 345 } 346 } 348 349 350 354 private final class NodeValueIterator extends InternalAxisIteratorBase 355 { 356 357 private DTMAxisIterator _source; 358 private String _value; 359 private boolean _op; 360 private final boolean _isReverse; 361 private int _returnType = RETURN_PARENT; 362 363 public NodeValueIterator(DTMAxisIterator source, int returnType, 364 String value, boolean op) 365 { 366 _source = source; 367 _returnType = returnType; 368 _value = value; 369 _op = op; 370 _isReverse = source.isReverse(); 371 } 372 373 public boolean isReverse() 374 { 375 return _isReverse; 376 } 377 378 public DTMAxisIterator cloneIterator() 379 { 380 try { 381 NodeValueIterator clone = (NodeValueIterator)super.clone(); 382 clone._isRestartable = false; 383 clone._source = _source.cloneIterator(); 384 clone._value = _value; 385 clone._op = _op; 386 return clone.reset(); 387 } 388 catch (CloneNotSupportedException e) { 389 BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR, 390 e.toString()); 391 return null; 392 } 393 } 394 395 public void setRestartable(boolean isRestartable) 396 { 397 _isRestartable = isRestartable; 398 _source.setRestartable(isRestartable); 399 } 400 401 public DTMAxisIterator reset() 402 { 403 _source.reset(); 404 return resetPosition(); 405 } 406 407 public int next() 408 { 409 int node; 410 while ((node = _source.next()) != END) { 411 String val = getStringValueX(node); 412 if (_value.equals(val) == _op) { 413 if (_returnType == RETURN_CURRENT) { 414 return returnNode(node); 415 } 416 else { 417 return returnNode(getParent(node)); 418 } 419 } 420 } 421 return END; 422 } 423 424 public DTMAxisIterator setStartNode(int node) 425 { 426 if (_isRestartable) { 427 _source.setStartNode(_startNode = node); 428 return resetPosition(); 429 } 430 return this; 431 } 432 433 public void setMark() 434 { 435 _source.setMark(); 436 } 437 438 public void gotoMark() 439 { 440 _source.gotoMark(); 441 } 442 } 444 public DTMAxisIterator getNodeValueIterator(DTMAxisIterator iterator, int type, 445 String value, boolean op) 446 { 447 return(DTMAxisIterator)(new NodeValueIterator(iterator, type, value, op)); 448 } 449 450 453 public DTMAxisIterator orderNodes(DTMAxisIterator source, int node) 454 { 455 return new DupFilterIterator(source); 456 } 457 458 462 public DTMAxisIterator getIterator() 463 { 464 return new SingletonIterator(getDocument()); 465 } 466 467 470 public int getNSType(int node) 471 { 472 String s = getNamespaceURI(node); 473 if (s == null) { 474 return 0; 475 } 476 int eType = getIdForNamespace(s); 477 return ((Integer )_nsIndex.get(new Integer (eType))).intValue(); 478 } 479 480 481 482 485 public int getNamespaceType(final int node) 486 { 487 return super.getNamespaceType(node); 488 } 489 490 493 private int[] setupMapping(String [] names, String [] uris, int[] types, int nNames) { 494 final int[] result = new int[m_expandedNameTable.getSize()]; 497 for (int i = 0; i < nNames; i++) { 498 int type = m_expandedNameTable.getExpandedTypeID(uris[i], names[i], types[i], false); 500 result[type] = type; 501 } 502 return result; 503 } 504 505 508 public int getGeneralizedType(final String name) { 509 return getGeneralizedType(name, true); 510 } 511 512 515 public int getGeneralizedType(final String name, boolean searchOnly) { 516 String lName, ns = null; 517 int index = -1; 518 int code; 519 520 if ((index = name.lastIndexOf(":"))> -1) { 522 ns = name.substring(0, index); 523 } 524 525 int lNameStartIdx = index+1; 528 529 if (name.charAt(lNameStartIdx) == '@') { 532 code = DTM.ATTRIBUTE_NODE; 533 lNameStartIdx++; 534 } 535 else { 536 code = DTM.ELEMENT_NODE; 537 } 538 539 lName = (lNameStartIdx == 0) ? name : name.substring(lNameStartIdx); 541 542 return m_expandedNameTable.getExpandedTypeID(ns, lName, code, searchOnly); 543 } 544 545 548 public short[] getMapping(String [] names, String [] uris, int[] types) 549 { 550 if (_namesSize < 0) { 553 return getMapping2(names, uris, types); 554 } 555 556 int i; 557 final int namesLength = names.length; 558 final int exLength = m_expandedNameTable.getSize(); 559 560 final short[] result = new short[exLength]; 561 562 for (i = 0; i < DTM.NTYPES; i++) { 564 result[i] = (short)i; 565 } 566 567 for (i = NTYPES; i < exLength; i++) { 568 result[i] = m_expandedNameTable.getType(i); 569 } 570 571 for (i = 0; i < namesLength; i++) { 573 int genType = m_expandedNameTable.getExpandedTypeID(uris[i], 574 names[i], 575 types[i], 576 true); 577 if (genType >= 0 && genType < exLength) { 578 result[genType] = (short)(i + DTM.NTYPES); 579 } 580 } 581 582 return result; 583 } 584 585 588 public int[] getReverseMapping(String [] names, String [] uris, int[] types) 589 { 590 int i; 591 final int[] result = new int[names.length + DTM.NTYPES]; 592 593 for (i = 0; i < DTM.NTYPES; i++) { 595 result[i] = i; 596 } 597 598 for (i = 0; i < names.length; i++) { 600 int type = m_expandedNameTable.getExpandedTypeID(uris[i], names[i], types[i], true); 601 result[i+DTM.NTYPES] = type; 602 } 603 return(result); 604 } 605 606 610 private short[] getMapping2(String [] names, String [] uris, int[] types) 611 { 612 int i; 613 final int namesLength = names.length; 614 final int exLength = m_expandedNameTable.getSize(); 615 int[] generalizedTypes = null; 616 if (namesLength > 0) { 617 generalizedTypes = new int[namesLength]; 618 } 619 620 int resultLength = exLength; 621 622 for (i = 0; i < namesLength; i++) { 623 generalizedTypes[i] = 628 m_expandedNameTable.getExpandedTypeID(uris[i], 629 names[i], 630 types[i], 631 false); 632 if (_namesSize < 0 && generalizedTypes[i] >= resultLength) { 633 resultLength = generalizedTypes[i] + 1; 634 } 635 } 636 637 final short[] result = new short[resultLength]; 638 639 for (i = 0; i < DTM.NTYPES; i++) { 641 result[i] = (short)i; 642 } 643 644 for (i = NTYPES; i < exLength; i++) { 645 result[i] = m_expandedNameTable.getType(i); 646 } 647 648 for (i = 0; i < namesLength; i++) { 650 int genType = generalizedTypes[i]; 651 if (genType >= 0 && genType < resultLength) { 652 result[genType] = (short)(i + DTM.NTYPES); 653 } 654 } 655 656 return(result); 657 } 658 661 public short[] getNamespaceMapping(String [] namespaces) 662 { 663 int i; 664 final int nsLength = namespaces.length; 665 final int mappingLength = _uriCount; 666 667 final short[] result = new short[mappingLength]; 668 669 for (i=0; i<mappingLength; i++) { 671 result[i] = (short)(-1); 672 } 673 674 for (i=0; i<nsLength; i++) { 675 int eType = getIdForNamespace(namespaces[i]); 676 Integer type = (Integer )_nsIndex.get(new Integer (eType)); 677 if (type != null) { 678 result[type.intValue()] = (short)i; 679 } 680 } 681 682 return(result); 683 } 684 685 688 public short[] getReverseNamespaceMapping(String [] namespaces) 689 { 690 int i; 691 final int length = namespaces.length; 692 final short[] result = new short[length]; 693 694 for (i = 0; i < length; i++) { 695 int eType = getIdForNamespace(namespaces[i]); 696 Integer type = (Integer )_nsIndex.get(new Integer (eType)); 697 result[i] = (type == null) ? -1 : type.shortValue(); 698 } 699 700 return result; 701 } 702 703 706 public SAXImpl(XSLTCDTMManager mgr, Source source, 707 int dtmIdentity, DTMWSFilter whiteSpaceFilter, 708 XMLStringFactory xstringfactory, 709 boolean doIndexing, boolean buildIdIndex) 710 { 711 this(mgr, source, dtmIdentity, whiteSpaceFilter, xstringfactory, 712 doIndexing, DEFAULT_BLOCKSIZE, buildIdIndex, false); 713 } 714 715 718 public SAXImpl(XSLTCDTMManager mgr, Source source, 719 int dtmIdentity, DTMWSFilter whiteSpaceFilter, 720 XMLStringFactory xstringfactory, 721 boolean doIndexing, int blocksize, 722 boolean buildIdIndex, 723 boolean newNameTable) 724 { 725 super(mgr, source, dtmIdentity, whiteSpaceFilter, xstringfactory, 726 doIndexing, blocksize, false, buildIdIndex, newNameTable); 727 728 _dtmManager = mgr; 729 _size = blocksize; 730 731 _xmlSpaceStack = new int[blocksize <= 64 ? 4 : 64]; 733 734 735 _xmlSpaceStack[0] = DTMDefaultBase.ROOTNODE; 736 737 if (source instanceof DOMSource ) { 740 _hasDOMSource = true; 741 DOMSource domsrc = (DOMSource )source; 742 Node node = domsrc.getNode(); 743 if (node instanceof Document ) { 744 _document = (Document )node; 745 } 746 else { 747 _document = node.getOwnerDocument(); 748 } 749 _node2Ids = new Hashtable(); 750 } 751 } 752 753 760 public void migrateTo(DTMManager manager) { 761 super.migrateTo(manager); 762 if (manager instanceof XSLTCDTMManager) { 763 _dtmManager = (XSLTCDTMManager)manager; 764 } 765 } 766 767 773 public int getElementById(String idString) 774 { 775 Node node = _document.getElementById(idString); 776 if (node != null) { 777 Integer id = (Integer )_node2Ids.get(node); 778 return (id != null) ? id.intValue() : DTM.NULL; 779 } 780 else { 781 return DTM.NULL; 782 } 783 } 784 785 788 public boolean hasDOMSource() 789 { 790 return _hasDOMSource; 791 } 792 793 794 795 796 797 801 private void xmlSpaceDefine(String val, final int node) 802 { 803 final boolean setting = val.equals(PRESERVE_STRING); 804 if (setting != _preserve) { 805 _xmlSpaceStack[_idx++] = node; 806 _preserve = setting; 807 } 808 } 809 810 814 private void xmlSpaceRevert(final int node) 815 { 816 if (node == _xmlSpaceStack[_idx - 1]) { 817 _idx--; 818 _preserve = !_preserve; 819 } 820 } 821 822 828 protected boolean getShouldStripWhitespace() 829 { 830 return _preserve ? false : super.getShouldStripWhitespace(); 831 } 832 833 836 private void handleTextEscaping() { 837 if (_disableEscaping && _textNodeToProcess != DTM.NULL 838 && _type(_textNodeToProcess) == DTM.TEXT_NODE) { 839 if (_dontEscape == null) { 840 _dontEscape = new BitArray(_size); 841 } 842 843 if (_textNodeToProcess >= _dontEscape.size()) { 845 _dontEscape.resize(_dontEscape.size() * 2); 846 } 847 848 _dontEscape.setBit(_textNodeToProcess); 849 _disableEscaping = false; 850 } 851 _textNodeToProcess = DTM.NULL; 852 } 853 854 855 856 857 858 859 862 public void characters(char[] ch, int start, int length) throws SAXException 863 { 864 super.characters(ch, start, length); 865 866 _disableEscaping = !_escaping; 867 _textNodeToProcess = getNumberOfNodes(); 868 } 869 870 873 public void startDocument() throws SAXException 874 { 875 super.startDocument(); 876 877 _nsIndex.put(new Integer (0), new Integer (_uriCount++)); 878 definePrefixAndUri(XML_PREFIX, XML_URI); 879 } 880 881 884 public void endDocument() throws SAXException 885 { 886 super.endDocument(); 887 888 handleTextEscaping(); 889 _namesSize = m_expandedNameTable.getSize(); 890 } 891 892 896 public void startElement(String uri, String localName, 897 String qname, Attributes attributes, 898 Node node) 899 throws SAXException 900 { 901 this.startElement(uri, localName, qname, attributes); 902 903 if (m_buildIdIndex) { 904 _node2Ids.put(node, new Integer (m_parents.peek())); 905 } 906 } 907 908 911 public void startElement(String uri, String localName, 912 String qname, Attributes attributes) 913 throws SAXException 914 { 915 super.startElement(uri, localName, qname, attributes); 916 917 handleTextEscaping(); 918 919 if (m_wsfilter != null) { 920 final int index = attributes.getIndex(XMLSPACE_STRING); 924 if (index >= 0) { 925 xmlSpaceDefine(attributes.getValue(index), m_parents.peek()); 926 } 927 } 928 } 929 930 933 public void endElement(String namespaceURI, String localName, String qname) 934 throws SAXException 935 { 936 super.endElement(namespaceURI, localName, qname); 937 938 handleTextEscaping(); 939 940 if (m_wsfilter != null) { 942 xmlSpaceRevert(m_previous); 943 } 944 } 945 946 949 public void processingInstruction(String target, String data) 950 throws SAXException 951 { 952 super.processingInstruction(target, data); 953 handleTextEscaping(); 954 } 955 956 960 public void ignorableWhitespace(char[] ch, int start, int length) 961 throws SAXException 962 { 963 super.ignorableWhitespace(ch, start, length); 964 _textNodeToProcess = getNumberOfNodes(); 965 } 966 967 970 public void startPrefixMapping(String prefix, String uri) 971 throws SAXException 972 { 973 super.startPrefixMapping(prefix, uri); 974 handleTextEscaping(); 975 976 definePrefixAndUri(prefix, uri); 977 } 978 979 private void definePrefixAndUri(String prefix, String uri) 980 throws SAXException 981 { 982 Integer eType = new Integer (getIdForNamespace(uri)); 984 if ((Integer )_nsIndex.get(eType) == null) { 985 _nsIndex.put(eType, new Integer (_uriCount++)); 986 } 987 } 988 989 992 public void comment(char[] ch, int start, int length) 993 throws SAXException 994 { 995 super.comment(ch, start, length); 996 handleTextEscaping(); 997 } 998 999 public boolean setEscaping(boolean value) { 1000 final boolean temp = _escaping; 1001 _escaping = value; 1002 return temp; 1003 } 1004 1005 1006 1007 1008 1009 1012 public void print(int node, int level) 1013 { 1014 switch(getNodeType(node)) 1015 { 1016 case DTM.ROOT_NODE: 1017 case DTM.DOCUMENT_NODE: 1018 print(getFirstChild(node), level); 1019 break; 1020 case DTM.TEXT_NODE: 1021 case DTM.COMMENT_NODE: 1022 case DTM.PROCESSING_INSTRUCTION_NODE: 1023 System.out.print(getStringValueX(node)); 1024 break; 1025 default: 1026 final String name = getNodeName(node); 1027 System.out.print("<" + name); 1028 for (int a = getFirstAttribute(node); a != DTM.NULL; a = getNextAttribute(a)) 1029 { 1030 System.out.print("\n" + getNodeName(a) + "=\"" + getStringValueX(a) + "\""); 1031 } 1032 System.out.print('>'); 1033 for (int child = getFirstChild(node); child != DTM.NULL; 1034 child = getNextSibling(child)) { 1035 print(child, level + 1); 1036 } 1037 System.out.println("</" + name + '>'); 1038 break; 1039 } 1040 } 1041 1042 1045 public String getNodeName(final int node) 1046 { 1047 int nodeh = node; 1049 final short type = getNodeType(nodeh); 1050 switch(type) 1051 { 1052 case DTM.ROOT_NODE: 1053 case DTM.DOCUMENT_NODE: 1054 case DTM.TEXT_NODE: 1055 case DTM.COMMENT_NODE: 1056 return EMPTYSTRING; 1057 case DTM.NAMESPACE_NODE: 1058 return this.getLocalName(nodeh); 1059 default: 1060 return super.getNodeName(nodeh); 1061 } 1062 } 1063 1064 1067 public String getNamespaceName(final int node) 1068 { 1069 if (node == DTM.NULL) { 1070 return ""; 1071 } 1072 1073 String s; 1074 return (s = getNamespaceURI(node)) == null ? EMPTYSTRING : s; 1075 } 1076 1077 1078 1081 public int getAttributeNode(final int type, final int element) 1082 { 1083 for (int attr = getFirstAttribute(element); 1084 attr != DTM.NULL; 1085 attr = getNextAttribute(attr)) 1086 { 1087 if (getExpandedTypeID(attr) == type) return attr; 1088 } 1089 return DTM.NULL; 1090 } 1091 1092 1095 public String getAttributeValue(final int type, final int element) 1096 { 1097 final int attr = getAttributeNode(type, element); 1098 return (attr != DTM.NULL) ? getStringValueX(attr) : EMPTYSTRING; 1099 } 1100 1101 1104 public String getAttributeValue(final String name, final int element) 1105 { 1106 return getAttributeValue(getGeneralizedType(name), element); 1107 } 1108 1109 1112 public DTMAxisIterator getChildren(final int node) 1113 { 1114 return (new ChildrenIterator()).setStartNode(node); 1115 } 1116 1117 1121 public DTMAxisIterator getTypedChildren(final int type) 1122 { 1123 return(new TypedChildrenIterator(type)); 1124 } 1125 1126 1132 public DTMAxisIterator getAxisIterator(final int axis) 1133 { 1134 switch (axis) 1135 { 1136 case Axis.SELF: 1137 return new SingletonIterator(); 1138 case Axis.CHILD: 1139 return new ChildrenIterator(); 1140 case Axis.PARENT: 1141 return new ParentIterator(); 1142 case Axis.ANCESTOR: 1143 return new AncestorIterator(); 1144 case Axis.ANCESTORORSELF: 1145 return (new AncestorIterator()).includeSelf(); 1146 case Axis.ATTRIBUTE: 1147 return new AttributeIterator(); 1148 case Axis.DESCENDANT: 1149 return new DescendantIterator(); 1150 case Axis.DESCENDANTORSELF: 1151 return (new DescendantIterator()).includeSelf(); 1152 case Axis.FOLLOWING: 1153 return new FollowingIterator(); 1154 case Axis.PRECEDING: 1155 return new PrecedingIterator(); 1156 case Axis.FOLLOWINGSIBLING: 1157 return new FollowingSiblingIterator(); 1158 case Axis.PRECEDINGSIBLING: 1159 return new PrecedingSiblingIterator(); 1160 case Axis.NAMESPACE: 1161 return new NamespaceIterator(); 1162 default: 1163 BasisLibrary.runTimeError(BasisLibrary.AXIS_SUPPORT_ERR, Axis.names[axis]); 1164 } 1165 return null; 1166 } 1167 1168 1172 public DTMAxisIterator getTypedAxisIterator(int axis, int type) 1173 { 1174 if (axis == Axis.CHILD) { 1176 return new TypedChildrenIterator(type); 1177 } 1178 1179 if (type == NO_TYPE) { 1180 return(EMPTYITERATOR); 1181 } 1182 1183 switch (axis) 1184 { 1185 case Axis.SELF: 1186 return new TypedSingletonIterator(type); 1187 case Axis.CHILD: 1188 return new TypedChildrenIterator(type); 1189 case Axis.PARENT: 1190 return new ParentIterator().setNodeType(type); 1191 case Axis.ANCESTOR: 1192 return new TypedAncestorIterator(type); 1193 case Axis.ANCESTORORSELF: 1194 return (new TypedAncestorIterator(type)).includeSelf(); 1195 case Axis.ATTRIBUTE: 1196 return new TypedAttributeIterator(type); 1197 case Axis.DESCENDANT: 1198 return new TypedDescendantIterator(type); 1199 case Axis.DESCENDANTORSELF: 1200 return (new TypedDescendantIterator(type)).includeSelf(); 1201 case Axis.FOLLOWING: 1202 return new TypedFollowingIterator(type); 1203 case Axis.PRECEDING: 1204 return new TypedPrecedingIterator(type); 1205 case Axis.FOLLOWINGSIBLING: 1206 return new TypedFollowingSiblingIterator(type); 1207 case Axis.PRECEDINGSIBLING: 1208 return new TypedPrecedingSiblingIterator(type); 1209 case Axis.NAMESPACE: 1210 return new TypedNamespaceIterator(type); 1211 default: 1212 BasisLibrary.runTimeError(BasisLibrary.TYPED_AXIS_SUPPORT_ERR, Axis.names[axis]); 1213 } 1214 return null; 1215 } 1216 1217 1224 public DTMAxisIterator getNamespaceAxisIterator(int axis, int ns) 1225 { 1226 1227 DTMAxisIterator iterator = null; 1228 1229 if (ns == NO_TYPE) { 1230 return EMPTYITERATOR; 1231 } 1232 else { 1233 switch (axis) { 1234 case Axis.CHILD: 1235 return new NamespaceChildrenIterator(ns); 1236 case Axis.ATTRIBUTE: 1237 return new NamespaceAttributeIterator(ns); 1238 default: 1239 return new NamespaceWildcardIterator(axis, ns); 1240 } 1241 } 1242 } 1243 1244 1249 public final class NamespaceWildcardIterator 1250 extends InternalAxisIteratorBase 1251 { 1252 1255 protected int m_nsType; 1256 1257 1261 protected DTMAxisIterator m_baseIterator; 1262 1263 1269 public NamespaceWildcardIterator(int axis, int nsType) { 1270 m_nsType = nsType; 1271 1272 switch (axis) { 1275 case Axis.ATTRIBUTE: { 1276 m_baseIterator = getAxisIterator(axis); 1279 } 1280 case Axis.NAMESPACE: { 1281 m_baseIterator = getAxisIterator(axis); 1284 } 1285 default: { 1286 m_baseIterator = getTypedAxisIterator(axis, 1289 DTM.ELEMENT_NODE); 1290 } 1291 } 1292 } 1293 1294 1302 public DTMAxisIterator setStartNode(int node) { 1303 if (_isRestartable) { 1304 _startNode = node; 1305 m_baseIterator.setStartNode(node); 1306 resetPosition(); 1307 } 1308 return this; 1309 } 1310 1311 1316 public int next() { 1317 int node; 1318 1319 while ((node = m_baseIterator.next()) != END) { 1320 if (getNSType(node) == m_nsType) { 1322 return returnNode(node); 1323 } 1324 } 1325 1326 return END; 1327 } 1328 1329 1335 public DTMAxisIterator cloneIterator() { 1336 try { 1337 DTMAxisIterator nestedClone = m_baseIterator.cloneIterator(); 1338 NamespaceWildcardIterator clone = 1339 (NamespaceWildcardIterator) super.clone(); 1340 1341 clone.m_baseIterator = nestedClone; 1342 clone.m_nsType = m_nsType; 1343 clone._isRestartable = false; 1344 1345 return clone; 1346 } catch (CloneNotSupportedException e) { 1347 BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR, 1348 e.toString()); 1349 return null; 1350 } 1351 } 1352 1353 1358 public boolean isReverse() { 1359 return m_baseIterator.isReverse(); 1360 } 1361 1362 public void setMark() { 1363 m_baseIterator.setMark(); 1364 } 1365 1366 public void gotoMark() { 1367 m_baseIterator.gotoMark(); 1368 } 1369 } 1370 1371 1377 public final class NamespaceChildrenIterator 1378 extends InternalAxisIteratorBase 1379 { 1380 1381 1382 private final int _nsType; 1383 1384 1390 public NamespaceChildrenIterator(final int type) { 1391 _nsType = type; 1392 } 1393 1394 1402 public DTMAxisIterator setStartNode(int node) { 1403 if (node == DTMDefaultBase.ROOTNODE) { 1405 node = getDocument(); 1406 } 1407 1408 if (_isRestartable) { 1409 _startNode = node; 1410 _currentNode = (node == DTM.NULL) ? DTM.NULL : NOTPROCESSED; 1411 1412 return resetPosition(); 1413 } 1414 1415 return this; 1416 } 1417 1418 1423 public int next() { 1424 if (_currentNode != DTM.NULL) { 1425 for (int node = (NOTPROCESSED == _currentNode) 1426 ? _firstch(makeNodeIdentity(_startNode)) 1427 : _nextsib(_currentNode); 1428 node != END; 1429 node = _nextsib(node)) { 1430 int nodeHandle = makeNodeHandle(node); 1431 1432 if (getNSType(nodeHandle) == _nsType) { 1433 _currentNode = node; 1434 1435 return returnNode(nodeHandle); 1436 } 1437 } 1438 } 1439 1440 return END; 1441 } 1442 } 1444 1447 public final class NamespaceAttributeIterator 1448 extends InternalAxisIteratorBase 1449 { 1450 1451 1452 private final int _nsType; 1453 1454 1460 public NamespaceAttributeIterator(int nsType) { 1461 super(); 1462 1463 _nsType = nsType; 1464 } 1465 1466 1474 public DTMAxisIterator setStartNode(int node) { 1475 if (node == DTMDefaultBase.ROOTNODE) { 1477 node = getDocument(); 1478 } 1479 1480 if (_isRestartable) { 1481 int nsType = _nsType; 1482 1483 _startNode = node; 1484 1485 for (node = getFirstAttribute(node); 1486 node != END; 1487 node = getNextAttribute(node)) { 1488 if (getNSType(node) == nsType) { 1489 break; 1490 } 1491 } 1492 1493 _currentNode = node; 1494 return resetPosition(); 1495 } 1496 1497 return this; 1498 } 1499 1500 1505 public int next() { 1506 int node = _currentNode; 1507 int nsType = _nsType; 1508 int nextNode; 1509 1510 if (node == END) { 1511 return END; 1512 } 1513 1514 for (nextNode = getNextAttribute(node); 1515 nextNode != END; 1516 nextNode = getNextAttribute(nextNode)) { 1517 if (getNSType(nextNode) == nsType) { 1518 break; 1519 } 1520 } 1521 1522 _currentNode = nextNode; 1523 1524 return returnNode(node); 1525 } 1526 } 1528 1532 public DTMAxisIterator getTypedDescendantIterator(int type) 1533 { 1534 return new TypedDescendantIterator(type); 1535 } 1536 1537 1540 public DTMAxisIterator getNthDescendant(int type, int n, boolean includeself) 1541 { 1542 DTMAxisIterator source = (DTMAxisIterator) new TypedDescendantIterator(type); 1543 return new NthDescendantIterator(n); 1544 } 1545 1546 1549 public void characters(final int node, SerializationHandler handler) 1550 throws TransletException 1551 { 1552 if (node != DTM.NULL) { 1553 try { 1554 dispatchCharactersEvents(node, handler, false); 1555 } catch (SAXException e) { 1556 throw new TransletException(e); 1557 } 1558 } 1559 } 1560 1561 1564 public void copy(DTMAxisIterator nodes, SerializationHandler handler) 1565 throws TransletException 1566 { 1567 int node; 1568 while ((node = nodes.next()) != DTM.NULL) { 1569 copy(node, handler); 1570 } 1571 } 1572 1573 1576 public void copy(SerializationHandler handler) throws TransletException 1577 { 1578 copy(getDocument(), handler); 1579 } 1580 1581 1588 public void copy(final int node, SerializationHandler handler) 1589 throws TransletException 1590 { 1591 copy(node, handler, false ); 1592 } 1593 1594 1595 private final void copy(final int node, SerializationHandler handler, boolean isChild) 1596 throws TransletException 1597 { 1598 int nodeID = makeNodeIdentity(node); 1599 int eType = _exptype2(nodeID); 1600 int type = _exptype2Type(eType); 1601 1602 try { 1603 switch(type) 1604 { 1605 case DTM.ROOT_NODE: 1606 case DTM.DOCUMENT_NODE: 1607 for(int c = _firstch2(nodeID); c != DTM.NULL; c = _nextsib2(c)) { 1608 copy(makeNodeHandle(c), handler, true); 1609 } 1610 break; 1611 case DTM.PROCESSING_INSTRUCTION_NODE: 1612 copyPI(node, handler); 1613 break; 1614 case DTM.COMMENT_NODE: 1615 handler.comment(getStringValueX(node)); 1616 break; 1617 case DTM.TEXT_NODE: 1618 boolean oldEscapeSetting = false; 1619 boolean escapeBit = false; 1620 1621 if (_dontEscape != null) { 1622 escapeBit = _dontEscape.getBit(getNodeIdent(node)); 1623 if (escapeBit) { 1624 oldEscapeSetting = handler.setEscaping(false); 1625 } 1626 } 1627 1628 copyTextNode(nodeID, handler); 1629 1630 if (escapeBit) { 1631 handler.setEscaping(oldEscapeSetting); 1632 } 1633 break; 1634 case DTM.ATTRIBUTE_NODE: 1635 copyAttribute(nodeID, eType, handler); 1636 break; 1637 case DTM.NAMESPACE_NODE: 1638 handler.namespaceAfterStartElement(getNodeNameX(node), getNodeValue(node)); 1639 break; 1640 default: 1641 if (type == DTM.ELEMENT_NODE) 1642 { 1643 final String name = copyElement(nodeID, eType, handler); 1645 copyNS(nodeID, handler,!isChild); 1648 copyAttributes(nodeID, handler); 1649 for (int c = _firstch2(nodeID); c != DTM.NULL; c = _nextsib2(c)) { 1651 copy(makeNodeHandle(c), handler, true); 1652 } 1653 1654 handler.endElement(name); 1656 } 1657 else { 1659 final String uri = getNamespaceName(node); 1660 if (uri.length() != 0) { 1661 final String prefix = getPrefix(node); 1662 handler.namespaceAfterStartElement(prefix, uri); 1663 } 1664 handler.addAttribute(getNodeName(node), getNodeValue(node)); 1665 } 1666 break; 1667 } 1668 } 1669 catch (Exception e) { 1670 throw new TransletException(e); 1671 } 1672 1673 } 1674 1677 private void copyPI(final int node, SerializationHandler handler) 1678 throws TransletException 1679 { 1680 final String target = getNodeName(node); 1681 final String value = getStringValueX(node); 1682 1683 try { 1684 handler.processingInstruction(target, value); 1685 } catch (Exception e) { 1686 throw new TransletException(e); 1687 } 1688 } 1689 1690 1693 public String shallowCopy(final int node, SerializationHandler handler) 1694 throws TransletException 1695 { 1696 int nodeID = makeNodeIdentity(node); 1697 int exptype = _exptype2(nodeID); 1698 int type = _exptype2Type(exptype); 1699 1700 try { 1701 switch(type) 1702 { 1703 case DTM.ELEMENT_NODE: 1704 final String name = copyElement(nodeID, exptype, handler); 1705 copyNS(nodeID, handler, true); 1706 return name; 1707 case DTM.ROOT_NODE: 1708 case DTM.DOCUMENT_NODE: 1709 return EMPTYSTRING; 1710 case DTM.TEXT_NODE: 1711 copyTextNode(nodeID, handler); 1712 return null; 1713 case DTM.PROCESSING_INSTRUCTION_NODE: 1714 copyPI(node, handler); 1715 return null; 1716 case DTM.COMMENT_NODE: 1717 handler.comment(getStringValueX(node)); 1718 return null; 1719 case DTM.NAMESPACE_NODE: 1720 handler.namespaceAfterStartElement(getNodeNameX(node), getNodeValue(node)); 1721 return null; 1722 case DTM.ATTRIBUTE_NODE: 1723 copyAttribute(nodeID, exptype, handler); 1724 return null; 1725 default: 1726 final String uri1 = getNamespaceName(node); 1727 if (uri1.length() != 0) { 1728 final String prefix = getPrefix(node); 1729 handler.namespaceAfterStartElement(prefix, uri1); 1730 } 1731 handler.addAttribute(getNodeName(node), getNodeValue(node)); 1732 return null; 1733 } 1734 } catch (Exception e) { 1735 throw new TransletException(e); 1736 } 1737 } 1738 1739 1742 public String getLanguage(int node) 1743 { 1744 int parent = node; 1745 while (DTM.NULL != parent) { 1746 if (DTM.ELEMENT_NODE == getNodeType(parent)) { 1747 int langAttr = getAttributeNode(parent, "http://www.w3.org/XML/1998/namespace", "lang"); 1748 1749 if (DTM.NULL != langAttr) { 1750 return getNodeValue(langAttr); 1751 } 1752 } 1753 1754 parent = getParent(parent); 1755 } 1756 return(null); 1757 } 1758 1759 1764 public DOMBuilder getBuilder() 1765 { 1766 return this; 1767 } 1768 1769 1773 public SerializationHandler getOutputDomBuilder() 1774 { 1775 return new ToXMLSAXHandler(this, "UTF-8"); 1776 } 1777 1778 1781 public DOM getResultTreeFrag(int initSize, int rtfType) 1782 { 1783 return getResultTreeFrag(initSize, rtfType, true); 1784 } 1785 1786 1794 public DOM getResultTreeFrag(int initSize, int rtfType, boolean addToManager) 1795 { 1796 if (rtfType == DOM.SIMPLE_RTF) { 1797 if (addToManager) { 1798 int dtmPos = _dtmManager.getFirstFreeDTMID(); 1799 SimpleResultTreeImpl rtf = new SimpleResultTreeImpl(_dtmManager, 1800 dtmPos << DTMManager.IDENT_DTM_NODE_BITS); 1801 _dtmManager.addDTM(rtf, dtmPos, 0); 1802 return rtf; 1803 } 1804 else { 1805 return new SimpleResultTreeImpl(_dtmManager, 0); 1806 } 1807 } 1808 else if (rtfType == DOM.ADAPTIVE_RTF) { 1809 if (addToManager) { 1810 int dtmPos = _dtmManager.getFirstFreeDTMID(); 1811 AdaptiveResultTreeImpl rtf = new AdaptiveResultTreeImpl(_dtmManager, 1812 dtmPos << DTMManager.IDENT_DTM_NODE_BITS, 1813 m_wsfilter, initSize, m_buildIdIndex); 1814 _dtmManager.addDTM(rtf, dtmPos, 0); 1815 return rtf; 1816 1817 } 1818 else { 1819 return new AdaptiveResultTreeImpl(_dtmManager, 0, 1820 m_wsfilter, initSize, m_buildIdIndex); 1821 } 1822 } 1823 else { 1824 return (DOM) _dtmManager.getDTM(null, true, m_wsfilter, 1825 true, false, false, 1826 initSize, m_buildIdIndex); 1827 } 1828 } 1829 1830 1833 public Hashtable getElementsWithIDs() { 1834 if (m_idAttributes == null) { 1835 return null; 1836 } 1837 1838 Enumeration idValues = m_idAttributes.keys(); 1840 if (!idValues.hasMoreElements()) { 1841 return null; 1842 } 1843 1844 Hashtable idAttrsTable = new Hashtable(); 1845 1846 while (idValues.hasMoreElements()) { 1847 Object idValue = idValues.nextElement(); 1848 1849 idAttrsTable.put(idValue, m_idAttributes.get(idValue)); 1850 } 1851 1852 return idAttrsTable; 1853 } 1854 1855 1861 public String getUnparsedEntityURI(String name) 1862 { 1863 if (_document != null) { 1865 String uri = ""; 1866 DocumentType doctype = _document.getDoctype(); 1867 if (doctype != null) { 1868 NamedNodeMap entities = doctype.getEntities(); 1869 1870 if (entities == null) { 1871 return uri; 1872 } 1873 1874 Entity entity = (Entity ) entities.getNamedItem(name); 1875 1876 if (entity == null) { 1877 return uri; 1878 } 1879 1880 String notationName = entity.getNotationName(); 1881 if (notationName != null) { 1882 uri = entity.getSystemId(); 1883 if (uri == null) { 1884 uri = entity.getPublicId(); 1885 } 1886 } 1887 } 1888 return uri; 1889 } 1890 else { 1891 return super.getUnparsedEntityURI(name); 1892 } 1893 } 1894 1895} 1896 | Popular Tags |