blob: 5d676ae4a7adce416793d97b70475e2a6479ec58 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2001, 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Jens Lukowski/Innoopract - initial renaming/restructuring
*
*******************************************************************************/
package org.eclipse.wst.xml.core.internal.document;
// for org.apache.xerces 3.2.1
// import org.apache.xerces.utils.XMLCharacterProperties;
// DMW modified for XML4J 4.0.1
import java.util.HashMap;
import java.util.Map;
import org.apache.xerces.dom.TreeWalkerImpl;
import org.eclipse.wst.sse.core.internal.ltk.modelhandler.IModelHandler;
import org.eclipse.wst.xml.core.internal.commentelement.impl.CommentElementRegistry;
import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument;
import org.eclipse.wst.xml.core.internal.contentmodel.CMEntityDeclaration;
import org.eclipse.wst.xml.core.internal.contentmodel.CMNamedNodeMap;
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery;
import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil;
import org.eclipse.wst.xml.core.internal.provisional.IXMLCharEntity;
import org.eclipse.wst.xml.core.internal.provisional.NameValidator;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
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.DocumentFragment;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.Entity;
import org.w3c.dom.EntityReference;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Notation;
import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.Text;
import org.w3c.dom.ranges.DocumentRange;
import org.w3c.dom.ranges.Range;
import org.w3c.dom.traversal.DocumentTraversal;
import org.w3c.dom.traversal.NodeFilter;
import org.w3c.dom.traversal.NodeIterator;
import org.w3c.dom.traversal.TreeWalker;
/**
* DocumentImpl class
*/
public class DocumentImpl extends NodeContainer implements IDOMDocument, DocumentRange, DocumentTraversal {
private static int maxDocTypeSearch = 500;
private static int noMaxSearch = -1;
/**
* Internal-use only class. This class was added to better able to handle
* repetetive request for getElementsByTagName. The cache is cleared when
* ever the document changes at all, so still not real efficient,
*/
class TagNameCache {
private boolean active = true;
private Map cache;
public TagNameCache() {
super();
cache = new HashMap();
}
/**
* @param b
*/
public void activate(boolean b) {
active = b;
if (!b)
clear();
}
public void addItem(String tagname, NodeListImpl nodelist) {
if (tagname == null || nodelist == null)
return;
cache.put(tagname, nodelist);
}
public void clear() {
cache.clear();
}
public NodeListImpl getItem(String tagName) {
NodeListImpl result = null;
if (active) {
result = (NodeListImpl) cache.get(tagName);
// if (result != null) {
// System.out.println("getElementsByTagname from cache: " +
// tagName);
// }
}
return result;
}
}
// this is a constant just to give compile-time control over
// whether or not to use the cache. If, in future, its found that
// there are no (or few) "duplicate requests" ... then this cache
// is not needed.
private static final boolean usetagnamecache = true;
// private DocumentTypeAdapter documentTypeAdapter = null;
private DOMModelImpl model = null;
private TagNameCache tagNameCache;
/**
* DocumentImpl constructor
*/
protected DocumentImpl() {
super();
if (usetagnamecache) {
tagNameCache = new TagNameCache();
}
}
/**
* DocumentImpl constructor
*
* @param that
* DocumentImpl
*/
protected DocumentImpl(DocumentImpl that) {
super(that);
if (usetagnamecache) {
tagNameCache = new TagNameCache();
}
}
/**
* @param b
*/
void activateTagNameCache(boolean b) {
tagNameCache.activate(b);
}
/**
* <p>
* EXPERIMENTAL! Based on the <a
* href='http://www.w3.org/TR/2001/WD-DOM-Level-3-Core-20010605'>Document
* Object Model (DOM) Level 3 Core Working Draft of 5 June 2001. </a>.
* <p>
* Changes the <code>ownerDocument</code> of a node, its children, as
* well as the attached attribute nodes if there are any. If the node has
* a parent it is first removed from its parent child list. This
* effectively allows moving a subtree from one document to another. The
* following list describes the specifics for each type of node.
* <dl>
* <dt>ATTRIBUTE_NODE</dt>
* <dd>The <code>ownerElement</code> attribute is set to
* <code>null</code> and the <code>specified</code> flag is set to
* <code>true</code> on the adopted <code>Attr</code>. The
* descendants of the source <code>Attr</code> are recursively adopted.
* </dd>
* <dt>DOCUMENT_FRAGMENT_NODE</dt>
* <dd>The descendants of the source node are recursively adopted.</dd>
* <dt>DOCUMENT_NODE</dt>
* <dd><code>Document</code> nodes cannot be adopted.</dd>
* <dt>DOCUMENT_TYPE_NODE</dt>
* <dd><code>DocumentType</code> nodes cannot be adopted.</dd>
* <dt>ELEMENT_NODE</dt>
* <dd>Specified attribute nodes of the source element are adopted, and
* the generated <code>Attr</code> nodes. Default attributes are
* discarded, though if the document being adopted into defines default
* attributes for this element name, those are assigned. The descendants
* of the source element are recursively adopted.</dd>
* <dt>ENTITY_NODE</dt>
* <dd><code>Entity</code> nodes cannot be adopted.</dd>
* <dt>ENTITY_REFERENCE_NODE</dt>
* <dd>Only the <code>EntityReference</code> node itself is adopted,
* the descendants are discarded, since the source and destination
* documents might have defined the entity differently. If the document
* being imported into provides a definition for this entity name, its
* value is assigned.</dd>
* <dt>NOTATION_NODE</dt>
* <dd><code>Notation</code> nodes cannot be adopted.</dd>
* <dt>PROCESSING_INSTRUCTION_NODE, TEXT_NODE, CDATA_SECTION_NODE,
* COMMENT_NODE</dt>
* <dd>These nodes can all be adopted. No specifics.</dd>
* Should this method simply return null when it fails? How "exceptional"
* is failure for this method?Stick with raising exceptions only in
* exceptional circumstances, return null on failure (F2F 19 Jun 2000).Can
* an entity node really be adopted?No, neither can Notation nodes (Telcon
* 13 Dec 2000).Does this affect keys and hashCode's of the adopted
* subtree nodes?If so, what about readonly-ness of key and hashCode?if
* not, would appendChild affect keys/hashCodes or would it generate
* exceptions if key's are duplicate? Update: Hashcodes have been dropped.
* Given that the key is only unique within a document an adopted node
* needs to be given a new key, but what does it mean for the application?
*
* @param source
* The node to move into this document.
* @return The adopted node, or <code>null</code> if this operation
* fails, such as when the source node comes from a different
* implementation.
* @exception DOMException
* NOT_SUPPORTED_ERR: Raised if the source node is of type
* <code>DOCUMENT</code>,<code>DOCUMENT_TYPE</code>.
* <br>
* NO_MODIFICATION_ALLOWED_ERR: Raised when the source node
* is readonly.
* @see DOM Level 3
*/
public org.w3c.dom.Node adoptNode(org.w3c.dom.Node source) throws org.w3c.dom.DOMException {
return null;
}
/**
* @param tagName
*/
protected void checkTagNameValidity(String tagName) {
if (!isValidName(tagName)) {
throw new DOMException(DOMException.INVALID_CHARACTER_ERR, createDOMExceptionMessage(DOMException.INVALID_CHARACTER_ERR, tagName));
}
}
/**
* cloneNode method
*
* @return org.w3c.dom.Node
* @param deep
* boolean
*/
public Node cloneNode(boolean deep) {
DocumentImpl cloned = new DocumentImpl(this);
if (deep)
cloned.importChildNodes(this, true);
return cloned;
}
/**
* createAttribute method
*
* @return org.w3c.dom.Attr
* @param name
* java.lang.String
*/
public Attr createAttribute(String name) throws DOMException {
AttrImpl attr = new AttrImpl();
attr.setOwnerDocument(this);
attr.setName(name);
return attr;
}
/**
*/
public Attr createAttributeNS(String uri, String name) throws DOMException {
AttrImpl attr = new AttrImpl();
attr.setOwnerDocument(this);
attr.setName(name);
attr.setNamespaceURI(uri);
return attr;
}
/**
* createCDATASection method
*
* @return org.w3c.dom.CDATASection
* @param data
* java.lang.String
*/
public CDATASection createCDATASection(String data) throws DOMException {
// allow CDATA section
// if (!isXMLType()) {
// throw new DOMException(DOMException.NOT_SUPPORTED_ERR, new
// String());
// }
CDATASectionImpl cdata = new CDATASectionImpl();
cdata.setOwnerDocument(this);
if (data != null)
cdata.setData(data);
return cdata;
}
/**
* createComment method
*
* @return org.w3c.dom.Comment
* @param data
* java.lang.String
*/
public Comment createComment(String data) {
CommentImpl comment = new CommentImpl();
comment.setOwnerDocument(this);
if (data != null)
comment.setData(data);
return comment;
}
public Element createCommentElement(String tagName, boolean isJSPTag) throws DOMException {
Element result = null;
if (!isJSPType() && isJSPTag) {
throw new DOMException(DOMException.INVALID_MODIFICATION_ERR, new String());
}
ElementImpl element = (ElementImpl) createElement(tagName);
element.setJSPTag(isJSPTag);
CommentElementRegistry registry = CommentElementRegistry.getInstance();
if (registry.setupCommentElement(element)) {
result = element;
}
else {
throw new DOMException(DOMException.INVALID_CHARACTER_ERR, new String());
}
return result;
}
/**
* createDoctype method
*
* @return org.w3c.dom.DocumentType
* @param name
* java.lang.String
*/
public DocumentType createDoctype(String name) {
DocumentTypeImpl docType = new DocumentTypeImpl();
docType.setOwnerDocument(this);
docType.setName(name);
return docType;
}
/**
* createDocumentFragment method
*
* @return org.w3c.dom.DocumentFragment
*/
public DocumentFragment createDocumentFragment() {
DocumentFragmentImpl fragment = new DocumentFragmentImpl();
fragment.setOwnerDocument(this);
return fragment;
}
/**
* createElement method
*
* @return org.w3c.dom.Element
* @param tagName
* java.lang.String
*/
public Element createElement(String tagName) throws DOMException {
checkTagNameValidity(tagName);
ElementImpl element = new ElementImpl();
element.setOwnerDocument(this);
element.setTagName(tagName);
return element;
}
/**
*/
public Element createElementNS(String uri, String tagName) throws DOMException {
if (!isValidName(tagName)) {
throw new DOMException(DOMException.INVALID_CHARACTER_ERR, new String());
}
ElementImpl element = (ElementImpl) createElement(tagName);
element.setNamespaceURI(uri);
return element;
}
/**
* createEntity method
*
* @return org.w3c.dom.Entity
* @param name
* java.lang.String
*/
public Entity createEntity(String name) {
EntityImpl entity = new EntityImpl();
entity.setOwnerDocument(this);
entity.setName(name);
return entity;
}
/**
* createEntityReference method
*
* @return org.w3c.dom.EntityReference
* @param name
* java.lang.String
*/
public EntityReference createEntityReference(String name) throws DOMException {
if (!isXMLType()) {
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, new String());
}
EntityReferenceImpl ref = new EntityReferenceImpl();
ref.setOwnerDocument(this);
ref.setName(name);
return ref;
}
/**
*/
public NodeIterator createNodeIterator(Node root, int whatToShow, NodeFilter filter, boolean entityReferenceExpansion) {
if (root == null)
root = this;
return new NodeIteratorImpl(root, whatToShow, filter);
}
/**
* createNotation method
*
* @return org.w3c.dom.Notation
* @param name
* java.lang.String
*/
public Notation createNotation(String name) {
NotationImpl notation = new NotationImpl();
notation.setOwnerDocument(this);
notation.setName(name);
return notation;
}
/**
* createProcessingInstruction method
*
* @return org.w3c.dom.ProcessingInstruction
* @param target
* java.lang.String
* @param data
* java.lang.String
*/
public ProcessingInstruction createProcessingInstruction(String target, String data) throws DOMException {
ProcessingInstructionImpl pi = new ProcessingInstructionImpl();
pi.setOwnerDocument(this);
pi.setTarget(target);
if (data != null)
pi.setData(data);
return pi;
}
/**
*/
public Range createRange() {
return new RangeImpl();
}
/**
* createTextNode method
*
* @return org.w3c.dom.Text
* @param data
* java.lang.String
*/
public Text createTextNode(String data) {
TextImpl text = new TextImpl();
text.setOwnerDocument(this);
text.setData(data);
return text;
}
/**
* Return an instance of tree walk
*/
/*
* (non-Javadoc)
*
* @see org.w3c.dom.traversal.DocumentTraversal#createTreeWalker(org.w3c.dom.Node,
* int, org.w3c.dom.traversal.NodeFilter, boolean)
*/
public TreeWalker createTreeWalker(Node root, int whatToShow, NodeFilter filter, boolean entityReferenceExpansion) {
if (root == null) {
String msg = "Program Error: root node can not be null for TreeWalker";
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
}
// ISSUE: we just use Xerces implementation for now, but longer term,
// we should make a
// thread/job safe version (as well as not rely on Xerces "impl"
// class.
return new TreeWalkerImpl(root, whatToShow, filter, entityReferenceExpansion);
}
private DocumentType findDoctype(Node node) {
int countSearch = 0;
for (Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) {
if (countSearch++ > maxDocTypeSearch) {
break;
}
if (child.getNodeType() == DOCUMENT_TYPE_NODE && child instanceof DocumentType) {
return (DocumentType) child;
}
else if (child.getNodeType() == ELEMENT_NODE && ((IDOMElement) child).isCommentTag()) {
// search DOCTYPE inside of generic comment element
DocumentType docType = findDoctype(child);
if (docType != null) {
return docType;
}
}
}
return null;
}
private Element findDocumentElement(String docName, Node node, Node[] firstFound, int max) {
int countSearch = 0;
for (Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) {
/*
* maxDocTypeSearch limits added via bug 151929
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=151929
* but, in other contexts,
* if noMaxSearch is specified, then do not "break out" of long searches
* */
if (max != noMaxSearch && countSearch++ > max) {
break;
}
if (child.getNodeType() != ELEMENT_NODE)
continue;
ElementImpl element = (ElementImpl) child;
if (element.isCommentTag()) {
Element docElement = findDocumentElement(docName, element, firstFound, max);
if (docElement != null) {
return docElement;
}
else {
// added 'else continue' to better handle cases where
// there is "more than one root" element
// especially complicated by CommentElements, which are
// sometimes treated as elements, but should
// be treated as comments in this context.
continue;
}
}
// note: the "name" won't match in the event of a jsp tag ... but
// incase
// the name is null, we do not want the jsp element returned as
// documentElement
if (element.isJSPTag())
continue;
if (docName == null)
return element;
// use local name for namespace
String localName = element.getLocalName();
if (localName == null)
continue;
if (isXMLType()) {
if (localName.equals(docName))
return element;
}
else {
if (localName.equalsIgnoreCase(docName))
return element;
}
if (firstFound[0] == null)
firstFound[0] = element;
}
return null;
}
/**
* getCharValue method
*
* @return java.lang.String
* @param name
* java.lang.String
*/
protected String getCharValue(String name) {
if (name == null)
return null;
int length = name.length();
if (length == 0)
return null;
if (name.charAt(0) == '#') { // character reference
if (length == 1)
return null;
int radix = 10;
String s = null;
// now allow hexadecimal also for non XML document
if (name.charAt(1) == 'x') { // hexadecimal
radix = 16;
s = name.substring(2);
}
else { // decimal
s = name.substring(1);
}
if (s == null || s.length() == 0)
return null;
if (s.charAt(0) == '-')
return null; // no minus accepted
char c = 0;
try {
c = (char) Integer.parseInt(s, radix);
}
catch (NumberFormatException ex) {
}
if (c == 0)
return null;
return String.valueOf(c);
}
// implicit character entities for XML
if (name.equals(IXMLCharEntity.LT_NAME))
return IXMLCharEntity.LT_VALUE;
if (name.equals(IXMLCharEntity.GT_NAME))
return IXMLCharEntity.GT_VALUE;
if (name.equals(IXMLCharEntity.AMP_NAME))
return IXMLCharEntity.AMP_VALUE;
if (name.equals(IXMLCharEntity.QUOT_NAME))
return IXMLCharEntity.QUOT_VALUE;
if (isXMLType()) {
if (name.equals(IXMLCharEntity.APOS_NAME))
return IXMLCharEntity.APOS_VALUE;
}
CMDocument cm = getCMDocument();
if (cm != null) {
CMNamedNodeMap map = cm.getEntities();
if (map != null) {
CMEntityDeclaration decl = (CMEntityDeclaration) map.getNamedItem(name);
if (decl != null) {
String value = decl.getValue();
if (value == null)
return null;
int valueLength = value.length();
if (valueLength > 1 && value.charAt(0) == '&' && value.charAt(1) == '#' && value.charAt(valueLength - 1) == ';') {
// character reference
return getCharValue(value.substring(1, valueLength - 1));
}
return value;
}
}
}
return null;
}
/**
*/
protected CMDocument getCMDocument() {
ModelQuery modelQuery = ModelQueryUtil.getModelQuery(this);
if (modelQuery == null)
return null;
return modelQuery.getCorrespondingCMDocument(this);
}
/**
* getDoctype method
*
* @return org.w3c.dom.DocumentType
*/
public DocumentType getDoctype() {
return findDoctype(this);
}
/**
* getDocumentElement
*
* @return org.w3c.dom.Element From DOM 2 Spec: documentElement of type
* Element [p.62] , readonly This is a convenience [p.119]
* attribute that allows direct access to the child node that is
* the root element of the document. For HTML documents, this is
* the element with the tagName "HTML". Note: we differ from this
* definition a little in that we don't necessarily take the first
* child but also look to match the name. In a well formed
* document, of course, the result is the same, but not
* necessarily the same in an ill-formed document.
*/
public Element getDocumentElement() {
String name = null;
DocumentType docType = getDocumentType();
if (docType != null) {
name = docType.getName();
}
Element first[] = new Element[1];
Element docElement = findDocumentElement(name, this, first, noMaxSearch);
if (docElement == null) {
docElement = first[0];
}
return docElement;
}
/**
*/
protected DocumentType getDocumentType() {
DocumentTypeAdapter adapter = (DocumentTypeAdapter) getAdapterFor(DocumentTypeAdapter.class);
if (adapter == null)
return getDoctype();
return adapter.getDocumentType();
}
public String getDocumentTypeId() {
DocumentType docType = getDocumentType();
if (docType == null)
return null;
String id = docType.getPublicId();
if (id == null)
id = docType.getSystemId();
return id;
}
/**
*/
public Element getElementById(String id) {
if (id == null)
return null;
NodeIterator it = createNodeIterator(this, NodeFilter.SHOW_ALL, null, false);
if (it == null)
return null;
for (Node node = it.nextNode(); node != null; node = it.nextNode()) {
if (node.getNodeType() != ELEMENT_NODE)
continue;
ElementImpl element = (ElementImpl) node;
String value = element.getAttribute("id");//$NON-NLS-1$
if (value != null && value.equals(id))
return element;
}
return null;
}
/**
* getElementsByTagName method
*
* @return org.w3c.dom.NodeList
* @param tagName
* java.lang.String
*/
public NodeList getElementsByTagName(String tagName) {
if (tagName == null)
return new NodeListImpl();
NodeListImpl elements = null;
if (usetagnamecache) {
elements = tagNameCache.getItem(tagName);
}
if (elements == null) {
elements = internalGetElementsByTagName(tagName);
}
return elements;
}
/**
*/
public NodeList getElementsByTagNameNS(String uri, String tagName) {
if (tagName == null)
return new NodeListImpl();
NodeIterator it = createNodeIterator(this, NodeFilter.SHOW_ALL, null, false);
if (it == null)
return new NodeListImpl();
NodeListImpl elements = new NodeListImpl();
if (uri != null && uri.length() == 1 && uri.charAt(0) == '*') {
uri = null; // do not care
}
if (tagName.length() == 1 && tagName.charAt(0) == '*') {
tagName = null; // do not care
}
for (Node node = it.nextNode(); node != null; node = it.nextNode()) {
if (node.getNodeType() != ELEMENT_NODE)
continue;
ElementImpl element = (ElementImpl) node;
if (tagName != null) {
String localName = element.getLocalName();
if (localName == null || !localName.equals(tagName))
continue;
}
if (uri != null) {
String nsURI = element.getNamespaceURI();
if (nsURI == null || !nsURI.equals(uri))
continue;
}
elements.appendNode(element);
}
return elements;
}
/**
* <p>
* EXPERIMENTAL! Based on the <a
* href='http://www.w3.org/TR/2001/WD-DOM-Level-3-Core-20010605'>Document
* Object Model (DOM) Level 3 Core Working Draft of 5 June 2001. </a>.
* <p>
* An attribute specifying, as part of the XML declaration, the encoding
* of this document. This is <code>null</code> when unspecified.
*
* @see DOM Level 3
*/
public java.lang.String getEncoding() {
return null;
}
/**
*/
public DOMImplementation getImplementation() {
return model;
}
/**
* other nodes will be referring to this one to get the owning model
*/
public IDOMModel getModel() {
return model;
}
/**
* getNodeName method
*
* @return java.lang.String
*/
public String getNodeName() {
return "#document";//$NON-NLS-1$
}
/**
* getNodeType method
*
* @return short
*/
public short getNodeType() {
return DOCUMENT_NODE;
}
/**
* <p>
* EXPERIMENTAL! Based on the <a
* href='http://www.w3.org/TR/2001/WD-DOM-Level-3-Core-20010605'>Document
* Object Model (DOM) Level 3 Core Working Draft of 5 June 2001. </a>.
* <p>
* An attribute specifying, as part of the XML declaration, whether this
* document is standalone.
*
* @see DOM Level 3
*/
public boolean getStandalone() {
return false;
}
/**
* <p>
* EXPERIMENTAL! Based on the <a
* href='http://www.w3.org/TR/2001/WD-DOM-Level-3-Core-20010605'>Document
* Object Model (DOM) Level 3 Core Working Draft of 5 June 2001. </a>.
* <p>
* An attribute specifying whether errors checking is enforced or not.
* When set to <code>false</code>, the implementation is free to not
* test every possible error case normally defined on DOM operations, and
* not raise any <code>DOMException</code>. In case of error, the
* behavior is undefined. This attribute is <code>true</code> by
* defaults.
*
* @see DOM Level 3
*/
public boolean getStrictErrorChecking() {
return false;
}
/**
* <p>
* EXPERIMENTAL! Based on the <a
* href='http://www.w3.org/TR/2001/WD-DOM-Level-3-Core-20010605'>Document
* Object Model (DOM) Level 3 Core Working Draft of 5 June 2001. </a>.
* <p>
* An attribute specifying, as part of the XML declaration, the version
* number of this document. This is <code>null</code> when unspecified.
*
* @see DOM Level 3
*/
public String getVersion() {
return null;
}
/**
*/
protected boolean ignoreCase() {
DocumentTypeAdapter adapter = (DocumentTypeAdapter) getAdapterFor(DocumentTypeAdapter.class);
if (adapter == null)
return false;
return (adapter.getTagNameCase() != DocumentTypeAdapter.STRICT_CASE);
}
/**
*/
protected void importChildNodes(Node parent, boolean deep) {
if (parent == null)
return;
removeChildNodes();
for (Node child = parent.getFirstChild(); child != null; child = child.getNextSibling()) {
Node imported = importNode(child, deep);
if (imported == null)
continue;
appendChild(imported);
}
}
/**
*/
public Node importNode(Node node, boolean deep) throws DOMException {
if (node == null)
return null;
NodeImpl imported = (NodeImpl) node.cloneNode(deep);
if (imported == null)
return null;
imported.setOwnerDocument(this, deep);
return imported;
}
private NodeListImpl internalGetElementsByTagName(String tagName) {
// System.out.println("getElementsByTagname: " + tagName);
NodeIterator it = createNodeIterator(this, NodeFilter.SHOW_ALL, null, false);
if (it == null)
return new NodeListImpl();
NodeListImpl elements = new NodeListImpl();
if (tagName.length() == 1 && tagName.charAt(0) == '*') {
tagName = null; // do not care
}
for (Node node = it.nextNode(); node != null; node = it.nextNode()) {
if (node.getNodeType() != ELEMENT_NODE)
continue;
if (tagName != null) {
ElementImpl element = (ElementImpl) node;
if (!element.matchTagName(tagName))
continue;
}
elements.appendNode(node);
}
if (usetagnamecache) {
tagNameCache.addItem(tagName, elements);
}
return elements;
}
/**
*/
public boolean isJSPDocument() {
Element element = getDocumentElement();
if (element == null)
return false;
String tagName = element.getTagName();
if (tagName == null)
return false;
return tagName.equals(JSPTag.JSP_ROOT);
}
/**
*/
public boolean isJSPType() {
if (this.model == null)
return false;
IModelHandler handler = this.model.getModelHandler();
if (handler == null)
return false;
String id = handler.getAssociatedContentTypeId();
if (id == null)
return false;
// ISSUE: -- avoid this hardcoded string
return id.equals("org.eclipse.jst.jsp.core.jspsource"); //$NON-NLS-1$
}
/**
*/
protected boolean isValidName(String name) {
if (name == null || name.length() == 0)
return false;
// // DMW: modified for XML4J 4.0.1
// if (XMLChar.isValidName(name)) return true;
if (NameValidator.isValid(name))
return true;
// special for invalid declaration
if (name.length() == 1 && name.charAt(0) == '!')
return true;
// special for JSP tag in tag name
if (name.startsWith(JSPTag.TAG_OPEN))
return true;
return false;
}
/**
*/
public boolean isXMLType() {
DocumentTypeAdapter adapter = (DocumentTypeAdapter) getAdapterFor(DocumentTypeAdapter.class);
if (adapter == null)
return true;
return adapter.isXMLType();
}
/**
*/
// protected void releaseDocumentType() {
// if (this.documentTypeAdapter == null)
// return;
// this.documentTypeAdapter.release();
// this.documentTypeAdapter = null;
// }
/**
* <p>
* EXPERIMENTAL! Based on the <a
* href='http://www.w3.org/TR/2001/WD-DOM-Level-3-Core-20010605'>Document
* Object Model (DOM) Level 3 Core Working Draft of 5 June 2001. </a>.
* <p>
* An attribute specifying, as part of the XML declaration, the encoding
* of this document. This is <code>null</code> when unspecified.
*
* @see DOM Level 3
*/
public void setEncoding(java.lang.String encoding) {
}
/**
* setModel method
*
* @param model
* XMLModel
*/
protected void setModel(IDOMModel model) {
this.model = (DOMModelImpl) model;
}
/**
* <p>
* EXPERIMENTAL! Based on the <a
* href='http://www.w3.org/TR/2001/WD-DOM-Level-3-Core-20010605'>Document
* Object Model (DOM) Level 3 Core Working Draft of 5 June 2001. </a>.
* <p>
* An attribute specifying, as part of the XML declaration, whether this
* document is standalone.
*
* @see DOM Level 3
*/
public void setStandalone(boolean standalone) {
}
/**
* <p>
* EXPERIMENTAL! Based on the <a
* href='http://www.w3.org/TR/2001/WD-DOM-Level-3-Core-20010605'>Document
* Object Model (DOM) Level 3 Core Working Draft of 5 June 2001. </a>.
* <p>
* An attribute specifying whether errors checking is enforced or not.
* When set to <code>false</code>, the implementation is free to not
* test every possible error case normally defined on DOM operations, and
* not raise any <code>DOMException</code>. In case of error, the
* behavior is undefined. This attribute is <code>true</code> by
* defaults.
*
* @see DOM Level 3
*/
public void setStrictErrorChecking(boolean strictErrorChecking) {
}
/**
* <p>
* EXPERIMENTAL! Based on the <a
* href='http://www.w3.org/TR/2001/WD-DOM-Level-3-Core-20010605'>Document
* Object Model (DOM) Level 3 Core Working Draft of 5 June 2001. </a>.
* <p>
* An attribute specifying, as part of the XML declaration, the version
* number of this document. This is <code>null</code> when unspecified.
*
* @see DOM Level 3
*/
public void setVersion(java.lang.String version) {
}
/**
* NOT IMPLEMENTED. Is defined here in preparation for DOM 3.
*/
public String getInputEncoding() {
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Not implmented in this version"); //$NON-NLS-1$
}
/**
* NOT IMPLEMENTED. Is defined here in preparation for DOM 3.
*/
public String getXmlEncoding() {
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Not implmented in this version"); //$NON-NLS-1$
}
/**
* NOT IMPLEMENTED. Is defined here in preparation for DOM 3.
*/
public boolean getXmlStandalone() {
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Not implmented in this version"); //$NON-NLS-1$
}
/**
* NOT IMPLEMENTED. Is defined here in preparation for DOM 3.
*/
public void setXmlStandalone(boolean xmlStandalone) throws DOMException {
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Not implmented in this version"); //$NON-NLS-1$
}
/**
* NOT IMPLEMENTED. Is defined here in preparation for DOM 3.
*/
public String getXmlVersion() {
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Not implmented in this version"); //$NON-NLS-1$
}
/**
* NOT IMPLEMENTED. Is defined here in preparation for DOM 3.
*/
public void setXmlVersion(String xmlVersion) throws DOMException {
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Not implmented in this version"); //$NON-NLS-1$
}
/**
* NOT IMPLEMENTED. Is defined here in preparation for DOM 3.
*/
public String getDocumentURI() {
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Not implmented in this version"); //$NON-NLS-1$
}
/**
* NOT IMPLEMENTED. Is defined here in preparation for DOM 3.
*/
public void setDocumentURI(String documentURI) {
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Not implmented in this version"); //$NON-NLS-1$
}
/**
* NOT IMPLEMENTED. Is defined here in preparation for DOM 3.
*/
public DOMConfiguration getDomConfig() {
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Not implmented in this version"); //$NON-NLS-1$
}
/**
* NOT IMPLEMENTED. Is defined here in preparation for DOM 3.
*/
public void normalizeDocument() {
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Not implmented in this version"); //$NON-NLS-1$
}
/**
* NOT IMPLEMENTED. Is defined here in preparation for DOM 3.
*/
public Node renameNode(Node n, String namespaceURI, String qualifiedName) throws DOMException {
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Not implmented in this version"); //$NON-NLS-1$
}
}