summaryrefslogtreecommitdiffstats
path: root/xml/src/main/java/org
diff options
context:
space:
mode:
authorJesse Wilson <jessewilson@google.com>2010-02-23 15:23:26 -0800
committerJesse Wilson <jessewilson@google.com>2010-02-23 17:56:48 -0800
commitbda224da00c0372a7752b1304aeda98e2930c4af (patch)
treea28550992209058749a605e25ee35a48cd459964 /xml/src/main/java/org
parentea6435b142df4aaaf8854b3200b9f442b331f143 (diff)
downloadlibcore-bda224da00c0372a7752b1304aeda98e2930c4af.zip
libcore-bda224da00c0372a7752b1304aeda98e2930c4af.tar.gz
libcore-bda224da00c0372a7752b1304aeda98e2930c4af.tar.bz2
Implementing still more DOM API for text nodes.
- Text.isElementContentWhitespace() - Text.getWholeText() - Text.replaceWholeText()
Diffstat (limited to 'xml/src/main/java/org')
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/CDATASectionImpl.java2
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/CharacterDataImpl.java7
-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.java2
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/NodeImpl.java4
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/dom/TextImpl.java84
-rw-r--r--xml/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java54
7 files changed, 107 insertions, 48 deletions
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/CDATASectionImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/CDATASectionImpl.java
index 33e216a..b28c9da 100644
--- a/xml/src/main/java/org/apache/harmony/xml/dom/CDATASectionImpl.java
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/CDATASectionImpl.java
@@ -31,7 +31,7 @@ import org.w3c.dom.Node;
*/
public class CDATASectionImpl extends TextImpl implements CDATASection {
- CDATASectionImpl(DocumentImpl document, String data) {
+ public CDATASectionImpl(DocumentImpl document, String data) {
super(document, data);
}
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/CharacterDataImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/CharacterDataImpl.java
index c39423c..6354747 100644
--- a/xml/src/main/java/org/apache/harmony/xml/dom/CharacterDataImpl.java
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/CharacterDataImpl.java
@@ -51,6 +51,13 @@ public abstract class CharacterDataImpl extends LeafNodeImpl implements
return buffer.toString();
}
+ /**
+ * Appends this node's text content to the given builder.
+ */
+ public void appendDataTo(StringBuilder stringBuilder) {
+ stringBuilder.append(buffer);
+ }
+
public int getLength() {
return buffer.length();
}
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 834cc47..1283eeb 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
@@ -31,7 +31,7 @@ import org.w3c.dom.DocumentType;
* the DOM implementation can easily access them while maintaining the DOM tree
* structure.
*/
-public class DOMImplementationImpl implements DOMImplementation {
+public final class DOMImplementationImpl implements DOMImplementation {
// Singleton instance.
private static DOMImplementationImpl instance;
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 c8819cb..b2f16d1 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
@@ -48,7 +48,7 @@ public class DocumentImpl extends InnerNodeImpl implements Document {
private DOMImplementation domImplementation;
- DocumentImpl(DOMImplementationImpl impl, String namespaceURI,
+ public DocumentImpl(DOMImplementationImpl impl, String namespaceURI,
String qualifiedName, DocumentType doctype) {
super(null);
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 ebfdd52..24ed102 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
@@ -224,7 +224,6 @@ public abstract class NodeImpl implements Node {
* account null arguments and the "*" special case.
*
* @param name The required name.
- * @param wildcard TODO
* @return True if and only if the actual name matches the required one.
*/
public boolean matchesName(String name, boolean wildcard) {
@@ -238,7 +237,6 @@ public abstract class NodeImpl implements Node {
*
* @param namespaceURI The required namespace.
* @param localName The required local name.
- * @param wildcard TODO
* @return True if and only if the actual namespace and local name match
* the required pair of namespace and local name.
*/
@@ -309,7 +307,7 @@ public abstract class NodeImpl implements Node {
removeChild(child);
}
// create a text node to hold the given content
- if (textContent != null && textContent.length() != 0){
+ if (textContent != null && textContent.length() != 0) {
appendChild(getOwnerDocument().createTextNode(textContent));
}
return;
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/TextImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/TextImpl.java
index 5c9d123..3840ef4 100644
--- a/xml/src/main/java/org/apache/harmony/xml/dom/TextImpl.java
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/TextImpl.java
@@ -32,7 +32,7 @@ import org.w3c.dom.Text;
*/
public class TextImpl extends CharacterDataImpl implements Text {
- TextImpl(DocumentImpl document, String data) {
+ public TextImpl(DocumentImpl document, String data) {
super(document, data);
}
@@ -46,7 +46,7 @@ public class TextImpl extends CharacterDataImpl implements Text {
return Node.TEXT_NODE;
}
- public Text splitText(int offset) throws DOMException {
+ public final Text splitText(int offset) throws DOMException {
Text newText = getOwnerDocument().createTextNode(
substringData(offset, getLength() - offset));
deleteData(0, offset);
@@ -61,15 +61,83 @@ public class TextImpl extends CharacterDataImpl implements Text {
return this;
}
- public boolean isElementContentWhitespace() {
- throw new UnsupportedOperationException(); // TODO
+ public final boolean isElementContentWhitespace() {
+ // Undefined because we don't validate. Whether whitespace characters
+ // constitute "element content whitespace" is defined by the containing
+ // element's declaration (DTD) and we don't parse that.
+ // TODO: wire this up when we support document validation
+ return false;
}
- public String getWholeText() {
- throw new UnsupportedOperationException(); // TODO
+ public final String getWholeText() {
+ // TODO: support entity references. This code should expand through
+ // the child elements of entity references.
+ // http://code.google.com/p/android/issues/detail?id=6807
+
+ StringBuilder result = new StringBuilder();
+ for (TextImpl n = firstTextNodeInCurrentRun(); n != null; n = n.nextTextNode()) {
+ n.appendDataTo(result);
+ }
+ return result.toString();
}
- public Text replaceWholeText(String content) throws DOMException {
- throw new UnsupportedOperationException(); // TODO
+ public final Text replaceWholeText(String content) throws DOMException {
+ // TODO: support entity references. This code should expand and replace
+ // the child elements of entity references.
+ // http://code.google.com/p/android/issues/detail?id=6807
+
+ Node parent = getParentNode();
+ Text result = null;
+
+ // delete all nodes in the current run of text...
+ for (TextImpl n = firstTextNodeInCurrentRun(); n != null; ) {
+
+ // ...except the current node if we have content for it
+ if (n == this && content != null && content.length() > 0) {
+ setData(content);
+ result = this;
+ n = n.nextTextNode();
+
+ } else {
+ Node toRemove = n; // because removeChild() detaches siblings
+ n = n.nextTextNode();
+ parent.removeChild(toRemove);
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Returns the first text or CDATA node in the current sequence of text and
+ * CDATA nodes.
+ */
+ private TextImpl firstTextNodeInCurrentRun() {
+ TextImpl firstTextInCurrentRun = this;
+ for (Node p = getPreviousSibling(); p != null; p = p.getPreviousSibling()) {
+ short nodeType = p.getNodeType();
+ if (nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE) {
+ firstTextInCurrentRun = (TextImpl) p;
+ } else {
+ break;
+ }
+ }
+ return firstTextInCurrentRun;
+ }
+
+ /**
+ * Returns the next sibling node if it exists and it is text or CDATA.
+ * Otherwise returns null.
+ */
+ private TextImpl nextTextNode() {
+ Node nextSibling = getNextSibling();
+ if (nextSibling == null) {
+ return null;
+ }
+
+ short nodeType = nextSibling.getNodeType();
+ return nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE
+ ? (TextImpl) nextSibling
+ : null;
}
}
diff --git a/xml/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java b/xml/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java
index 52240aa..ca2ff98 100644
--- a/xml/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java
+++ b/xml/src/main/java/org/apache/harmony/xml/parsers/DocumentBuilderImpl.java
@@ -23,10 +23,14 @@ import java.util.StringTokenizer;
import javax.xml.parsers.DocumentBuilder;
+import org.apache.harmony.xml.dom.CDATASectionImpl;
+import org.apache.harmony.xml.dom.DocumentImpl;
+import org.apache.harmony.xml.dom.TextImpl;
import org.kxml2.io.KXmlParser;
import org.w3c.dom.Attr;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
@@ -49,7 +53,7 @@ import org.apache.harmony.xml.dom.DOMImplementationImpl;
*/
class DocumentBuilderImpl extends DocumentBuilder {
- private static DOMImplementation dom = DOMImplementationImpl.getInstance();
+ private static DOMImplementationImpl dom = DOMImplementationImpl.getInstance();
private boolean coalescing;
@@ -72,25 +76,6 @@ class DocumentBuilderImpl extends DocumentBuilder {
return dom;
}
- /**
- * Reflects whether this DocumentBuilder is configured to ignore comments.
- *
- * @return True if and only if comments are ignored.
- */
- public boolean isIgnoringComments() {
- return ignoreComments;
- }
-
- /**
- * Reflects whether this DocumentBuilder is configured to ignore element
- * content whitespace.
- *
- * @return True if and only if whitespace element content is ignored.
- */
- public boolean isIgnoringElementContentWhitespace() {
- return ignoreElementContentWhitespace;
- }
-
@Override
public boolean isNamespaceAware() {
return namespaceAware;
@@ -112,7 +97,10 @@ class DocumentBuilderImpl extends DocumentBuilder {
throw new IllegalArgumentException();
}
- Document document = newDocument();
+ String namespaceURI = null;
+ String qualifiedName = null;
+ DocumentType doctype = null;
+ DocumentImpl document = new DocumentImpl(dom, namespaceURI, qualifiedName, doctype);
try {
KXmlParser parser = new KXmlParser();
@@ -189,7 +177,7 @@ class DocumentBuilderImpl extends DocumentBuilder {
* @throws XmlPullParserException If a parsing error occurs.
* @throws IOException If a general IO error occurs.
*/
- private void parse(XmlPullParser parser, Document document, Node node,
+ private void parse(XmlPullParser parser, DocumentImpl document, Node node,
int endToken) throws XmlPullParserException, IOException {
int token = parser.getEventType();
@@ -271,7 +259,7 @@ class DocumentBuilderImpl extends DocumentBuilder {
* whitespace at all.
*/
if (!ignoreElementContentWhitespace) {
- appendText(document, node, true, parser.getText());
+ appendText(document, node, token, parser.getText());
}
} else if (token == XmlPullParser.TEXT || token == XmlPullParser.CDSECT) {
/*
@@ -279,7 +267,7 @@ class DocumentBuilderImpl extends DocumentBuilder {
* That's the easiest case. We simply take it and create a new text node,
* or merge with an adjacent text node.
*/
- appendText(document, node, token == XmlPullParser.TEXT, parser.getText());
+ appendText(document, node, token, parser.getText());
} else if (token == XmlPullParser.ENTITY_REF) {
/*
* Found an entity reference. If an entity resolver is
@@ -294,7 +282,7 @@ class DocumentBuilderImpl extends DocumentBuilder {
String replacement = resolveStandardEntity(entity);
if (replacement != null) {
- appendText(document, node, true, replacement);
+ appendText(document, node, token, replacement);
} else {
node.appendChild(document.createEntityReference(entity));
}
@@ -380,17 +368,17 @@ class DocumentBuilderImpl extends DocumentBuilder {
}
/**
- * @param isText true for a normal TextNode, false for a CDATA section.
- * (If we're not coalescing, it matters which kind of node we put into the DOM.)
+ * @param token the XML pull parser token type, such as XmlPullParser.CDSECT
+ * or XmlPullParser.ENTITY_REF.
*/
- private void appendText(Document document, Node node, boolean isText, String text) {
+ private void appendText(DocumentImpl document, Node parent, int token, String text) {
// Ignore empty runs.
if (text.length() == 0) {
return;
}
// Merge with any previous text node if possible.
if (coalescing) {
- Node lastChild = node.getLastChild();
+ Node lastChild = parent.getLastChild();
if (lastChild != null && lastChild.getNodeType() == Node.TEXT_NODE) {
Text textNode = (Text) lastChild;
textNode.setData(textNode.getNodeValue() + text);
@@ -398,11 +386,9 @@ class DocumentBuilderImpl extends DocumentBuilder {
}
}
// Okay, we really do need a new text node
- if (isText) {
- node.appendChild(document.createTextNode(text));
- } else {
- node.appendChild(document.createCDATASection(text));
- }
+ parent.appendChild(token == XmlPullParser.CDSECT
+ ? new CDATASectionImpl(document, text)
+ : new TextImpl(document, text));
}
@Override