# HG changeset patch # User lana # Date 1443284553 25200 # Node ID 5625643929aa69dad88d8c5d6ede45b4b6330f48 # Parent a7e186d534d56b3187ec1dcddb3078520e6cf8c2# Parent ed81078b4e7f57378f63960c2def5286491cb540 Merge diff -r a7e186d534d5 -r 5625643929aa jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ElementImpl.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ElementImpl.java Fri Sep 25 22:59:26 2015 -0700 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ElementImpl.java Sat Sep 26 09:22:33 2015 -0700 @@ -3,11 +3,12 @@ * DO NOT REMOVE OR ALTER! */ /* - * Copyright 1999-2002,2004 The Apache Software Foundation. - * - * 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 + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 * @@ -17,70 +18,75 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.sun.org.apache.xerces.internal.dom; import org.w3c.dom.Attr; import org.w3c.dom.DOMException; import org.w3c.dom.Element; +import org.w3c.dom.ElementTraversal; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.Text; - import org.w3c.dom.TypeInfo; import com.sun.org.apache.xerces.internal.util.URI; /** - * Elements represent most of the "markup" and structure of the - * document. They contain both the data for the element itself - * (element name and attributes), and any contained nodes, including - * document text (as children). + * Elements represent most of the "markup" and structure of the document. They + * contain both the data for the element itself (element name and attributes), + * and any contained nodes, including document text (as children). *
* Elements may have Attributes associated with them; the API for this is * defined in Node, but the function is implemented here. In general, XML * applications should retrive Attributes as Nodes, since they may contain - * entity references and hence be a fairly complex sub-tree. HTML users will - * be dealing with simple string values, and convenience methods are provided - * to work in terms of Strings. + * entity references and hence be a fairly complex sub-tree. HTML users will be + * dealing with simple string values, and convenience methods are provided to + * work in terms of Strings. *
* ElementImpl does not support Namespaces. ElementNSImpl, which inherits from * it, does. + * * @see ElementNSImpl * * @xerces.internal * - * @author Arnaud Le Hors, IBM + * @author Arnaud Le Hors, IBM * @author Joe Kesselman, IBM * @author Andy Clark, IBM * @author Ralf Pfeiffer, IBM - * @since PR-DOM-Level-1-19980818. + * @since PR-DOM-Level-1-19980818. */ public class ElementImpl - extends ParentNode - implements Element, TypeInfo { + extends ParentNode + implements Element, ElementTraversal, TypeInfo { // // Constants // - - /** Serialization version. */ + /** + * Serialization version. + */ static final long serialVersionUID = 3717253516652722278L; // // Data // - /** Element name. */ + /** + * Element name. + */ protected String name; - /** Attributes. */ + /** + * Attributes. + */ protected AttributeMap attributes; // // Constructors // - - /** Factory constructor. */ + /** + * Factory constructor. + */ public ElementImpl(CoreDocumentImpl ownerDoc, String name) { super(ownerDoc); this.name = name; @@ -88,7 +94,8 @@ } // for ElementNSImpl - protected ElementImpl() {} + protected ElementImpl() { + } // Support for DOM Level 3 renameNode method. // Note: This only deals with part of the pb. CoreDocumentImpl @@ -97,26 +104,45 @@ if (needsSyncData()) { synchronizeData(); } - this.name = name; + if (ownerDocument.errorChecking) { + int colon1 = name.indexOf(':'); + if (colon1 != -1) { + String msg + = DOMMessageFormatter.formatMessage( + DOMMessageFormatter.DOM_DOMAIN, + "NAMESPACE_ERR", + null); + throw new DOMException(DOMException.NAMESPACE_ERR, msg); + } + if (!CoreDocumentImpl.isXMLName(name, ownerDocument.isXML11Version())) { + String msg = DOMMessageFormatter.formatMessage( + DOMMessageFormatter.DOM_DOMAIN, + "INVALID_CHARACTER_ERR", null); + throw new DOMException(DOMException.INVALID_CHARACTER_ERR, + msg); + } + } + this.name = name; reconcileDefaultAttributes(); } // // Node methods // - - /** - * A short integer indicating what type of node this is. The named - * constants for this value are defined in the org.w3c.dom.Node interface. + * A short integer indicating what type of node this is. The named constants + * for this value are defined in the org.w3c.dom.Node interface. */ public short getNodeType() { return Node.ELEMENT_NODE; } /** - * Returns the element name + * Returns the node name + * + * @return the node name */ + @Override public String getNodeName() { if (needsSyncData()) { synchronizeData(); @@ -129,7 +155,10 @@ * from Node rather than specified on Element; in fact only Elements will * ever have Attributes, but they want to allow folks to "blindly" operate * on the tree as a set of Nodes. + * + * @return all Attributes */ + @Override public NamedNodeMap getAttributes() { if (needsSyncData()) { @@ -143,12 +172,13 @@ } // getAttributes():NamedNodeMap /** - * Return a duplicate copy of this Element. Note that its children - * will not be copied unless the "deep" flag is true, but Attributes - * are always replicated. + * Return a duplicate copy of this Element. Note that its children will not + * be copied unless the "deep" flag is true, but Attributes are + * {@code always} replicated. * * @see org.w3c.dom.Node#cloneNode(boolean) */ + @Override public Node cloneNode(boolean deep) { ElementImpl newnode = (ElementImpl) super.cloneNode(deep); @@ -160,10 +190,12 @@ } // cloneNode(boolean):Node - /** - * DOM Level 3 WD - Experimental. - * Retrieve baseURI + /** + * DOM Level 3 WD - Experimental. Retrieve baseURI + * + * @return the baseURI */ + @Override public String getBaseURI() { if (needsSyncData()) { @@ -174,62 +206,61 @@ // 1. The base URI specified by an xml:base attribute on the element, // if one exists if (attributes != null) { - Attr attrNode = (Attr)attributes.getNamedItem("xml:base"); + final Attr attrNode = getXMLBaseAttribute(); if (attrNode != null) { - String uri = attrNode.getNodeValue(); - if (uri.length() != 0 ) {// attribute value is always empty string + final String uri = attrNode.getNodeValue(); + if (uri.length() != 0) {// attribute value is always empty string try { - uri = new URI(uri).toString(); - } - catch (com.sun.org.apache.xerces.internal.util.URI.MalformedURIException e) { - // This may be a relative URI. + URI _uri = new URI(uri, true); + // If the URI is already absolute return it; otherwise it's relative and we need to resolve it. + if (_uri.isAbsoluteURI()) { + return _uri.toString(); + } // Make any parentURI into a URI object to use with the URI(URI, String) constructor String parentBaseURI = (this.ownerNode != null) ? this.ownerNode.getBaseURI() : null; - if (parentBaseURI != null){ - try{ - uri = new URI(new URI(parentBaseURI), uri).toString(); - } - catch (com.sun.org.apache.xerces.internal.util.URI.MalformedURIException ex){ + if (parentBaseURI != null) { + try { + URI _parentBaseURI = new URI(parentBaseURI); + _uri.absolutize(_parentBaseURI); + return _uri.toString(); + } catch (com.sun.org.apache.xerces.internal.util.URI.MalformedURIException ex) { // This should never happen: parent should have checked the URI and returned null if invalid. return null; } - return uri; } + // REVISIT: what should happen in this case? + return null; + } catch (com.sun.org.apache.xerces.internal.util.URI.MalformedURIException ex) { return null; } - return uri; } } } // 2.the base URI of the element's parent element within the // document or external entity, if one exists - // 3. the base URI of the document entity or external entity - // containing the element - - // ownerNode serves as a parent or as document - String baseURI = (this.ownerNode != null) ? this.ownerNode.getBaseURI() : null ; - //base URI of parent element is not null - if(baseURI != null){ - try { - //return valid absolute base URI - return new URI(baseURI).toString(); - } - catch (com.sun.org.apache.xerces.internal.util.URI.MalformedURIException e){ - return null; - } - } - return null; + // 3. the base URI of the document entity or external entity + // containing the element + // ownerNode serves as a parent or as document + return (this.ownerNode != null) ? this.ownerNode.getBaseURI() : null; } //getBaseURI - + /** + * NON-DOM Returns the xml:base attribute. + * + * @return the xml:base attribute + */ + protected Attr getXMLBaseAttribute() { + return (Attr) attributes.getNamedItem("xml:base"); + } // getXMLBaseAttribute():Attr /** - * NON-DOM - * set the ownerDocument of this node, its children, and its attributes + * NON-DOM set the ownerDocument of this node, its children, and its + * attributes */ - void setOwnerDocument(CoreDocumentImpl doc) { + @Override + protected void setOwnerDocument(CoreDocumentImpl doc) { super.setOwnerDocument(doc); if (attributes != null) { attributes.setOwnerDocument(doc); @@ -239,15 +270,14 @@ // // Element methods // - /** - * Look up a single Attribute by name. Returns the Attribute's - * string value, or an empty string (NOT null!) to indicate that the - * name did not map to a currently defined attribute. + * Look up a single Attribute by name. Returns the Attribute's string value, + * or an empty string (NOT null!) to indicate that the name did not map to a + * currently defined attribute. *
- * Note: Attributes may contain complex node trees. This method - * returns the "flattened" string obtained from Attribute.getValue(). - * If you need the structure information, see getAttributeNode(). + * Note: Attributes may contain complex node trees. This method returns the + * "flattened" string obtained from Attribute.getValue(). If you need the + * structure information, see getAttributeNode(). */ public String getAttribute(String name) { @@ -257,16 +287,15 @@ if (attributes == null) { return ""; } - Attr attr = (Attr)(attributes.getNamedItem(name)); + Attr attr = (Attr) (attributes.getNamedItem(name)); return (attr == null) ? "" : attr.getValue(); } // getAttribute(String):String - /** - * Look up a single Attribute by name. Returns the Attribute Node, - * so its complete child tree is available. This could be important in - * XML, where the string rendering may not be sufficient information. + * Look up a single Attribute by name. Returns the Attribute Node, so its + * complete child tree is available. This could be important in XML, where + * the string rendering may not be sufficient information. *
* If no matching attribute is available, returns null. */ @@ -278,36 +307,32 @@ if (attributes == null) { return null; } - return (Attr)attributes.getNamedItem(name); + return (Attr) attributes.getNamedItem(name); } // getAttributeNode(String):Attr - /** - * Returns a NodeList of all descendent nodes (children, - * grandchildren, and so on) which are Elements and which have the - * specified tag name. + * Returns a NodeList of all descendent nodes (children, grandchildren, and + * so on) which are Elements and which have the specified tag name. *
- * Note: NodeList is a "live" view of the DOM. Its contents will - * change as the DOM changes, and alterations made to the NodeList - * will be reflected in the DOM. + * Note: NodeList is a "live" view of the DOM. Its contents will change as + * the DOM changes, and alterations made to the NodeList will be reflected + * in the DOM. * - * @param tagname The type of element to gather. To obtain a list of - * all elements no matter what their names, use the wild-card tag - * name "*". + * @param tagname The type of element to gather. To obtain a list of all + * elements no matter what their names, use the wild-card tag name "*". * * @see DeepNodeListImpl */ public NodeList getElementsByTagName(String tagname) { - return new DeepNodeListImpl(this,tagname); + return new DeepNodeListImpl(this, tagname); } /** - * Returns the name of the Element. Note that Element.nodeName() is - * defined to also return the tag name. + * Returns the name of the Element. Note that Element.nodeName() is defined + * to also return the tag name. *
- * This is case-preserving in XML. HTML should uppercasify it on the - * way in. + * This is case-preserving in XML. HTML should uppercasify it on the way in. */ public String getTagName() { if (needsSyncData()) { @@ -326,9 +351,9 @@ *
* To normalize a Document, normalize its top-level Element child. *
- * As of PR-DOM-Level-1-19980818, CDATA -- despite being a subclass of
- * Text -- is considered "markup" and will _not_ be merged either with
- * normal Text or with other CDATASections.
+ * As of PR-DOM-Level-1-19980818, CDATA -- despite being a subclass of Text
+ * -- is considered "markup" and will _not_ be merged either with normal
+ * Text or with other CDATASections.
*/
public void normalize() {
// No need to normalize if already normalized.
@@ -347,35 +372,27 @@
// 1) There is an adjacent text node
// 2) There is no adjacent text node, but kid is
// an empty text node.
- if ( kid.getNodeType() == Node.TEXT_NODE )
- {
+ if (kid.getNodeType() == Node.TEXT_NODE) {
// If an adjacent text node, merge it with kid
- if ( next!=null && next.getNodeType() == Node.TEXT_NODE )
- {
- ((Text)kid).appendData(next.getNodeValue());
- removeChild( next );
+ if (next != null && next.getNodeType() == Node.TEXT_NODE) {
+ ((Text) kid).appendData(next.getNodeValue());
+ removeChild(next);
next = kid; // Don't advance; there might be another.
- }
- else
- {
+ } else {
// If kid is empty, remove it
- if ( kid.getNodeValue() == null || kid.getNodeValue().length() == 0 ) {
- removeChild( kid );
+ if (kid.getNodeValue() == null || kid.getNodeValue().length() == 0) {
+ removeChild(kid);
}
}
- }
-
- // Otherwise it might be an Element, which is handled recursively
+ } // Otherwise it might be an Element, which is handled recursively
else if (kid.getNodeType() == Node.ELEMENT_NODE) {
kid.normalize();
}
}
// We must also normalize all of the attributes
- if ( attributes!=null )
- {
- for( int i=0; i
- * Note that this call "succeeds" even if no attribute by this name
- * existed -- unlike removeAttributeNode, which will throw a not-found
- * exception in that case.
+ * Note that this call "succeeds" even if no attribute by this name existed
+ * -- unlike removeAttributeNode, which will throw a not-found exception in
+ * that case.
*
* @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) if the node is
* readonly.
@@ -421,16 +437,14 @@
} // removeAttribute(String)
-
/**
- * Remove the specified attribute/value pair. If the removed
- * Attribute has a default value, it is immediately replaced.
+ * Remove the specified attribute/value pair. If the removed Attribute has a
+ * default value, it is immediately replaced.
*
- * NOTE: Specifically removes THIS NODE -- not the node with this
- * name, nor the node with these contents. If the specific Attribute
- * object passed in is not stored in this Element, we throw a
- * DOMException. If you really want to remove an attribute by name,
- * use removeAttribute().
+ * NOTE: Specifically removes THIS NODE -- not the node with this name, nor
+ * the node with these contents. If the specific Attribute object passed in
+ * is not stored in this Element, we throw a DOMException. If you really
+ * want to remove an attribute by name, use removeAttribute().
*
* @return the Attribute object that was removed.
* @throws DOMException(NOT_FOUND_ERR) if oldattr is not an attribute of
@@ -439,7 +453,7 @@
* readonly.
*/
public Attr removeAttributeNode(Attr oldAttr)
- throws DOMException {
+ throws DOMException {
if (ownerDocument.errorChecking && isReadOnly()) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null);
@@ -458,19 +472,18 @@
} // removeAttributeNode(Attr):Attr
-
/**
- * Add a new name/value pair, or replace the value of the existing
- * attribute having that name.
+ * Add a new name/value pair, or replace the value of the existing attribute
+ * having that name.
*
- * Note: this method supports only the simplest kind of Attribute,
- * one whose value is a string contained in a single Text node.
- * If you want to assert a more complex value (which XML permits,
- * though HTML doesn't), see setAttributeNode().
+ * Note: this method supports only the simplest kind of Attribute, one whose
+ * value is a string contained in a single Text node. If you want to assert
+ * a more complex value (which XML permits, though HTML doesn't), see
+ * setAttributeNode().
*
- * The attribute is created with specified=true, meaning it's an
- * explicit value rather than inherited from the DTD as a default.
- * Again, setAttributeNode can be used to achieve other results.
+ * The attribute is created with specified=true, meaning it's an explicit
+ * value rather than inherited from the DTD as a default. Again,
+ * setAttributeNode can be used to achieve other results.
*
* @throws DOMException(INVALID_NAME_ERR) if the name is not acceptable.
* (Attribute factory will do that test for us.)
@@ -478,54 +491,52 @@
* @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) if the node is
* readonly.
*/
- public void setAttribute(String name, String value) {
+ public void setAttribute(String name, String value) {
- if (ownerDocument.errorChecking && isReadOnly()) {
- String msg =
- DOMMessageFormatter.formatMessage(
- DOMMessageFormatter.DOM_DOMAIN,
- "NO_MODIFICATION_ALLOWED_ERR",
- null);
- throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, msg);
- }
+ if (ownerDocument.errorChecking && isReadOnly()) {
+ String msg
+ = DOMMessageFormatter.formatMessage(
+ DOMMessageFormatter.DOM_DOMAIN,
+ "NO_MODIFICATION_ALLOWED_ERR",
+ null);
+ throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, msg);
+ }
- if (needsSyncData()) {
- synchronizeData();
- }
+ if (needsSyncData()) {
+ synchronizeData();
+ }
- Attr newAttr = getAttributeNode(name);
- if (newAttr == null) {
- newAttr = getOwnerDocument().createAttribute(name);
+ Attr newAttr = getAttributeNode(name);
+ if (newAttr == null) {
+ newAttr = getOwnerDocument().createAttribute(name);
- if (attributes == null) {
- attributes = new AttributeMap(this, null);
- }
+ if (attributes == null) {
+ attributes = new AttributeMap(this, null);
+ }
- newAttr.setNodeValue(value);
- attributes.setNamedItem(newAttr);
- }
- else {
- newAttr.setNodeValue(value);
- }
+ newAttr.setNodeValue(value);
+ attributes.setNamedItem(newAttr);
+ } else {
+ newAttr.setNodeValue(value);
+ }
- } // setAttribute(String,String)
+ } // setAttribute(String,String)
/**
- * Add a new attribute/value pair, or replace the value of the
- * existing attribute with that name.
+ * Add a new attribute/value pair, or replace the value of the existing
+ * attribute with that name.
*
* This method allows you to add an Attribute that has already been
* constructed, and hence avoids the limitations of the simple
- * setAttribute() call. It can handle attribute values that have
- * arbitrarily complex tree structure -- in particular, those which
- * had entity references mixed into their text.
+ * setAttribute() call. It can handle attribute values that have arbitrarily
+ * complex tree structure -- in particular, those which had entity
+ * references mixed into their text.
*
- * @throws DOMException(INUSE_ATTRIBUTE_ERR) if the Attribute object
- * has already been assigned to another Element.
+ * @throws DOMException(INUSE_ATTRIBUTE_ERR) if the Attribute object has
+ * already been assigned to another Element.
*/
public Attr setAttributeNode(Attr newAttr)
- throws DOMException
- {
+ throws DOMException {
if (needsSyncData()) {
synchronizeData();
@@ -535,13 +546,13 @@
if (isReadOnly()) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null);
throw new DOMException(
- DOMException.NO_MODIFICATION_ALLOWED_ERR,
- msg);
+ DOMException.NO_MODIFICATION_ALLOWED_ERR,
+ msg);
}
if (newAttr.getOwnerDocument() != ownerDocument) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "WRONG_DOCUMENT_ERR", null);
- throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, msg);
+ throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, msg);
}
}
@@ -556,19 +567,16 @@
//
// DOM2: Namespace methods
//
-
/**
- * Introduced in DOM Level 2.
+ * Introduced in DOM Level 2.
+ *
*
* Retrieves an attribute value by local name and namespace URI.
*
- * @param namespaceURI
- * The namespace URI of the attribute to
- * retrieve.
- * @param localName The local name of the attribute to retrieve.
- * @return String The Attr value as a string, or empty string
- * if that attribute
- * does not have a specified or default value.
+ * @param namespaceURI The namespace URI of the attribute to retrieve.
+ * @param localName The local name of the attribute to retrieve.
+ * @return String The Attr value as a string, or empty string if that
+ * attribute does not have a specified or default value.
* @since WD-DOM-Level-2-19990923
*/
public String getAttributeNS(String namespaceURI, String localName) {
@@ -581,89 +589,85 @@
return "";
}
- Attr attr = (Attr)(attributes.getNamedItemNS(namespaceURI, localName));
+ Attr attr = (Attr) (attributes.getNamedItemNS(namespaceURI, localName));
return (attr == null) ? "" : attr.getValue();
} // getAttributeNS(String,String):String
/**
- * Introduced in DOM Level 2.
- *
- * Adds a new attribute.
- * If the given namespaceURI is null or an empty string and the
- * qualifiedName has a prefix that is "xml", the new attribute is bound to
- * the predefined namespace "http://www.w3.org/XML/1998/namespace"
- * [Namespaces]. If an attribute with the same local name and namespace
- * URI is already present on the element, its prefix is changed to be the
- * prefix part of the qualifiedName, and its value is changed to be the
- * value parameter. This value is a simple string, it is not parsed as it
- * is being set. So any markup (such as syntax to be recognized as an
- * entity reference) is treated as literal text, and needs to be
- * appropriately escaped by the implementation when it is written out. In
- * order to assign an attribute value that contains entity references, the
- * user must create an Attr node plus any Text and EntityReference nodes,
- * build the appropriate subtree, and use setAttributeNodeNS or
- * setAttributeNode to assign it as the value of an attribute.
+ * Introduced in DOM Level 2.
+ *
*
- * @param namespaceURI The namespace URI of the attribute to create
- * or alter.
- * @param qualifiedName The qualified name of the attribute to create or
- * alter.
- * @param value The value to set in string form.
- * @throws INVALID_CHARACTER_ERR: Raised if the specified
- * name contains an invalid character.
+ * Adds a new attribute. If the given namespaceURI is null or an empty
+ * string and the qualifiedName has a prefix that is "xml", the new
+ * attribute is bound to the predefined namespace
+ * "http://www.w3.org/XML/1998/namespace" [Namespaces]. If an attribute with
+ * the same local name and namespace URI is already present on the element,
+ * its prefix is changed to be the prefix part of the qualifiedName, and its
+ * value is changed to be the value parameter. This value is a simple
+ * string, it is not parsed as it is being set. So any markup (such as
+ * syntax to be recognized as an entity reference) is treated as literal
+ * text, and needs to be appropriately escaped by the implementation when it
+ * is written out. In order to assign an attribute value that contains
+ * entity references, the user must create an Attr node plus any Text and
+ * EntityReference nodes, build the appropriate subtree, and use
+ * setAttributeNodeNS or setAttributeNode to assign it as the value of an
+ * attribute.
*
- * @throws NO_MODIFICATION_ALLOWED_ERR: Raised if this
- * node is readonly.
+ * @param namespaceURI The namespace URI of the attribute to create or
+ * alter.
+ * @param qualifiedName The qualified name of the attribute to create or
+ * alter.
+ * @param value The value to set in string form.
+ * @throws INVALID_CHARACTER_ERR: Raised if the specified name contains an
+ * invalid character.
*
- * @throws NAMESPACE_ERR: Raised if the qualifiedName
- * has a prefix that is "xml" and the namespaceURI
- * is neither null nor an empty string nor
- * "http://www.w3.org/XML/1998/namespace", or if
- * the qualifiedName has a prefix that is "xmlns"
- * but the namespaceURI is neither null nor an
- * empty string, or if if the qualifiedName has a
- * prefix different from "xml" and "xmlns" and the
- * namespaceURI is null or an empty string.
+ * @throws NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
+ *
+ * @throws NAMESPACE_ERR: Raised if the qualifiedName has a prefix that is
+ * "xml" and the namespaceURI is neither null nor an empty string nor
+ * "http://www.w3.org/XML/1998/namespace", or if the qualifiedName has a
+ * prefix that is "xmlns" but the namespaceURI is neither null nor an empty
+ * string, or if if the qualifiedName has a prefix different from "xml" and
+ * "xmlns" and the namespaceURI is null or an empty string.
* @since WD-DOM-Level-2-19990923
*/
- public void setAttributeNS(String namespaceURI,String qualifiedName,
- String value) {
- if (ownerDocument.errorChecking && isReadOnly()) {
- String msg =
- DOMMessageFormatter.formatMessage(
- DOMMessageFormatter.DOM_DOMAIN,
- "NO_MODIFICATION_ALLOWED_ERR",
- null);
- throw new DOMException(
- DOMException.NO_MODIFICATION_ALLOWED_ERR,
- msg);
- }
- if (needsSyncData()) {
- synchronizeData();
- }
- int index = qualifiedName.indexOf(':');
- String prefix, localName;
- if (index < 0) {
- prefix = null;
- localName = qualifiedName;
- }
- else {
- prefix = qualifiedName.substring(0, index);
- localName = qualifiedName.substring(index + 1);
- }
- Attr newAttr = getAttributeNodeNS(namespaceURI, localName);
- if (newAttr == null) {
+ public void setAttributeNS(String namespaceURI, String qualifiedName,
+ String value) {
+ if (ownerDocument.errorChecking && isReadOnly()) {
+ String msg
+ = DOMMessageFormatter.formatMessage(
+ DOMMessageFormatter.DOM_DOMAIN,
+ "NO_MODIFICATION_ALLOWED_ERR",
+ null);
+ throw new DOMException(
+ DOMException.NO_MODIFICATION_ALLOWED_ERR,
+ msg);
+ }
+ if (needsSyncData()) {
+ synchronizeData();
+ }
+ int index = qualifiedName.indexOf(':');
+ String prefix, localName;
+ if (index < 0) {
+ prefix = null;
+ localName = qualifiedName;
+ } else {
+ prefix = qualifiedName.substring(0, index);
+ localName = qualifiedName.substring(index + 1);
+ }
+ Attr newAttr = getAttributeNodeNS(namespaceURI, localName);
+ if (newAttr == null) {
// REVISIT: this is not efficient, we are creating twice the same
// strings for prefix and localName.
- newAttr = getOwnerDocument().createAttributeNS(
- namespaceURI,
- qualifiedName);
- if (attributes == null) {
- attributes = new AttributeMap(this, null);
- }
- newAttr.setNodeValue(value);
- attributes.setNamedItemNS(newAttr);
+ newAttr = getOwnerDocument().createAttributeNS(
+ namespaceURI,
+ qualifiedName);
+ if (attributes == null) {
+ attributes = new AttributeMap(this, null);
+ }
+ newAttr.setNodeValue(value);
+ attributes.setNamedItemNS(newAttr);
}
else {
if (newAttr instanceof AttrNSImpl){
@@ -694,25 +698,24 @@
attributes.setNamedItemNS(newAttr);
}
- newAttr.setNodeValue(value);
- }
+ newAttr.setNodeValue(value);
+ }
} // setAttributeNS(String,String,String)
-
/**
- * Introduced in DOM Level 2.
+ * Introduced in DOM Level 2.
+ *
*
* Removes an attribute by local name and namespace URI. If the removed
- * attribute has a default value it is immediately replaced.
- * The replacing attribute has the same namespace URI and local name,
- * as well as the original prefix.
+ * attribute has a default value it is immediately replaced. The replacing
+ * attribute has the same namespace URI and local name, as well as the
+ * original prefix.
*
- * @param namespaceURI The namespace URI of the attribute to remove.
+ * @param namespaceURI The namespace URI of the attribute to remove.
*
- * @param localName The local name of the attribute to remove.
- * @throws NO_MODIFICATION_ALLOWED_ERR: Raised if this
- * node is readonly.
+ * @param localName The local name of the attribute to remove.
+ * @throws NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
* @since WD-DOM-Level-2-19990923
*/
public void removeAttributeNS(String namespaceURI, String localName) {
@@ -737,15 +740,13 @@
/**
* Retrieves an Attr node by local name and namespace URI.
*
- * @param namespaceURI The namespace URI of the attribute to
- * retrieve.
- * @param localName The local name of the attribute to retrieve.
- * @return Attr The Attr node with the specified attribute
- * local name and namespace
- * URI or null if there is no such attribute.
+ * @param namespaceURI The namespace URI of the attribute to retrieve.
+ * @param localName The local name of the attribute to retrieve.
+ * @return Attr The Attr node with the specified attribute local name and
+ * namespace URI or null if there is no such attribute.
* @since WD-DOM-Level-2-19990923
*/
- public Attr getAttributeNodeNS(String namespaceURI, String localName){
+ public Attr getAttributeNodeNS(String namespaceURI, String localName) {
if (needsSyncData()) {
synchronizeData();
@@ -753,40 +754,34 @@
if (attributes == null) {
return null;
}
- return (Attr)attributes.getNamedItemNS(namespaceURI, localName);
+ return (Attr) attributes.getNamedItemNS(namespaceURI, localName);
} // getAttributeNodeNS(String,String):Attr
/**
- * Introduced in DOM Level 2.
+ * Introduced in DOM Level 2.
+ *
*
- * Adds a new attribute. If an attribute with that local name and
- * namespace URI is already present in the element, it is replaced
- * by the new one.
+ * Adds a new attribute. If an attribute with that local name and namespace
+ * URI is already present in the element, it is replaced by the new one.
*
- * @param Attr The Attr node to add to the attribute list. When
- * the Node has no namespaceURI, this method behaves
- * like setAttributeNode.
- * @return Attr If the newAttr attribute replaces an existing attribute
- * with the same local name and namespace URI, the *
- * previously existing Attr node is returned, otherwise
- * null is returned.
- * @throws WRONG_DOCUMENT_ERR: Raised if newAttr
- * was created from a different document than the one that
- * created the element.
+ * @param newAttr The Attr node to add to the attribute list. When the Node
+ * has no namespaceURI, this method behaves like setAttributeNode.
+ * @return Attr If the newAttr attribute replaces an existing attribute with
+ * the same local name and namespace URI, the * previously existing Attr
+ * node is returned, otherwise null is returned.
+ * @throws WRONG_DOCUMENT_ERR: Raised if newAttr was created from a
+ * different document than the one that created the element.
*
- * @throws NO_MODIFICATION_ALLOWED_ERR: Raised if
- * this node is readonly.
+ * @throws NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
*
- * @throws INUSE_ATTRIBUTE_ERR: Raised if newAttr is
- * already an attribute of another Element object. The
- * DOM user must explicitly clone Attr nodes to re-use
- * them in other elements.
+ * @throws INUSE_ATTRIBUTE_ERR: Raised if newAttr is already an attribute of
+ * another Element object. The DOM user must explicitly clone Attr nodes to
+ * re-use them in other elements.
* @since WD-DOM-Level-2-19990923
*/
public Attr setAttributeNodeNS(Attr newAttr)
- throws DOMException
- {
+ throws DOMException {
if (needsSyncData()) {
synchronizeData();
@@ -794,9 +789,9 @@
if (ownerDocument.errorChecking) {
if (isReadOnly()) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null);
- throw new DOMException(
- DOMException.NO_MODIFICATION_ALLOWED_ERR,
- msg);
+ throw new DOMException(
+ DOMException.NO_MODIFICATION_ALLOWED_ERR,
+ msg);
}
if (newAttr.getOwnerDocument() != ownerDocument) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "WRONG_DOCUMENT_ERR", null);
@@ -813,9 +808,9 @@
} // setAttributeNodeNS(Attr):Attr
/**
- * NON-DOM: sets attribute node for this element
- */
- protected int setXercesAttributeNode (Attr attr){
+ * NON-DOM: sets attribute node for this element
+ */
+ protected int setXercesAttributeNode(Attr attr) {
if (needsSyncData()) {
synchronizeData();
@@ -829,9 +824,9 @@
}
/**
- * NON-DOM: get inded of an attribute
- */
- protected int getXercesAttribute(String namespaceURI, String localName){
+ * NON-DOM: get inded of an attribute
+ */
+ protected int getXercesAttribute(String namespaceURI, String localName) {
if (needsSyncData()) {
synchronizeData();
@@ -868,32 +863,30 @@
}
/**
- * Introduced in DOM Level 2.
+ * Introduced in DOM Level 2.
+ *
*
* Returns a NodeList of all the Elements with a given local name and
* namespace URI in the order in which they would be encountered in a
* preorder traversal of the Document tree, starting from this node.
*
- * @param namespaceURI The namespace URI of the elements to match
- * on. The special value "*" matches all
- * namespaces. When it is null or an empty
- * string, this method behaves like
- * getElementsByTagName.
- * @param localName The local name of the elements to match on.
- * The special value "*" matches all local names.
- * @return NodeList A new NodeList object containing all the matched
- * Elements.
+ * @param namespaceURI The namespace URI of the elements to match on. The
+ * special value "*" matches all namespaces. When it is null or an empty
+ * string, this method behaves like getElementsByTagName.
+ * @param localName The local name of the elements to match on. The special
+ * value "*" matches all local names.
+ * @return NodeList A new NodeList object containing all the matched
+ * Elements.
* @since WD-DOM-Level-2-19990923
*/
public NodeList getElementsByTagNameNS(String namespaceURI,
- String localName) {
+ String localName) {
return new DeepNodeListImpl(this, namespaceURI, localName);
}
/**
- * DOM Level 3 WD- Experimental.
- * Override inherited behavior from NodeImpl and ParentNode to check on
- * attributes
+ * DOM Level 3 WD- Experimental. Override inherited behavior from NodeImpl
+ * and ParentNode to check on attributes
*/
public boolean isEqualNode(Node arg) {
if (!super.isEqualNode(arg)) {
@@ -917,10 +910,9 @@
if (n2 == null || !((NodeImpl) n1).isEqualNode(n2)) {
return false;
}
- }
- else {
+ } else {
Node n2 = map2.getNamedItemNS(n1.getNamespaceURI(),
- n1.getLocalName());
+ n1.getLocalName());
if (n2 == null || !((NodeImpl) n1).isEqualNode(n2)) {
return false;
}
@@ -941,8 +933,8 @@
if (isReadOnly()) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null);
throw new DOMException(
- DOMException.NO_MODIFICATION_ALLOWED_ERR,
- msg);
+ DOMException.NO_MODIFICATION_ALLOWED_ERR,
+ msg);
}
if (at.getOwnerElement() != this) {
@@ -953,8 +945,7 @@
((AttrImpl) at).isIdAttribute(makeId);
if (!makeId) {
ownerDocument.removeIdentifier(at.getValue());
- }
- else {
+ } else {
ownerDocument.putIdentifier(at.getValue(), this);
}
}
@@ -968,19 +959,19 @@
}
Attr at = getAttributeNode(name);
- if( at == null){
- String msg = DOMMessageFormatter.formatMessage(
- DOMMessageFormatter.DOM_DOMAIN,
- "NOT_FOUND_ERR", null);
+ if (at == null) {
+ String msg = DOMMessageFormatter.formatMessage(
+ DOMMessageFormatter.DOM_DOMAIN,
+ "NOT_FOUND_ERR", null);
throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
- }
+ }
- if (ownerDocument.errorChecking) {
+ if (ownerDocument.errorChecking) {
if (isReadOnly()) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null);
throw new DOMException(
- DOMException.NO_MODIFICATION_ALLOWED_ERR,
- msg);
+ DOMException.NO_MODIFICATION_ALLOWED_ERR,
+ msg);
}
if (at.getOwnerElement() != this) {
@@ -992,8 +983,7 @@
((AttrImpl) at).isIdAttribute(makeId);
if (!makeId) {
ownerDocument.removeIdentifier(at.getValue());
- }
- else {
+ } else {
ownerDocument.putIdentifier(at.getValue(), this);
}
}
@@ -1002,51 +992,52 @@
* DOM Level 3: register the given attribute node as an ID attribute
*/
public void setIdAttributeNS(String namespaceURI, String localName,
- boolean makeId) {
+ boolean makeId) {
if (needsSyncData()) {
synchronizeData();
}
//if namespace uri is empty string, set it to 'null'
if (namespaceURI != null) {
- namespaceURI = (namespaceURI.length() == 0)? null : namespaceURI;
+ namespaceURI = (namespaceURI.length() == 0) ? null : namespaceURI;
}
Attr at = getAttributeNodeNS(namespaceURI, localName);
- if( at == null){
- String msg = DOMMessageFormatter.formatMessage(
- DOMMessageFormatter.DOM_DOMAIN,
- "NOT_FOUND_ERR", null);
+ if (at == null) {
+ String msg = DOMMessageFormatter.formatMessage(
+ DOMMessageFormatter.DOM_DOMAIN,
+ "NOT_FOUND_ERR", null);
throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
- }
+ }
- if (ownerDocument.errorChecking) {
+ if (ownerDocument.errorChecking) {
if (isReadOnly()) {
- String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null);
+ String msg = DOMMessageFormatter.formatMessage(
+ DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null);
throw new DOMException(
- DOMException.NO_MODIFICATION_ALLOWED_ERR,
- msg);
+ DOMException.NO_MODIFICATION_ALLOWED_ERR,
+ msg);
}
if (at.getOwnerElement() != this) {
- String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NOT_FOUND_ERR", null);
+ String msg = DOMMessageFormatter.formatMessage(
+ DOMMessageFormatter.DOM_DOMAIN, "NOT_FOUND_ERR", null);
throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
}
}
((AttrImpl) at).isIdAttribute(makeId);
if (!makeId) {
ownerDocument.removeIdentifier(at.getValue());
- }
- else {
+ } else {
ownerDocument.putIdentifier(at.getValue(), this);
}
- }
+ }
/**
* @see org.w3c.dom.TypeInfo#getTypeName()
*/
- public String getTypeName() {
+ public String getTypeName() {
return null;
- }
+ }
/**
* @see org.w3c.dom.TypeInfo#getTypeNamespace()
@@ -1056,33 +1047,32 @@
}
/**
- * Introduced in DOM Level 3.
+ * Introduced in DOM Level 3.
+ *
* Checks if a type is derived from another by restriction. See:
* http://www.w3.org/TR/DOM-Level-3-Core/core.html#TypeInfo-isDerivedFrom
*
- * @param ancestorNS
- * The namspace of the ancestor type declaration
- * @param ancestorName
- * The name of the ancestor type declaration
- * @param type
- * The reference type definition
+ * @param typeNamespaceArg The namspace of the ancestor type declaration
+ * @param typeNameArg The name of the ancestor type declaration
+ * @param derivationMethod The derivation method
*
- * @return boolean True if the type is derived by restriciton for the
- * reference type
+ * @return boolean True if the type is derived by restriction for the
+ * reference type
*/
public boolean isDerivedFrom(String typeNamespaceArg,
- String typeNameArg,
- int derivationMethod) {
+ String typeNameArg,
+ int derivationMethod) {
return false;
}
- /**
- * Method getSchemaTypeInfo.
- * @return TypeInfo
- */
- public TypeInfo getSchemaTypeInfo(){
- if(needsSyncData()) {
+ /**
+ * Method getSchemaTypeInfo.
+ *
+ * @return TypeInfo
+ */
+ public TypeInfo getSchemaTypeInfo() {
+ if (needsSyncData()) {
synchronizeData();
}
return this;
@@ -1091,25 +1081,24 @@
//
// Public methods
//
-
/**
* NON-DOM: Subclassed to flip the attributes' readonly switch as well.
+ *
* @see NodeImpl#setReadOnly
*/
public void setReadOnly(boolean readOnly, boolean deep) {
- super.setReadOnly(readOnly,deep);
+ super.setReadOnly(readOnly, deep);
if (attributes != null) {
- attributes.setReadOnly(readOnly,true);
+ attributes.setReadOnly(readOnly, true);
}
}
-
-
//
// Protected methods
//
-
- /** Synchronizes the data (name and value) for fast nodes. */
+ /**
+ * Synchronizes the data (name and value) for fast nodes.
+ */
protected void synchronizeData() {
// no need to sync in the future
@@ -1141,7 +1130,9 @@
}
}
- /** Setup the default attributes. */
+ /**
+ * Setup the default attributes.
+ */
protected void setupDefaultAttributes() {
NamedNodeMapImpl defaults = getDefaultAttributes();
if (defaults != null) {
@@ -1149,7 +1140,9 @@
}
}
- /** Reconcile default attributes. */
+ /**
+ * Reconcile default attributes.
+ */
protected void reconcileDefaultAttributes() {
if (attributes != null) {
NamedNodeMapImpl defaults = getDefaultAttributes();
@@ -1157,17 +1150,19 @@
}
}
- /** Get the default attributes. */
+ /**
+ * Get the default attributes.
+ */
protected NamedNodeMapImpl getDefaultAttributes() {
- DocumentTypeImpl doctype =
- (DocumentTypeImpl) ownerDocument.getDoctype();
+ DocumentTypeImpl doctype
+ = (DocumentTypeImpl) ownerDocument.getDoctype();
if (doctype == null) {
return null;
}
- ElementDefinitionImpl eldef =
- (ElementDefinitionImpl)doctype.getElements()
- .getNamedItem(getNodeName());
+ ElementDefinitionImpl eldef
+ = (ElementDefinitionImpl) doctype.getElements()
+ .getNamedItem(getNodeName());
if (eldef == null) {
return null;
}
@@ -1175,4 +1170,208 @@
} // getDefaultAttributes()
+ //
+ // ElementTraversal methods
+ //
+ /**
+ * @see
+ * Element Traversal Specification
+ */
+ @Override
+ public final int getChildElementCount() {
+ int count = 0;
+ Element child = getFirstElementChild();
+ while (child != null) {
+ ++count;
+ child = ((ElementImpl) child).getNextElementSibling();
+ }
+ return count;
+ } // getChildElementCount():int
+
+ /**
+ * @see
+ * Element Traversal Specification
+ */
+ @Override
+ public final Element getFirstElementChild() {
+ Node n = getFirstChild();
+ while (n != null) {
+ switch (n.getNodeType()) {
+ case Node.ELEMENT_NODE:
+ return (Element) n;
+ case Node.ENTITY_REFERENCE_NODE:
+ final Element e = getFirstElementChild(n);
+ if (e != null) {
+ return e;
+ }
+ break;
+ }
+ n = n.getNextSibling();
+ }
+ return null;
+ } // getFirstElementChild():Element
+
+ /**
+ * @see
+ * Element Traversal Specification
+ */
+ @Override
+ public final Element getLastElementChild() {
+ Node n = getLastChild();
+ while (n != null) {
+ switch (n.getNodeType()) {
+ case Node.ELEMENT_NODE:
+ return (Element) n;
+ case Node.ENTITY_REFERENCE_NODE:
+ final Element e = getLastElementChild(n);
+ if (e != null) {
+ return e;
+ }
+ break;
+ }
+ n = n.getPreviousSibling();
+ }
+ return null;
+ } // getLastElementChild():Element
+
+ /**
+ * @see
+ * Element Traversal Specification
+ */
+ @Override
+ public final Element getNextElementSibling() {
+ Node n = getNextLogicalSibling(this);
+ while (n != null) {
+ switch (n.getNodeType()) {
+ case Node.ELEMENT_NODE:
+ return (Element) n;
+ case Node.ENTITY_REFERENCE_NODE:
+ final Element e = getFirstElementChild(n);
+ if (e != null) {
+ return e;
+ }
+ break;
+ }
+ n = getNextLogicalSibling(n);
+ }
+ return null;
+ } // getNextElementSibling():Element
+
+ /**
+ * @see
+ * Element Traversal Specification
+ */
+ @Override
+ public final Element getPreviousElementSibling() {
+ Node n = getPreviousLogicalSibling(this);
+ while (n != null) {
+ switch (n.getNodeType()) {
+ case Node.ELEMENT_NODE:
+ return (Element) n;
+ case Node.ENTITY_REFERENCE_NODE:
+ final Element e = getLastElementChild(n);
+ if (e != null) {
+ return e;
+ }
+ break;
+ }
+ n = getPreviousLogicalSibling(n);
+ }
+ return null;
+ } // getPreviousElementSibling():Element
+
+ // Returns the first element node found from a
+ // non-recursive in order traversal of the given node.
+ private Element getFirstElementChild(Node n) {
+ final Node top = n;
+ while (n != null) {
+ if (n.getNodeType() == Node.ELEMENT_NODE) {
+ return (Element) n;
+ }
+ Node next = n.getFirstChild();
+ while (next == null) {
+ if (top == n) {
+ break;
+ }
+ next = n.getNextSibling();
+ if (next == null) {
+ n = n.getParentNode();
+ if (n == null || top == n) {
+ return null;
+ }
+ }
+ }
+ n = next;
+ }
+ return null;
+ } // getFirstElementChild(Node):Element
+
+ // Returns the first element node found from a
+ // non-recursive reverse order traversal of the given node.
+ private Element getLastElementChild(Node n) {
+ final Node top = n;
+ while (n != null) {
+ if (n.getNodeType() == Node.ELEMENT_NODE) {
+ return (Element) n;
+ }
+ Node next = n.getLastChild();
+ while (next == null) {
+ if (top == n) {
+ break;
+ }
+ next = n.getPreviousSibling();
+ if (next == null) {
+ n = n.getParentNode();
+ if (n == null || top == n) {
+ return null;
+ }
+ }
+ }
+ n = next;
+ }
+ return null;
+ } // getLastElementChild(Node):Element
+
+ // Returns the next logical sibling with respect to the given node.
+ private Node getNextLogicalSibling(Node n) {
+ Node next = n.getNextSibling();
+ // If "n" has no following sibling and its parent is an entity reference node we
+ // need to continue the search through the following siblings of the entity
+ // reference as these are logically siblings of the given node.
+ if (next == null) {
+ Node parent = n.getParentNode();
+ while (parent != null && parent.getNodeType() == Node.ENTITY_REFERENCE_NODE) {
+ next = parent.getNextSibling();
+ if (next != null) {
+ break;
+ }
+ parent = parent.getParentNode();
+ }
+ }
+ return next;
+ } // getNextLogicalSibling(Node):Node
+
+ // Returns the previous logical sibling with respect to the given node.
+ private Node getPreviousLogicalSibling(Node n) {
+ Node prev = n.getPreviousSibling();
+ // If "n" has no previous sibling and its parent is an entity reference node we
+ // need to continue the search through the previous siblings of the entity
+ // reference as these are logically siblings of the given node.
+ if (prev == null) {
+ Node parent = n.getParentNode();
+ while (parent != null && parent.getNodeType() == Node.ENTITY_REFERENCE_NODE) {
+ prev = parent.getPreviousSibling();
+ if (prev != null) {
+ break;
+ }
+ parent = parent.getParentNode();
+ }
+ }
+ return prev;
+ } // getPreviousLogicalSibling(Node):Node
} // class ElementImpl
diff -r a7e186d534d5 -r 5625643929aa jaxp/src/java.xml/share/classes/org/w3c/dom/ElementTraversal.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/src/java.xml/share/classes/org/w3c/dom/ElementTraversal.java Sat Sep 26 09:22:33 2015 -0700
@@ -0,0 +1,103 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * Copyright (c) 2015 World Wide Web Consortium,
+ *
+ * (Massachusetts Institute of Technology, European Research Consortium for
+ * Informatics and Mathematics, Keio University, Beihang). All Rights Reserved.
+ * This work is distributed under the W3C(r) Software License [1] in the hope that
+ * it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * [1] http://www.w3.org/Consortium/Legal/copyright-software
+ */
+
+package org.w3c.dom;
+
+/**
+ * The {@code ElementTraversal} interface is a set of read-only attributes
+ * which allow an author to easily navigate between elements in a document.
+ *
+ * In conforming implementations of Element Traversal, all objects that
+ * implement {@link Element} must also implement the {@code ElementTraversal}
+ * interface. Four of the methods,
+ * {@link #getFirstElementChild}, {@link #getLastElementChild},
+ * {@link #getPreviousElementSibling}, and {@link #getNextElementSibling},
+ * each provides a live reference to another element with the defined
+ * relationship to the current element, if the related element exists. The
+ * fifth method, {@link #getChildElementCount}, exposes the number of child
+ * elements of an element, for preprocessing before navigation.
+ *
+ * @see
+ * Element Traversal Specification.
+ *
+ * @since 9
+ */
+public interface ElementTraversal {
+
+ /**
+ * Returns a reference to the first child node of the element which is of
+ * the {@link Element} type.
+ *
+ * @return a reference to an element child, {@code null} if the element has
+ * no child of the {@link Element} type.
+ */
+ Element getFirstElementChild();
+
+ /**
+ * Returns a reference to the last child node of the element which is of
+ * the {@link Element} type.
+ *
+ * @return a reference to an element child, {@code null} if the element has
+ * no child of the {@link Element} type.
+ */
+ Element getLastElementChild();
+
+ /**
+ * Returns a reference to the sibling node of the element which most immediately
+ * precedes the element in document order, and which is of the {@link Element} type.
+ *
+ * @return a reference to an element child, {@code null} if the element has
+ * no sibling node of the {@link Element} type that comes before this one.
+ */
+ Element getPreviousElementSibling();
+
+ /**
+ * Returns a reference to the sibling node of the element which most immediately
+ * follows the element in document order, and which is of the {@link Element} type.
+ *
+ * @return a reference to an element child, {@code null} if the element has
+ * no sibling node of the {@link Element} type that comes after this one.
+ */
+ Element getNextElementSibling();
+
+ /**
+ * Returns the current number of child nodes of the element which are of
+ * the {@link Element} type.
+ *
+ * @return the number of element children, or {@code 0} if the element has
+ * no element children.
+ */
+ int getChildElementCount();
+}
diff -r a7e186d534d5 -r 5625643929aa jaxp/test/javax/xml/jaxp/unittest/dom/ElementTraversal.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/dom/ElementTraversal.java Sat Sep 26 09:22:33 2015 -0700
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package dom;
+
+import java.io.IOException;
+import java.io.InputStream;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+/*
+ * @bug 8135283
+ * @summary Tests for the Element Traversal interface.
+ */
+
+public class ElementTraversal {
+ /*
+ Verifies the ElementTraversal interface by exercising all of its five
+ methods while reading through the xml document.
+ */
+ @Test(dataProvider = "doc")
+ public void test(Document doc) {
+ org.w3c.dom.ElementTraversal et = (org.w3c.dom.ElementTraversal)doc.getDocumentElement();
+ //4 toys are listed
+ Assert.assertEquals(et.getChildElementCount(), 4);
+
+ //The 1st is the Martian
+ Element toy1 = et.getFirstElementChild();
+ verify(toy1, "1", "The Martian");
+
+ //toy1 has no previous element
+ Element noE = ((org.w3c.dom.ElementTraversal)toy1).getPreviousElementSibling();
+ Assert.assertEquals(noE, null);
+
+ //The 1st toy's next element is toy2, the Doll
+ Element toy2 = ((org.w3c.dom.ElementTraversal)toy1).getNextElementSibling();
+ verify(toy2, "2", "The Doll");
+
+ //The last toy is toy4, the Spaceship
+ Element toy4 = et.getLastElementChild();
+ verify(toy4, "4", "The Spaceship");
+
+ //toy4 has no next element
+ noE = ((org.w3c.dom.ElementTraversal)toy4).getNextElementSibling();
+ Assert.assertEquals(noE, null);
+
+ //toy4's previous element is toy3, Transformer X
+ //toy3 is also an EntityReference
+ Element toy3 = ((org.w3c.dom.ElementTraversal)toy4).getPreviousElementSibling();
+ verify(toy3, "3", "Transformer X");
+ }
+
+ /**
+ * Verifies that the values matches the specified element.
+ * @param id the value of the id attribute
+ * @param name the value of its name element
+ */
+ void verify(Element e, String id, String name) {
+ Assert.assertEquals(e.getAttribute("id"), id);
+ Element toyName = ((org.w3c.dom.ElementTraversal)e).getFirstElementChild();
+ Assert.assertEquals(toyName.getTextContent(), name);
+ }
+
+
+ /*
+ * DataProvider: a Document object
+ */
+ @DataProvider(name = "doc")
+ Object[][] getXPath() {
+ return new Object[][]{{getDoc()}};
+ }
+ Document getDoc() {
+ InputStream xmlFile = getClass().getResourceAsStream("ElementTraversal.xml");
+ Document doc = null;
+ try {
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ dbf.setExpandEntityReferences(false);
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ doc = db.parse(xmlFile);
+ } catch (ParserConfigurationException | SAXException | IOException e) {
+ System.out.println("fail: " + e.getMessage());
+ }
+
+ return doc;
+ }
+}
diff -r a7e186d534d5 -r 5625643929aa jaxp/test/javax/xml/jaxp/unittest/dom/ElementTraversal.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/dom/ElementTraversal.xml Sat Sep 26 09:22:33 2015 -0700
@@ -0,0 +1,24 @@
+
+Transformer X