1 16 19 package org.apache.xml.dtm.ref.sax2dtm; 20 21 import java.util.Hashtable ; 22 import java.util.Vector ; 23 import javax.xml.transform.Source ; 24 import javax.xml.transform.SourceLocator ; 25 26 import org.apache.xml.dtm.*; 27 import org.apache.xml.dtm.ref.*; 28 import org.apache.xml.utils.StringVector; 29 import org.apache.xml.utils.IntVector; 30 import org.apache.xml.utils.FastStringBuffer; 31 import org.apache.xml.utils.IntStack; 32 import org.apache.xml.utils.SuballocatedIntVector; 33 import org.apache.xml.utils.SystemIDResolver; 34 import org.apache.xml.utils.WrappedRuntimeException; 35 import org.apache.xml.utils.XMLString; 36 import org.apache.xml.utils.XMLStringFactory; 37 import org.apache.xml.res.XMLErrorResources; 38 import org.apache.xml.res.XMLMessages; 39 import org.xml.sax.*; 40 import org.xml.sax.ext.*; 41 42 46 public class SAX2DTM extends DTMDefaultBaseIterators 47 implements EntityResolver, DTDHandler, ContentHandler, ErrorHandler, 48 DeclHandler, LexicalHandler 49 { 50 51 private static final boolean DEBUG = false; 52 53 65 private IncrementalSAXSource m_incrementalSAXSource = null; 66 67 80 protected FastStringBuffer m_chars; 82 83 85 protected SuballocatedIntVector m_data; 86 87 90 transient protected IntStack m_parents; 91 92 95 transient protected int m_previous = 0; 96 97 100 transient protected java.util.Vector m_prefixMappings = 101 new java.util.Vector (); 102 103 106 transient protected IntStack m_contextIndexes; 107 108 109 transient protected int m_textType = DTM.TEXT_NODE; 110 111 115 transient protected int m_coalescedTextType = DTM.TEXT_NODE; 116 117 118 transient protected Locator m_locator = null; 119 120 121 transient private String m_systemId = null; 122 123 124 transient protected boolean m_insideDTD = false; 125 126 127 protected DTMTreeWalker m_walker = new DTMTreeWalker(); 128 129 130 protected DTMStringPool m_valuesOrPrefixes; 131 132 135 protected boolean m_endDocumentOccured = false; 136 137 138 protected SuballocatedIntVector m_dataOrQName; 139 140 144 protected Hashtable m_idAttributes = new Hashtable (); 145 146 149 static final String [] m_fixednames = { null, null, null, "#text", "#cdata_section", null, null, null, "#comment", "#document", null, "#document-fragment", null }; 157 161 private Vector m_entities = null; 162 163 164 private static final int ENTITY_FIELD_PUBLICID = 0; 165 166 167 private static final int ENTITY_FIELD_SYSTEMID = 1; 168 169 170 private static final int ENTITY_FIELD_NOTATIONNAME = 2; 171 172 173 private static final int ENTITY_FIELD_NAME = 3; 174 175 176 private static final int ENTITY_FIELDS_PER = 4; 177 178 183 protected int m_textPendingStart = -1; 184 185 191 protected boolean m_useSourceLocationProperty = false; 192 193 197 protected static boolean m_source_location = false; 198 199 201 protected StringVector m_sourceSystemId; 202 204 protected IntVector m_sourceLine; 205 207 protected IntVector m_sourceColumn; 208 209 221 public SAX2DTM(DTMManager mgr, Source source, int dtmIdentity, 222 DTMWSFilter whiteSpaceFilter, 223 XMLStringFactory xstringfactory, 224 boolean doIndexing) 225 { 226 227 this(mgr, source, dtmIdentity, whiteSpaceFilter, 228 xstringfactory, doIndexing, DEFAULT_BLOCKSIZE, true, false); 229 } 230 231 247 public SAX2DTM(DTMManager mgr, Source source, int dtmIdentity, 248 DTMWSFilter whiteSpaceFilter, 249 XMLStringFactory xstringfactory, 250 boolean doIndexing, 251 int blocksize, 252 boolean usePrevsib, 253 boolean newNameTable) 254 { 255 256 super(mgr, source, dtmIdentity, whiteSpaceFilter, 257 xstringfactory, doIndexing, blocksize, usePrevsib, newNameTable); 258 259 if (blocksize <= 64) 262 { 263 m_data = new SuballocatedIntVector(blocksize, DEFAULT_NUMBLOCKS_SMALL); 264 m_dataOrQName = new SuballocatedIntVector(blocksize, DEFAULT_NUMBLOCKS_SMALL); 265 m_valuesOrPrefixes = new DTMStringPool(16); 266 m_chars = new FastStringBuffer(7, 10); 267 m_contextIndexes = new IntStack(4); 268 m_parents = new IntStack(4); 269 } 270 else 271 { 272 m_data = new SuballocatedIntVector(blocksize, DEFAULT_NUMBLOCKS); 273 m_dataOrQName = new SuballocatedIntVector(blocksize, DEFAULT_NUMBLOCKS); 274 m_valuesOrPrefixes = new DTMStringPool(); 275 m_chars = new FastStringBuffer(10, 13); 276 m_contextIndexes = new IntStack(); 277 m_parents = new IntStack(); 278 } 279 280 285 m_data.addElement(0); 287 289 m_useSourceLocationProperty = m_source_location; 291 m_sourceSystemId = (m_useSourceLocationProperty) ? new StringVector() : null; 292 m_sourceLine = (m_useSourceLocationProperty) ? new IntVector() : null; 293 m_sourceColumn = (m_useSourceLocationProperty) ? new IntVector() : null; 294 } 295 296 300 public static void setUseSourceLocation(boolean useSourceLocation) 301 { 302 m_source_location = useSourceLocation; 303 } 304 305 312 protected int _dataOrQName(int identity) 313 { 314 315 if (identity < m_size) 316 return m_dataOrQName.elementAt(identity); 317 318 while (true) 322 { 323 boolean isMore = nextNode(); 324 325 if (!isMore) 326 return NULL; 327 else if (identity < m_size) 328 return m_dataOrQName.elementAt(identity); 329 } 330 } 331 332 335 public void clearCoRoutine() 336 { 337 clearCoRoutine(true); 338 } 339 340 347 public void clearCoRoutine(boolean callDoTerminate) 348 { 349 350 if (null != m_incrementalSAXSource) 351 { 352 if (callDoTerminate) 353 m_incrementalSAXSource.deliverMoreNodes(false); 354 355 m_incrementalSAXSource = null; 356 } 357 } 358 359 372 public void setIncrementalSAXSource(IncrementalSAXSource incrementalSAXSource) 373 { 374 375 m_incrementalSAXSource = incrementalSAXSource; 383 384 incrementalSAXSource.setContentHandler(this); 386 incrementalSAXSource.setLexicalHandler(this); 387 incrementalSAXSource.setDTDHandler(this); 388 389 } 394 395 407 public ContentHandler getContentHandler() 408 { 409 410 if (m_incrementalSAXSource instanceof IncrementalSAXSource_Filter) 411 return (ContentHandler) m_incrementalSAXSource; 412 else 413 return this; 414 } 415 416 426 public LexicalHandler getLexicalHandler() 427 { 428 429 if (m_incrementalSAXSource instanceof IncrementalSAXSource_Filter) 430 return (LexicalHandler) m_incrementalSAXSource; 431 else 432 return this; 433 } 434 435 440 public EntityResolver getEntityResolver() 441 { 442 return this; 443 } 444 445 450 public DTDHandler getDTDHandler() 451 { 452 return this; 453 } 454 455 460 public ErrorHandler getErrorHandler() 461 { 462 return this; 463 } 464 465 470 public DeclHandler getDeclHandler() 471 { 472 return this; 473 } 474 475 481 public boolean needsTwoThreads() 482 { 483 return null != m_incrementalSAXSource; 484 } 485 486 503 public void dispatchCharactersEvents(int nodeHandle, ContentHandler ch, 504 boolean normalize) 505 throws SAXException 506 { 507 508 int identity = makeNodeIdentity(nodeHandle); 509 510 if (identity == DTM.NULL) 511 return; 512 513 int type = _type(identity); 514 515 if (isTextType(type)) 516 { 517 int dataIndex = m_dataOrQName.elementAt(identity); 518 int offset = m_data.elementAt(dataIndex); 519 int length = m_data.elementAt(dataIndex + 1); 520 521 if(normalize) 522 m_chars.sendNormalizedSAXcharacters(ch, offset, length); 523 else 524 m_chars.sendSAXcharacters(ch, offset, length); 525 } 526 else 527 { 528 int firstChild = _firstch(identity); 529 530 if (DTM.NULL != firstChild) 531 { 532 int offset = -1; 533 int length = 0; 534 int startNode = identity; 535 536 identity = firstChild; 537 538 do { 539 type = _type(identity); 540 541 if (isTextType(type)) 542 { 543 int dataIndex = _dataOrQName(identity); 544 545 if (-1 == offset) 546 { 547 offset = m_data.elementAt(dataIndex); 548 } 549 550 length += m_data.elementAt(dataIndex + 1); 551 } 552 553 identity = getNextNodeIdentity(identity); 554 } while (DTM.NULL != identity && (_parent(identity) >= startNode)); 555 556 if (length > 0) 557 { 558 if(normalize) 559 m_chars.sendNormalizedSAXcharacters(ch, offset, length); 560 else 561 m_chars.sendSAXcharacters(ch, offset, length); 562 } 563 } 564 else if(type != DTM.ELEMENT_NODE) 565 { 566 int dataIndex = _dataOrQName(identity); 567 568 if (dataIndex < 0) 569 { 570 dataIndex = -dataIndex; 571 dataIndex = m_data.elementAt(dataIndex + 1); 572 } 573 574 String str = m_valuesOrPrefixes.indexToString(dataIndex); 575 576 if(normalize) 577 FastStringBuffer.sendNormalizedSAXcharacters(str.toCharArray(), 578 0, str.length(), ch); 579 else 580 ch.characters(str.toCharArray(), 0, str.length()); 581 } 582 } 583 } 584 585 586 595 public String getNodeName(int nodeHandle) 596 { 597 598 int expandedTypeID = getExpandedTypeID(nodeHandle); 599 int namespaceID = m_expandedNameTable.getNamespaceID(expandedTypeID); 601 602 if (0 == namespaceID) 603 { 604 int type = getNodeType(nodeHandle); 607 608 if (type == DTM.NAMESPACE_NODE) 609 { 610 if (null == m_expandedNameTable.getLocalName(expandedTypeID)) 611 return "xmlns"; 612 else 613 return "xmlns:" + m_expandedNameTable.getLocalName(expandedTypeID); 614 } 615 else if (0 == m_expandedNameTable.getLocalNameID(expandedTypeID)) 616 { 617 return m_fixednames[type]; 618 } 619 else 620 return m_expandedNameTable.getLocalName(expandedTypeID); 621 } 622 else 623 { 624 int qnameIndex = m_dataOrQName.elementAt(makeNodeIdentity(nodeHandle)); 625 626 if (qnameIndex < 0) 627 { 628 qnameIndex = -qnameIndex; 629 qnameIndex = m_data.elementAt(qnameIndex); 630 } 631 632 return m_valuesOrPrefixes.indexToString(qnameIndex); 633 } 634 } 635 636 644 public String getNodeNameX(int nodeHandle) 645 { 646 647 int expandedTypeID = getExpandedTypeID(nodeHandle); 648 int namespaceID = m_expandedNameTable.getNamespaceID(expandedTypeID); 649 650 if (0 == namespaceID) 651 { 652 String name = m_expandedNameTable.getLocalName(expandedTypeID); 653 654 if (name == null) 655 return ""; 656 else 657 return name; 658 } 659 else 660 { 661 int qnameIndex = m_dataOrQName.elementAt(makeNodeIdentity(nodeHandle)); 662 663 if (qnameIndex < 0) 664 { 665 qnameIndex = -qnameIndex; 666 qnameIndex = m_data.elementAt(qnameIndex); 667 } 668 669 return m_valuesOrPrefixes.indexToString(qnameIndex); 670 } 671 } 672 673 684 public boolean isAttributeSpecified(int attributeHandle) 685 { 686 687 return true; } 690 691 699 public String getDocumentTypeDeclarationSystemIdentifier() 700 { 701 702 703 error(XMLMessages.createXMLMessage(XMLErrorResources.ER_METHOD_NOT_SUPPORTED, null)); 705 return null; 706 } 707 708 715 protected int getNextNodeIdentity(int identity) 716 { 717 718 identity += 1; 719 720 while (identity >= m_size) 721 { 722 if (null == m_incrementalSAXSource) 723 return DTM.NULL; 724 725 nextNode(); 726 } 727 728 return identity; 729 } 730 731 739 public void dispatchToEvents(int nodeHandle, org.xml.sax.ContentHandler ch) 740 throws org.xml.sax.SAXException 741 { 742 743 DTMTreeWalker treeWalker = m_walker; 744 ContentHandler prevCH = treeWalker.getcontentHandler(); 745 746 if (null != prevCH) 747 { 748 treeWalker = new DTMTreeWalker(); 749 } 750 751 treeWalker.setcontentHandler(ch); 752 treeWalker.setDTM(this); 753 754 try 755 { 756 treeWalker.traverse(nodeHandle); 757 } 758 finally 759 { 760 treeWalker.setcontentHandler(null); 761 } 762 } 763 764 769 public int getNumberOfNodes() 770 { 771 return m_size; 772 } 773 774 780 protected boolean nextNode() 781 { 782 783 if (null == m_incrementalSAXSource) 784 return false; 785 786 if (m_endDocumentOccured) 787 { 788 clearCoRoutine(); 789 790 return false; 791 } 792 793 Object gotMore = m_incrementalSAXSource.deliverMoreNodes(true); 794 795 if (!(gotMore instanceof Boolean )) 803 { 804 if(gotMore instanceof RuntimeException ) 805 { 806 throw (RuntimeException )gotMore; 807 } 808 else if(gotMore instanceof Exception ) 809 { 810 throw new WrappedRuntimeException((Exception )gotMore); 811 } 812 clearCoRoutine(); 814 815 return false; 816 817 } 819 820 if (gotMore != Boolean.TRUE) 821 { 822 823 clearCoRoutine(); 826 } 828 829 return true; 830 } 831 832 839 private final boolean isTextType(int type) 840 { 841 return (DTM.TEXT_NODE == type || DTM.CDATA_SECTION_NODE == type); 842 } 843 844 860 873 protected int addNode(int type, int expandedTypeID, 874 int parentIndex, int previousSibling, 875 int dataOrPrefix, boolean canHaveFirstChild) 876 { 877 int nodeIndex = m_size++; 879 880 if(m_dtmIdent.size() == (nodeIndex>>>DTMManager.IDENT_DTM_NODE_BITS)) 882 { 883 addNewDTMID(nodeIndex); 884 } 885 886 m_firstch.addElement(canHaveFirstChild ? NOTPROCESSED : DTM.NULL); 887 m_nextsib.addElement(NOTPROCESSED); 888 m_parent.addElement(parentIndex); 889 m_exptype.addElement(expandedTypeID); 890 m_dataOrQName.addElement(dataOrPrefix); 891 892 if (m_prevsib != null) { 893 m_prevsib.addElement(previousSibling); 894 } 895 896 if (DTM.NULL != previousSibling) { 897 m_nextsib.setElementAt(nodeIndex,previousSibling); 898 } 899 900 if (m_locator != null && m_useSourceLocationProperty) { 901 setSourceLocation(); 902 } 903 904 907 switch(type) 909 { 910 case DTM.NAMESPACE_NODE: 911 declareNamespaceInContext(parentIndex,nodeIndex); 912 break; 913 case DTM.ATTRIBUTE_NODE: 914 break; 915 default: 916 if (DTM.NULL == previousSibling && DTM.NULL != parentIndex) { 917 m_firstch.setElementAt(nodeIndex,parentIndex); 918 } 919 break; 920 } 921 922 return nodeIndex; 923 } 924 925 930 protected void addNewDTMID(int nodeIndex) { 931 try 932 { 933 if(m_mgr==null) 934 throw new ClassCastException (); 935 936 DTMManagerDefault mgrD=(DTMManagerDefault)m_mgr; 938 int id=mgrD.getFirstFreeDTMID(); 939 mgrD.addDTM(this,id,nodeIndex); 940 m_dtmIdent.addElement(id<<DTMManager.IDENT_DTM_NODE_BITS); 941 } 942 catch(ClassCastException e) 943 { 944 error(XMLMessages.createXMLMessage(XMLErrorResources.ER_NO_DTMIDS_AVAIL, null)); } 949 } 950 951 958 public void migrateTo(DTMManager manager) { 959 super.migrateTo(manager); 960 961 int numDTMs = m_dtmIdent.size(); 964 int dtmId = m_mgrDefault.getFirstFreeDTMID(); 965 int nodeIndex = 0; 966 for (int i = 0; i < numDTMs; i++) 967 { 968 m_dtmIdent.setElementAt(dtmId << DTMManager.IDENT_DTM_NODE_BITS, i); 969 m_mgrDefault.addDTM(this, dtmId, nodeIndex); 970 dtmId++; 971 nodeIndex += (1 << DTMManager.IDENT_DTM_NODE_BITS); 972 } 973 } 974 975 979 protected void setSourceLocation() { 980 m_sourceSystemId.addElement(m_locator.getSystemId()); 981 m_sourceLine.addElement(m_locator.getLineNumber()); 982 m_sourceColumn.addElement(m_locator.getColumnNumber()); 983 984 if (m_sourceSystemId.size() != m_size) { 988 System.err.println("CODING ERROR in Source Location: " + m_size 989 + " != " 990 + m_sourceSystemId.size()); 991 System.exit(1); 992 } 993 } 994 995 1004 public String getNodeValue(int nodeHandle) 1005 { 1006 1007 int identity = makeNodeIdentity(nodeHandle); 1008 int type = _type(identity); 1009 1010 if (isTextType(type)) 1011 { 1012 int dataIndex = _dataOrQName(identity); 1013 int offset = m_data.elementAt(dataIndex); 1014 int length = m_data.elementAt(dataIndex + 1); 1015 1016 return m_chars.getString(offset, length); 1018 } 1019 else if (DTM.ELEMENT_NODE == type || DTM.DOCUMENT_FRAGMENT_NODE == type 1020 || DTM.DOCUMENT_NODE == type) 1021 { 1022 return null; 1023 } 1024 else 1025 { 1026 int dataIndex = _dataOrQName(identity); 1027 1028 if (dataIndex < 0) 1029 { 1030 dataIndex = -dataIndex; 1031 dataIndex = m_data.elementAt(dataIndex + 1); 1032 } 1033 1034 return m_valuesOrPrefixes.indexToString(dataIndex); 1035 } 1036 } 1037 1038 1046 public String getLocalName(int nodeHandle) 1047 { 1048 return m_expandedNameTable.getLocalName(_exptype(makeNodeIdentity(nodeHandle))); 1049 } 1050 1051 1085 public String getUnparsedEntityURI(String name) 1086 { 1087 1088 String url = ""; 1089 1090 if (null == m_entities) 1091 return url; 1092 1093 int n = m_entities.size(); 1094 1095 for (int i = 0; i < n; i += ENTITY_FIELDS_PER) 1096 { 1097 String ename = (String ) m_entities.elementAt(i + ENTITY_FIELD_NAME); 1098 1099 if (null != ename && ename.equals(name)) 1100 { 1101 String nname = (String ) m_entities.elementAt(i 1102 + ENTITY_FIELD_NOTATIONNAME); 1103 1104 if (null != nname) 1105 { 1106 1107 url = (String ) m_entities.elementAt(i + ENTITY_FIELD_SYSTEMID); 1117 1118 if (null == url) 1119 { 1120 url = (String ) m_entities.elementAt(i + ENTITY_FIELD_PUBLICID); 1121 } 1122 } 1123 1124 break; 1125 } 1126 } 1127 1128 return url; 1129 } 1130 1131 1143 public String getPrefix(int nodeHandle) 1144 { 1145 1146 int identity = makeNodeIdentity(nodeHandle); 1147 int type = _type(identity); 1148 1149 if (DTM.ELEMENT_NODE == type) 1150 { 1151 int prefixIndex = _dataOrQName(identity); 1152 1153 if (0 == prefixIndex) 1154 return ""; 1155 else 1156 { 1157 String qname = m_valuesOrPrefixes.indexToString(prefixIndex); 1158 1159 return getPrefix(qname, null); 1160 } 1161 } 1162 else if (DTM.ATTRIBUTE_NODE == type) 1163 { 1164 int prefixIndex = _dataOrQName(identity); 1165 1166 if (prefixIndex < 0) 1167 { 1168 prefixIndex = m_data.elementAt(-prefixIndex); 1169 1170 String qname = m_valuesOrPrefixes.indexToString(prefixIndex); 1171 1172 return getPrefix(qname, null); 1173 } 1174 } 1175 1176 return ""; 1177 } 1178 1179 1191 public int getAttributeNode(int nodeHandle, String namespaceURI, 1192 String name) 1193 { 1194 1195 for (int attrH = getFirstAttribute(nodeHandle); DTM.NULL != attrH; 1196 attrH = getNextAttribute(attrH)) 1197 { 1198 String attrNS = getNamespaceURI(attrH); 1199 String attrName = getLocalName(attrH); 1200 boolean nsMatch = namespaceURI == attrNS 1201 || (namespaceURI != null 1202 && namespaceURI.equals(attrNS)); 1203 1204 if (nsMatch && name.equals(attrName)) 1205 return attrH; 1206 } 1207 1208 return DTM.NULL; 1209 } 1210 1211 1221 public String getDocumentTypeDeclarationPublicIdentifier() 1222 { 1223 1224 1225 error(XMLMessages.createXMLMessage(XMLErrorResources.ER_METHOD_NOT_SUPPORTED, null)); 1227 return null; 1228 } 1229 1230 1241 public String getNamespaceURI(int nodeHandle) 1242 { 1243 1244 return m_expandedNameTable.getNamespace(_exptype(makeNodeIdentity(nodeHandle))); 1245 } 1246 1247 1256 public XMLString getStringValue(int nodeHandle) 1257 { 1258 int identity = makeNodeIdentity(nodeHandle); 1259 int type; 1260 if(identity==DTM.NULL) type = DTM.NULL; 1262 else 1263 type= _type(identity); 1264 1265 if (isTextType(type)) 1266 { 1267 int dataIndex = _dataOrQName(identity); 1268 int offset = m_data.elementAt(dataIndex); 1269 int length = m_data.elementAt(dataIndex + 1); 1270 1271 return m_xstrf.newstr(m_chars, offset, length); 1272 } 1273 else 1274 { 1275 int firstChild = _firstch(identity); 1276 1277 if (DTM.NULL != firstChild) 1278 { 1279 int offset = -1; 1280 int length = 0; 1281 int startNode = identity; 1282 1283 identity = firstChild; 1284 1285 do { 1286 type = _type(identity); 1287 1288 if (isTextType(type)) 1289 { 1290 int dataIndex = _dataOrQName(identity); 1291 1292 if (-1 == offset) 1293 { 1294 offset = m_data.elementAt(dataIndex); 1295 } 1296 1297 length += m_data.elementAt(dataIndex + 1); 1298 } 1299 1300 identity = getNextNodeIdentity(identity); 1301 } while (DTM.NULL != identity && (_parent(identity) >= startNode)); 1302 1303 if (length > 0) 1304 { 1305 return m_xstrf.newstr(m_chars, offset, length); 1306 } 1307 } 1308 else if(type != DTM.ELEMENT_NODE) 1309 { 1310 int dataIndex = _dataOrQName(identity); 1311 1312 if (dataIndex < 0) 1313 { 1314 dataIndex = -dataIndex; 1315 dataIndex = m_data.elementAt(dataIndex + 1); 1316 } 1317 return m_xstrf.newstr(m_valuesOrPrefixes.indexToString(dataIndex)); 1318 } 1319 } 1320 1321 return m_xstrf.emptystr(); 1322 } 1323 1324 1331 public boolean isWhitespace(int nodeHandle) 1332 { 1333 int identity = makeNodeIdentity(nodeHandle); 1334 int type; 1335 if(identity==DTM.NULL) type = DTM.NULL; 1337 else 1338 type= _type(identity); 1339 1340 if (isTextType(type)) 1341 { 1342 int dataIndex = _dataOrQName(identity); 1343 int offset = m_data.elementAt(dataIndex); 1344 int length = m_data.elementAt(dataIndex + 1); 1345 1346 return m_chars.isWhitespace(offset, length); 1347 } 1348 return false; 1349 } 1350 1351 1368 public int getElementById(String elementId) 1369 { 1370 1371 Integer intObj; 1372 boolean isMore = true; 1373 1374 do 1375 { 1376 intObj = (Integer ) m_idAttributes.get(elementId); 1377 1378 if (null != intObj) 1379 return makeNodeHandle(intObj.intValue()); 1380 1381 if (!isMore || m_endDocumentOccured) 1382 break; 1383 1384 isMore = nextNode(); 1385 } 1386 while (null == intObj); 1387 1388 return DTM.NULL; 1389 } 1390 1391 1400 public String getPrefix(String qname, String uri) 1401 { 1402 1403 String prefix; 1404 int uriIndex = -1; 1405 1406 if (null != uri && uri.length() > 0) 1407 { 1408 1409 do 1410 { 1411 uriIndex = m_prefixMappings.indexOf(uri, ++uriIndex); 1412 } while ( (uriIndex & 0x01) == 0); 1413 1414 if (uriIndex >= 0) 1415 { 1416 prefix = (String ) m_prefixMappings.elementAt(uriIndex - 1); 1417 } 1418 else if (null != qname) 1419 { 1420 int indexOfNSSep = qname.indexOf(':'); 1421 1422 if (qname.equals("xmlns")) 1423 prefix = ""; 1424 else if (qname.startsWith("xmlns:")) 1425 prefix = qname.substring(indexOfNSSep + 1); 1426 else 1427 prefix = (indexOfNSSep > 0) 1428 ? qname.substring(0, indexOfNSSep) : null; 1429 } 1430 else 1431 { 1432 prefix = null; 1433 } 1434 } 1435 else if (null != qname) 1436 { 1437 int indexOfNSSep = qname.indexOf(':'); 1438 1439 if (indexOfNSSep > 0) 1440 { 1441 if (qname.startsWith("xmlns:")) 1442 prefix = qname.substring(indexOfNSSep + 1); 1443 else 1444 prefix = qname.substring(0, indexOfNSSep); 1445 } 1446 else 1447 { 1448 if (qname.equals("xmlns")) 1449 prefix = ""; 1450 else 1451 prefix = null; 1452 } 1453 } 1454 else 1455 { 1456 prefix = null; 1457 } 1458 1459 return prefix; 1460 } 1461 1462 1470 public int getIdForNamespace(String uri) 1471 { 1472 1473 return m_valuesOrPrefixes.stringToIndex(uri); 1474 1475 } 1476 1477 1486 public String getNamespaceURI(String prefix) 1487 { 1488 1489 String uri = ""; 1490 int prefixIndex = m_contextIndexes.peek() - 1 ; 1491 1492 if(null == prefix) 1493 prefix = ""; 1494 1495 do 1496 { 1497 prefixIndex = m_prefixMappings.indexOf(prefix, ++prefixIndex); 1498 } while ( (prefixIndex >= 0) && (prefixIndex & 0x01) == 0x01); 1499 1500 if (prefixIndex > -1) 1501 { 1502 uri = (String ) m_prefixMappings.elementAt(prefixIndex + 1); 1503 } 1504 1505 1506 return uri; 1507 } 1508 1509 1515 public void setIDAttribute(String id, int elem) 1516 { 1517 m_idAttributes.put(id, new Integer (elem)); 1518 } 1519 1520 1524 protected void charactersFlush() 1525 { 1526 1527 if (m_textPendingStart >= 0) { 1529 int length = m_chars.size() - m_textPendingStart; 1530 boolean doStrip = false; 1531 1532 if (getShouldStripWhitespace()) 1533 { 1534 doStrip = m_chars.isWhitespace(m_textPendingStart, length); 1535 } 1536 1537 if (doStrip) 1538 m_chars.setLength(m_textPendingStart); else 1540 { 1541 int exName = m_expandedNameTable.getExpandedTypeID(DTM.TEXT_NODE); 1542 int dataIndex = m_data.size(); 1543 1544 m_previous = addNode(m_coalescedTextType, exName, 1545 m_parents.peek(), m_previous, dataIndex, false); 1546 1547 m_data.addElement(m_textPendingStart); 1548 m_data.addElement(length); 1549 } 1550 1551 m_textPendingStart = -1; 1553 m_textType = m_coalescedTextType = DTM.TEXT_NODE; 1554 } 1555 } 1556 1557 1561 1582 public InputSource resolveEntity(String publicId, String systemId) 1583 throws SAXException 1584 { 1585 return null; 1586 } 1587 1588 1592 1609 public void notationDecl(String name, String publicId, String systemId) 1610 throws SAXException 1611 { 1612 1613 } 1615 1616 1634 public void unparsedEntityDecl( 1635 String name, String publicId, String systemId, String notationName) 1636 throws SAXException 1637 { 1638 1639 if (null == m_entities) 1640 { 1641 m_entities = new Vector (); 1642 } 1643 1644 try 1645 { 1646 systemId = SystemIDResolver.getAbsoluteURI(systemId, 1647 getDocumentBaseURI()); 1648 } 1649 catch (Exception e) 1650 { 1651 throw new org.xml.sax.SAXException (e); 1652 } 1653 1654 m_entities.addElement(publicId); 1656 1657 m_entities.addElement(systemId); 1659 1660 m_entities.addElement(notationName); 1662 1663 m_entities.addElement(name); 1665 } 1666 1667 1671 1682 public void setDocumentLocator(Locator locator) 1683 { 1684 m_locator = locator; 1685 m_systemId = locator.getSystemId(); 1686 } 1687 1688 1695 public void startDocument() throws SAXException 1696 { 1697 if (DEBUG) 1698 System.out.println("startDocument"); 1699 1700 1701 int doc = addNode(DTM.DOCUMENT_NODE, 1702 m_expandedNameTable.getExpandedTypeID(DTM.DOCUMENT_NODE), 1703 DTM.NULL, DTM.NULL, 0, true); 1704 1705 m_parents.push(doc); 1706 m_previous = DTM.NULL; 1707 1708 m_contextIndexes.push(m_prefixMappings.size()); } 1710 1711 1718 public void endDocument() throws SAXException 1719 { 1720 if (DEBUG) 1721 System.out.println("endDocument"); 1722 1723 charactersFlush(); 1724 1725 m_nextsib.setElementAt(NULL,0); 1726 1727 if (m_firstch.elementAt(0) == NOTPROCESSED) 1728 m_firstch.setElementAt(NULL,0); 1729 1730 if (DTM.NULL != m_previous) 1731 m_nextsib.setElementAt(DTM.NULL,m_previous); 1732 1733 m_parents = null; 1734 m_prefixMappings = null; 1735 m_contextIndexes = null; 1736 1737 m_endDocumentOccured = true; 1738 1739 m_locator = null; 1741 } 1742 1743 1756 public void startPrefixMapping(String prefix, String uri) 1757 throws SAXException 1758 { 1759 1760 if (DEBUG) 1761 System.out.println("startPrefixMapping: prefix: " + prefix + ", uri: " 1762 + uri); 1763 1764 if(null == prefix) 1765 prefix = ""; 1766 m_prefixMappings.addElement(prefix); m_prefixMappings.addElement(uri); } 1769 1770 1782 public void endPrefixMapping(String prefix) throws SAXException 1783 { 1784 if (DEBUG) 1785 System.out.println("endPrefixMapping: prefix: " + prefix); 1786 1787 if(null == prefix) 1788 prefix = ""; 1789 1790 int index = m_contextIndexes.peek() - 1; 1791 1792 do 1793 { 1794 index = m_prefixMappings.indexOf(prefix, ++index); 1795 } while ( (index >= 0) && ((index & 0x01) == 0x01) ); 1796 1797 1798 if (index > -1) 1799 { 1800 m_prefixMappings.setElementAt("%@$#^@#", index); 1801 m_prefixMappings.setElementAt("%@$#^@#", index + 1); 1802 } 1803 1804 } 1806 1807 1815 protected boolean declAlreadyDeclared(String prefix) 1816 { 1817 1818 int startDecls = m_contextIndexes.peek(); 1819 java.util.Vector prefixMappings = m_prefixMappings; 1820 int nDecls = prefixMappings.size(); 1821 1822 for (int i = startDecls; i < nDecls; i += 2) 1823 { 1824 String prefixDecl = (String ) prefixMappings.elementAt(i); 1825 1826 if (prefixDecl == null) 1827 continue; 1828 1829 if (prefixDecl.equals(prefix)) 1830 return true; 1831 } 1832 1833 return false; 1834 } 1835 1836 boolean m_pastFirstElement=false; 1837 1838 1861 public void startElement( 1862 String uri, String localName, String qName, Attributes attributes) 1863 throws SAXException 1864 { 1865 if (DEBUG) 1866 { 1867 System.out.println("startElement: uri: " + uri + ", localname: " 1868 + localName + ", qname: "+qName+", atts: " + attributes); 1869 1870 boolean DEBUG_ATTRS=true; 1871 if(DEBUG_ATTRS & attributes!=null) 1872 { 1873 int n = attributes.getLength(); 1874 if(n==0) 1875 System.out.println("\tempty attribute list"); 1876 else for (int i = 0; i < n; i++) 1877 System.out.println("\t attr: uri: " + attributes.getURI(i) + 1878 ", localname: " + attributes.getLocalName(i) + 1879 ", qname: " + attributes.getQName(i) + 1880 ", type: " + attributes.getType(i) + 1881 ", value: " + attributes.getValue(i) 1882 ); 1883 } 1884 } 1885 1886 charactersFlush(); 1887 1888 int exName = m_expandedNameTable.getExpandedTypeID(uri, localName, DTM.ELEMENT_NODE); 1889 String prefix = getPrefix(qName, uri); 1890 int prefixIndex = (null != prefix) 1891 ? m_valuesOrPrefixes.stringToIndex(qName) : 0; 1892 1893 int elemNode = addNode(DTM.ELEMENT_NODE, exName, 1894 m_parents.peek(), m_previous, prefixIndex, true); 1895 1896 if(m_indexing) 1897 indexNode(exName, elemNode); 1898 1899 1900 m_parents.push(elemNode); 1901 1902 int startDecls = m_contextIndexes.peek(); 1903 int nDecls = m_prefixMappings.size(); 1904 int prev = DTM.NULL; 1905 1906 if(!m_pastFirstElement) 1907 { 1908 prefix="xml"; 1910 String declURL = "http://www.w3.org/XML/1998/namespace"; 1911 exName = m_expandedNameTable.getExpandedTypeID(null, prefix, DTM.NAMESPACE_NODE); 1912 int val = m_valuesOrPrefixes.stringToIndex(declURL); 1913 prev = addNode(DTM.NAMESPACE_NODE, exName, elemNode, 1914 prev, val, false); 1915 m_pastFirstElement=true; 1916 } 1917 1918 for (int i = startDecls; i < nDecls; i += 2) 1919 { 1920 prefix = (String ) m_prefixMappings.elementAt(i); 1921 1922 if (prefix == null) 1923 continue; 1924 1925 String declURL = (String ) m_prefixMappings.elementAt(i + 1); 1926 1927 exName = m_expandedNameTable.getExpandedTypeID(null, prefix, DTM.NAMESPACE_NODE); 1928 1929 int val = m_valuesOrPrefixes.stringToIndex(declURL); 1930 1931 prev = addNode(DTM.NAMESPACE_NODE, exName, elemNode, 1932 prev, val, false); 1933 } 1934 1935 int n = attributes.getLength(); 1936 1937 for (int i = 0; i < n; i++) 1938 { 1939 String attrUri = attributes.getURI(i); 1940 String attrQName = attributes.getQName(i); 1941 String valString = attributes.getValue(i); 1942 1943 prefix = getPrefix(attrQName, attrUri); 1944 1945 int nodeType; 1946 1947 String attrLocalName = attributes.getLocalName(i); 1948 1949 if ((null != attrQName) 1950 && (attrQName.equals("xmlns") 1951 || attrQName.startsWith("xmlns:"))) 1952 { 1953 if (declAlreadyDeclared(prefix)) 1954 continue; 1956 nodeType = DTM.NAMESPACE_NODE; 1957 } 1958 else 1959 { 1960 nodeType = DTM.ATTRIBUTE_NODE; 1961 1962 if (attributes.getType(i).equalsIgnoreCase("ID")) 1963 setIDAttribute(valString, elemNode); 1964 } 1965 1966 if(null == valString) 1969 valString = ""; 1970 1971 int val = m_valuesOrPrefixes.stringToIndex(valString); 1972 1974 if (null != prefix) 1975 { 1976 1977 prefixIndex = m_valuesOrPrefixes.stringToIndex(attrQName); 1978 1979 int dataIndex = m_data.size(); 1980 1981 m_data.addElement(prefixIndex); 1982 m_data.addElement(val); 1983 1984 val = -dataIndex; 1985 } 1986 1987 exName = m_expandedNameTable.getExpandedTypeID(attrUri, attrLocalName, nodeType); 1988 prev = addNode(nodeType, exName, elemNode, prev, val, 1989 false); 1990 } 1991 1992 if (DTM.NULL != prev) 1993 m_nextsib.setElementAt(DTM.NULL,prev); 1994 1995 if (null != m_wsfilter) 1996 { 1997 short wsv = m_wsfilter.getShouldStripSpace(makeNodeHandle(elemNode), this); 1998 boolean shouldStrip = (DTMWSFilter.INHERIT == wsv) 1999 ? getShouldStripWhitespace() 2000 : (DTMWSFilter.STRIP == wsv); 2001 2002 pushShouldStripWhitespace(shouldStrip); 2003 } 2004 2005 m_previous = DTM.NULL; 2006 2007 m_contextIndexes.push(m_prefixMappings.size()); } 2009 2010 2033 public void endElement(String uri, String localName, String qName) 2034 throws SAXException 2035 { 2036 if (DEBUG) 2037 System.out.println("endElement: uri: " + uri + ", localname: " 2038 + localName + ", qname: "+qName); 2039 2040 charactersFlush(); 2041 2042 m_contextIndexes.quickPop(1); 2045 2046 int topContextIndex = m_contextIndexes.peek(); 2048 if (topContextIndex != m_prefixMappings.size()) { 2049 m_prefixMappings.setSize(topContextIndex); 2050 } 2051 2052 int lastNode = m_previous; 2053 2054 m_previous = m_parents.pop(); 2055 2056 if (DTM.NULL == lastNode) 2058 m_firstch.setElementAt(DTM.NULL,m_previous); 2059 else 2060 m_nextsib.setElementAt(DTM.NULL,lastNode); 2061 2062 popShouldStripWhitespace(); 2063 } 2064 2065 2081 public void characters(char ch[], int start, int length) throws SAXException 2082 { 2083 if (m_textPendingStart == -1) { 2085 m_textPendingStart = m_chars.size(); 2086 m_coalescedTextType = m_textType; 2087 } 2088 else if (m_textType == DTM.TEXT_NODE) 2093 { 2094 m_coalescedTextType = DTM.TEXT_NODE; 2095 } 2096 2097 m_chars.append(ch, start, length); 2098 } 2099 2100 2116 public void ignorableWhitespace(char ch[], int start, int length) 2117 throws SAXException 2118 { 2119 2120 characters(ch, start, length); 2123 } 2124 2125 2140 public void processingInstruction(String target, String data) 2141 throws SAXException 2142 { 2143 if (DEBUG) 2144 System.out.println("processingInstruction: target: " + target +", data: "+data); 2145 2146 charactersFlush(); 2147 2148 int exName = m_expandedNameTable.getExpandedTypeID(null, target, 2149 DTM.PROCESSING_INSTRUCTION_NODE); 2150 int dataIndex = m_valuesOrPrefixes.stringToIndex(data); 2151 2152 m_previous = addNode(DTM.PROCESSING_INSTRUCTION_NODE, exName, 2153 m_parents.peek(), m_previous, 2154 dataIndex, false); 2155 } 2156 2157 2170 public void skippedEntity(String name) throws SAXException 2171 { 2172 2173 } 2176 2177 2181 2195 public void warning(SAXParseException e) throws SAXException 2196 { 2197 2198 System.err.println(e.getMessage()); 2200 } 2201 2202 2216 public void error(SAXParseException e) throws SAXException 2217 { 2218 throw e; 2219 } 2220 2221 2238 public void fatalError(SAXParseException e) throws SAXException 2239 { 2240 throw e; 2241 } 2242 2243 2247 2260 public void elementDecl(String name, String model) throws SAXException 2261 { 2262 2263 } 2265 2266 2285 public void attributeDecl( 2286 String eName, String aName, String type, String valueDefault, String value) 2287 throws SAXException 2288 { 2289 2290 } 2292 2293 2306 public void internalEntityDecl(String name, String value) 2307 throws SAXException 2308 { 2309 2310 } 2312 2313 2328 public void externalEntityDecl( 2329 String name, String publicId, String systemId) throws SAXException 2330 { 2331 2332 } 2334 2335 2339 2360 public void startDTD(String name, String publicId, String systemId) 2361 throws SAXException 2362 { 2363 2364 m_insideDTD = true; 2365 } 2366 2367 2373 public void endDTD() throws SAXException 2374 { 2375 2376 m_insideDTD = false; 2377 } 2378 2379 2401 public void startEntity(String name) throws SAXException 2402 { 2403 2404 } 2406 2407 2414 public void endEntity(String name) throws SAXException 2415 { 2416 2417 } 2419 2420 2430 public void startCDATA() throws SAXException 2431 { 2432 m_textType = DTM.CDATA_SECTION_NODE; 2433 } 2434 2435 2441 public void endCDATA() throws SAXException 2442 { 2443 m_textType = DTM.TEXT_NODE; 2444 } 2445 2446 2458 public void comment(char ch[], int start, int length) throws SAXException 2459 { 2460 2461 if (m_insideDTD) return; 2463 2464 charactersFlush(); 2465 2466 int exName = m_expandedNameTable.getExpandedTypeID(DTM.COMMENT_NODE); 2467 2468 int dataIndex = m_valuesOrPrefixes.stringToIndex(new String (ch, start, 2471 length)); 2472 2473 2474 m_previous = addNode(DTM.COMMENT_NODE, exName, 2475 m_parents.peek(), m_previous, dataIndex, false); 2476 } 2477 2478 2487 public void setProperty(String property, Object value) 2488 { 2489 } 2490 2491 2499 public SourceLocator getSourceLocatorFor(int node) 2500 { 2501 if (m_useSourceLocationProperty) 2502 { 2503 2504 node = makeNodeIdentity(node); 2505 2506 2507 return new NodeLocator(null, 2508 m_sourceSystemId.elementAt(node), 2509 m_sourceLine.elementAt(node), 2510 m_sourceColumn.elementAt(node)); 2511 } 2512 else if(m_locator!=null) 2513 { 2514 return new NodeLocator(null,m_locator.getSystemId(),-1,-1); 2515 } 2516 else if(m_systemId!=null) 2517 { 2518 return new NodeLocator(null,m_systemId,-1,-1); 2519 } 2520 return null; 2521 } 2522} 2523 | Popular Tags |