aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2012-12-07 15:08:53 -0800
committerTor Norbye <tnorbye@google.com>2012-12-07 15:08:53 -0800
commit69fa7f69b9a82e2c669dad67f71433e09fb44702 (patch)
tree2c34f2b9bacc8223b8948ab1cd7a80f48d3c341b /common
parenta7ec962feba1e5e47b8e3494f215b8bc83b0ed0c (diff)
downloadsdk-69fa7f69b9a82e2c669dad67f71433e09fb44702.zip
sdk-69fa7f69b9a82e2c669dad67f71433e09fb44702.tar.gz
sdk-69fa7f69b9a82e2c669dad67f71433e09fb44702.tar.bz2
Add simple XML dump method
Change-Id: I46709d9903e3f2daf4165e17f1e4b581cc217315
Diffstat (limited to 'common')
-rw-r--r--common/.settings/org.moreunit.prefs3
-rw-r--r--common/src/main/java/com/android/utils/XmlUtils.java140
-rw-r--r--common/src/test/.settings/org.moreunit.prefs4
-rw-r--r--common/src/test/java/com/android/utils/XmlUtilsTest.java54
4 files changed, 198 insertions, 3 deletions
diff --git a/common/.settings/org.moreunit.prefs b/common/.settings/org.moreunit.prefs
index c0ed4c1..3001cbf 100644
--- a/common/.settings/org.moreunit.prefs
+++ b/common/.settings/org.moreunit.prefs
@@ -1,5 +1,4 @@
-#Thu Jan 05 10:46:32 PST 2012
eclipse.preferences.version=1
org.moreunit.prefixes=
-org.moreunit.unitsourcefolder=common\:src\:common-tests\:src
+org.moreunit.unitsourcefolder=common\:src/main/java\:common-tests\:java
org.moreunit.useprojectsettings=true
diff --git a/common/src/main/java/com/android/utils/XmlUtils.java b/common/src/main/java/com/android/utils/XmlUtils.java
index 0969eb1..c77baee 100644
--- a/common/src/main/java/com/android/utils/XmlUtils.java
+++ b/common/src/main/java/com/android/utils/XmlUtils.java
@@ -29,11 +29,14 @@ import static com.android.SdkConstants.XMLNS_URI;
import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
+import com.google.common.base.Splitter;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
+import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
import java.util.HashSet;
@@ -275,4 +278,139 @@ public class XmlUtils {
}
}
}
-}
+
+ /**
+ * Dump an XML tree to string. This isn't going to do a beautiful job pretty
+ * printing the XML; it's intended mostly for non-user editable files and
+ * for debugging. If true, preserve whitespace exactly as in the DOM
+ * document (typically used for a DOM which is already formatted), otherwise
+ * this method will insert some newlines here and there (for example, one
+ * per element and one per attribute.)
+ *
+ * @param node the node (which can be a document, an element, a text node,
+ * etc.
+ * @param preserveWhitespace whether to preserve the whitespace (text nodes)
+ * in the DOM
+ * @return a string version of the file
+ */
+ public static String toXml(Node node, boolean preserveWhitespace) {
+ StringBuilder sb = new StringBuilder(1000);
+
+ append(sb, node, 0, preserveWhitespace);
+
+ return sb.toString();
+ }
+
+ private static void indent(StringBuilder sb, int indent) {
+ for (int i = 0; i < indent; i++) {
+ sb.append(" ");
+ }
+ }
+
+ private static void append(
+ @NonNull StringBuilder sb,
+ @NonNull Node node,
+ int indent,
+ boolean preserveWhitespace) {
+ short nodeType = node.getNodeType();
+ switch (nodeType) {
+ case Node.DOCUMENT_NODE:
+ case Node.DOCUMENT_FRAGMENT_NODE: {
+ sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); //$NON-NLS-1$
+ NodeList children = node.getChildNodes();
+ for (int i = 0, n = children.getLength(); i < n; i++) {
+ append(sb, children.item(i), indent, preserveWhitespace);
+ }
+ break;
+ }
+ case Node.COMMENT_NODE:
+ case Node.TEXT_NODE: {
+ if (nodeType == Node.COMMENT_NODE) {
+ if (!preserveWhitespace) {
+ indent(sb, indent);
+ }
+ sb.append("<!--"); //$NON-NLS-1$
+ if (!preserveWhitespace) {
+ sb.append('\n');
+ }
+ }
+ String text = node.getNodeValue();
+ if (!preserveWhitespace) {
+ text = text.trim();
+ for (String line : Splitter.on('\n').split(text)) {
+ indent(sb, indent + 1);
+ sb.append(toXmlTextValue(line));
+ sb.append('\n');
+ }
+ } else {
+ sb.append(toXmlTextValue(text));
+ }
+ if (nodeType == Node.COMMENT_NODE) {
+ if (!preserveWhitespace) {
+ indent(sb, indent);
+ }
+ sb.append("-->"); //$NON-NLS-1$
+ if (!preserveWhitespace) {
+ sb.append('\n');
+ }
+ }
+ break;
+ }
+ case Node.ELEMENT_NODE: {
+ if (!preserveWhitespace) {
+ indent(sb, indent);
+ }
+ sb.append('<');
+ Element element = (Element) node;
+ sb.append(element.getTagName());
+
+ NamedNodeMap attributes = element.getAttributes();
+ NodeList children = element.getChildNodes();
+ int childCount = children.getLength();
+ int attributeCount = attributes.getLength();
+
+ if (attributeCount > 0) {
+ for (int i = 0; i < attributeCount; i++) {
+ Node attribute = attributes.item(i);
+ sb.append(' ');
+ sb.append(attribute.getNodeName());
+ sb.append('=').append('"');
+ sb.append(toXmlAttributeValue(attribute.getNodeValue()));
+ sb.append('"');
+ }
+ }
+
+ if (childCount == 0) {
+ sb.append('/');
+ }
+ sb.append('>');
+ if (!preserveWhitespace) {
+ sb.append('\n');
+ }
+ if (childCount > 0) {
+ for (int i = 0; i < childCount; i++) {
+ Node child = children.item(i);
+ append(sb, child, indent + 1, preserveWhitespace);
+ }
+ if (!preserveWhitespace) {
+ if (sb.charAt(sb.length() - 1) != '\n') {
+ sb.append('\n');
+ }
+ indent(sb, indent);
+ }
+ sb.append('<').append('/');
+ sb.append(element.getTagName());
+ sb.append('>');
+ if (!preserveWhitespace) {
+ sb.append('\n');
+ }
+ }
+ break;
+ }
+
+ default:
+ throw new UnsupportedOperationException(
+ "Unsupported node type " + nodeType + ": not yet implemented");
+ }
+ }
+} \ No newline at end of file
diff --git a/common/src/test/.settings/org.moreunit.prefs b/common/src/test/.settings/org.moreunit.prefs
new file mode 100644
index 0000000..5c0456e
--- /dev/null
+++ b/common/src/test/.settings/org.moreunit.prefs
@@ -0,0 +1,4 @@
+eclipse.preferences.version=1
+org.moreunit.prefixes=
+org.moreunit.unitsourcefolder=common-tests\:java\:common\:src/main/java
+org.moreunit.useprojectsettings=true
diff --git a/common/src/test/java/com/android/utils/XmlUtilsTest.java b/common/src/test/java/com/android/utils/XmlUtilsTest.java
index 0e9289b..edf0235 100644
--- a/common/src/test/java/com/android/utils/XmlUtilsTest.java
+++ b/common/src/test/java/com/android/utils/XmlUtilsTest.java
@@ -18,11 +18,13 @@ package com.android.utils;
import static com.android.SdkConstants.XMLNS;
import com.android.SdkConstants;
+import com.android.annotations.Nullable;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
@@ -113,4 +115,56 @@ public class XmlUtilsTest extends TestCase {
XmlUtils.appendXmlTextValue(sb, "<\"'>&");
assertEquals("&lt;\"'>&amp;", sb.toString());
}
+
+ public void testNew() throws Exception {
+ Document doc = createEmptyPlainDocument();
+ Element root = doc.createElement("myroot");
+ doc.appendChild(root);
+ root.setAttribute("foo", "bar");
+ root.setAttribute("baz", "baz");
+ Element child = doc.createElement("mychild");
+ root.appendChild(child);
+ Element child2 = doc.createElement("hasComment");
+ root.appendChild(child2);
+ Node comment = doc.createComment("This is my comment");
+ child2.appendChild(comment);
+ Element child3 = doc.createElement("hasText");
+ root.appendChild(child3);
+ Node text = doc.createTextNode(" This is my text ");
+ child3.appendChild(text);
+
+ String xml = XmlUtils.toXml(doc, false);
+ assertEquals(
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
+ "<myroot baz=\"baz\" foo=\"bar\">\n" +
+ " <mychild/>\n" +
+ " <hasComment>\n" +
+ " <!--\n" +
+ " This is my comment\n" +
+ " -->\n" +
+ " </hasComment>\n" +
+ " <hasText>\n" +
+ " This is my text\n" +
+ " </hasText>\n" +
+ "</myroot>\n",
+ xml);
+
+ xml = XmlUtils.toXml(doc, true);
+ assertEquals(
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
+ "<myroot baz=\"baz\" foo=\"bar\"><mychild/><hasComment><!--This is my comment--></hasComment><hasText> This is my text </hasText></myroot>",
+ xml);
+
+ }
+
+ @Nullable
+ private static Document createEmptyPlainDocument() throws Exception {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setNamespaceAware(true);
+ factory.setValidating(false);
+ factory.setIgnoringComments(true);
+ DocumentBuilder builder;
+ builder = factory.newDocumentBuilder();
+ return builder.newDocument();
+ }
}