1 16 19 package com.sun.org.apache.xml.internal.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 com.sun.org.apache.xml.internal.dtm.*; 27 import com.sun.org.apache.xml.internal.dtm.ref.*; 28 import com.sun.org.apache.xml.internal.utils.StringVector; 29 import com.sun.org.apache.xml.internal.utils.IntVector; 30 import com.sun.org.apache.xml.internal.utils.FastStringBuffer; 31 import com.sun.org.apache.xml.internal.utils.IntStack; 32 import com.sun.org.apache.xml.internal.utils.SuballocatedIntVector; 33 import com.sun.org.apache.xml.internal.utils.SystemIDResolver; 34 import com.sun.org.apache.xml.internal.utils.WrappedRuntimeException; 35 import com.sun.org.apache.xml.internal.utils.XMLString; 36 import com.sun.org.apache.xml.internal.utils.XMLStringFactory; 37 import com.sun.org.apache.xml.internal.res.XMLErrorResources; 38 import com.sun.org.apache.xml.internal.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 410 public ContentHandler getContentHandler() 411 { 412 413 if (m_incrementalSAXSource.getClass().getName().equals("com.sun.org.apache.xml.internal.dtm.ref.IncrementalSAXSource_Filter")) 414 return (ContentHandler) m_incrementalSAXSource; 415 else 416 return this; 417 } 418 419 432 public LexicalHandler getLexicalHandler() 433 { 434 435 if (m_incrementalSAXSource.getClass().getName().equals("com.sun.org.apache.xml.internal.dtm.ref.IncrementalSAXSource_Filter")) 436 return (LexicalHandler) m_incrementalSAXSource; 437 else 438 return this; 439 } 440 441 446 public EntityResolver getEntityResolver() 447 { 448 return this; 449 } 450 451 456 public DTDHandler getDTDHandler() 457 { 458 return this; 459 } 460 461 466 public ErrorHandler getErrorHandler() 467 { 468 return this; 469 } 470 471 476 public DeclHandler getDeclHandler() 477 { 478 return this; 479 } 480 481 487 public boolean needsTwoThreads() 488 { 489 return null != m_incrementalSAXSource; 490 } 491 492 509 public void dispatchCharactersEvents(int nodeHandle, ContentHandler ch, 510 boolean normalize) 511 throws SAXException 512 { 513 514 int identity = makeNodeIdentity(nodeHandle); 515 516 if (identity == DTM.NULL) 517 return; 518 519 int type = _type(identity); 520 521 if (isTextType(type)) 522 { 523 int dataIndex = m_dataOrQName.elementAt(identity); 524 int offset = m_data.elementAt(dataIndex); 525 int length = m_data.elementAt(dataIndex + 1); 526 527 if(normalize) 528 m_chars.sendNormalizedSAXcharacters(ch, offset, length); 529 else 530 m_chars.sendSAXcharacters(ch, offset, length); 531 } 532 else 533 { 534 int firstChild = _firstch(identity); 535 536 if (DTM.NULL != firstChild) 537 { 538 int offset = -1; 539 int length = 0; 540 int startNode = identity; 541 542 identity = firstChild; 543 544 do { 545 type = _type(identity); 546 547 if (isTextType(type)) 548 { 549 int dataIndex = _dataOrQName(identity); 550 551 if (-1 == offset) 552 { 553 offset = m_data.elementAt(dataIndex); 554 } 555 556 length += m_data.elementAt(dataIndex + 1); 557 } 558 559 identity = getNextNodeIdentity(identity); 560 } while (DTM.NULL != identity && (_parent(identity) >= startNode)); 561 562 if (length > 0) 563 { 564 if(normalize) 565 m_chars.sendNormalizedSAXcharacters(ch, offset, length); 566 else 567 m_chars.sendSAXcharacters(ch, offset, length); 568 } 569 } 570 else if(type != DTM.ELEMENT_NODE) 571 { 572 int dataIndex = _dataOrQName(identity); 573 574 if (dataIndex < 0) 575 { 576 dataIndex = -dataIndex; 577 dataIndex = m_data.elementAt(dataIndex + 1); 578 } 579 580 String str = m_valuesOrPrefixes.indexToString(dataIndex); 581 582 if(normalize) 583 FastStringBuffer.sendNormalizedSAXcharacters(str.toCharArray(), 584 0, str.length(), ch); 585 else 586 ch.characters(str.toCharArray(), 0, str.length()); 587 } 588 } 589 } 590 591 592 601 public String getNodeName(int nodeHandle) 602 { 603 604 int expandedTypeID = getExpandedTypeID(nodeHandle); 605 int namespaceID = m_expandedNameTable.getNamespaceID(expandedTypeID); 607 608 if (0 == namespaceID) 609 { 610 int type = getNodeType(nodeHandle); 613 614 if (type == DTM.NAMESPACE_NODE) 615 { 616 if (null == m_expandedNameTable.getLocalName(expandedTypeID)) 617 return "xmlns"; 618 else 619 return "xmlns:" + m_expandedNameTable.getLocalName(expandedTypeID); 620 } 621 else if (0 == m_expandedNameTable.getLocalNameID(expandedTypeID)) 622 { 623 return m_fixednames[type]; 624 } 625 else 626 return m_expandedNameTable.getLocalName(expandedTypeID); 627 } 628 else 629 { 630 int qnameIndex = m_dataOrQName.elementAt(makeNodeIdentity(nodeHandle)); 631 632 if (qnameIndex < 0) 633 { 634 qnameIndex = -qnameIndex; 635 qnameIndex = m_data.elementAt(qnameIndex); 636 } 637 638 return m_valuesOrPrefixes.indexToString(qnameIndex); 639 } 640 } 641 642 650 public String getNodeNameX(int nodeHandle) 651 { 652 653 int expandedTypeID = getExpandedTypeID(nodeHandle); 654 int namespaceID = m_expandedNameTable.getNamespaceID(expandedTypeID); 655 656 if (0 == namespaceID) 657 { 658 String name = m_expandedNameTable.getLocalName(expandedTypeID); 659 660 if (name == null) 661 return ""; 662 else 663 return name; 664 } 665 else 666 { 667 int qnameIndex = m_dataOrQName.elementAt(makeNodeIdentity(nodeHandle)); 668 669 if (qnameIndex < 0) 670 { 671 qnameIndex = -qnameIndex; 672 qnameIndex = m_data.elementAt(qnameIndex); 673 } 674 675 return m_valuesOrPrefixes.indexToString(qnameIndex); 676 } 677 } 678 679 690 public boolean isAttributeSpecified(int attributeHandle) 691 { 692 693 return true; } 696 697 705 public String getDocumentTypeDeclarationSystemIdentifier() 706 { 707 708 709 error(XMLMessages.createXMLMessage(XMLErrorResources.ER_METHOD_NOT_SUPPORTED, null)); 711 return null; 712 } 713 714 721 protected int getNextNodeIdentity(int identity) 722 { 723 724 identity += 1; 725 726 while (identity >= m_size) 727 { 728 if (null == m_incrementalSAXSource) 729 return DTM.NULL; 730 731 nextNode(); 732 } 733 734 return identity; 735 } 736 737 745 public void dispatchToEvents(int nodeHandle, org.xml.sax.ContentHandler ch) 746 throws org.xml.sax.SAXException 747 { 748 749 DTMTreeWalker treeWalker = m_walker; 750 ContentHandler prevCH = treeWalker.getcontentHandler(); 751 752 if (null != prevCH) 753 { 754 treeWalker = new DTMTreeWalker(); 755 } 756 757 treeWalker.setcontentHandler(ch); 758 treeWalker.setDTM(this); 759 760 try 761 { 762 treeWalker.traverse(nodeHandle); 763 } 764 finally 765 { 766 treeWalker.setcontentHandler(null); 767 } 768 } 769 770 775 public int getNumberOfNodes() 776 { 777 return m_size; 778 } 779 780 786 protected boolean nextNode() 787 { 788 789 if (null == m_incrementalSAXSource) 790 return false; 791 792 if (m_endDocumentOccured) 793 { 794 clearCoRoutine(); 795 796 return false; 797 } 798 799 Object gotMore = m_incrementalSAXSource.deliverMoreNodes(true); 800 801 if (!(gotMore instanceof Boolean )) 809 { 810 if(gotMore instanceof RuntimeException ) 811 { 812 throw (RuntimeException )gotMore; 813 } 814 else if(gotMore instanceof Exception ) 815 { 816 throw new WrappedRuntimeException((Exception )gotMore); 817 } 818 clearCoRoutine(); 820 821 return false; 822 823 } 825 826 if (gotMore != Boolean.TRUE) 827 { 828 829 clearCoRoutine(); 832 } 834 835 return true; 836 } 837 838 845 private final boolean isTextType(int type) 846 { 847 return (DTM.TEXT_NODE == type || DTM.CDATA_SECTION_NODE == type); 848 } 849 850 866 879 protected int addNode(int type, int expandedTypeID, 880 int parentIndex, int previousSibling, 881 int dataOrPrefix, boolean canHaveFirstChild) 882 { 883 int nodeIndex = m_size++; 885 886 if(m_dtmIdent.size() == (nodeIndex>>>DTMManager.IDENT_DTM_NODE_BITS)) 888 { 889 addNewDTMID(nodeIndex); 890 } 891 892 m_firstch.addElement(canHaveFirstChild ? NOTPROCESSED : DTM.NULL); 893 m_nextsib.addElement(NOTPROCESSED); 894 m_parent.addElement(parentIndex); 895 m_exptype.addElement(expandedTypeID); 896 m_dataOrQName.addElement(dataOrPrefix); 897 898 if (m_prevsib != null) { 899 m_prevsib.addElement(previousSibling); 900 } 901 902 if (DTM.NULL != previousSibling) { 903 m_nextsib.setElementAt(nodeIndex,previousSibling); 904 } 905 906 if (m_locator != null && m_useSourceLocationProperty) { 907 setSourceLocation(); 908 } 909 910 913 switch(type) 915 { 916 case DTM.NAMESPACE_NODE: 917 declareNamespaceInContext(parentIndex,nodeIndex); 918 break; 919 case DTM.ATTRIBUTE_NODE: 920 break; 921 default: 922 if (DTM.NULL == previousSibling && DTM.NULL != parentIndex) { 923 m_firstch.setElementAt(nodeIndex,parentIndex); 924 } 925 break; 926 } 927 928 return nodeIndex; 929 } 930 931 936 protected void addNewDTMID(int nodeIndex) { 937 try 938 { 939 if(m_mgr==null) 940 throw new ClassCastException (); 941 942 DTMManagerDefault mgrD=(DTMManagerDefault)m_mgr; 944 int id=mgrD.getFirstFreeDTMID(); 945 mgrD.addDTM(this,id,nodeIndex); 946 m_dtmIdent.addElement(id<<DTMManager.IDENT_DTM_NODE_BITS); 947 } 948 catch(ClassCastException e) 949 { 950 error(XMLMessages.createXMLMessage(XMLErrorResources.ER_NO_DTMIDS_AVAIL, null)); } 955 } 956 957 964 public void migrateTo(DTMManager manager) { 965 super.migrateTo(manager); 966 967 int numDTMs = m_dtmIdent.size(); 970 int dtmId = m_mgrDefault.getFirstFreeDTMID(); 971 int nodeIndex = 0; 972 for (int i = 0; i < numDTMs; i++) 973 { 974 m_dtmIdent.setElementAt(dtmId << DTMManager.IDENT_DTM_NODE_BITS, i); 975 m_mgrDefault.addDTM(this, dtmId, nodeIndex); 976 dtmId++; 977 nodeIndex += (1 << DTMManager.IDENT_DTM_NODE_BITS); 978 } 979 } 980 981 985 protected void setSourceLocation() { 986 m_sourceSystemId.addElement(m_locator.getSystemId()); 987 m_sourceLine.addElement(m_locator.getLineNumber()); 988 m_sourceColumn.addElement(m_locator.getColumnNumber()); 989 990 if (m_sourceSystemId.size() != m_size) { 994 System.err.println("CODING ERROR in Source Location: " + m_size 995 + " != " 996 + m_sourceSystemId.size()); 997 System.exit(1); 998 } 999 } 1000 1001 1010 public String getNodeValue(int nodeHandle) 1011 { 1012 1013 int identity = makeNodeIdentity(nodeHandle); 1014 int type = _type(identity); 1015 1016 if (isTextType(type)) 1017 { 1018 int dataIndex = _dataOrQName(identity); 1019 int offset = m_data.elementAt(dataIndex); 1020 int length = m_data.elementAt(dataIndex + 1); 1021 1022 return m_chars.getString(offset, length); 1024 } 1025 else if (DTM.ELEMENT_NODE == type || DTM.DOCUMENT_FRAGMENT_NODE == type 1026 || DTM.DOCUMENT_NODE == type) 1027 { 1028 return null; 1029 } 1030 else 1031 { 1032 int dataIndex = _dataOrQName(identity); 1033 1034 if (dataIndex < 0) 1035 { 1036 dataIndex = -dataIndex; 1037 dataIndex = m_data.elementAt(dataIndex + 1); 1038 } 1039 1040 return m_valuesOrPrefixes.indexToString(dataIndex); 1041 } 1042 } 1043 1044 1052 public String getLocalName(int nodeHandle) 1053 { 1054 return m_expandedNameTable.getLocalName(_exptype(makeNodeIdentity(nodeHandle))); 1055 } 1056 1057 1091 public String getUnparsedEntityURI(String name) 1092 { 1093 1094 String url = ""; 1095 1096 if (null == m_entities) 1097 return url; 1098 1099 int n = m_entities.size(); 1100 1101 for (int i = 0; i < n; i += ENTITY_FIELDS_PER) 1102 { 1103 String ename = (String ) m_entities.elementAt(i + ENTITY_FIELD_NAME); 1104 1105 if (null != ename && ename.equals(name)) 1106 { 1107 String nname = (String ) m_entities.elementAt(i 1108 + ENTITY_FIELD_NOTATIONNAME); 1109 1110 if (null != nname) 1111 { 1112 1113 url = (String ) m_entities.elementAt(i + ENTITY_FIELD_SYSTEMID); 1123 1124 if (null == url) 1125 { 1126 url = (String ) m_entities.elementAt(i + ENTITY_FIELD_PUBLICID); 1127 } 1128 } 1129 1130 break; 1131 } 1132 } 1133 1134 return url; 1135 } 1136 1137 1149 public String getPrefix(int nodeHandle) 1150 { 1151 1152 int identity = makeNodeIdentity(nodeHandle); 1153 int type = _type(identity); 1154 1155 if (DTM.ELEMENT_NODE == type) 1156 { 1157 int prefixIndex = _dataOrQName(identity); 1158 1159 if (0 == prefixIndex) 1160 return ""; 1161 else 1162 { 1163 String qname = m_valuesOrPrefixes.indexToString(prefixIndex); 1164 1165 return getPrefix(qname, null); 1166 } 1167 } 1168 else if (DTM.ATTRIBUTE_NODE == type) 1169 { 1170 int prefixIndex = _dataOrQName(identity); 1171 1172 if (prefixIndex < 0) 1173 { 1174 prefixIndex = m_data.elementAt(-prefixIndex); 1175 1176 String qname = m_valuesOrPrefixes.indexToString(prefixIndex); 1177 1178 return getPrefix(qname, null); 1179 } 1180 } 1181 1182 return ""; 1183 } 1184 1185 1197 public int getAttributeNode(int nodeHandle, String namespaceURI, 1198 String name) 1199 { 1200 1201 for (int attrH = getFirstAttribute(nodeHandle); DTM.NULL != attrH; 1202 attrH = getNextAttribute(attrH)) 1203 { 1204 String attrNS = getNamespaceURI(attrH); 1205 String attrName = getLocalName(attrH); 1206 boolean nsMatch = namespaceURI == attrNS 1207 || (namespaceURI != null 1208 && namespaceURI.equals(attrNS)); 1209 1210 if (nsMatch && name.equals(attrName)) 1211 return attrH; 1212 } 1213 1214 return DTM.NULL; 1215 } 1216 1217 1227 public String getDocumentTypeDeclarationPublicIdentifier() 1228 { 1229 1230 1231 error(XMLMessages.createXMLMessage(XMLErrorResources.ER_METHOD_NOT_SUPPORTED, null)); 1233 return null; 1234 } 1235 1236 1247 public String getNamespaceURI(int nodeHandle) 1248 { 1249 1250 return m_expandedNameTable.getNamespace(_exptype(makeNodeIdentity(nodeHandle))); 1251 } 1252 1253 1262 public XMLString getStringValue(int nodeHandle) 1263 { 1264 int identity = makeNodeIdentity(nodeHandle); 1265 int type; 1266 if(identity==DTM.NULL) type = DTM.NULL; 1268 else 1269 type= _type(identity); 1270 1271 if (isTextType(type)) 1272 { 1273 int dataIndex = _dataOrQName(identity); 1274 int offset = m_data.elementAt(dataIndex); 1275 int length = m_data.elementAt(dataIndex + 1); 1276 1277 return m_xstrf.newstr(m_chars, offset, length); 1278 } 1279 else 1280 { 1281 int firstChild = _firstch(identity); 1282 1283 if (DTM.NULL != firstChild) 1284 { 1285 int offset = -1; 1286 int length = 0; 1287 int startNode = identity; 1288 1289 identity = firstChild; 1290 1291 do { 1292 type = _type(identity); 1293 1294 if (isTextType(type)) 1295 { 1296 int dataIndex = _dataOrQName(identity); 1297 1298 if (-1 == offset) 1299 { 1300 offset = m_data.elementAt(dataIndex); 1301 } 1302 1303 length += m_data.elementAt(dataIndex + 1); 1304 } 1305 1306 identity = getNextNodeIdentity(identity); 1307 } while (DTM.NULL != identity && (_parent(identity) >= startNode)); 1308 1309 if (length > 0) 1310 { 1311 return m_xstrf.newstr(m_chars, offset, length); 1312 } 1313 } 1314 else if(type != DTM.ELEMENT_NODE) 1315 { 1316 int dataIndex = _dataOrQName(identity); 1317 1318 if (dataIndex < 0) 1319 { 1320 dataIndex = -dataIndex; 1321 dataIndex = m_data.elementAt(dataIndex + 1); 1322 } 1323 return m_xstrf.newstr(m_valuesOrPrefixes.indexToString(dataIndex)); 1324 } 1325 } 1326 1327 return m_xstrf.emptystr(); 1328 } 1329 1330 1337 public boolean isWhitespace(int nodeHandle) 1338 { 1339 int identity = makeNodeIdentity(nodeHandle); 1340 int type; 1341 if(identity==DTM.NULL) type = DTM.NULL; 1343 else 1344 type= _type(identity); 1345 1346 if (isTextType(type)) 1347 { 1348 int dataIndex = _dataOrQName(identity); 1349 int offset = m_data.elementAt(dataIndex); 1350 int length = m_data.elementAt(dataIndex + 1); 1351 1352 return m_chars.isWhitespace(offset, length); 1353 } 1354 return false; 1355 } 1356 1357 1374 public int getElementById(String elementId) 1375 { 1376 1377 Integer intObj; 1378 boolean isMore = true; 1379 1380 do 1381 { 1382 intObj = (Integer ) m_idAttributes.get(elementId); 1383 1384 if (null != intObj) 1385 return makeNodeHandle(intObj.intValue()); 1386 1387 if (!isMore || m_endDocumentOccured) 1388 break; 1389 1390 isMore = nextNode(); 1391 } 1392 while (null == intObj); 1393 1394 return DTM.NULL; 1395 } 1396 1397 1406 public String getPrefix(String qname, String uri) 1407 { 1408 1409 String prefix; 1410 int uriIndex = -1; 1411 1412 if (null != uri && uri.length() > 0) 1413 { 1414 1415 do 1416 { 1417 uriIndex = m_prefixMappings.indexOf(uri, ++uriIndex); 1418 } while ( (uriIndex & 0x01) == 0); 1419 1420 if (uriIndex >= 0) 1421 { 1422 prefix = (String ) m_prefixMappings.elementAt(uriIndex - 1); 1423 } 1424 else if (null != qname) 1425 { 1426 int indexOfNSSep = qname.indexOf(':'); 1427 1428 if (qname.equals("xmlns")) 1429 prefix = ""; 1430 else if (qname.startsWith("xmlns:")) 1431 prefix = qname.substring(indexOfNSSep + 1); 1432 else 1433 prefix = (indexOfNSSep > 0) 1434 ? qname.substring(0, indexOfNSSep) : null; 1435 } 1436 else 1437 { 1438 prefix = null; 1439 } 1440 } 1441 else if (null != qname) 1442 { 1443 int indexOfNSSep = qname.indexOf(':'); 1444 1445 if (indexOfNSSep > 0) 1446 { 1447 if (qname.startsWith("xmlns:")) 1448 prefix = qname.substring(indexOfNSSep + 1); 1449 else 1450 prefix = qname.substring(0, indexOfNSSep); 1451 } 1452 else 1453 { 1454 if (qname.equals("xmlns")) 1455 prefix = ""; 1456 else 1457 prefix = null; 1458 } 1459 } 1460 else 1461 { 1462 prefix = null; 1463 } 1464 1465 return prefix; 1466 } 1467 1468 1476 public int getIdForNamespace(String uri) 1477 { 1478 1479 return m_valuesOrPrefixes.stringToIndex(uri); 1480 1481 } 1482 1483 1492 public String getNamespaceURI(String prefix) 1493 { 1494 1495 String uri = ""; 1496 int prefixIndex = m_contextIndexes.peek() - 1 ; 1497 1498 if(null == prefix) 1499 prefix = ""; 1500 1501 do 1502 { 1503 prefixIndex = m_prefixMappings.indexOf(prefix, ++prefixIndex); 1504 } while ( (prefixIndex >= 0) && (prefixIndex & 0x01) == 0x01); 1505 1506 if (prefixIndex > -1) 1507 { 1508 uri = (String ) m_prefixMappings.elementAt(prefixIndex + 1); 1509 } 1510 1511 1512 return uri; 1513 } 1514 1515 1521 public void setIDAttribute(String id, int elem) 1522 { 1523 m_idAttributes.put(id, new Integer (elem)); 1524 } 1525 1526 1530 protected void charactersFlush() 1531 { 1532 1533 if (m_textPendingStart >= 0) { 1535 int length = m_chars.size() - m_textPendingStart; 1536 boolean doStrip = false; 1537 1538 if (getShouldStripWhitespace()) 1539 { 1540 doStrip = m_chars.isWhitespace(m_textPendingStart, length); 1541 } 1542 1543 if (doStrip) 1544 m_chars.setLength(m_textPendingStart); else 1546 { 1547 int exName = m_expandedNameTable.getExpandedTypeID(DTM.TEXT_NODE); 1548 int dataIndex = m_data.size(); 1549 1550 m_previous = addNode(m_coalescedTextType, exName, 1551 m_parents.peek(), m_previous, dataIndex, false); 1552 1553 m_data.addElement(m_textPendingStart); 1554 m_data.addElement(length); 1555 } 1556 1557 m_textPendingStart = -1; 1559 m_textType = m_coalescedTextType = DTM.TEXT_NODE; 1560 } 1561 } 1562 1563 1567 1588 public InputSource resolveEntity(String publicId, String systemId) 1589 throws SAXException 1590 { 1591 return null; 1592 } 1593 1594 1598 1615 public void notationDecl(String name, String publicId, String systemId) 1616 throws SAXException 1617 { 1618 1619 } 1621 1622 1640 public void unparsedEntityDecl( 1641 String name, String publicId, String systemId, String notationName) 1642 throws SAXException 1643 { 1644 1645 if (null == m_entities) 1646 { 1647 m_entities = new Vector (); 1648 } 1649 1650 try 1651 { 1652 systemId = SystemIDResolver.getAbsoluteURI(systemId, 1653 getDocumentBaseURI()); 1654 } 1655 catch (Exception e) 1656 { 1657 throw new org.xml.sax.SAXException (e); 1658 } 1659 1660 m_entities.addElement(publicId); 1662 1663 m_entities.addElement(systemId); 1665 1666 m_entities.addElement(notationName); 1668 1669 m_entities.addElement(name); 1671 } 1672 1673 1677 1688 public void setDocumentLocator(Locator locator) 1689 { 1690 m_locator = locator; 1691 m_systemId = locator.getSystemId(); 1692 } 1693 1694 1701 public void startDocument() throws SAXException 1702 { 1703 if (DEBUG) 1704 System.out.println("startDocument"); 1705 1706 1707 int doc = addNode(DTM.DOCUMENT_NODE, 1708 m_expandedNameTable.getExpandedTypeID(DTM.DOCUMENT_NODE), 1709 DTM.NULL, DTM.NULL, 0, true); 1710 1711 m_parents.push(doc); 1712 m_previous = DTM.NULL; 1713 1714 m_contextIndexes.push(m_prefixMappings.size()); } 1716 1717 1724 public void endDocument() throws SAXException 1725 { 1726 if (DEBUG) 1727 System.out.println("endDocument"); 1728 1729 charactersFlush(); 1730 1731 m_nextsib.setElementAt(NULL,0); 1732 1733 if (m_firstch.elementAt(0) == NOTPROCESSED) 1734 m_firstch.setElementAt(NULL,0); 1735 1736 if (DTM.NULL != m_previous) 1737 m_nextsib.setElementAt(DTM.NULL,m_previous); 1738 1739 m_parents = null; 1740 m_prefixMappings = null; 1741 m_contextIndexes = null; 1742 1743 m_endDocumentOccured = true; 1744 1745 m_locator = null; 1747 } 1748 1749 1762 public void startPrefixMapping(String prefix, String uri) 1763 throws SAXException 1764 { 1765 1766 if (DEBUG) 1767 System.out.println("startPrefixMapping: prefix: " + prefix + ", uri: " 1768 + uri); 1769 1770 if(null == prefix) 1771 prefix = ""; 1772 m_prefixMappings.addElement(prefix); m_prefixMappings.addElement(uri); } 1775 1776 1788 public void endPrefixMapping(String prefix) throws SAXException 1789 { 1790 if (DEBUG) 1791 System.out.println("endPrefixMapping: prefix: " + prefix); 1792 1793 if(null == prefix) 1794 prefix = ""; 1795 1796 int index = m_contextIndexes.peek() - 1; 1797 1798 do 1799 { 1800 index = m_prefixMappings.indexOf(prefix, ++index); 1801 } while ( (index >= 0) && ((index & 0x01) == 0x01) ); 1802 1803 1804 if (index > -1) 1805 { 1806 m_prefixMappings.setElementAt("%@$#^@#", index); 1807 m_prefixMappings.setElementAt("%@$#^@#", index + 1); 1808 } 1809 1810 } 1812 1813 1821 protected boolean declAlreadyDeclared(String prefix) 1822 { 1823 1824 int startDecls = m_contextIndexes.peek(); 1825 java.util.Vector prefixMappings = m_prefixMappings; 1826 int nDecls = prefixMappings.size(); 1827 1828 for (int i = startDecls; i < nDecls; i += 2) 1829 { 1830 String prefixDecl = (String ) prefixMappings.elementAt(i); 1831 1832 if (prefixDecl == null) 1833 continue; 1834 1835 if (prefixDecl.equals(prefix)) 1836 return true; 1837 } 1838 1839 return false; 1840 } 1841 1842 boolean m_pastFirstElement=false; 1843 1844 1867 public void startElement( 1868 String uri, String localName, String qName, Attributes attributes) 1869 throws SAXException 1870 { 1871 if (DEBUG) 1872 { 1873 System.out.println("startElement: uri: " + uri + ", localname: " 1874 + localName + ", qname: "+qName+", atts: " + attributes); 1875 1876 boolean DEBUG_ATTRS=true; 1877 if(DEBUG_ATTRS & attributes!=null) 1878 { 1879 int n = attributes.getLength(); 1880 if(n==0) 1881 System.out.println("\tempty attribute list"); 1882 else for (int i = 0; i < n; i++) 1883 System.out.println("\t attr: uri: " + attributes.getURI(i) + 1884 ", localname: " + attributes.getLocalName(i) + 1885 ", qname: " + attributes.getQName(i) + 1886 ", type: " + attributes.getType(i) + 1887 ", value: " + attributes.getValue(i) 1888 ); 1889 } 1890 } 1891 1892 charactersFlush(); 1893 1894 int exName = m_expandedNameTable.getExpandedTypeID(uri, localName, DTM.ELEMENT_NODE); 1895 String prefix = getPrefix(qName, uri); 1896 int prefixIndex = (null != prefix) 1897 ? m_valuesOrPrefixes.stringToIndex(qName) : 0; 1898 1899 int elemNode = addNode(DTM.ELEMENT_NODE, exName, 1900 m_parents.peek(), m_previous, prefixIndex, true); 1901 1902 if(m_indexing) 1903 indexNode(exName, elemNode); 1904 1905 1906 m_parents.push(elemNode); 1907 1908 int startDecls = m_contextIndexes.peek(); 1909 int nDecls = m_prefixMappings.size(); 1910 int prev = DTM.NULL; 1911 1912 if(!m_pastFirstElement) 1913 { 1914 prefix="xml"; 1916 String declURL = "http://www.w3.org/XML/1998/namespace"; 1917 exName = m_expandedNameTable.getExpandedTypeID(null, prefix, DTM.NAMESPACE_NODE); 1918 int val = m_valuesOrPrefixes.stringToIndex(declURL); 1919 prev = addNode(DTM.NAMESPACE_NODE, exName, elemNode, 1920 prev, val, false); 1921 m_pastFirstElement=true; 1922 } 1923 1924 for (int i = startDecls; i < nDecls; i += 2) 1925 { 1926 prefix = (String ) m_prefixMappings.elementAt(i); 1927 1928 if (prefix == null) 1929 continue; 1930 1931 String declURL = (String ) m_prefixMappings.elementAt(i + 1); 1932 1933 exName = m_expandedNameTable.getExpandedTypeID(null, prefix, DTM.NAMESPACE_NODE); 1934 1935 int val = m_valuesOrPrefixes.stringToIndex(declURL); 1936 1937 prev = addNode(DTM.NAMESPACE_NODE, exName, elemNode, 1938 prev, val, false); 1939 } 1940 1941 int n = attributes.getLength(); 1942 1943 for (int i = 0; i < n; i++) 1944 { 1945 String attrUri = attributes.getURI(i); 1946 String attrQName = attributes.getQName(i); 1947 String valString = attributes.getValue(i); 1948 1949 prefix = getPrefix(attrQName, attrUri); 1950 1951 int nodeType; 1952 1953 String attrLocalName = attributes.getLocalName(i); 1954 1955 if ((null != attrQName) 1956 && (attrQName.equals("xmlns") 1957 || attrQName.startsWith("xmlns:"))) 1958 { 1959 if (declAlreadyDeclared(prefix)) 1960 continue; 1962 nodeType = DTM.NAMESPACE_NODE; 1963 } 1964 else 1965 { 1966 nodeType = DTM.ATTRIBUTE_NODE; 1967 1968 if (attributes.getType(i).equalsIgnoreCase("ID")) 1969 setIDAttribute(valString, elemNode); 1970 } 1971 1972 if(null == valString) 1975 valString = ""; 1976 1977 int val = m_valuesOrPrefixes.stringToIndex(valString); 1978 1980 if (null != prefix) 1981 { 1982 1983 prefixIndex = m_valuesOrPrefixes.stringToIndex(attrQName); 1984 1985 int dataIndex = m_data.size(); 1986 1987 m_data.addElement(prefixIndex); 1988 m_data.addElement(val); 1989 1990 val = -dataIndex; 1991 } 1992 1993 exName = m_expandedNameTable.getExpandedTypeID(attrUri, attrLocalName, nodeType); 1994 prev = addNode(nodeType, exName, elemNode, prev, val, 1995 false); 1996 } 1997 1998 if (DTM.NULL != prev) 1999 m_nextsib.setElementAt(DTM.NULL,prev); 2000 2001 if (null != m_wsfilter) 2002 { 2003 short wsv = m_wsfilter.getShouldStripSpace(makeNodeHandle(elemNode), this); 2004 boolean shouldStrip = (DTMWSFilter.INHERIT == wsv) 2005 ? getShouldStripWhitespace() 2006 : (DTMWSFilter.STRIP == wsv); 2007 2008 pushShouldStripWhitespace(shouldStrip); 2009 } 2010 2011 m_previous = DTM.NULL; 2012 2013 m_contextIndexes.push(m_prefixMappings.size()); } 2015 2016 2039 public void endElement(String uri, String localName, String qName) 2040 throws SAXException 2041 { 2042 if (DEBUG) 2043 System.out.println("endElement: uri: " + uri + ", localname: " 2044 + localName + ", qname: "+qName); 2045 2046 charactersFlush(); 2047 2048 m_contextIndexes.quickPop(1); 2051 2052 int topContextIndex = m_contextIndexes.peek(); 2054 if (topContextIndex != m_prefixMappings.size()) { 2055 m_prefixMappings.setSize(topContextIndex); 2056 } 2057 2058 int lastNode = m_previous; 2059 2060 m_previous = m_parents.pop(); 2061 2062 if (DTM.NULL == lastNode) 2064 m_firstch.setElementAt(DTM.NULL,m_previous); 2065 else 2066 m_nextsib.setElementAt(DTM.NULL,lastNode); 2067 2068 popShouldStripWhitespace(); 2069 } 2070 2071 2087 public void characters(char ch[], int start, int length) throws SAXException 2088 { 2089 if (m_textPendingStart == -1) { 2091 m_textPendingStart = m_chars.size(); 2092 m_coalescedTextType = m_textType; 2093 } 2094 else if (m_textType == DTM.TEXT_NODE) 2099 { 2100 m_coalescedTextType = DTM.TEXT_NODE; 2101 } 2102 2103 m_chars.append(ch, start, length); 2104 } 2105 2106 2122 public void ignorableWhitespace(char ch[], int start, int length) 2123 throws SAXException 2124 { 2125 2126 characters(ch, start, length); 2129 } 2130 2131 2146 public void processingInstruction(String target, String data) 2147 throws SAXException 2148 { 2149 if (DEBUG) 2150 System.out.println("processingInstruction: target: " + target +", data: "+data); 2151 2152 charactersFlush(); 2153 2154 int exName = m_expandedNameTable.getExpandedTypeID(null, target, 2155 DTM.PROCESSING_INSTRUCTION_NODE); 2156 int dataIndex = m_valuesOrPrefixes.stringToIndex(data); 2157 2158 m_previous = addNode(DTM.PROCESSING_INSTRUCTION_NODE, exName, 2159 m_parents.peek(), m_previous, 2160 dataIndex, false); 2161 } 2162 2163 2176 public void skippedEntity(String name) throws SAXException 2177 { 2178 2179 } 2182 2183 2187 2201 public void warning(SAXParseException e) throws SAXException 2202 { 2203 2204 System.err.println(e.getMessage()); 2206 } 2207 2208 2222 public void error(SAXParseException e) throws SAXException 2223 { 2224 throw e; 2225 } 2226 2227 2244 public void fatalError(SAXParseException e) throws SAXException 2245 { 2246 throw e; 2247 } 2248 2249 2253 2266 public void elementDecl(String name, String model) throws SAXException 2267 { 2268 2269 } 2271 2272 2291 public void attributeDecl( 2292 String eName, String aName, String type, String valueDefault, String value) 2293 throws SAXException 2294 { 2295 2296 } 2298 2299 2312 public void internalEntityDecl(String name, String value) 2313 throws SAXException 2314 { 2315 2316 } 2318 2319 2334 public void externalEntityDecl( 2335 String name, String publicId, String systemId) throws SAXException 2336 { 2337 2338 } 2340 2341 2345 2366 public void startDTD(String name, String publicId, String systemId) 2367 throws SAXException 2368 { 2369 2370 m_insideDTD = true; 2371 } 2372 2373 2379 public void endDTD() throws SAXException 2380 { 2381 2382 m_insideDTD = false; 2383 } 2384 2385 2407 public void startEntity(String name) throws SAXException 2408 { 2409 2410 } 2412 2413 2420 public void endEntity(String name) throws SAXException 2421 { 2422 2423 } 2425 2426 2436 public void startCDATA() throws SAXException 2437 { 2438 m_textType = DTM.CDATA_SECTION_NODE; 2439 } 2440 2441 2447 public void endCDATA() throws SAXException 2448 { 2449 m_textType = DTM.TEXT_NODE; 2450 } 2451 2452 2464 public void comment(char ch[], int start, int length) throws SAXException 2465 { 2466 2467 if (m_insideDTD) return; 2469 2470 charactersFlush(); 2471 2472 int exName = m_expandedNameTable.getExpandedTypeID(DTM.COMMENT_NODE); 2473 2474 int dataIndex = m_valuesOrPrefixes.stringToIndex(new String (ch, start, 2477 length)); 2478 2479 2480 m_previous = addNode(DTM.COMMENT_NODE, exName, 2481 m_parents.peek(), m_previous, dataIndex, false); 2482 } 2483 2484 2493 public void setProperty(String property, Object value) 2494 { 2495 } 2496 2497 2505 public SourceLocator getSourceLocatorFor(int node) 2506 { 2507 if (m_useSourceLocationProperty) 2508 { 2509 2510 node = makeNodeIdentity(node); 2511 2512 2513 return new NodeLocator(null, 2514 m_sourceSystemId.elementAt(node), 2515 m_sourceLine.elementAt(node), 2516 m_sourceColumn.elementAt(node)); 2517 } 2518 else if(m_locator!=null) 2519 { 2520 return new NodeLocator(null,m_locator.getSystemId(),-1,-1); 2521 } 2522 else if(m_systemId!=null) 2523 { 2524 return new NodeLocator(null,m_systemId,-1,-1); 2525 } 2526 return null; 2527 } 2528} 2529 | Popular Tags |