1 2 58 59 package org.enhydra.apache.xerces.dom; 60 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 70 106 public abstract class ParentNode 107 extends ChildNode { 108 109 110 static final long serialVersionUID = 2815829867152120872L; 111 112 113 protected CoreDocumentImpl ownerDocument; 114 115 116 protected ChildNode firstChild = null; 117 118 120 121 protected transient int fCachedLength = -1; 122 123 124 protected transient ChildNode fCachedChild; 125 126 127 protected transient int fCachedChildIndex = -1; 128 129 133 137 protected ParentNode(CoreDocumentImpl ownerDocument) { 138 super(ownerDocument); 139 this.ownerDocument = ownerDocument; 140 } 141 142 143 public ParentNode() {} 144 145 149 167 public Node cloneNode(boolean deep) { 168 169 if (needsSyncChildren()) { 170 synchronizeChildren(); 171 } 172 ParentNode newnode = (ParentNode) super.cloneNode(deep); 173 174 newnode.ownerDocument = ownerDocument; 176 177 newnode.firstChild = null; 179 180 newnode.fCachedChildIndex = -1; 182 newnode.fCachedLength = -1; 183 184 if (deep) { 186 for (ChildNode child = firstChild; 187 child != null; 188 child = child.nextSibling) { 189 newnode.appendChild(child.cloneNode(true)); 190 } 191 } 192 193 return newnode; 194 195 } 197 202 public Document getOwnerDocument() { 203 return ownerDocument; 204 } 205 206 210 CoreDocumentImpl ownerDocument() { 211 return ownerDocument; 212 } 213 214 218 void setOwnerDocument(CoreDocumentImpl doc) { 219 if (needsSyncChildren()) { 220 synchronizeChildren(); 221 } 222 super.setOwnerDocument(doc); 223 ownerDocument = doc; 224 for (ChildNode child = firstChild; 225 child != null; child = child.nextSibling) { 226 child.setOwnerDocument(doc); 227 } 228 } 229 230 234 public boolean hasChildNodes() { 235 if (needsSyncChildren()) { 236 synchronizeChildren(); 237 } 238 return firstChild != null; 239 } 240 241 254 public NodeList getChildNodes() { 255 256 if (needsSyncChildren()) { 257 synchronizeChildren(); 258 } 259 return this; 260 261 } 263 264 public Node getFirstChild() { 265 266 if (needsSyncChildren()) { 267 synchronizeChildren(); 268 } 269 return firstChild; 270 271 } 273 274 public Node getLastChild() { 275 276 if (needsSyncChildren()) { 277 synchronizeChildren(); 278 } 279 return lastChild(); 280 281 } 283 final ChildNode lastChild() { 284 return firstChild != null ? firstChild.previousSibling : null; 286 } 287 288 final void lastChild(ChildNode node) { 289 if (firstChild != null) { 291 firstChild.previousSibling = node; 292 } 293 } 294 295 323 public Node insertBefore(Node newChild, Node refChild) 324 throws DOMException { 325 return internalInsertBefore(newChild, refChild, false); 327 } 329 334 Node internalInsertBefore(Node newChild, Node refChild, boolean replace) 335 throws DOMException { 336 337 boolean errorChecking = ownerDocument.errorChecking; 338 339 if (newChild.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE) { 340 347 355 if (errorChecking) { 358 for (Node kid = newChild.getFirstChild(); kid != null; kid = kid.getNextSibling()) { 360 361 if (!ownerDocument.isKidOK(this, kid)) { 362 throw new DOMException ( 363 DOMException.HIERARCHY_REQUEST_ERR, 364 "DOM006 Hierarchy request error"); 365 } 366 } 367 } 368 369 while (newChild.hasChildNodes()) { 370 insertBefore(newChild.getFirstChild(), refChild); 371 } 372 return newChild; 373 } 374 375 if (newChild == refChild) { 376 refChild = refChild.getNextSibling(); 378 removeChild(newChild); 379 insertBefore(newChild, refChild); 380 return newChild; 381 } 382 383 if (needsSyncChildren()) { 384 synchronizeChildren(); 385 } 386 387 if (errorChecking) { 388 if (isReadOnly()) { 389 throw new DOMException ( 390 DOMException.NO_MODIFICATION_ALLOWED_ERR, 391 "DOM001 Modification not allowed"); 392 } 393 if (newChild.getOwnerDocument() != ownerDocument) { 394 throw new DOMException (DOMException.WRONG_DOCUMENT_ERR, 395 "DOM005 Wrong document"); 396 } 397 if (!ownerDocument.isKidOK(this, newChild)) { 398 throw new DOMException (DOMException.HIERARCHY_REQUEST_ERR, 399 "DOM006 Hierarchy request error"); 400 } 401 if (refChild != null && refChild.getParentNode() != this) { 403 throw new DOMException (DOMException.NOT_FOUND_ERR, 404 "DOM008 Not found"); 405 } 406 407 boolean treeSafe = true; 411 for (NodeImpl a = this; treeSafe && a != null; a = a.parentNode()) 412 { 413 treeSafe = newChild != a; 414 } 415 if(!treeSafe) { 416 throw new DOMException (DOMException.HIERARCHY_REQUEST_ERR, 417 "DOM006 Hierarchy request error"); 418 } 419 } 420 421 ownerDocument.insertingNode(this, replace); 423 424 ChildNode newInternal = (ChildNode)newChild; 426 427 Node oldparent = newInternal.parentNode(); 428 if (oldparent != null) { 429 oldparent.removeChild(newInternal); 430 } 431 432 ChildNode refInternal = (ChildNode)refChild; 434 435 newInternal.ownerNode = this; 437 newInternal.isOwned(true); 438 439 if (firstChild == null) { 442 firstChild = newInternal; 444 newInternal.isFirstChild(true); 445 newInternal.previousSibling = newInternal; 446 } 447 else { 448 if (refInternal == null) { 449 ChildNode lastChild = firstChild.previousSibling; 451 lastChild.nextSibling = newInternal; 452 newInternal.previousSibling = lastChild; 453 firstChild.previousSibling = newInternal; 454 } 455 else { 456 if (refChild == firstChild) { 458 firstChild.isFirstChild(false); 460 newInternal.nextSibling = firstChild; 461 newInternal.previousSibling = firstChild.previousSibling; 462 firstChild.previousSibling = newInternal; 463 firstChild = newInternal; 464 newInternal.isFirstChild(true); 465 } 466 else { 467 ChildNode prev = refInternal.previousSibling; 469 newInternal.nextSibling = refInternal; 470 prev.nextSibling = newInternal; 471 refInternal.previousSibling = newInternal; 472 newInternal.previousSibling = prev; 473 } 474 } 475 } 476 477 changed(); 478 479 if (fCachedLength != -1) { 481 fCachedLength++; 482 } 483 if (fCachedChildIndex != -1) { 484 if (fCachedChild == refInternal) { 487 fCachedChild = newInternal; 488 } else { 489 fCachedChildIndex = -1; 491 } 492 } 493 494 ownerDocument.insertedNode(this, newInternal, replace); 496 497 checkNormalizationAfterInsert(newInternal); 498 499 return newChild; 500 501 } 503 515 public Node removeChild(Node oldChild) 516 throws DOMException { 517 return internalRemoveChild(oldChild, false); 519 } 521 526 Node internalRemoveChild(Node oldChild, boolean replace) 527 throws DOMException { 528 529 CoreDocumentImpl ownerDocument = ownerDocument(); 530 if (ownerDocument.errorChecking) { 531 if (isReadOnly()) { 532 throw new DOMException ( 533 DOMException.NO_MODIFICATION_ALLOWED_ERR, 534 "DOM001 Modification not allowed"); 535 } 536 if (oldChild != null && oldChild.getParentNode() != this) { 537 throw new DOMException (DOMException.NOT_FOUND_ERR, 538 "DOM008 Not found"); 539 } 540 } 541 542 ChildNode oldInternal = (ChildNode) oldChild; 543 544 ownerDocument.removingNode(this, oldInternal, replace); 546 547 if (fCachedLength != -1) { 549 fCachedLength--; 550 } 551 if (fCachedChildIndex != -1) { 552 if (fCachedChild == oldInternal) { 555 fCachedChildIndex--; 556 fCachedChild = oldInternal.previousSibling(); 557 } else { 558 fCachedChildIndex = -1; 560 } 561 } 562 563 if (oldInternal == firstChild) { 566 oldInternal.isFirstChild(false); 568 firstChild = oldInternal.nextSibling; 569 if (firstChild != null) { 570 firstChild.isFirstChild(true); 571 firstChild.previousSibling = oldInternal.previousSibling; 572 } 573 } else { 574 ChildNode prev = oldInternal.previousSibling; 575 ChildNode next = oldInternal.nextSibling; 576 prev.nextSibling = next; 577 if (next == null) { 578 firstChild.previousSibling = prev; 580 } else { 581 next.previousSibling = prev; 583 } 584 } 585 586 ChildNode oldPreviousSibling = oldInternal.previousSibling(); 588 589 oldInternal.ownerNode = ownerDocument; 591 oldInternal.isOwned(false); 592 oldInternal.nextSibling = null; 593 oldInternal.previousSibling = null; 594 595 changed(); 596 597 ownerDocument.removedNode(this, replace); 599 600 checkNormalizationAfterRemove(oldPreviousSibling); 601 602 return oldInternal; 603 604 } 606 627 public Node replaceChild(Node newChild, Node oldChild) 628 throws DOMException { 629 635 ownerDocument.replacingNode(this); 637 638 internalInsertBefore(newChild, oldChild, true); 639 if (newChild != oldChild) { 640 internalRemoveChild(oldChild, true); 641 } 642 643 ownerDocument.replacedNode(this); 645 646 return oldChild; 647 } 648 649 653 658 private int nodeListGetLength() { 659 660 if (fCachedLength == -1) { ChildNode node; 662 if (fCachedChildIndex != -1 && fCachedChild != null) { 664 fCachedLength = fCachedChildIndex; 665 node = fCachedChild; 666 } else { 667 node = firstChild; 668 fCachedLength = 0; 669 } 670 for (; node != null; node = node.nextSibling) { 671 fCachedLength++; 672 } 673 } 674 675 return fCachedLength; 676 677 } 679 683 public int getLength() { 684 return nodeListGetLength(); 685 } 686 687 692 private Node nodeListItem(int index) { 693 if (fCachedChildIndex != -1 && fCachedChild != null) { 695 if (fCachedChildIndex < index) { 696 while (fCachedChildIndex < index && fCachedChild != null) { 697 fCachedChildIndex++; 698 fCachedChild = fCachedChild.nextSibling; 699 } 700 } 701 else if (fCachedChildIndex > index) { 702 while (fCachedChildIndex > index && fCachedChild != null) { 703 fCachedChildIndex--; 704 fCachedChild = fCachedChild.previousSibling(); 705 } 706 } 707 return fCachedChild; 708 } 709 710 fCachedChild = firstChild; 712 for (fCachedChildIndex = 0; 713 fCachedChildIndex < index && fCachedChild != null; 714 fCachedChildIndex++) { 715 fCachedChild = fCachedChild.nextSibling; 716 } 717 return fCachedChild; 718 719 } 721 727 public Node item(int index) { 728 return nodeListItem(index); 729 } 731 743 protected final NodeList getChildNodesUnoptimized() { 744 if (needsSyncChildren()) { 745 synchronizeChildren(); 746 } 747 return new NodeList () { 748 751 public int getLength() { 752 return nodeListGetLength(); 753 } 755 758 public Node item(int index) { 759 return nodeListItem(index); 760 } }; 762 } 764 768 773 public void normalize() { 774 if (isNormalized()) { 776 return; 777 } 778 if (needsSyncChildren()) { 779 synchronizeChildren(); 780 } 781 ChildNode kid; 782 for (kid = firstChild; kid != null; kid = kid.nextSibling) { 783 kid.normalize(); 784 } 785 isNormalized(true); 786 } 787 788 792 800 public void setReadOnly(boolean readOnly, boolean deep) { 801 802 super.setReadOnly(readOnly, deep); 803 804 if (deep) { 805 806 if (needsSyncChildren()) { 807 synchronizeChildren(); 808 } 809 810 for (ChildNode mykid = firstChild; 812 mykid != null; 813 mykid = mykid.nextSibling) { 814 if (mykid.getNodeType() != Node.ENTITY_REFERENCE_NODE) { 815 mykid.setReadOnly(readOnly,true); 816 } 817 } 818 } 819 } 821 825 829 protected void synchronizeChildren() { 830 needsSyncChildren(false); 832 } 833 834 849 void checkNormalizationAfterInsert(ChildNode insertedChild) { 850 if (insertedChild.getNodeType() == Node.TEXT_NODE) { 852 ChildNode prev = insertedChild.previousSibling(); 853 ChildNode next = insertedChild.nextSibling; 854 if ((prev != null && prev.getNodeType() == Node.TEXT_NODE) || 857 (next != null && next.getNodeType() == Node.TEXT_NODE)) { 858 isNormalized(false); 859 } 860 } 861 else { 862 if (!insertedChild.isNormalized()) { 865 isNormalized(false); 866 } 867 } 868 } 870 882 void checkNormalizationAfterRemove(ChildNode previousSibling) { 883 if (previousSibling != null && 887 previousSibling.getNodeType() == Node.TEXT_NODE) { 888 889 ChildNode next = previousSibling.nextSibling; 890 if (next != null && next.getNodeType() == Node.TEXT_NODE) { 891 isNormalized(false); 892 } 893 } 894 } 896 900 901 private void writeObject(ObjectOutputStream out) throws IOException { 902 903 if (needsSyncChildren()) { 905 synchronizeChildren(); 906 } 907 out.defaultWriteObject(); 909 910 } 912 913 private void readObject(ObjectInputStream ois) 914 throws ClassNotFoundException , IOException { 915 916 ois.defaultReadObject(); 918 919 922 needsSyncChildren(false); 923 924 fCachedLength = -1; 926 fCachedChildIndex = -1; 927 928 } 930 } | Popular Tags |