1 57 58 package org.enhydra.apache.xerces.dom; 59 60 import java.util.Vector ; 61 62 import org.enhydra.apache.xerces.framework.XMLAttrList; 63 import org.enhydra.apache.xerces.utils.StringPool; 64 import org.w3c.dom.Element ; 65 import org.w3c.dom.Node ; 66 67 82 public class DeferredDocumentImpl 83 extends DocumentImpl 84 implements DeferredNode { 85 86 90 91 static final long serialVersionUID = 5186323580749626857L; 92 93 95 96 private static final boolean DEBUG_PRINT_REF_COUNTS = false; 97 98 99 private static final boolean DEBUG_PRINT_TABLES = false; 100 101 102 private static final boolean DEBUG_IDS = false; 103 104 106 107 protected static final int CHUNK_SHIFT = 11; 109 110 protected static final int CHUNK_SIZE = (1 << CHUNK_SHIFT); 111 112 113 protected static final int CHUNK_MASK = CHUNK_SIZE - 1; 114 115 116 protected static final int INITIAL_CHUNK_COUNT = (1 << (16 - CHUNK_SHIFT)); 118 122 124 125 protected transient int fNodeCount = 0; 126 127 128 protected transient int fNodeType[][]; 129 130 131 protected transient int fNodeName[][]; 132 133 134 protected transient int fNodeValue[][]; 135 136 137 protected transient int fNodeParent[][]; 138 139 140 protected transient int fNodeLastChild[][]; 141 142 143 protected transient int fNodePrevSib[][]; 144 145 146 protected transient int fNodeURI[][]; 147 148 149 protected transient int fIdCount; 150 151 152 protected transient int fIdName[]; 153 154 155 protected transient int fIdElement[]; 156 157 158 protected transient StringPool fStringPool; 159 160 162 protected boolean fNamespacesEnabled = false; 165 166 private final StringBuffer fBufferStr = new StringBuffer (); 167 private final Vector fStrChunks = new Vector (); 168 172 176 public DeferredDocumentImpl(StringPool stringPool) { 177 this(stringPool, false); 178 } 180 184 public DeferredDocumentImpl(StringPool stringPool, boolean namespacesEnabled) { 185 this(stringPool, namespacesEnabled, false); 186 } 188 189 public DeferredDocumentImpl(StringPool stringPool, 190 boolean namespaces, boolean grammarAccess) { 191 super(grammarAccess); 192 193 fStringPool = stringPool; 194 195 needsSyncData(true); 196 needsSyncChildren(true); 197 198 fNamespacesEnabled = namespaces; 199 200 } 202 206 207 boolean getNamespacesEnabled() { 208 return fNamespacesEnabled; 209 } 210 211 213 214 public int createDocument() { 215 int nodeIndex = createNode(Node.DOCUMENT_NODE); 216 return nodeIndex; 217 } 218 219 220 public int createDocumentType(int rootElementNameIndex, int publicId, int systemId) { 221 222 int nodeIndex = createNode(Node.DOCUMENT_TYPE_NODE); 224 int chunk = nodeIndex >> CHUNK_SHIFT; 225 int index = nodeIndex & CHUNK_MASK; 226 227 230 int extraDataIndex = createNode((short)0); int echunk = extraDataIndex >> CHUNK_SHIFT; 233 int eindex = extraDataIndex & CHUNK_MASK; 234 235 setChunkIndex(fNodeName, rootElementNameIndex, chunk, index); 237 setChunkIndex(fNodeValue, extraDataIndex, chunk, index); 238 setChunkIndex(fNodeName, publicId, echunk, eindex); 239 setChunkIndex(fNodeValue, systemId, echunk, eindex); 240 241 return nodeIndex; 243 244 } 246 public void setInternalSubset(int doctypeIndex, int subsetIndex) { 247 int chunk = doctypeIndex >> CHUNK_SHIFT; 248 int index = doctypeIndex & CHUNK_MASK; 249 int extraDataIndex = fNodeValue[chunk][index]; 250 int echunk = extraDataIndex >> CHUNK_SHIFT; 251 int eindex = extraDataIndex & CHUNK_MASK; 252 setChunkIndex(fNodeLastChild, subsetIndex, echunk, eindex); 253 } 254 255 256 public int createNotation(int notationName, int publicId, int systemId) throws Exception { 257 258 int nodeIndex = createNode(Node.NOTATION_NODE); 260 int chunk = nodeIndex >> CHUNK_SHIFT; 261 int index = nodeIndex & CHUNK_MASK; 262 263 int extraDataIndex = createNode((short)0); int echunk = extraDataIndex >> CHUNK_SHIFT; 266 int eindex = extraDataIndex & CHUNK_MASK; 267 268 setChunkIndex(fNodeName, notationName, chunk, index); 270 setChunkIndex(fNodeValue, extraDataIndex, chunk, index); 271 setChunkIndex(fNodeName, publicId, echunk, eindex); 272 setChunkIndex(fNodeValue, systemId, echunk, eindex); 273 274 return nodeIndex; 276 277 } 279 280 public int createEntity(int entityName, int publicId, int systemId, int notationName) throws Exception { 281 int nodeIndex = createNode(Node.ENTITY_NODE); 283 int chunk = nodeIndex >> CHUNK_SHIFT; 284 int index = nodeIndex & CHUNK_MASK; 285 286 int extraDataIndex = createNode((short)0); int echunk = extraDataIndex >> CHUNK_SHIFT; 289 int eindex = extraDataIndex & CHUNK_MASK; 290 291 int extraDataIndex2 = createNode((short)0); int echunk2 = extraDataIndex2 >> CHUNK_SHIFT; 294 int eindex2 = extraDataIndex2 & CHUNK_MASK; 295 296 setChunkIndex(fNodeName, entityName, chunk, index); 298 setChunkIndex(fNodeValue, extraDataIndex, chunk, index); 299 setChunkIndex(fNodeLastChild, notationName, echunk, eindex); 300 setChunkIndex(fNodeName, publicId, echunk, eindex); 301 setChunkIndex(fNodeValue, extraDataIndex2, echunk, eindex); 302 setChunkIndex(fNodeName, systemId, echunk2, eindex2); 303 304 setChunkIndex(fNodeValue, -1, echunk2, eindex2); 306 setChunkIndex(fNodeLastChild, -1, echunk2, eindex2); 307 308 return nodeIndex; 310 311 } 313 public void setEntityInfo(int currentEntityDecl, int versionIndex, int encodingIndex){ 316 int eNodeIndex = getNodeValue(getNodeValue(currentEntityDecl, false), false); 317 if (eNodeIndex !=-1) { 318 int echunk = eNodeIndex >> CHUNK_SHIFT; 319 int eindex = eNodeIndex & CHUNK_MASK; 320 setChunkIndex(fNodeValue, versionIndex, echunk, eindex); 321 setChunkIndex(fNodeLastChild, encodingIndex, echunk, eindex); 322 } 323 } 324 325 326 public int createEntityReference(int nameIndex) throws Exception { 327 328 int nodeIndex = createNode(Node.ENTITY_REFERENCE_NODE); 330 int chunk = nodeIndex >> CHUNK_SHIFT; 331 int index = nodeIndex & CHUNK_MASK; 332 setChunkIndex(fNodeName, nameIndex, chunk, index); 333 334 return nodeIndex; 336 337 } 339 340 public int createElement(int elementNameIndex, 341 XMLAttrList attrList, int attrListIndex) { 342 return createElement(elementNameIndex, -1, attrList, attrListIndex); 343 } 344 345 346 public int createElement(int elementNameIndex, int elementURIIndex, 347 XMLAttrList attrList, int attrListIndex) { 348 349 int elementNodeIndex = createNode(Node.ELEMENT_NODE); 351 int elementChunk = elementNodeIndex >> CHUNK_SHIFT; 352 int elementIndex = elementNodeIndex & CHUNK_MASK; 353 setChunkIndex(fNodeName, elementNameIndex, elementChunk, elementIndex); 354 setChunkIndex(fNodeURI, elementURIIndex, elementChunk, elementIndex); 355 356 if (attrListIndex != -1) { 358 int first = attrList.getFirstAttr(attrListIndex); 359 int lastAttrNodeIndex = -1; 360 int lastAttrChunk = -1; 361 int lastAttrIndex = -1; 362 for (int index = first; 363 index != -1; 364 index = attrList.getNextAttr(index)) { 365 366 int attrNodeIndex = 368 createAttribute(attrList.getAttrName(index), 369 attrList.getAttrURI(index), 370 attrList.getAttValue(index), 371 attrList.isSpecified(index)); 372 int attrChunk = attrNodeIndex >> CHUNK_SHIFT; 373 int attrIndex = attrNodeIndex & CHUNK_MASK; 374 setChunkIndex(fNodeParent, elementNodeIndex, attrChunk, attrIndex); 375 376 if (index == first) { 378 setChunkIndex(fNodeValue, attrNodeIndex, elementChunk, elementIndex); 379 } 380 else { 381 setChunkIndex(fNodePrevSib, attrNodeIndex, lastAttrChunk, lastAttrIndex); 382 } 383 384 lastAttrNodeIndex = attrNodeIndex; 386 lastAttrChunk = attrChunk; 387 lastAttrIndex = attrIndex; 388 } 389 } 390 391 return elementNodeIndex; 393 394 } 396 public int createAttribute(int attrNameIndex, 397 int attrValueIndex, boolean specified) { 398 return createAttribute(attrNameIndex, -1, attrValueIndex, specified); 399 } 400 401 402 public int createAttribute(int attrNameIndex, int attrURIIndex, 403 int attrValueIndex, boolean specified) { 404 405 int nodeIndex = createNode(NodeImpl.ATTRIBUTE_NODE); 407 int chunk = nodeIndex >> CHUNK_SHIFT; 408 int index = nodeIndex & CHUNK_MASK; 409 setChunkIndex(fNodeName, attrNameIndex, chunk, index); 410 setChunkIndex(fNodeURI, attrURIIndex, chunk, index); 411 setChunkIndex(fNodeValue, specified ? 1 : 0, chunk, index); 412 413 int textNodeIndex = createTextNode(attrValueIndex, false); 415 appendChild(nodeIndex, textNodeIndex); 416 417 return nodeIndex; 419 420 } 422 423 public int createElementDefinition(int elementNameIndex) { 424 425 int nodeIndex = createNode(NodeImpl.ELEMENT_DEFINITION_NODE); 427 int chunk = nodeIndex >> CHUNK_SHIFT; 428 int index = nodeIndex & CHUNK_MASK; 429 setChunkIndex(fNodeName, elementNameIndex, chunk, index); 430 431 return nodeIndex; 433 434 } 436 437 public int createTextNode(int dataIndex, boolean ignorableWhitespace) { 438 439 int nodeIndex = createNode(Node.TEXT_NODE); 441 int chunk = nodeIndex >> CHUNK_SHIFT; 442 int index = nodeIndex & CHUNK_MASK; 443 setChunkIndex(fNodeValue, dataIndex, chunk, index); 444 setChunkIndex(fNodeLastChild, 446 ignorableWhitespace ? 1 : 0, chunk, index); 447 448 return nodeIndex; 450 451 } 453 454 public int createCDATASection(int dataIndex, boolean ignorableWhitespace) { 455 456 int nodeIndex = createNode(Node.CDATA_SECTION_NODE); 458 int chunk = nodeIndex >> CHUNK_SHIFT; 459 int index = nodeIndex & CHUNK_MASK; 460 setChunkIndex(fNodeValue, dataIndex, chunk, index); 461 setChunkIndex(fNodeLastChild, 463 ignorableWhitespace ? 1 : 0, chunk, index); 464 465 return nodeIndex; 467 468 } 470 471 public int createProcessingInstruction(int targetIndex, int dataIndex) { 472 473 int nodeIndex = createNode(Node.PROCESSING_INSTRUCTION_NODE); 475 int chunk = nodeIndex >> CHUNK_SHIFT; 476 int index = nodeIndex & CHUNK_MASK; 477 setChunkIndex(fNodeName, targetIndex, chunk, index); 478 setChunkIndex(fNodeValue, dataIndex, chunk, index); 479 480 return nodeIndex; 482 483 } 485 486 public int createComment(int dataIndex) { 487 488 int nodeIndex = createNode(Node.COMMENT_NODE); 490 int chunk = nodeIndex >> CHUNK_SHIFT; 491 int index = nodeIndex & CHUNK_MASK; 492 setChunkIndex(fNodeValue, dataIndex, chunk, index); 493 494 return nodeIndex; 496 497 } 499 500 public void appendChild(int parentIndex, int childIndex) { 501 502 int pchunk = parentIndex >> CHUNK_SHIFT; 504 int pindex = parentIndex & CHUNK_MASK; 505 int cchunk = childIndex >> CHUNK_SHIFT; 506 int cindex = childIndex & CHUNK_MASK; 507 setChunkIndex(fNodeParent, parentIndex, cchunk, cindex); 508 509 int olast = getChunkIndex(fNodeLastChild, pchunk, pindex); 511 setChunkIndex(fNodePrevSib, olast, cchunk, cindex); 512 513 setChunkIndex(fNodeLastChild, childIndex, pchunk, pindex); 515 516 517 } 519 520 public int setAttributeNode(int elemIndex, int attrIndex) { 521 522 int echunk = elemIndex >> CHUNK_SHIFT; 523 int eindex = elemIndex & CHUNK_MASK; 524 int achunk = attrIndex >> CHUNK_SHIFT; 525 int aindex = attrIndex & CHUNK_MASK; 526 527 String attrName = 529 fStringPool.toString(getChunkIndex(fNodeName, achunk, aindex)); 530 int oldAttrIndex = getChunkIndex(fNodeValue, echunk, eindex); 531 int nextIndex = -1; 532 int oachunk = -1; 533 int oaindex = -1; 534 while (oldAttrIndex != -1) { 535 oachunk = oldAttrIndex >> CHUNK_SHIFT; 536 oaindex = oldAttrIndex & CHUNK_MASK; 537 String oldAttrName = 538 fStringPool.toString(getChunkIndex(fNodeName, oachunk, oaindex)); 539 if (oldAttrName.equals(attrName)) { 540 break; 541 } 542 nextIndex = oldAttrIndex; 543 oldAttrIndex = getChunkIndex(fNodePrevSib, oachunk, oaindex); 544 } 545 546 if (oldAttrIndex != -1) { 548 549 int prevIndex = getChunkIndex(fNodePrevSib, oachunk, oaindex); 551 if (nextIndex == -1) { 552 setChunkIndex(fNodeValue, prevIndex, echunk, eindex); 553 } 554 else { 555 int pchunk = nextIndex >> CHUNK_SHIFT; 556 int pindex = nextIndex & CHUNK_MASK; 557 setChunkIndex(fNodePrevSib, prevIndex, pchunk, pindex); 558 } 559 560 clearChunkIndex(fNodeType, oachunk, oaindex); 562 clearChunkIndex(fNodeName, oachunk, oaindex); 563 clearChunkIndex(fNodeValue, oachunk, oaindex); 564 clearChunkIndex(fNodeParent, oachunk, oaindex); 565 clearChunkIndex(fNodePrevSib, oachunk, oaindex); 566 int attrTextIndex = 567 clearChunkIndex(fNodeLastChild, oachunk, oaindex); 568 int atchunk = attrTextIndex >> CHUNK_SHIFT; 569 int atindex = attrTextIndex & CHUNK_MASK; 570 clearChunkIndex(fNodeType, atchunk, atindex); 571 clearChunkIndex(fNodeValue, atchunk, atindex); 572 clearChunkIndex(fNodeParent, atchunk, atindex); 573 clearChunkIndex(fNodeLastChild, atchunk, atindex); 574 } 575 576 int prevIndex = getChunkIndex(fNodeValue, echunk, eindex); 578 setChunkIndex(fNodeValue, attrIndex, echunk, eindex); 579 setChunkIndex(fNodePrevSib, prevIndex, achunk, aindex); 580 581 return oldAttrIndex; 583 584 } 586 587 public int insertBefore(int parentIndex, int newChildIndex, int refChildIndex) { 588 589 if (refChildIndex == -1) { 590 appendChild(parentIndex, newChildIndex); 591 return newChildIndex; 592 } 593 594 int nchunk = newChildIndex >> CHUNK_SHIFT; 595 int nindex = newChildIndex & CHUNK_MASK; 596 int rchunk = refChildIndex >> CHUNK_SHIFT; 597 int rindex = refChildIndex & CHUNK_MASK; 598 int previousIndex = getChunkIndex(fNodePrevSib, rchunk, rindex); 599 setChunkIndex(fNodePrevSib, newChildIndex, rchunk, rindex); 600 setChunkIndex(fNodePrevSib, previousIndex, nchunk, nindex); 601 602 return newChildIndex; 603 604 } 606 607 public void setAsLastChild(int parentIndex, int childIndex) { 608 609 int pchunk = parentIndex >> CHUNK_SHIFT; 610 int pindex = parentIndex & CHUNK_MASK; 611 int chunk = childIndex >> CHUNK_SHIFT; 612 int index = childIndex & CHUNK_MASK; 613 setChunkIndex(fNodeLastChild, childIndex, pchunk, pindex); 614 } 616 620 public int getParentNode(int nodeIndex) { 621 return getParentNode(nodeIndex, false); 622 } 623 624 628 public int getParentNode(int nodeIndex, boolean free) { 629 630 if (nodeIndex == -1) { 631 return -1; 632 } 633 634 int chunk = nodeIndex >> CHUNK_SHIFT; 635 int index = nodeIndex & CHUNK_MASK; 636 return free ? clearChunkIndex(fNodeParent, chunk, index) 637 : getChunkIndex(fNodeParent, chunk, index); 638 639 } 641 642 public int getLastChild(int nodeIndex) { 643 return getLastChild(nodeIndex, true); 644 } 645 646 650 public int getLastChild(int nodeIndex, boolean free) { 651 652 if (nodeIndex == -1) { 653 return -1; 654 } 655 656 int chunk = nodeIndex >> CHUNK_SHIFT; 657 int index = nodeIndex & CHUNK_MASK; 658 return free ? clearChunkIndex(fNodeLastChild, chunk, index) 659 : getChunkIndex(fNodeLastChild, chunk, index); 660 661 } 663 667 public int getPrevSibling(int nodeIndex) { 668 return getPrevSibling(nodeIndex, true); 669 } 670 671 675 public int getPrevSibling(int nodeIndex, boolean free) { 676 677 if (nodeIndex == -1) { 678 return -1; 679 } 680 681 int chunk = nodeIndex >> CHUNK_SHIFT; 682 int index = nodeIndex & CHUNK_MASK; 683 int type = getChunkIndex(fNodeType, chunk, index); 684 if (type == Node.TEXT_NODE) { 685 do { 686 nodeIndex = getChunkIndex(fNodePrevSib, chunk, index); 687 if (nodeIndex == -1) { 688 break; 689 } 690 chunk = nodeIndex >> CHUNK_SHIFT; 691 index = nodeIndex & CHUNK_MASK; 692 type = getChunkIndex(fNodeType, chunk, index); 693 } while (type == Node.TEXT_NODE); 694 } 695 else { 696 nodeIndex = getChunkIndex(fNodePrevSib, chunk, index); 697 } 698 699 return nodeIndex; 700 701 } 703 708 public int getRealPrevSibling(int nodeIndex) { 709 return getRealPrevSibling(nodeIndex, true); 710 } 711 712 716 public int getRealPrevSibling(int nodeIndex, boolean free) { 717 718 if (nodeIndex == -1) { 719 return -1; 720 } 721 722 int chunk = nodeIndex >> CHUNK_SHIFT; 723 int index = nodeIndex & CHUNK_MASK; 724 return free ? clearChunkIndex(fNodePrevSib, chunk, index) 725 : getChunkIndex(fNodePrevSib, chunk, index); 726 727 } 729 734 public int lookupElementDefinition(int elementNameIndex) { 735 736 if (fNodeCount > 1) { 737 738 int docTypeIndex = -1; 740 int nchunk = 0; 741 int nindex = 0; 742 for (int index = getChunkIndex(fNodeLastChild, nchunk, nindex); 743 index != -1; 744 index = getChunkIndex(fNodePrevSib, nchunk, nindex)) { 745 746 nchunk = index >> CHUNK_SHIFT; 747 nindex = index & CHUNK_MASK; 748 if (getChunkIndex(fNodeType, nchunk, nindex) == Node.DOCUMENT_TYPE_NODE) { 749 docTypeIndex = index; 750 break; 751 } 752 } 753 754 if (docTypeIndex == -1) { 756 return -1; 757 } 758 nchunk = docTypeIndex >> CHUNK_SHIFT; 759 nindex = docTypeIndex & CHUNK_MASK; 760 for (int index = getChunkIndex(fNodeLastChild, nchunk, nindex); 761 index != -1; 762 index = getChunkIndex(fNodePrevSib, nchunk, nindex)) { 763 764 nchunk = index >> CHUNK_SHIFT; 765 nindex = index & CHUNK_MASK; 766 if (getChunkIndex(fNodeName, nchunk, nindex) == elementNameIndex) { 767 return index; 768 } 769 } 770 } 771 772 return -1; 773 774 } 776 777 public DeferredNode getNodeObject(int nodeIndex) { 778 779 if (nodeIndex == -1) { 781 return null; 782 } 783 784 int chunk = nodeIndex >> CHUNK_SHIFT; 786 int index = nodeIndex & CHUNK_MASK; 787 int type = getChunkIndex(fNodeType, chunk, index); 788 if (type != Node.TEXT_NODE) { 789 clearChunkIndex(fNodeType, chunk, index); 790 } 791 792 DeferredNode node = null; 794 switch (type) { 795 796 800 case Node.ATTRIBUTE_NODE: { 801 if (fNamespacesEnabled) { 802 node = new DeferredAttrNSImpl(this, nodeIndex); 803 } else { 804 node = new DeferredAttrImpl(this, nodeIndex); 805 } 806 break; 807 } 808 809 case Node.CDATA_SECTION_NODE: { 810 node = new DeferredCDATASectionImpl(this, nodeIndex); 811 break; 812 } 813 814 case Node.COMMENT_NODE: { 815 node = new DeferredCommentImpl(this, nodeIndex); 816 break; 817 } 818 819 case Node.DOCUMENT_NODE: { 827 node = this; 829 break; 830 } 831 832 case Node.DOCUMENT_TYPE_NODE: { 833 node = new DeferredDocumentTypeImpl(this, nodeIndex); 834 docType = (DocumentTypeImpl)node; 836 break; 837 } 838 839 case Node.ELEMENT_NODE: { 840 841 if (DEBUG_IDS) { 842 System.out.println("getNodeObject(ELEMENT_NODE): "+nodeIndex); 843 } 844 845 if (fNamespacesEnabled) { 847 node = new DeferredElementNSImpl(this, nodeIndex); 848 } else { 849 node = new DeferredElementImpl(this, nodeIndex); 850 } 851 852 if (docElement == null) { 854 docElement = (ElementImpl)node; 855 } 856 857 if (fIdElement != null) { 860 int idIndex = DeferredDocumentImpl.binarySearch(fIdElement, 0, fIdCount-1, nodeIndex); 861 while (idIndex != -1) { 862 863 if (DEBUG_IDS) { 864 System.out.println(" id index: "+idIndex); 865 System.out.println(" fIdName["+idIndex+ 866 "]: "+fIdName[idIndex]); 867 } 868 869 int nameIndex = fIdName[idIndex]; 871 if (nameIndex != -1) { 872 String name = fStringPool.toString(nameIndex); 873 if (DEBUG_IDS) { 874 System.out.println(" name: "+name); 875 System.out.print("getNodeObject()#"); 876 } 877 putIdentifier0(name, (Element )node); 878 fIdName[idIndex] = -1; 879 } 880 881 if (idIndex + 1 < fIdCount && 884 fIdElement[idIndex + 1] == nodeIndex) { 885 idIndex++; 886 } 887 else { 888 idIndex = -1; 889 } 890 } 891 } 892 break; 893 } 894 895 case Node.ENTITY_NODE: { 896 node = new DeferredEntityImpl(this, nodeIndex); 897 break; 898 } 899 900 case Node.ENTITY_REFERENCE_NODE: { 901 node = new DeferredEntityReferenceImpl(this, nodeIndex); 902 break; 903 } 904 905 case Node.NOTATION_NODE: { 906 node = new DeferredNotationImpl(this, nodeIndex); 907 break; 908 } 909 910 case Node.PROCESSING_INSTRUCTION_NODE: { 911 node = new DeferredProcessingInstructionImpl(this, nodeIndex); 912 break; 913 } 914 915 case Node.TEXT_NODE: { 916 node = new DeferredTextImpl(this, nodeIndex); 917 break; 918 } 919 920 924 case NodeImpl.ELEMENT_DEFINITION_NODE: { 925 node = new DeferredElementDefinitionImpl(this, nodeIndex); 926 break; 927 } 928 929 default: { 930 throw new IllegalArgumentException ("type: "+type); 931 } 932 933 } 935 if (node != null) { 937 return node; 938 } 939 940 throw new IllegalArgumentException (); 942 943 } 945 946 public String getNodeNameString(int nodeIndex) { 947 return getNodeNameString(nodeIndex, true); 948 } 950 954 public String getNodeNameString(int nodeIndex, boolean free) { 955 956 if (nodeIndex == -1) { 957 return null; 958 } 959 960 int chunk = nodeIndex >> CHUNK_SHIFT; 961 int index = nodeIndex & CHUNK_MASK; 962 int nameIndex = free 963 ? clearChunkIndex(fNodeName, chunk, index) 964 : getChunkIndex(fNodeName, chunk, index); 965 if (nameIndex == -1) { 966 return null; 967 } 968 969 return fStringPool.toString(nameIndex); 970 971 } 973 974 public String getNodeValueString(int nodeIndex) { 975 return getNodeValueString(nodeIndex, true); 976 } 978 982 public String getNodeValueString(int nodeIndex, boolean free) { 983 984 if (nodeIndex == -1) { 985 return null; 986 } 987 988 int chunk = nodeIndex >> CHUNK_SHIFT; 989 int index = nodeIndex & CHUNK_MASK; 990 int valueIndex = free 991 ? clearChunkIndex(fNodeValue, chunk, index) 992 : getChunkIndex(fNodeValue, chunk, index); 993 if (valueIndex == -1) { 994 return null; 995 } 996 997 int type = getChunkIndex(fNodeType, chunk, index); 998 if (type == Node.TEXT_NODE) { 999 int prevSib = getRealPrevSibling(nodeIndex); 1000 if (prevSib != -1 && getNodeType(prevSib, false) == Node.TEXT_NODE) { 1001 fStrChunks.addElement(fStringPool.toString(valueIndex)); 1002 do { 1003 chunk = prevSib >> CHUNK_SHIFT; 1004 index = prevSib & CHUNK_MASK; 1005 valueIndex = getChunkIndex(fNodeValue, chunk, index); 1006 fStrChunks.addElement(fStringPool.toString(valueIndex)); 1009 prevSib = getChunkIndex(fNodePrevSib, chunk, index); 1010 if (prevSib == -1) { 1011 break; 1012 } 1013 } while (getNodeType(prevSib, false) == Node.TEXT_NODE); 1014 for (int i=fStrChunks.size()-1; i>=0; i--) { 1015 fBufferStr.append((String )fStrChunks.elementAt(i)); 1016 } 1017 1018 String value = fBufferStr.toString(); 1019 fStrChunks.setSize(0); 1020 fBufferStr.setLength(0); 1021 return value; 1022 } 1023 } 1024 1025 return fStringPool.toString(valueIndex); 1026 1027 } 1029 1030 public int getNodeName(int nodeIndex) { 1031 return getNodeName(nodeIndex, true); 1032 } 1033 1034 1038 public int getNodeName(int nodeIndex, boolean free) { 1039 1040 if (nodeIndex == -1) { 1041 return -1; 1042 } 1043 1044 int chunk = nodeIndex >> CHUNK_SHIFT; 1045 int index = nodeIndex & CHUNK_MASK; 1046 return free ? clearChunkIndex(fNodeName, chunk, index) 1047 : getChunkIndex(fNodeName, chunk, index); 1048 1049 } 1051 1055 public int getNodeValue(int nodeIndex) { 1056 return getNodeValue(nodeIndex, true); 1057 } 1058 1059 1063 public int getNodeValue(int nodeIndex, boolean free) { 1064 1065 if (nodeIndex == -1) { 1066 return -1; 1067 } 1068 1069 int chunk = nodeIndex >> CHUNK_SHIFT; 1070 int index = nodeIndex & CHUNK_MASK; 1071 return free ? clearChunkIndex(fNodeValue, chunk, index) 1072 : getChunkIndex(fNodeValue, chunk, index); 1073 1074 } 1076 1077 public short getNodeType(int nodeIndex) { 1078 return getNodeType(nodeIndex, true); 1079 } 1080 1081 1085 public short getNodeType(int nodeIndex, boolean free) { 1086 1087 if (nodeIndex == -1) { 1088 return -1; 1089 } 1090 1091 int chunk = nodeIndex >> CHUNK_SHIFT; 1092 int index = nodeIndex & CHUNK_MASK; 1093 if (free) { 1094 return (short)clearChunkIndex(fNodeType, chunk, index); 1095 } 1096 return (short)getChunkIndex(fNodeType, chunk, index); 1097 1098 } 1100 1101 public int getAttribute(int elemIndex, int nameIndex) { 1102 if (elemIndex == -1 || nameIndex == -1) { 1103 return -1; 1104 } 1105 int echunk = elemIndex >> CHUNK_SHIFT; 1106 int eindex = elemIndex & CHUNK_MASK; 1107 int attrIndex = getChunkIndex(fNodeValue, echunk, eindex); 1108 while (attrIndex != -1) { 1109 int achunk = attrIndex >> CHUNK_SHIFT; 1110 int aindex = attrIndex & CHUNK_MASK; 1111 if (getChunkIndex(fNodeName, achunk, aindex) == nameIndex) { 1112 return getChunkIndex(fNodeValue, achunk, aindex); 1113 } 1114 attrIndex = getChunkIndex(fNodePrevSib, achunk, aindex); 1115 } 1116 return -1; 1117 } 1118 1119 1120 public short getNodeURI(int nodeIndex) { 1121 return getNodeURI(nodeIndex, true); 1122 } 1123 1124 1128 public short getNodeURI(int nodeIndex, boolean free) { 1129 1130 if (nodeIndex == -1) { 1131 return -1; 1132 } 1133 1134 int chunk = nodeIndex >> CHUNK_SHIFT; 1135 int index = nodeIndex & CHUNK_MASK; 1136 if (free) { 1137 return (short)clearChunkIndex(fNodeURI, chunk, index); 1138 } 1139 return (short)getChunkIndex(fNodeURI, chunk, index); 1140 1141 } 1143 1145 1146 public void putIdentifier(int nameIndex, int elementNodeIndex) { 1147 1148 if (DEBUG_IDS) { 1149 System.out.println("putIdentifier("+nameIndex+", "+elementNodeIndex+')'+ 1150 " // "+ 1151 fStringPool.toString(nameIndex)+ 1152 ", "+ 1153 fStringPool.toString(getChunkIndex(fNodeName, elementNodeIndex >> CHUNK_SHIFT, elementNodeIndex & CHUNK_MASK))); 1154 } 1155 1156 if (fIdName == null) { 1158 fIdName = new int[64]; 1159 fIdElement = new int[64]; 1160 } 1161 1162 if (fIdCount == fIdName.length) { 1164 int idName[] = new int[fIdCount * 2]; 1165 System.arraycopy(fIdName, 0, idName, 0, fIdCount); 1166 fIdName = idName; 1167 1168 int idElement[] = new int[idName.length]; 1169 System.arraycopy(fIdElement, 0, idElement, 0, fIdCount); 1170 fIdElement = idElement; 1171 } 1172 1173 fIdName[fIdCount] = nameIndex; 1175 fIdElement[fIdCount] = elementNodeIndex; 1176 fIdCount++; 1177 1178 } 1180 1184 1185 public void print() { 1186 1187 if (DEBUG_PRINT_REF_COUNTS) { 1188 System.out.print("num\t"); 1189 System.out.print("type\t"); 1190 System.out.print("name\t"); 1191 System.out.print("val\t"); 1192 System.out.print("par\t"); 1193 System.out.print("fch\t"); 1194 System.out.print("nsib"); 1195 System.out.println(); 1196 for (int i = 0; i < fNodeType.length; i++) { 1197 if (fNodeType[i] != null) { 1198 System.out.print("--------"); 1200 System.out.print("--------"); 1201 System.out.print("--------"); 1202 System.out.print("--------"); 1203 System.out.print("--------"); 1204 System.out.print("--------"); 1205 System.out.print("--------"); 1206 System.out.println(); 1207 1208 System.out.print(i); 1210 System.out.print('\t'); 1211 System.out.print(fNodeType[i][CHUNK_SIZE]); 1212 System.out.print('\t'); 1213 System.out.print(fNodeName[i][CHUNK_SIZE]); 1214 System.out.print('\t'); 1215 System.out.print(fNodeValue[i][CHUNK_SIZE]); 1216 System.out.print('\t'); 1217 System.out.print(fNodeParent[i][CHUNK_SIZE]); 1218 System.out.print('\t'); 1219 System.out.print(fNodeLastChild[i][CHUNK_SIZE]); 1220 System.out.print('\t'); 1221 System.out.print(fNodePrevSib[i][CHUNK_SIZE]); 1222 System.out.println(); 1223 1224 System.out.print(i); 1226 System.out.print('\t'); 1227 System.out.print(fNodeType[i][CHUNK_SIZE + 1]); 1228 System.out.print('\t'); 1229 System.out.print(fNodeName[i][CHUNK_SIZE + 1]); 1230 System.out.print('\t'); 1231 System.out.print(fNodeValue[i][CHUNK_SIZE + 1]); 1232 System.out.print('\t'); 1233 System.out.print(fNodeParent[i][CHUNK_SIZE + 1]); 1234 System.out.print('\t'); 1235 System.out.print(fNodeLastChild[i][CHUNK_SIZE + 1]); 1236 System.out.print('\t'); 1237 System.out.print(fNodePrevSib[i][CHUNK_SIZE + 1]); 1238 System.out.println(); 1239 } 1240 } 1241 } 1242 1243 if (DEBUG_PRINT_TABLES) { 1244 System.out.println("# start table"); 1246 for (int i = 0; i < fNodeCount; i++) { 1247 int chunk = i >> CHUNK_SHIFT; 1248 int index = i & CHUNK_MASK; 1249 if (i % 10 == 0) { 1250 System.out.print("num\t"); 1251 System.out.print("type\t"); 1252 System.out.print("name\t"); 1253 System.out.print("val\t"); 1254 System.out.print("par\t"); 1255 System.out.print("fch\t"); 1256 System.out.print("nsib"); 1257 System.out.println(); 1258 } 1259 System.out.print(i); 1260 System.out.print('\t'); 1261 System.out.print(getChunkIndex(fNodeType, chunk, index)); 1262 System.out.print('\t'); 1263 System.out.print(getChunkIndex(fNodeName, chunk, index)); 1264 System.out.print('\t'); 1265 System.out.print(getChunkIndex(fNodeValue, chunk, index)); 1266 System.out.print('\t'); 1267 System.out.print(getChunkIndex(fNodeParent, chunk, index)); 1268 System.out.print('\t'); 1269 System.out.print(getChunkIndex(fNodeLastChild, chunk, index)); 1270 System.out.print('\t'); 1271 System.out.print(getChunkIndex(fNodePrevSib, chunk, index)); 1272 1289 System.out.println(); 1290 } 1291 System.out.println("# end table"); 1292 } 1293 1294 } 1296 1300 1301 public int getNodeIndex() { 1302 return 0; 1303 } 1304 1305 1309 1310 protected StringPool getStringPool() { 1311 return fStringPool; 1312 } 1313 1314 1315 protected void synchronizeData() { 1316 1317 needsSyncData(false); 1319 1320 if (fIdElement != null) { 1322 1323 1330 IntVector path = new IntVector(); 1331 for (int i = 0; i < fIdCount; i++) { 1332 1333 int elementNodeIndex = fIdElement[i]; 1335 int idNameIndex = fIdName[i]; 1336 if (idNameIndex == -1) { 1337 continue; 1338 } 1339 1340 path.removeAllElements(); 1342 int index = elementNodeIndex; 1343 do { 1344 path.addElement(index); 1345 int pchunk = index >> CHUNK_SHIFT; 1346 int pindex = index & CHUNK_MASK; 1347 index = getChunkIndex(fNodeParent, pchunk, pindex); 1348 } while (index != -1); 1349 1350 Node place = this; 1355 for (int j = path.size() - 2; j >= 0; j--) { 1356 index = path.elementAt(j); 1357 Node child = place.getLastChild(); 1358 while (child != null) { 1359 if (child instanceof DeferredNode) { 1360 int nodeIndex = ((DeferredNode)child).getNodeIndex(); 1361 if (nodeIndex == index) { 1362 place = child; 1363 break; 1364 } 1365 } 1366 child = child.getPreviousSibling(); 1367 } 1368 } 1369 1370 Element element = (Element )place; 1372 String name = fStringPool.toString(idNameIndex); 1373 putIdentifier0(name, element); 1374 fIdName[i] = -1; 1375 1376 while (i + 1 < fIdCount && fIdElement[i + 1] == elementNodeIndex) { 1378 idNameIndex = fIdName[++i]; 1379 if (idNameIndex == -1) { 1380 continue; 1381 } 1382 name = fStringPool.toString(idNameIndex); 1383 putIdentifier0(name, element); 1384 } 1385 } 1386 1387 } 1389 } 1391 1397 protected void synchronizeChildren() { 1398 1399 if (needsSyncData()) { 1400 synchronizeData(); 1401 1406 if (!needsSyncChildren()) { 1407 return; 1408 } 1409 } 1410 1411 boolean orig = mutationEvents; 1413 mutationEvents = false; 1414 1415 needsSyncChildren(false); 1417 1418 getNodeType(0); 1419 1420 ChildNode first = null; 1422 ChildNode last = null; 1423 for (int index = getLastChild(0); 1424 index != -1; 1425 index = getPrevSibling(index)) { 1426 1427 ChildNode node = (ChildNode)getNodeObject(index); 1428 if (last == null) { 1429 last = node; 1430 } 1431 else { 1432 first.previousSibling = node; 1433 } 1434 node.ownerNode = this; 1435 node.isOwned(true); 1436 node.nextSibling = first; 1437 first = node; 1438 1439 int type = node.getNodeType(); 1441 if (type == Node.ELEMENT_NODE) { 1442 docElement = (ElementImpl)node; 1443 } 1444 else if (type == Node.DOCUMENT_TYPE_NODE) { 1445 docType = (DocumentTypeImpl)node; 1446 } 1447 } 1448 1449 if (first != null) { 1450 firstChild = first; 1451 first.isFirstChild(true); 1452 lastChild(last); 1453 } 1454 1455 mutationEvents = orig; 1457 1458 } 1460 1468 protected final void synchronizeChildren(AttrImpl a, int nodeIndex) { 1469 1470 boolean orig = getMutationEvents(); 1472 setMutationEvents(false); 1473 1474 a.needsSyncChildren(false); 1476 1477 int last = getLastChild(nodeIndex); 1480 int prev = getPrevSibling(last); 1481 if (prev == -1) { 1482 a.value = getNodeValueString(last); 1483 a.hasStringValue(true); 1484 } 1485 else { 1486 ChildNode firstNode = null; 1487 ChildNode lastNode = null; 1488 for (int index = last; index != -1; 1489 index = getPrevSibling(index)) { 1490 1491 ChildNode node = (ChildNode) getNodeObject(index); 1492 if (lastNode == null) { 1493 lastNode = node; 1494 } 1495 else { 1496 firstNode.previousSibling = node; 1497 } 1498 node.ownerNode = a; 1499 node.isOwned(true); 1500 node.nextSibling = firstNode; 1501 firstNode = node; 1502 } 1503 if (lastNode != null) { 1504 a.value = firstNode; firstNode.isFirstChild(true); 1506 a.lastChild(lastNode); 1507 } 1508 a.hasStringValue(false); 1509 } 1510 1511 setMutationEvents(orig); 1513 1514 } 1516 1517 1525 protected final void synchronizeChildren(ParentNode p, int nodeIndex) { 1526 1527 boolean orig = getMutationEvents(); 1529 setMutationEvents(false); 1530 1531 p.needsSyncChildren(false); 1533 1534 ChildNode firstNode = null; 1536 ChildNode lastNode = null; 1537 for (int index = getLastChild(nodeIndex); 1538 index != -1; 1539 index = getPrevSibling(index)) { 1540 1541 ChildNode node = (ChildNode) getNodeObject(index); 1542 if (lastNode == null) { 1543 lastNode = node; 1544 } 1545 else { 1546 firstNode.previousSibling = node; 1547 } 1548 node.ownerNode = p; 1549 node.isOwned(true); 1550 node.nextSibling = firstNode; 1551 firstNode = node; 1552 } 1553 if (lastNode != null) { 1554 p.firstChild = firstNode; 1555 firstNode.isFirstChild(true); 1556 p.lastChild(lastNode); 1557 } 1558 1559 setMutationEvents(orig); 1561 1562 } 1564 1566 1567 protected boolean ensureCapacity(int chunk, int index) { 1568 1569 if (fNodeType == null) { 1571 fNodeType = new int[INITIAL_CHUNK_COUNT][]; 1572 fNodeName = new int[INITIAL_CHUNK_COUNT][]; 1573 fNodeValue = new int[INITIAL_CHUNK_COUNT][]; 1574 fNodeParent = new int[INITIAL_CHUNK_COUNT][]; 1575 fNodeLastChild = new int[INITIAL_CHUNK_COUNT][]; 1576 fNodePrevSib = new int[INITIAL_CHUNK_COUNT][]; 1577 fNodeURI = new int[INITIAL_CHUNK_COUNT][]; 1578 } 1579 1580 try { 1582 return fNodeType[chunk][index] != 0; 1583 } 1584 1585 catch (ArrayIndexOutOfBoundsException ex) { 1587 int newsize = chunk * 2; 1588 1589 int[][] newArray = new int[newsize][]; 1590 System.arraycopy(fNodeType, 0, newArray, 0, chunk); 1591 fNodeType = newArray; 1592 1593 newArray = new int[newsize][]; 1594 System.arraycopy(fNodeName, 0, newArray, 0, chunk); 1595 fNodeName = newArray; 1596 1597 newArray = new int[newsize][]; 1598 System.arraycopy(fNodeValue, 0, newArray, 0, chunk); 1599 fNodeValue = newArray; 1600 1601 newArray = new int[newsize][]; 1602 System.arraycopy(fNodeParent, 0, newArray, 0, chunk); 1603 fNodeParent = newArray; 1604 1605 newArray = new int[newsize][]; 1606 System.arraycopy(fNodeLastChild, 0, newArray, 0, chunk); 1607 fNodeLastChild = newArray; 1608 1609 newArray = new int[newsize][]; 1610 System.arraycopy(fNodePrevSib, 0, newArray, 0, chunk); 1611 fNodePrevSib = newArray; 1612 1613 newArray = new int[newsize][]; 1614 System.arraycopy(fNodeURI, 0, newArray, 0, chunk); 1615 fNodeURI = newArray; 1616 } 1617 1618 catch (NullPointerException ex) { 1619 } 1621 1622 createChunk(fNodeType, chunk); 1624 createChunk(fNodeName, chunk); 1625 createChunk(fNodeValue, chunk); 1626 createChunk(fNodeParent, chunk); 1627 createChunk(fNodeLastChild, chunk); 1628 createChunk(fNodePrevSib, chunk); 1629 createChunk(fNodeURI, chunk); 1630 1631 return true; 1633 1634 } 1636 1637 protected int createNode(short nodeType) { 1638 1639 int chunk = fNodeCount >> CHUNK_SHIFT; 1641 int index = fNodeCount & CHUNK_MASK; 1642 ensureCapacity(chunk, index); 1643 1644 setChunkIndex(fNodeType, nodeType, chunk, index); 1646 1647 return fNodeCount++; 1649 1650 } 1652 1667 protected static int binarySearch(final int values[], 1668 int start, int end, int target) { 1669 1670 if (DEBUG_IDS) { 1671 System.out.println("binarySearch(), target: "+target); 1672 } 1673 1674 while (start <= end) { 1676 1677 int middle = (start + end) / 2; 1679 int value = values[middle]; 1680 if (DEBUG_IDS) { 1681 System.out.print(" value: "+value+", target: "+target+" // "); 1682 print(values, start, end, middle, target); 1683 } 1684 if (value == target) { 1685 while (middle > 0 && values[middle - 1] == target) { 1686 middle--; 1687 } 1688 if (DEBUG_IDS) { 1689 System.out.println("FOUND AT "+middle); 1690 } 1691 return middle; 1692 } 1693 1694 if (value > target) { 1696 end = middle - 1; 1697 } 1698 else { 1699 start = middle + 1; 1700 } 1701 1702 } 1704 if (DEBUG_IDS) { 1706 System.out.println("NOT FOUND!"); 1707 } 1708 return -1; 1709 1710 } 1712 1716 1717 private final void createChunk(int data[][], int chunk) { 1718 data[chunk] = new int[CHUNK_SIZE + 2]; 1719 for (int i = 0; i < CHUNK_SIZE; i++) { 1720 data[chunk][i] = -1; 1721 } 1722 } 1723 1724 1729 private final int setChunkIndex(int data[][], int value, int chunk, int index) { 1730 if (value == -1) { 1731 return clearChunkIndex(data, chunk, index); 1732 } 1733 int ovalue = data[chunk][index]; 1734 if (ovalue == -1) { 1735 data[chunk][CHUNK_SIZE]++; 1736 } 1737 data[chunk][index] = value; 1738 return ovalue; 1739 } 1740 1741 1744 private final int getChunkIndex(int data[][], int chunk, int index) { 1745 return data[chunk] != null ? data[chunk][index] : -1; 1746 } 1747 1748 1755 private final int clearChunkIndex(int data[][], int chunk, int index) { 1756 int value = data[chunk] != null ? data[chunk][index] : -1; 1757 if (value != -1) { 1758 data[chunk][CHUNK_SIZE + 1]++; 1759 data[chunk][index] = -1; 1760 if (data[chunk][CHUNK_SIZE] == data[chunk][CHUNK_SIZE + 1]) { 1761 data[chunk] = null; 1762 } 1763 } 1764 return value; 1765 } 1766 1767 1772 private final void putIdentifier0(String idName, Element element) { 1773 1774 if (DEBUG_IDS) { 1775 System.out.println("putIdentifier0("+ 1776 idName+", "+ 1777 element+')'); 1778 } 1779 1780 if (identifiers == null) { 1782 identifiers = new java.util.Hashtable (); 1783 } 1784 1785 identifiers.put(idName, element); 1787 1788 } 1790 1791 private static void print(int values[], int start, int end, 1792 int middle, int target) { 1793 1794 if (DEBUG_IDS) { 1795 System.out.print(start); 1796 System.out.print(" ["); 1797 for (int i = start; i < end; i++) { 1798 if (middle == i) { 1799 System.out.print("!"); 1800 } 1801 System.out.print(values[i]); 1802 if (values[i] == target) { 1803 System.out.print("*"); 1804 } 1805 if (i < end - 1) { 1806 System.out.print(" "); 1807 } 1808 } 1809 System.out.println("] "+end); 1810 } 1811 1812 } 1814 1818 1821 static class IntVector { 1822 1823 1827 1828 private int data[]; 1829 1830 1831 private int size; 1832 1833 1837 1838 public int size() { 1839 return size; 1840 } 1841 1842 1843 public int elementAt(int index) { 1844 return data[index]; 1845 } 1846 1847 1848 public void addElement(int element) { 1849 ensureCapacity(size + 1); 1850 data[size++] = element; 1851 } 1852 1853 1854 public void removeAllElements() { 1855 size = 0; 1856 } 1857 1858 1862 1863 private void ensureCapacity(int newsize) { 1864 1865 if (data == null) { 1866 data = new int[newsize + 15]; 1867 } 1868 else if (newsize > data.length) { 1869 int newdata[] = new int[newsize + 15]; 1870 System.arraycopy(data, 0, newdata, 0, data.length); 1871 data = newdata; 1872 } 1873 1874 } 1876 } 1878} | Popular Tags |