summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Wilson <jessewilson@google.com>2010-03-15 22:05:59 -0700
committerAndroid Git Automerger <android-git-automerger@android.com>2010-03-15 22:05:59 -0700
commita2993c4388c76e18bc303005439420dd8ab83cbf (patch)
tree646268c30298f8a6a4658eb5e89cfb5c347639ee
parent9f013cac04b2b24101ee97b92944706140a81760 (diff)
parent503917e646b5ebd3f23dfe0cb41270cfe484693a (diff)
downloadlibcore-a2993c4388c76e18bc303005439420dd8ab83cbf.zip
libcore-a2993c4388c76e18bc303005439420dd8ab83cbf.tar.gz
libcore-a2993c4388c76e18bc303005439420dd8ab83cbf.tar.bz2
am 27182541: Implementing Document.renameNode() and DOMImplementation.getFeature().
Merge commit '271825415aa961bdd9f28a551575bcee6f27b4ab' into dalvik-dev * commit '271825415aa961bdd9f28a551575bcee6f27b4ab': Implementing Document.renameNode() and DOMImplementation.getFeature().
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/AttrImpl.java40
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/DOMImplementationImpl.java2
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/DocumentImpl.java15
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/ElementImpl.java33
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/NodeImpl.java54
-rw-r--r--xml/src/test/java/org/apache/harmony/xml/XsltXPathConformanceTestSuite.java2
-rw-r--r--xml/src/test/java/tests/xml/DomTest.java182
7 files changed, 228 insertions, 100 deletions
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/AttrImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/AttrImpl.java
index 56a4817..c601de6 100644
--- a/xml/src/main/java/org/apache/harmony/xml/dom/AttrImpl.java
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/AttrImpl.java
@@ -36,49 +36,19 @@ public final class AttrImpl extends NodeImpl implements Attr {
// Maintained by ElementImpl.
ElementImpl ownerElement;
-
- private boolean namespaceAware;
-
boolean isId;
-
- private String namespaceURI;
- private String localName;
+ boolean namespaceAware;
+ String namespaceURI;
+ String prefix;
+ String localName;
- private String prefix;
-
private String value;
AttrImpl(DocumentImpl document, String namespaceURI, String qualifiedName) {
super(document);
- namespaceAware = true;
- this.namespaceURI = namespaceURI;
-
- if (qualifiedName == null || "".equals(qualifiedName)) {
- throw new DOMException(DOMException.NAMESPACE_ERR, qualifiedName);
- }
-
- int prefixSeparator = qualifiedName.lastIndexOf(":");
- if (prefixSeparator != -1) {
- setPrefix(qualifiedName.substring(0, prefixSeparator));
- qualifiedName = qualifiedName.substring(prefixSeparator + 1);
- }
-
- localName = qualifiedName;
-
- if ("".equals(localName)) {
- throw new DOMException(DOMException.NAMESPACE_ERR, localName);
- }
-
- if ("xmlns".equals(localName) && !"http://www.w3.org/2000/xmlns/".equals(namespaceURI)) {
- throw new DOMException(DOMException.NAMESPACE_ERR, localName);
- }
-
- if (!DocumentImpl.isXMLIdentifier(localName)) {
- throw new DOMException(DOMException.INVALID_CHARACTER_ERR, localName);
- }
-
+ setNameNS(this, namespaceURI, qualifiedName);
value = "";
}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/DOMImplementationImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/DOMImplementationImpl.java
index b662a13..3106c3f 100644
--- a/xml/src/main/java/org/apache/harmony/xml/dom/DOMImplementationImpl.java
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/DOMImplementationImpl.java
@@ -85,6 +85,6 @@ public final class DOMImplementationImpl implements DOMImplementation {
}
public Object getFeature(String feature, String version) {
- throw new UnsupportedOperationException(); // TODO
+ return hasFeature(feature, version) ? this : null;
}
}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/DocumentImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/DocumentImpl.java
index c677e58..56283a8 100644
--- a/xml/src/main/java/org/apache/harmony/xml/dom/DocumentImpl.java
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/DocumentImpl.java
@@ -299,6 +299,16 @@ public final class DocumentImpl extends InnerNodeImpl implements Document {
}
}
+ public Node renameNode(Node node, String namespaceURI, String qualifiedName) {
+ if (node.getOwnerDocument() != this) {
+ throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, null);
+ }
+
+ setNameNS((NodeImpl) node, namespaceURI, qualifiedName);
+ notifyUserDataHandlers(UserDataHandler.NODE_RENAMED, node, null);
+ return node;
+ }
+
public AttrImpl createAttribute(String name) {
return new AttrImpl(this, name);
}
@@ -467,11 +477,6 @@ public final class DocumentImpl extends InnerNodeImpl implements Document {
((DOMConfigurationImpl) getDomConfig()).normalize(root);
}
- public Node renameNode(Node n, String namespaceURI, String qualifiedName) {
- // TODO: callback the UserDataHandler with a NODE_RENAMED event
- throw new UnsupportedOperationException(); // TODO
- }
-
/**
* Returns a map with the user data objects attached to the specified node.
* This map is readable and writable.
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/ElementImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/ElementImpl.java
index c3e5a2e..cbc4570 100644
--- a/xml/src/main/java/org/apache/harmony/xml/dom/ElementImpl.java
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/ElementImpl.java
@@ -39,37 +39,16 @@ import java.util.List;
*/
public class ElementImpl extends InnerNodeImpl implements Element {
- private boolean namespaceAware;
-
- private String namespaceURI;
-
- private String prefix;
-
- private String localName;
+ boolean namespaceAware;
+ String namespaceURI;
+ String prefix;
+ String localName;
private List<AttrImpl> attributes = new ArrayList<AttrImpl>();
ElementImpl(DocumentImpl document, String namespaceURI, String qualifiedName) {
super(document);
-
- this.namespaceAware = true;
- this.namespaceURI = namespaceURI;
-
- if (qualifiedName == null || "".equals(qualifiedName)) {
- throw new DOMException(DOMException.NAMESPACE_ERR, qualifiedName);
- }
-
- int p = qualifiedName.lastIndexOf(":");
- if (p != -1) {
- setPrefix(qualifiedName.substring(0, p));
- qualifiedName = qualifiedName.substring(p + 1);
- }
-
- if (!DocumentImpl.isXMLIdentifier(qualifiedName)) {
- throw new DOMException(DOMException.INVALID_CHARACTER_ERR, qualifiedName);
- }
-
- this.localName = qualifiedName;
+ setNameNS(this, namespaceURI, qualifiedName);
}
ElementImpl(DocumentImpl document, String name) {
@@ -383,7 +362,7 @@ public class ElementImpl extends InnerNodeImpl implements Element {
public void setPrefix(String prefix) {
this.prefix = validatePrefix(prefix, namespaceAware, namespaceURI);
}
-
+
public class ElementAttrNamedNodeMapImpl implements NamedNodeMap {
public int getLength() {
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/NodeImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/NodeImpl.java
index 359a042..8beb18c 100644
--- a/xml/src/main/java/org/apache/harmony/xml/dom/NodeImpl.java
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/NodeImpl.java
@@ -198,7 +198,7 @@ public abstract class NodeImpl implements Node {
* @param namespaceAware whether this node is namespace aware
* @param namespaceURI this node's namespace URI
*/
- protected String validatePrefix(String prefix, boolean namespaceAware, String namespaceURI) {
+ static String validatePrefix(String prefix, boolean namespaceAware, String namespaceURI) {
if (!namespaceAware) {
throw new DOMException(DOMException.NAMESPACE_ERR, prefix);
}
@@ -216,6 +216,58 @@ public abstract class NodeImpl implements Node {
}
/**
+ * Sets the element or attribute node to be namespace-aware and assign it
+ * the specified name and namespace URI.
+ *
+ * @param node an AttrImpl or ElementImpl node.
+ * @param namespaceURI this node's namespace URI. May be null.
+ * @param qualifiedName a possibly-prefixed name like "img" or "html:img".
+ */
+ static void setNameNS(NodeImpl node, String namespaceURI, String qualifiedName) {
+ if (qualifiedName == null) {
+ throw new DOMException(DOMException.NAMESPACE_ERR, qualifiedName);
+ }
+
+ String prefix = null;
+ int p = qualifiedName.lastIndexOf(":");
+ if (p != -1) {
+ prefix = validatePrefix(qualifiedName.substring(0, p), true, namespaceURI);
+ qualifiedName = qualifiedName.substring(p + 1);
+ }
+
+ if (!DocumentImpl.isXMLIdentifier(qualifiedName)) {
+ throw new DOMException(DOMException.INVALID_CHARACTER_ERR, qualifiedName);
+ }
+
+ switch (node.getNodeType()) {
+ case ATTRIBUTE_NODE:
+ if ("xmlns".equals(qualifiedName)
+ && !"http://www.w3.org/2000/xmlns/".equals(namespaceURI)) {
+ throw new DOMException(DOMException.NAMESPACE_ERR, qualifiedName);
+ }
+
+ AttrImpl attr = (AttrImpl) node;
+ attr.namespaceAware = true;
+ attr.namespaceURI = namespaceURI;
+ attr.prefix = prefix;
+ attr.localName = qualifiedName;
+ break;
+
+ case ELEMENT_NODE:
+ ElementImpl element = (ElementImpl) node;
+ element.namespaceAware = true;
+ element.namespaceURI = namespaceURI;
+ element.prefix = prefix;
+ element.localName = qualifiedName;
+ break;
+
+ default:
+ throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
+ "Cannot rename nodes of type " + node.getNodeType());
+ }
+ }
+
+ /**
* Checks whether a required string matches an actual string. This utility
* method is used for comparing namespaces and such. It takes into account
* null arguments and the "*" special case.
diff --git a/xml/src/test/java/org/apache/harmony/xml/XsltXPathConformanceTestSuite.java b/xml/src/test/java/org/apache/harmony/xml/XsltXPathConformanceTestSuite.java
index 3f0d2cb..0438e98 100644
--- a/xml/src/test/java/org/apache/harmony/xml/XsltXPathConformanceTestSuite.java
+++ b/xml/src/test/java/org/apache/harmony/xml/XsltXPathConformanceTestSuite.java
@@ -73,7 +73,7 @@ import java.util.List;
* suite zip file from the OASIS project site.</li>
* <li>Unzip.
* <li>Copy the files to a device: <code>adb shell mkdir /data/oasis ;
- * adb push ./XSLT-Conformance-TC /data/oasis</code>.
+ * adb push ./XSLT-Conformance-TC/data/oasis</code>.
* <li>Invoke this class' main method, passing the on-device path to the test
* suite's <code>catalog.xml</code> file as an argument.
* </ul>
diff --git a/xml/src/test/java/tests/xml/DomTest.java b/xml/src/test/java/tests/xml/DomTest.java
index 3bafb78..2f364d0 100644
--- a/xml/src/test/java/tests/xml/DomTest.java
+++ b/xml/src/test/java/tests/xml/DomTest.java
@@ -61,6 +61,7 @@ import java.util.regex.Pattern;
import static org.w3c.dom.UserDataHandler.NODE_ADOPTED;
import static org.w3c.dom.UserDataHandler.NODE_CLONED;
import static org.w3c.dom.UserDataHandler.NODE_IMPORTED;
+import static org.w3c.dom.UserDataHandler.NODE_RENAMED;
/**
* Construct a DOM and then interrogate it.
@@ -512,25 +513,25 @@ public class DomTest extends TestCase {
}
public void testCoreFeature() {
- assertTrue(domImplementation.hasFeature("Core", null));
- assertTrue(domImplementation.hasFeature("Core", ""));
- assertTrue(domImplementation.hasFeature("Core", "1.0"));
- assertTrue(domImplementation.hasFeature("Core", "2.0"));
- assertTrue(domImplementation.hasFeature("Core", "3.0"));
- assertTrue(domImplementation.hasFeature("CORE", "3.0"));
- assertTrue(domImplementation.hasFeature("+Core", "3.0"));
- assertFalse(domImplementation.hasFeature("Core", "4.0"));
+ assertFeature("Core", null);
+ assertFeature("Core", "");
+ assertFeature("Core", "1.0");
+ assertFeature("Core", "2.0");
+ assertFeature("Core", "3.0");
+ assertFeature("CORE", "3.0");
+ assertFeature("+Core", "3.0");
+ assertNoFeature("Core", "4.0");
}
public void testXmlFeature() {
- assertTrue(domImplementation.hasFeature("XML", null));
- assertTrue(domImplementation.hasFeature("XML", ""));
- assertTrue(domImplementation.hasFeature("XML", "1.0"));
- assertTrue(domImplementation.hasFeature("XML", "2.0"));
- assertTrue(domImplementation.hasFeature("XML", "3.0"));
- assertTrue(domImplementation.hasFeature("Xml", "3.0"));
- assertTrue(domImplementation.hasFeature("+XML", "3.0"));
- assertFalse(domImplementation.hasFeature("XML", "4.0"));
+ assertFeature("XML", null);
+ assertFeature("XML", "");
+ assertFeature("XML", "1.0");
+ assertFeature("XML", "2.0");
+ assertFeature("XML", "3.0");
+ assertFeature("Xml", "3.0");
+ assertFeature("+XML", "3.0");
+ assertNoFeature("XML", "4.0");
}
/**
@@ -538,26 +539,35 @@ public class DomTest extends TestCase {
* http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#Document3-version
*/
public void testXmlVersionFeature() {
- String message = "This implementation does not support the XMLVersion feature";
- assertTrue(message, domImplementation.hasFeature("XMLVersion", null));
- assertTrue(message, domImplementation.hasFeature("XMLVersion", ""));
- assertTrue(message, domImplementation.hasFeature("XMLVersion", "1.0"));
- assertTrue(message, domImplementation.hasFeature("XMLVersion", "1.1"));
- assertTrue(message, domImplementation.hasFeature("XMLVERSION", "1.1"));
- assertTrue(message, domImplementation.hasFeature("+XMLVersion", "1.1"));
- assertFalse(domImplementation.hasFeature("XMLVersion", "1.2"));
- assertFalse(domImplementation.hasFeature("XMLVersion", "2.0"));
- assertFalse(domImplementation.hasFeature("XMLVersion", "2.0"));
+ assertFeature("XMLVersion", null);
+ assertFeature("XMLVersion", "");
+ assertFeature("XMLVersion", "1.0");
+ assertFeature("XMLVersion", "1.1");
+ assertFeature("XMLVERSION", "1.1");
+ assertFeature("+XMLVersion", "1.1");
+ assertNoFeature("XMLVersion", "1.2");
+ assertNoFeature("XMLVersion", "2.0");
+ assertNoFeature("XMLVersion", "2.0");
}
public void testLsFeature() {
- assertTrue("This implementation does not support the LS feature",
- domImplementation.hasFeature("LS", "3.0"));
+ assertFeature("LS", "3.0");
}
public void testElementTraversalFeature() {
- assertTrue("This implementation does not support the ElementTraversal feature",
- domImplementation.hasFeature("ElementTraversal", "1.0"));
+ assertFeature("ElementTraversal", "1.0");
+ }
+
+ private void assertFeature(String feature, String version) {
+ String message = "This implementation is expected to support "
+ + feature + " v. " + version + " but does not.";
+ assertTrue(message, domImplementation.hasFeature(feature, version));
+ assertNotNull(message, domImplementation.getFeature(feature, version));
+ }
+
+ private void assertNoFeature(String feature, String version) {
+ assertFalse(domImplementation.hasFeature(feature, version));
+ assertNull(domImplementation.getFeature(feature, version));
}
public void testIsSupported() {
@@ -1189,6 +1199,118 @@ public class DomTest extends TestCase {
assertFalse(typeInfo.isDerivedFrom("x", "y", TypeInfo.DERIVATION_UNION));
}
+ public void testRenameElement() {
+ document.renameNode(description, null, "desc");
+ assertEquals("desc", description.getTagName());
+ assertEquals("desc", description.getLocalName());
+ assertEquals(null, description.getPrefix());
+ assertEquals(null, description.getNamespaceURI());
+ }
+
+ public void testRenameElementWithPrefix() {
+ try {
+ document.renameNode(description, null, "a:desc");
+ fail();
+ } catch (DOMException e) {
+ }
+ }
+
+ public void testRenameElementWithNamespace() {
+ document.renameNode(description, "http://sales", "desc");
+ assertEquals("desc", description.getTagName());
+ assertEquals("desc", description.getLocalName());
+ assertEquals(null, description.getPrefix());
+ assertEquals("http://sales", description.getNamespaceURI());
+ }
+
+ public void testRenameElementWithPrefixAndNamespace() {
+ document.renameNode(description, "http://sales", "a:desc");
+ assertEquals("a:desc", description.getTagName());
+ assertEquals("desc", description.getLocalName());
+ assertEquals("a", description.getPrefix());
+ assertEquals("http://sales", description.getNamespaceURI());
+ }
+
+ public void testRenameAttribute() {
+ document.renameNode(deluxe, null, "special");
+ assertEquals("special", deluxe.getName());
+ assertEquals("special", deluxe.getLocalName());
+ assertEquals(null, deluxe.getPrefix());
+ assertEquals(null, deluxe.getNamespaceURI());
+ }
+
+ public void testRenameAttributeWithPrefix() {
+ try {
+ document.renameNode(deluxe, null, "a:special");
+ fail();
+ } catch (DOMException e) {
+ }
+ }
+
+ public void testRenameAttributeWithNamespace() {
+ document.renameNode(deluxe, "http://sales", "special");
+ assertEquals("special", deluxe.getName());
+ assertEquals("special", deluxe.getLocalName());
+ assertEquals(null, deluxe.getPrefix());
+ assertEquals("http://sales", deluxe.getNamespaceURI());
+ }
+
+ public void testRenameAttributeWithPrefixAndNamespace() {
+ document.renameNode(deluxe, "http://sales", "a:special");
+ assertEquals("a:special", deluxe.getName());
+ assertEquals("special", deluxe.getLocalName());
+ assertEquals("a", deluxe.getPrefix());
+ assertEquals("http://sales", deluxe.getNamespaceURI());
+ }
+
+ public void testUserDataHandlerNotifiedOfRenames() {
+ RecordingHandler handler = new RecordingHandler();
+ description.setUserData("a", "apple", handler);
+ deluxe.setUserData("b", "banana", handler);
+ standard.setUserData("c", "cat", handler);
+
+ document.renameNode(deluxe, null, "special");
+ document.renameNode(description, null, "desc");
+
+ Set<String> expected = new HashSet<String>();
+ expected.add(notification(NODE_RENAMED, "a", "apple", description, null));
+ expected.add(notification(NODE_RENAMED, "b", "banana", deluxe, null));
+ assertEquals(expected, handler.calls);
+ }
+
+ public void testRenameToInvalid() {
+ try {
+ document.renameNode(description, null, "xmlns:foo");
+ fail();
+ } catch (DOMException e) {
+ }
+ try {
+ document.renameNode(description, null, "xml:foo");
+ fail();
+ } catch (DOMException e) {
+ }
+ try {
+ document.renameNode(deluxe, null, "xmlns");
+ fail();
+ } catch (DOMException e) {
+ }
+ }
+
+ public void testRenameNodeOtherThanElementOrAttribute() {
+ for (Node node : allNodes) {
+ if (node.getNodeType() == Node.ATTRIBUTE_NODE
+ || node.getNodeType() == Node.ELEMENT_NODE) {
+ continue;
+ }
+
+ try {
+ document.renameNode(node, null, "foo");
+ fail();
+ } catch (DOMException e) {
+ }
+ }
+ }
+
private class RecordingHandler implements UserDataHandler {
final Set<String> calls = new HashSet<String>();
public void handle(short operation, String key, Object data, Node src, Node dst) {