All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.marklogic.dom.DocumentImpl Maven / Gradle / Ivy

/*
 * Copyright 2003-2019 MarkLogic Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.marklogic.dom;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Attr;
import org.w3c.dom.CDATASection;
import org.w3c.dom.Comment;
import org.w3c.dom.DOMConfiguration;
import org.w3c.dom.DOMException;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.EntityReference;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.Text;

import com.marklogic.tree.ExpandedTree;

/**
 * A read-only W3C DOM Node implementation of MarkLogic's internal
 * representation of an XML or text document as stored in the expanded tree
 * cache of a forest on disk.
 * 
 * 

* This interface is effectively read-only: Setters and update methods inherited * from org.w3c.Node are not supported and will raise an exception * if called. To create a modifiable copy of a node for XML document, use * {@link #cloneNode}. Text document cannot be cloned. *

* * @author jchen */ public class DocumentImpl extends NodeImpl implements Document { public static final Log LOG = LogFactory.getLog(DocumentImpl.class); private Element documentElement; /** * owner document for cloneNode */ private Document ownerDocCloned; private static DocumentBuilderFactory dbf = null; private int isXMLDoc; static final int UNKNOWN_TYPE = -1; static final int VALID_XML = 0; static final int NON_XML = 1; public DocumentImpl(ExpandedTree tree, int node) { super(tree, node); isXMLDoc = UNKNOWN_TYPE; } private static synchronized DocumentBuilderFactory getDocumentBuilderFactory() { if (dbf == null) { dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); } return dbf; } /** * {@inheritDoc} *

* Text documents in MarkLogic cannot be cloned. * UnsupportedOperationException will be thrown if cloneNode is call on text * document. *

* DocumentType node will not be cloned as it is not part of the Expanded * Tree. * * */ public Node cloneNode(boolean deep) { try { if (isXMLDoc == UNKNOWN_TYPE) isXMLDoc = getDocumentType(); if (isXMLDoc == NON_XML) { throw new UnsupportedOperationException( "Text document cannot be cloned"); } // initialize a new doc owner node initClonedOwnerDoc(); } catch (ParserConfigurationException e) { throw new RuntimeException("Internal Error:" + e); } if (deep) { for (NodeImpl n = (NodeImpl) getFirstChild(); n != null; n = (NodeImpl) n .getNextSibling()) { ownerDocCloned.appendChild(n.cloneNode(ownerDocCloned, true)); } } return ownerDocCloned; } protected void initClonedOwnerDoc() throws ParserConfigurationException { ownerDocCloned = getDocumentBuilderFactory().newDocumentBuilder().newDocument(); ownerDocCloned.setDocumentURI(getDocumentURI()); ownerDocCloned.setXmlVersion(getXmlVersion()); } /** * Document can be an XML document or a text document. * @return true if XML document; otherwise false. */ public boolean isXMLDoc() { if (isXMLDoc == UNKNOWN_TYPE) isXMLDoc = getDocumentType(); return isXMLDoc == VALID_XML; } /** * Check root node of a document to see if it conform to DOM Structure * Model. The root node can only be ELEMENT_NODE, * PROCESSING_INSTRUCTION_NODE or COMMENT_NODE. * * @return 1(NON_XML) if root node violates DOM Structure Model; otherwise * 0(VALID_XML). */ private int getDocumentType() { NodeList children = getChildNodes(); int elemCount = 0; for (int i = 0; i < children.getLength(); i++) { Node n = children.item(i); switch (n.getNodeType()) { case Node.ELEMENT_NODE: elemCount++; break; case Node.PROCESSING_INSTRUCTION_NODE: case Node.COMMENT_NODE: continue; default: return NON_XML; } } return elemCount <= 1 ? VALID_XML : NON_XML; } @Override public String getNodeName() { return "#document"; } @Override public Document getOwnerDocument() { return null; } protected int getNumChildren() { return tree.docNodeNumChildren[tree.nodeRepID[node]]; } public int getFirstChildIndex() { return tree.docNodeChildNodeRepID[tree.nodeRepID[node]]; } public NodeList getChildNodes() { return new NodeList() { public int getLength() { return getNumChildren(); } public Node item(int index) { return (index < getNumChildren()) ? tree .node(getFirstChildIndex() + index) : null; } }; } public Node getFirstChild() { int i = getFirstChildIndex(); return (i != Integer.MAX_VALUE) ? tree.node(i) : null; } public Node getLastChild() { int i = tree.docNodeChildNodeRepID[tree.nodeRepID[node]]; return (i != Integer.MAX_VALUE) ? tree.node(i + tree.docNodeNumChildren[node] - 1) : null; } public boolean hasChildNodes() { return (getFirstChildIndex() != Integer.MAX_VALUE); } protected Node getNextChild(int child) { if (child - getFirstChildIndex() + 1 < getNumChildren()) { return tree.node(child + 1); } else { return null; } } protected Node getPreviousChild(int node) { if (node != getFirstChildIndex()) { return tree.node(node - 1); } else { return null; } } /** Unsupported. */ public Node adoptNode(Node arg0) throws DOMException { throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, null); } /** Unsupported. */ public Attr createAttribute(String arg0) throws DOMException { throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, null); } /** Unsupported. */ public Attr createAttributeNS(String arg0, String arg1) throws DOMException { throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, null); } /** Unsupported. */ public CDATASection createCDATASection(String arg0) throws DOMException { throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, null); } /** Unsupported. */ public Comment createComment(String arg0) { throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, null); } /** Unsupported. */ public DocumentFragment createDocumentFragment() { throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, null); } /** Unsupported. */ public Element createElement(String arg0) throws DOMException { throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, null); } /** Unsupported. */ public Element createElementNS(String arg0, String arg1) throws DOMException { throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, null); } /** Unsupported. */ public EntityReference createEntityReference(String arg0) throws DOMException { throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, null); } /** Unsupported. */ public ProcessingInstruction createProcessingInstruction(String arg0, String arg1) throws DOMException { throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, null); } /** Unsupported. */ public Text createTextNode(String arg0) { throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, null); } /** * Returns a dummy DocumentTypeImpl object that contains nothing. It is not * expected to do anything with the returned object. */ public DocumentType getDoctype() { return new DocumentTypeImpl(tree, node); } public Element getDocumentElement() { if (documentElement != null) return documentElement; NodeList children = getChildNodes(); for (int i = 0; i < children.getLength(); i++) { Node n = children.item(i); if (n.getNodeType() == Node.ELEMENT_NODE) { documentElement = (Element) n; break; } } return documentElement; } @Override public boolean isDefaultNamespace(String namespaceURI) { Element e = getDocumentElement(); return e != null ? e.isDefaultNamespace(namespaceURI) : false; } public String getDocumentURI() { return tree.getDocumentURI(); } /** Unsupported. */ public DOMConfiguration getDomConfig() { return null; } /** Unsupported. */ public Element getElementById(String arg0) { return null; } public NodeList getElementsByTagNameNS(String namespaceURI, String name) { return getElementsByTagNameNSOrNodeName(namespaceURI, name, false); } public NodeList getElementsByTagName(String localName) { return getElementsByTagNameNSOrNodeName(null, localName, true); } /** Unsupported. */ public DOMImplementation getImplementation() { return null; } /** Unsupported. */ public String getInputEncoding() { return null; } /** Unsupported. */ public boolean getStrictErrorChecking() { return false; } /** Unsupported. */ public String getXmlEncoding() { return null; } /** Unsupported. */ public boolean getXmlStandalone() { return true; } public String getXmlVersion() { return "1.0"; } /** Unsupported. */ public Node importNode(Node arg0, boolean arg1) throws DOMException { return null; } @Override public String lookupNamespaceURI(String prefix) { return getDocumentElement().lookupNamespaceURI(prefix); } @Override public String lookupPrefix(String namespaceURI) { return getDocumentElement().lookupPrefix(namespaceURI); } /** Unsupported. */ public void normalizeDocument() { throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, null); } /** Unsupported. */ public Node renameNode(Node arg0, String arg1, String arg2) throws DOMException { throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, null); } /** Unsupported. */ public void setDocumentURI(String arg0) { throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, null); } /** Unsupported. */ public void setStrictErrorChecking(boolean arg0) { throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, null); } /** Unsupported. */ public void setXmlStandalone(boolean arg0) throws DOMException { throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, null); } /** Unsupported. */ public void setXmlVersion(String arg0) throws DOMException { throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, null); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy