1 23 24 package org.enhydra.xml.lazydom; 25 26 import org.enhydra.apache.xerces.dom.DocumentImpl; 27 import org.enhydra.xml.io.OutputOptions; 28 import org.enhydra.xml.io.PreFormattedTextDocument; 29 import org.enhydra.xml.xmlc.XMLObject; 30 import org.enhydra.xml.xmlc.XMLObjectLink; 31 import org.w3c.dom.Attr ; 32 import org.w3c.dom.CDATASection ; 33 import org.w3c.dom.Comment ; 34 import org.w3c.dom.DOMException ; 35 import org.w3c.dom.DOMImplementation ; 36 import org.w3c.dom.Document ; 37 import org.w3c.dom.DocumentType ; 38 import org.w3c.dom.Element ; 39 import org.w3c.dom.Entity ; 40 import org.w3c.dom.EntityReference ; 41 import org.w3c.dom.Node ; 42 import org.w3c.dom.NodeList ; 43 import org.w3c.dom.Notation ; 44 import org.w3c.dom.ProcessingInstruction ; 45 import org.w3c.dom.Text ; 46 47 54 102 public class LazyDocument extends DocumentImpl 103 implements LazyParent, PreFormattedTextDocument, XMLObjectLink { 104 105 112 public LazyDocument(DocumentType documentType, 113 TemplateDOM templateDOM) { 114 super(null); if (templateDOM != null) { 116 fTemplateDOM = templateDOM; 117 fExpandedNodes = new LazyNode[fTemplateDOM.getMaxNodeId()+1]; 118 fExpandedNodes[DOCUMENT_NODE_ID] = this; 119 fTemplateNode = (LazyDocument)fTemplateDOM.getNode(DOCUMENT_NODE_ID); 120 fNodeId = fTemplateNode.getNodeId(); 121 if (documentType != null) { 122 throw new LazyDOMException(LazyDOMException.NOT_SUPPORTED_ERR, 123 "can't specify both DocumentType and TemplateDOM"); 124 } 125 } else { 126 fDocTypeExpanded = true; 128 fChildrenExpanded = true; 129 fIsTemplateNode = true; 131 if (documentType != null) { 136 try { 137 ((LazyDocumentType)documentType).setOwnerDocument(this); 138 } catch (ClassCastException e) { 139 throw new LazyDOMException(LazyDOMException.WRONG_DOCUMENT_ERR, 140 "DOM005 Wrong document"); 141 } 142 appendChild(documentType); 143 } 144 } 145 } 146 147 150 public LazyDocument() { 151 this(null, null); 152 } 153 154 157 public Element getDocumentElement() { 158 if (!fChildrenExpanded) { 159 expandChildren(); 160 } 161 return super.getDocumentElement(); 162 } 163 164 167 public DOMImplementation getImplementation() { 168 return LazyDOMImplementation.getDOMImplementation(); 169 } 170 171 175 179 private TemplateDOM fTemplateDOM; 180 181 185 private LazyNode[] fExpandedNodes; 186 187 190 private boolean fExpanding = false; 191 192 196 protected final void enterExpansion() { 197 if (fExpanding) { 198 throw new LazyDOMError("recursive call doing lazy DOM expansion"); 199 } 200 fExpanding = true; 201 } 202 203 207 protected final void leaveExpansion() { 208 fExpanding = false; 209 } 210 211 216 private LazyNode createLazyNode(int nodeId) { 217 LazyNode template = fTemplateDOM.getNode(nodeId); 218 switch (template.getNodeType()) { 219 case ELEMENT_NODE: 220 return createElement(nodeId); 221 case ATTRIBUTE_NODE: 222 return createAttribute(nodeId); 223 case TEXT_NODE: 224 return createTextNode(nodeId); 225 case CDATA_SECTION_NODE: 226 return createCDATASection(nodeId); 227 case ENTITY_REFERENCE_NODE: 228 return createEntityReference(nodeId); 229 case ENTITY_NODE: 230 return createEntity(nodeId); 231 case PROCESSING_INSTRUCTION_NODE: 232 return createProcessingInstruction(nodeId); 233 case COMMENT_NODE: 234 return createComment(nodeId); 235 case NOTATION_NODE: 236 return createNotation(nodeId); 237 case DOCUMENT_TYPE_NODE: 238 return createDocumentType(nodeId); 239 case DOCUMENT_NODE: 240 case DOCUMENT_FRAGMENT_NODE: 241 throw new LazyDOMError(nodeId, "Can't create node from template of type " 242 + template.getNodeType()); 243 default: 244 throw new LazyDOMError(nodeId, "Invalid node type " 245 + template.getNodeType()); 246 } 247 } 248 249 254 public final LazyNode getNodeById(int nodeId) { 255 if (fExpandedNodes[nodeId] == null) { 256 synchronized(this) { 257 if (fExpandedNodes[nodeId] == null) { 258 fExpandedNodes[nodeId] = createLazyNode(nodeId); 259 } 260 } 261 } 262 return fExpandedNodes[nodeId]; 263 } 264 265 269 public final LazyNode getNodeFromTemplate(LazyNode template) { 270 return getNodeById(template.getNodeId()); 271 } 272 273 278 private void expandNodeChildren(LazyParent node) { 279 if (!node.areChildrenExpanded()) { 280 LazyNode template = node.getTemplateNode(); 281 if (template == null) { 282 throw new LazyDOMError("bug: expandNodeChildren null template on: " 283 + node.getClass()); } 285 for (LazyNode templateChild = (LazyNode)template.getFirstChild(); 286 templateChild != null; 287 templateChild = (LazyNode)templateChild.getNextSibling()) { 288 if (!(templateChild instanceof DocumentType )) { 290 LazyNode child = getNodeFromTemplate(templateChild); 291 node.appendChildWhileExpanding(child); 292 if (child instanceof LazyParent) { 293 ((LazyParent)child).setParentExpanded(); 295 } 296 } 297 } 298 node.setChildrenExpanded(); 299 } 300 } 301 302 309 protected synchronized void doExpandParent(LazyParent node) { 310 if (!node.isParentExpanded() && !fExpanding) { 314 enterExpansion(); 315 try { 316 LazyParent parentTemplate = (LazyParent)node.getTemplateNode().getParentNode(); 317 if (parentTemplate != null) { 318 expandNodeChildren((LazyParent)getNodeFromTemplate(parentTemplate)); 319 } 320 node.setParentExpanded(); 321 } finally { 322 leaveExpansion(); 323 } 324 } 325 } 326 327 334 protected synchronized void doExpandChildren(LazyParent node) { 335 enterExpansion(); 336 try { 337 expandNodeChildren(node); 338 } finally { 339 leaveExpansion(); 340 } 341 } 342 343 347 public final LazyNode getExpandedNode(int nodeId) { 348 return fExpandedNodes[nodeId]; 349 } 350 351 354 public final LazyNode getTemplateNode(int nodeId) { 355 return fTemplateDOM.getNode(nodeId); 356 } 357 358 362 365 private boolean fDocTypeExpanded = false; 366 367 371 private boolean fExpandingDocType = false; 372 373 376 private LazyDocument fTemplateNode = null; 377 378 381 public boolean isDocTypeExpanded() { 382 return fDocTypeExpanded; 383 } 384 385 389 public LazyDocument getTemplateDocument() { 390 return fTemplateNode; 391 } 392 393 396 public Node cloneNode(boolean deep) { 397 400 if (deep) { 401 if (!fDocTypeExpanded) { 403 doExpandDocType(); 404 } 405 if (!fChildrenExpanded) { 406 expandChildren(); 407 } 408 } 409 410 415 LazyDocument newdoc = new LazyDocument(); 416 newdoc.fTemplateDOM = null; 417 newdoc.fExpandedNodes = null; 418 newdoc.fDocTypeExpanded = true; 419 newdoc.fChildrenExpanded = true; 420 421 cloneNode(newdoc, deep); 422 newdoc.mutationEvents = mutationEvents; 423 return newdoc; 424 } 425 426 430 433 private int fNodeId = NULL_NODE_ID; 434 435 438 private boolean fIsTemplateNode; 439 440 443 public void makeTemplateNode(int nodeId) { 444 fNodeId = nodeId; 445 fIsTemplateNode = true; 446 } 447 448 451 public int getNodeId() { 452 return fNodeId; 453 } 454 455 458 public boolean isTemplateNode() { 459 return fIsTemplateNode; 460 } 461 462 465 public LazyNode getTemplateNode() { 466 return fTemplateNode; 467 } 468 469 472 public LazyNode templateClone(Document ownerDocument) { 473 throw new LazyDOMError("templateClone not support on LazyDocument node"); 474 } 475 476 481 public void setNodeValue(String value) { 482 fNodeId = NULL_NODE_ID; 483 super.setNodeValue(value); 484 } 485 486 490 494 private boolean fChildrenExpanded = false; 495 496 499 public boolean isParentExpanded() { 500 return true; 501 } 502 503 506 public void setParentExpanded() { 507 throw new LazyDOMError("setParentExpanded invalid on document"); 508 } 509 510 513 public void setParentWhileExpanding(Node parent) { 514 throw new LazyDOMError("setParentWhileExpanding invalid on document"); 515 } 516 517 520 public boolean areChildrenExpanded() { 521 return fChildrenExpanded; 522 } 523 524 527 public void setChildrenExpanded() { 528 fChildrenExpanded = true; 529 } 530 531 534 public void appendChildWhileExpanding(Node child) { 535 super.insertBefore(child, null); 536 } 537 538 541 private void expandParent() { 542 doExpandParent(this); 543 } 544 545 548 private void expandChildren() { 549 doExpandChildren(this); 550 } 551 552 555 public NodeList getChildNodes() { 556 if (!fChildrenExpanded) { 557 expandChildren(); 558 } 559 return super.getChildNodes(); 560 } 561 562 565 public Node getFirstChild() { 566 if (!fChildrenExpanded) { 567 expandChildren(); 568 } 569 return super.getFirstChild(); 570 } 571 572 575 public Node getLastChild() { 576 if (!fChildrenExpanded) { 577 expandChildren(); 578 } 579 return super.getLastChild(); 580 } 581 582 585 public Node insertBefore(Node newChild, 586 Node refChild) 587 throws DOMException { 588 if (!fChildrenExpanded) { 589 expandChildren(); 590 } 591 return super.insertBefore(newChild, refChild); 592 } 593 594 597 public Node replaceChild(Node newChild, 598 Node oldChild) 599 throws DOMException { 600 if (!fChildrenExpanded) { 601 expandChildren(); 602 } 603 return super.replaceChild(newChild, oldChild); 604 } 605 606 609 public Node removeChild(Node oldChild) 610 throws DOMException { 611 if (!fChildrenExpanded) { 612 expandChildren(); 613 } 614 return super.removeChild(oldChild); 615 } 616 617 620 public Node appendChild(Node newChild) 621 throws DOMException { 622 if (!fChildrenExpanded) { 623 expandChildren(); 624 } 625 return super.appendChild(newChild); 626 } 627 628 631 public boolean hasChildNodes() { 632 if (!fChildrenExpanded) { 633 return fTemplateNode.hasChildNodes(); 634 } else { 635 return super.hasChildNodes(); 636 } 637 } 638 639 642 public void normalize() { 643 if (!fChildrenExpanded) { 644 expandChildren(); 645 } 646 super.normalize(); 647 } 648 649 653 656 private synchronized void doExpandDocType() { 657 if (!fDocTypeExpanded) { 658 if (fExpandingDocType) { 659 throw new LazyDOMError("recursive call expanding Lazy DOM DocumentType"); 660 } 661 fExpandingDocType = true; 662 try { 663 LazyDocumentType template = (LazyDocumentType)fTemplateNode.getDoctype(); 664 if (template != null) { 665 docType = (LazyDocumentType)getNodeFromTemplate(template); 666 } 667 fDocTypeExpanded = true; 668 } finally { 669 fExpandingDocType = false; 670 } 671 } 672 } 673 674 677 public DocumentType getDoctype() { 678 if (!fDocTypeExpanded) { 679 doExpandDocType(); 680 } 681 return super.getDoctype(); 682 } 683 684 688 691 public Element createElement(String tagName) throws DOMException { 692 return new LazyElementNoNS(this, null, tagName); 693 } 694 695 698 public Text createTextNode(String data) { 699 return new LazyText(this, null, data); 700 } 701 702 705 public Comment createComment(String data) { 706 return new LazyComment(this, null, data); 707 } 708 709 712 public CDATASection createCDATASection(String data) throws DOMException { 713 return new LazyCDATASection(this, null, data); 714 } 715 716 719 public ProcessingInstruction createProcessingInstruction(String target, 720 String data) { 721 return new LazyProcessingInstruction(this, null, target, data); 722 } 723 724 727 public Attr createAttribute(String name) throws DOMException { 728 return new LazyAttrNoNS(this, null, name); 729 } 730 731 734 public Notation createNotation(String name) throws DOMException { 735 return new LazyNotation(this, null, name, null, null); 736 } 737 738 741 public EntityReference createEntityReference(String name) throws DOMException { 742 return new LazyEntityReference(this, null, name); 743 } 744 745 748 public Element createElementNS(String namespaceURI, 749 String qualifiedName) throws DOMException { 750 return new LazyElementNS(this, null, namespaceURI, qualifiedName); 751 } 752 753 756 public Attr createAttributeNS(String namespaceURI, 757 String qualifiedName) throws DOMException { 758 return new LazyAttrNS(this, null, namespaceURI, qualifiedName); 759 } 760 761 765 public DocumentType createDocumentType(String qualifiedName, 766 String publicID, 767 String systemID, 768 String internalSubset) throws DOMException { 769 return new LazyDocumentType(this, null, qualifiedName, publicID, systemID, internalSubset); 770 } 771 772 777 public DocumentType createDocumentType(String qualifiedName, 778 String publicID, 779 String systemID) throws DOMException { 780 781 return new LazyDocumentType(this, null, qualifiedName, publicID, systemID, null); 782 783 } 784 788 public Entity createEntity(String name) throws DOMException { 789 return new LazyEntity(this, null, name, null, null, null); 790 } 791 792 796 800 public LazyElement createElement(int nodeId) throws DOMException { 801 Node template = (LazyElement)fTemplateDOM.getNode(nodeId); 802 if (template instanceof LazyElementNS) { 803 return new LazyElementNS(this, (LazyElementNS)template, null, null); 804 } else { 805 return new LazyElementNoNS(this, (LazyElementNoNS)template, null); 806 } 807 } 808 809 813 public LazyText createTextNode(int nodeId) { 814 return new LazyText(this, (LazyText)fTemplateDOM.getNode(nodeId), null); 815 } 816 817 821 public LazyComment createComment(int nodeId) { 822 return new LazyComment(this, (LazyComment)fTemplateDOM.getNode(nodeId), null); 823 } 824 825 829 public LazyCDATASection createCDATASection(int nodeId) throws DOMException { 830 return new LazyCDATASection(this, (LazyCDATASection)fTemplateDOM.getNode(nodeId), null); 831 } 832 833 837 public LazyProcessingInstruction createProcessingInstruction(int nodeId) { 838 return new LazyProcessingInstruction(this, (LazyProcessingInstruction)fTemplateDOM.getNode(nodeId), null, null); 839 } 840 841 845 public LazyAttr createAttribute(int nodeId) throws DOMException { 846 Node template = fTemplateDOM.getNode(nodeId); 847 if (template instanceof LazyAttrNS) { 848 return new LazyAttrNS(this, (LazyAttrNS)template, null, null); 849 } else { 850 return new LazyAttrNoNS(this, (LazyAttrNoNS)fTemplateDOM.getNode(nodeId), null); 851 } 852 } 853 854 858 public LazyNotation createNotation(int nodeId) throws DOMException { 859 return new LazyNotation(this, (LazyNotation)fTemplateDOM.getNode(nodeId), 860 null, null, null); 861 } 862 863 867 public LazyEntityReference createEntityReference(int nodeId) throws DOMException { 868 return new LazyEntityReference(this, (LazyEntityReference)fTemplateDOM.getNode(nodeId), null); 869 } 870 871 875 public LazyDocumentType createDocumentType(int nodeId) throws DOMException { 876 return new LazyDocumentType(this, (LazyDocumentType)fTemplateDOM.getNode(nodeId), 879 null, null, null, null); 880 } 881 882 886 public LazyEntity createEntity(int nodeId) throws DOMException { 887 return new LazyEntity(this, (LazyEntity)fTemplateDOM.getNode(nodeId), 888 null, null, null, null); 889 } 890 891 895 902 public LazyElement createTemplateElement(String tagName, 903 int nodeId, 904 String preFormattedText) throws DOMException { 905 LazyElement element = (LazyElement)createElement(tagName); 906 element.makeTemplateNode(nodeId, preFormattedText); 907 return element; 908 } 909 910 917 public LazyText createTemplateTextNode(String data, 918 int nodeId, 919 String preFormattedText) { 920 LazyText text = (LazyText)createTextNode(data); 921 text.makeTemplateNode(nodeId, preFormattedText); 922 return text; 923 } 924 925 932 public LazyComment createTemplateComment(String data, 933 int nodeId) { 934 LazyComment comment = (LazyComment)createComment(data); 935 comment.makeTemplateNode(nodeId); 936 return comment; 937 } 938 939 946 public LazyCDATASection createTemplateCDATASection(String data, 947 int nodeId) throws DOMException { 948 LazyCDATASection cdataSection = (LazyCDATASection)createCDATASection(data); 949 cdataSection.makeTemplateNode(nodeId); 950 return cdataSection; 951 } 952 953 960 public LazyProcessingInstruction createTemplateProcessingInstruction(String target, 961 String data, 962 int nodeId) { 963 LazyProcessingInstruction pi = (LazyProcessingInstruction)createProcessingInstruction(target, data); 964 pi.makeTemplateNode(nodeId); 965 return pi; 966 } 967 968 975 public LazyAttr createTemplateAttribute(String name, 976 int nodeId) throws DOMException { 977 LazyAttr attr = (LazyAttr)createAttribute(name); 978 attr.makeTemplateNode(nodeId); 979 return attr; 980 } 981 982 989 public LazyAttr createTemplateAttributeNS(String namespaceURI, 990 String qualifiedName, 991 int nodeId) throws DOMException { 992 LazyAttr attr = (LazyAttr)createAttributeNS(namespaceURI, qualifiedName); 993 attr.makeTemplateNode(nodeId); 994 return attr; 995 } 996 997 1004 public LazyNotation createTemplateNotation(String name, 1005 int nodeId) throws DOMException { 1006 LazyNotation notation = (LazyNotation) createNotation(name); 1007 notation.makeTemplateNode(nodeId); 1008 return notation; 1009 } 1010 1011 1018 public LazyEntityReference createTemplateEntityReference(String name, 1019 int nodeId) throws DOMException { 1020 LazyEntityReference entityRef = (LazyEntityReference)createEntityReference(name); 1021 entityRef.makeTemplateNode(nodeId); 1022 return entityRef; 1023 } 1024 1025 1032 public LazyElement createTemplateElementNS(String namespaceURI, 1033 String qualifiedName, 1034 int nodeId, 1035 String preFormattedText) throws DOMException { 1036 LazyElement element = (LazyElement)createElementNS(namespaceURI, 1037 qualifiedName); 1038 element.makeTemplateNode(nodeId, preFormattedText); 1039 return element; 1040 } 1041 1042 1049 public LazyAttr createAttributeNS(String namespaceURI, 1050 String qualifiedName, 1051 int nodeId) throws DOMException { 1052 LazyAttr attr = (LazyAttr)createAttributeNS(namespaceURI, qualifiedName); 1053 attr.makeTemplateNode(nodeId); 1054 return attr; 1055 } 1056 1057 1063 public LazyDocumentType createTemplateDocumentType(String qualifiedName, 1064 String publicID, 1065 String systemID, 1066 String internalSubset, 1067 int nodeId) throws DOMException { 1068 LazyDocumentType docType = new LazyDocumentType(this, null, qualifiedName, publicID, 1069 systemID, internalSubset); 1070 docType.makeTemplateNode(nodeId); 1071 return docType; 1072 } 1073 1074 1080 public LazyEntity createTemplateEntity(String name, 1081 String publicId, 1082 String systemId, 1083 String notationName, 1084 int nodeId) throws DOMException { 1085 LazyEntity entity = new LazyEntity(this, null, name, publicId, 1086 systemId, notationName); 1087 entity.makeTemplateNode(nodeId); 1088 return entity; 1089 } 1090 1091 1095 1098 private OutputOptions fPreFormatOutputOptions; 1099 1100 1104 public void setPreFormatOutputOptions(OutputOptions outputOptions) { 1105 fPreFormatOutputOptions = outputOptions; 1106 } 1107 1108 1111 public OutputOptions getPreFormatOutputOptions() { 1112 return fPreFormatOutputOptions; 1113 } 1114 1115 1119 1122 private XMLObject fXmlObjectLink; 1123 1124 1127 public void setXMLObject(XMLObject xmlObject) { 1128 fXmlObjectLink = xmlObject; 1129 } 1130 1131 1134 public XMLObject getXMLObject() { 1135 return fXmlObjectLink; 1136 } 1137} 1138 | Popular Tags |