1 57 58 package com.sun.org.apache.xerces.internal.dom; 59 60 import java.io.Serializable ; 61 import java.io.IOException ; 62 import java.io.ObjectInputStream ; 63 import java.io.ObjectOutputStream ; 64 65 import org.w3c.dom.DOMException ; 66 import org.w3c.dom.Document ; 67 import org.w3c.dom.Node ; 68 import org.w3c.dom.NodeList ; 69 import org.w3c.dom.UserDataHandler ; 70 71 108 public abstract class ParentNode 109 extends ChildNode { 110 111 112 static final long serialVersionUID = 2815829867152120872L; 113 114 115 protected CoreDocumentImpl ownerDocument; 116 117 118 protected ChildNode firstChild = null; 119 120 122 123 protected transient NodeListCache fNodeListCache = null; 124 125 129 133 protected ParentNode(CoreDocumentImpl ownerDocument) { 134 super(ownerDocument); 135 this.ownerDocument = ownerDocument; 136 } 137 138 139 public ParentNode() {} 140 141 145 163 public Node cloneNode(boolean deep) { 164 165 if (needsSyncChildren()) { 166 synchronizeChildren(); 167 } 168 ParentNode newnode = (ParentNode) super.cloneNode(deep); 169 170 newnode.ownerDocument = ownerDocument; 172 173 newnode.firstChild = null; 175 176 newnode.fNodeListCache = null; 178 179 if (deep) { 181 for (ChildNode child = firstChild; 182 child != null; 183 child = child.nextSibling) { 184 newnode.appendChild(child.cloneNode(true)); 185 } 186 } 187 188 return newnode; 189 190 } 192 197 public Document getOwnerDocument() { 198 return ownerDocument; 199 } 200 201 205 CoreDocumentImpl ownerDocument() { 206 return ownerDocument; 207 } 208 209 213 void setOwnerDocument(CoreDocumentImpl doc) { 214 if (needsSyncChildren()) { 215 synchronizeChildren(); 216 } 217 super.setOwnerDocument(doc); 218 ownerDocument = doc; 219 for (ChildNode child = firstChild; 220 child != null; child = child.nextSibling) { 221 child.setOwnerDocument(doc); 222 } 223 } 224 225 229 public boolean hasChildNodes() { 230 if (needsSyncChildren()) { 231 synchronizeChildren(); 232 } 233 return firstChild != null; 234 } 235 236 249 public NodeList getChildNodes() { 250 251 if (needsSyncChildren()) { 252 synchronizeChildren(); 253 } 254 return this; 255 256 } 258 259 public Node getFirstChild() { 260 261 if (needsSyncChildren()) { 262 synchronizeChildren(); 263 } 264 return firstChild; 265 266 } 268 269 public Node getLastChild() { 270 271 if (needsSyncChildren()) { 272 synchronizeChildren(); 273 } 274 return lastChild(); 275 276 } 278 final ChildNode lastChild() { 279 return firstChild != null ? firstChild.previousSibling : null; 281 } 282 283 final void lastChild(ChildNode node) { 284 if (firstChild != null) { 286 firstChild.previousSibling = node; 287 } 288 } 289 290 318 public Node insertBefore(Node newChild, Node refChild) 319 throws DOMException { 320 return internalInsertBefore(newChild, refChild, false); 322 } 324 329 Node internalInsertBefore(Node newChild, Node refChild, boolean replace) 330 throws DOMException { 331 332 boolean errorChecking = ownerDocument.errorChecking; 333 334 if (newChild.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE) { 335 342 350 if (errorChecking) { 353 for (Node kid = newChild.getFirstChild(); kid != null; kid = kid.getNextSibling()) { 355 356 if (!ownerDocument.isKidOK(this, kid)) { 357 throw new DOMException ( 358 DOMException.HIERARCHY_REQUEST_ERR, 359 DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "HIERARCHY_REQUEST_ERR", null)); 360 } 361 } 362 } 363 364 while (newChild.hasChildNodes()) { 365 insertBefore(newChild.getFirstChild(), refChild); 366 } 367 return newChild; 368 } 369 370 if (newChild == refChild) { 371 refChild = refChild.getNextSibling(); 373 removeChild(newChild); 374 insertBefore(newChild, refChild); 375 return newChild; 376 } 377 378 if (needsSyncChildren()) { 379 synchronizeChildren(); 380 } 381 382 if (errorChecking) { 383 if (isReadOnly()) { 384 throw new DOMException ( 385 DOMException.NO_MODIFICATION_ALLOWED_ERR, 386 DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null)); 387 } 388 if (newChild.getOwnerDocument() != ownerDocument && newChild != ownerDocument) { 389 throw new DOMException (DOMException.WRONG_DOCUMENT_ERR, 390 DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "WRONG_DOCUMENT_ERR", null)); 391 } 392 if (!ownerDocument.isKidOK(this, newChild)) { 393 throw new DOMException (DOMException.HIERARCHY_REQUEST_ERR, 394 DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "HIERARCHY_REQUEST_ERR", null)); 395 } 396 if (refChild != null && refChild.getParentNode() != this) { 398 throw new DOMException (DOMException.NOT_FOUND_ERR, 399 DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NOT_FOUND_ERR", null)); 400 } 401 402 boolean treeSafe = true; 406 for (NodeImpl a = this; treeSafe && a != null; a = a.parentNode()) 407 { 408 treeSafe = newChild != a; 409 } 410 if(!treeSafe) { 411 throw new DOMException (DOMException.HIERARCHY_REQUEST_ERR, 412 DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "HIERARCHY_REQUEST_ERR", null)); 413 } 414 } 415 416 ownerDocument.insertingNode(this, replace); 418 419 ChildNode newInternal = (ChildNode)newChild; 421 422 Node oldparent = newInternal.parentNode(); 423 if (oldparent != null) { 424 oldparent.removeChild(newInternal); 425 } 426 427 ChildNode refInternal = (ChildNode)refChild; 429 430 newInternal.ownerNode = this; 432 newInternal.isOwned(true); 433 434 if (firstChild == null) { 437 firstChild = newInternal; 439 newInternal.isFirstChild(true); 440 newInternal.previousSibling = newInternal; 441 } 442 else { 443 if (refInternal == null) { 444 ChildNode lastChild = firstChild.previousSibling; 446 lastChild.nextSibling = newInternal; 447 newInternal.previousSibling = lastChild; 448 firstChild.previousSibling = newInternal; 449 } 450 else { 451 if (refChild == firstChild) { 453 firstChild.isFirstChild(false); 455 newInternal.nextSibling = firstChild; 456 newInternal.previousSibling = firstChild.previousSibling; 457 firstChild.previousSibling = newInternal; 458 firstChild = newInternal; 459 newInternal.isFirstChild(true); 460 } 461 else { 462 ChildNode prev = refInternal.previousSibling; 464 newInternal.nextSibling = refInternal; 465 prev.nextSibling = newInternal; 466 refInternal.previousSibling = newInternal; 467 newInternal.previousSibling = prev; 468 } 469 } 470 } 471 472 changed(); 473 474 if (fNodeListCache != null) { 476 if (fNodeListCache.fLength != -1) { 477 fNodeListCache.fLength++; 478 } 479 if (fNodeListCache.fChildIndex != -1) { 480 if (fNodeListCache.fChild == refInternal) { 483 fNodeListCache.fChild = newInternal; 484 } else { 485 fNodeListCache.fChildIndex = -1; 487 } 488 } 489 } 490 491 ownerDocument.insertedNode(this, newInternal, replace); 493 494 checkNormalizationAfterInsert(newInternal); 495 496 return newChild; 497 498 } 500 512 public Node removeChild(Node oldChild) 513 throws DOMException { 514 return internalRemoveChild(oldChild, false); 516 } 518 523 Node internalRemoveChild(Node oldChild, boolean replace) 524 throws DOMException { 525 526 CoreDocumentImpl ownerDocument = ownerDocument(); 527 if (ownerDocument.errorChecking) { 528 if (isReadOnly()) { 529 throw new DOMException ( 530 DOMException.NO_MODIFICATION_ALLOWED_ERR, 531 DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null)); 532 } 533 if (oldChild != null && oldChild.getParentNode() != this) { 534 throw new DOMException (DOMException.NOT_FOUND_ERR, 535 DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NOT_FOUND_ERR", null)); 536 } 537 } 538 539 ChildNode oldInternal = (ChildNode) oldChild; 540 541 ownerDocument.removingNode(this, oldInternal, replace); 543 544 if (fNodeListCache != null) { 546 if (fNodeListCache.fLength != -1) { 547 fNodeListCache.fLength--; 548 } 549 if (fNodeListCache.fChildIndex != -1) { 550 if (fNodeListCache.fChild == oldInternal) { 553 fNodeListCache.fChildIndex--; 554 fNodeListCache.fChild = oldInternal.previousSibling(); 555 } else { 556 fNodeListCache.fChildIndex = -1; 558 } 559 } 560 } 561 562 if (oldInternal == firstChild) { 565 oldInternal.isFirstChild(false); 567 firstChild = oldInternal.nextSibling; 568 if (firstChild != null) { 569 firstChild.isFirstChild(true); 570 firstChild.previousSibling = oldInternal.previousSibling; 571 } 572 } else { 573 ChildNode prev = oldInternal.previousSibling; 574 ChildNode next = oldInternal.nextSibling; 575 prev.nextSibling = next; 576 if (next == null) { 577 firstChild.previousSibling = prev; 579 } else { 580 next.previousSibling = prev; 582 } 583 } 584 585 ChildNode oldPreviousSibling = oldInternal.previousSibling(); 587 588 oldInternal.ownerNode = ownerDocument; 590 oldInternal.isOwned(false); 591 oldInternal.nextSibling = null; 592 oldInternal.previousSibling = null; 593 594 changed(); 595 596 ownerDocument.removedNode(this, replace); 598 599 checkNormalizationAfterRemove(oldPreviousSibling); 600 601 return oldInternal; 602 603 } 605 626 public Node replaceChild(Node newChild, Node oldChild) 627 throws DOMException { 628 634 ownerDocument.replacingNode(this); 636 637 internalInsertBefore(newChild, oldChild, true); 638 if (newChild != oldChild) { 639 internalRemoveChild(oldChild, true); 640 } 641 642 ownerDocument.replacedNode(this); 644 645 return oldChild; 646 } 647 648 652 public String getTextContent() throws DOMException { 653 Node child = getFirstChild(); 654 if (child != null) { 655 Node next = child.getNextSibling(); 656 if (next == null) { 657 return hasTextContent(child) ? ((NodeImpl) child).getTextContent() : ""; 658 } 659 if (fBufferStr == null){ 660 fBufferStr = new StringBuffer (); 661 } 662 else { 663 fBufferStr.setLength(0); 664 } 665 getTextContent(fBufferStr); 666 return fBufferStr.toString(); 667 } 668 return ""; 669 } 670 671 void getTextContent(StringBuffer buf) throws DOMException { 673 Node child = getFirstChild(); 674 while (child != null) { 675 if (hasTextContent(child)) { 676 ((NodeImpl) child).getTextContent(buf); 677 } 678 child = child.getNextSibling(); 679 } 680 } 681 682 final boolean hasTextContent(Node child) { 684 return child.getNodeType() != Node.COMMENT_NODE && 685 child.getNodeType() != Node.PROCESSING_INSTRUCTION_NODE && 686 (child.getNodeType() != Node.TEXT_NODE || 687 ((TextImpl) child).isIgnorableWhitespace() == false); 688 } 689 690 694 public void setTextContent(String textContent) 695 throws DOMException { 696 Node child; 698 while ((child = getFirstChild()) != null) { 699 removeChild(child); 700 } 701 if (textContent != null && textContent.length() != 0){ 703 appendChild(ownerDocument().createTextNode(textContent)); 704 } 705 } 706 707 711 716 private int nodeListGetLength() { 717 718 if (fNodeListCache == null) { 719 if (firstChild == null) { 721 return 0; 722 } 723 if (firstChild == lastChild()) { 724 return 1; 725 } 726 fNodeListCache = ownerDocument.getNodeListCache(this); 728 } 729 if (fNodeListCache.fLength == -1) { int l; 731 ChildNode n; 732 if (fNodeListCache.fChildIndex != -1 && 734 fNodeListCache.fChild != null) { 735 l = fNodeListCache.fChildIndex; 736 n = fNodeListCache.fChild; 737 } else { 738 n = firstChild; 739 l = 0; 740 } 741 while (n != null) { 742 l++; 743 n = n.nextSibling; 744 } 745 fNodeListCache.fLength = l; 746 } 747 748 return fNodeListCache.fLength; 749 750 } 752 756 public int getLength() { 757 return nodeListGetLength(); 758 } 759 760 765 private Node nodeListItem(int index) { 766 767 if (fNodeListCache == null) { 768 if (firstChild == lastChild()) { 770 return index == 0 ? firstChild : null; 771 } 772 fNodeListCache = ownerDocument.getNodeListCache(this); 774 } 775 int i = fNodeListCache.fChildIndex; 776 ChildNode n = fNodeListCache.fChild; 777 boolean firstAccess = true; 778 if (i != -1 && n != null) { 780 firstAccess = false; 781 if (i < index) { 782 while (i < index && n != null) { 783 i++; 784 n = n.nextSibling; 785 } 786 } 787 else if (i > index) { 788 while (i > index && n != null) { 789 i--; 790 n = n.previousSibling(); 791 } 792 } 793 } 794 else { 795 n = firstChild; 797 for (i = 0; i < index && n != null; i++) { 798 n = n.nextSibling; 799 } 800 } 801 802 if (!firstAccess && (n == firstChild || n == lastChild())) { 804 fNodeListCache.fChildIndex = -1; 805 fNodeListCache.fChild = null; 806 ownerDocument.freeNodeListCache(fNodeListCache); 807 } 812 else { 813 fNodeListCache.fChildIndex = i; 815 fNodeListCache.fChild = n; 816 } 817 return n; 818 819 } 821 827 public Node item(int index) { 828 return nodeListItem(index); 829 } 831 843 protected final NodeList getChildNodesUnoptimized() { 844 if (needsSyncChildren()) { 845 synchronizeChildren(); 846 } 847 return new NodeList () { 848 851 public int getLength() { 852 return nodeListGetLength(); 853 } 855 858 public Node item(int index) { 859 return nodeListItem(index); 860 } }; 862 } 864 868 873 public void normalize() { 874 if (isNormalized()) { 876 return; 877 } 878 if (needsSyncChildren()) { 879 synchronizeChildren(); 880 } 881 ChildNode kid; 882 for (kid = firstChild; kid != null; kid = kid.nextSibling) { 883 kid.normalize(); 884 } 885 isNormalized(true); 886 } 887 888 892 public boolean isEqualNode(Node arg) { 893 if (!super.isEqualNode(arg)) { 894 return false; 895 } 896 Node child1 = getFirstChild(); 900 Node child2 = arg.getFirstChild(); 901 while (child1 != null && child2 != null) { 902 if (!((NodeImpl) child1).isEqualNode(child2)) { 903 return false; 904 } 905 child1 = child1.getNextSibling(); 906 child2 = child2.getNextSibling(); 907 } 908 if (child1 != child2) { 909 return false; 910 } 911 return true; 912 } 913 914 918 926 public void setReadOnly(boolean readOnly, boolean deep) { 927 928 super.setReadOnly(readOnly, deep); 929 930 if (deep) { 931 932 if (needsSyncChildren()) { 933 synchronizeChildren(); 934 } 935 936 for (ChildNode mykid = firstChild; 938 mykid != null; 939 mykid = mykid.nextSibling) { 940 if (mykid.getNodeType() != Node.ENTITY_REFERENCE_NODE) { 941 mykid.setReadOnly(readOnly,true); 942 } 943 } 944 } 945 } 947 951 955 protected void synchronizeChildren() { 956 needsSyncChildren(false); 958 } 959 960 975 void checkNormalizationAfterInsert(ChildNode insertedChild) { 976 if (insertedChild.getNodeType() == Node.TEXT_NODE) { 978 ChildNode prev = insertedChild.previousSibling(); 979 ChildNode next = insertedChild.nextSibling; 980 if ((prev != null && prev.getNodeType() == Node.TEXT_NODE) || 983 (next != null && next.getNodeType() == Node.TEXT_NODE)) { 984 isNormalized(false); 985 } 986 } 987 else { 988 if (!insertedChild.isNormalized()) { 991 isNormalized(false); 992 } 993 } 994 } 996 1008 void checkNormalizationAfterRemove(ChildNode previousSibling) { 1009 if (previousSibling != null && 1013 previousSibling.getNodeType() == Node.TEXT_NODE) { 1014 1015 ChildNode next = previousSibling.nextSibling; 1016 if (next != null && next.getNodeType() == Node.TEXT_NODE) { 1017 isNormalized(false); 1018 } 1019 } 1020 } 1022 1026 1027 private void writeObject(ObjectOutputStream out) throws IOException { 1028 1029 if (needsSyncChildren()) { 1031 synchronizeChildren(); 1032 } 1033 out.defaultWriteObject(); 1035 1036 } 1038 1039 private void readObject(ObjectInputStream ois) 1040 throws ClassNotFoundException , IOException { 1041 1042 ois.defaultReadObject(); 1044 1045 needsSyncChildren(false); 1048 1049 } 1051 1054 class UserDataRecord implements Serializable { 1055 Object fData; 1056 UserDataHandler fHandler; 1057 UserDataRecord(Object data, UserDataHandler handler) { 1058 fData = data; 1059 fHandler = handler; 1060 } 1061 } 1062} | Popular Tags |