/******************************************************************************* * Copyright (c) 2001, 2011 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 * * Balazs Banfai: Bug 154737 getUserData/setUserData support for Node * https://bugs.eclipse.org/bugs/show_bug.cgi?id=154737 * David Carver (STAR) - bug 296999 - Inefficient use of new String() * David Carver (Intalio) - bug 273004 - add check for valid xml characters in createAttribute *******************************************************************************/ 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.Collections; import java.util.HashMap; import java.util.LinkedHashMap; 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.CMElementDeclaration; 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.UserDataHandler; 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; } } private class LimitedCache extends LinkedHashMap { private static final long serialVersionUID = 1L; private static final int MAX_SIZE = 10; public LimitedCache() { super(0, 0.75f, true); } protected boolean removeEldestEntry(java.util.Map.Entry entry) { return size() > MAX_SIZE; } } // 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; private Map fCMCache; /** * DocumentImpl constructor */ protected DocumentImpl() { super(); if (usetagnamecache) { tagNameCache = new TagNameCache(); } fCMCache = Collections.synchronizedMap(new LimitedCache()); } /** * DocumentImpl constructor * * @param that * DocumentImpl */ protected DocumentImpl(DocumentImpl that) { super(that); if (usetagnamecache) { tagNameCache = new TagNameCache(); } fCMCache = Collections.synchronizedMap(new LimitedCache()); } /** * @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? * * TODO: Needs to notify UserDataHandlers for the node if any * * @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 { checkTagNameValidity(name); AttrImpl attr = new AttrImpl(); attr.setOwnerDocument(this); attr.setName(name); return attr; } /** */ public Attr createAttributeNS(String uri, String name) throws DOMException { checkTagNameValidity(name); 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, DOMMessages.INVALID_MODIFICATION_ERR); } 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, DOMMessages.INVALID_CHARACTER_ERR); } 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, DOMMessages.INVALID_CHARACTER_ERR); } 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, DOMMessages.NOT_SUPPORTED_ERR); } 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 = DOMMessages.NOT_SUPPORTED_ERR + " - 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; if (element.hasAttribute("id") && id.equals(element.getAttribute("id"))) //$NON-NLS-1$ //$NON-NLS-2$ return element; } return null; } 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; //successful import, notify UserDataHandlers if any NodeImpl nodeToNotify=(NodeImpl) node; nodeToNotify.notifyUserDataHandlers(UserDataHandler.NODE_IMPORTED, 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; } /** * Provides an element's attribute declarations * @param element the element to retrieve the attribute map of * @return a <code>CMNamedNodeMap</code> of attributes if the declaration exists; null otherwise. */ CMNamedNodeMap getCMAttributes(Element element) { CMNamedNodeMap map = (CMNamedNodeMap) fCMCache.get(element); if (map == null) { ModelQuery modelQuery = ModelQueryUtil.getModelQuery(this); CMElementDeclaration decl = modelQuery != null ? modelQuery.getCMElementDeclaration(element) : null; if (decl != null) { map = decl.getAttributes(); fCMCache.put(element, map); } } return map; } /** * <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 implemented 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 implemented 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 implemented 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 implemented 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 implemented 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 implemented 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 implemented 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 implemented 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 implemented 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 implemented 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 implemented in this version"); //$NON-NLS-1$ } }