From 35e1602ed1480e750c6307d87704a0f8813e97eb Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Thu, 3 Jan 2013 13:49:38 -0800 Subject: [PATCH] Improved XStreamDOM by adding more methods --- .../java/jenkins/util/xstream/XStreamDOM.java | 48 ++++++++++++++++++- .../jenkins/util/xstream/XStreamDOMTest.java | 16 ++++++- .../util/xstream/XStreamDOMTest.data2.xml | 4 ++ 3 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 core/src/test/resources/jenkins/util/xstream/XStreamDOMTest.data2.xml diff --git a/core/src/main/java/jenkins/util/xstream/XStreamDOM.java b/core/src/main/java/jenkins/util/xstream/XStreamDOM.java index b35914c251..552ccafc4d 100644 --- a/core/src/main/java/jenkins/util/xstream/XStreamDOM.java +++ b/core/src/main/java/jenkins/util/xstream/XStreamDOM.java @@ -35,11 +35,18 @@ import com.thoughtworks.xstream.io.xml.AbstractXmlReader; import com.thoughtworks.xstream.io.xml.AbstractXmlWriter; import com.thoughtworks.xstream.io.xml.DocumentReader; import com.thoughtworks.xstream.io.xml.XmlFriendlyReplacer; +import com.thoughtworks.xstream.io.xml.XppDriver; import hudson.Util; import hudson.util.VariableResolver; import hudson.util.XStream2; +import org.apache.commons.io.IOUtils; +import java.io.InputStream; import java.io.OutputStream; +import java.io.Reader; +import java.io.StringReader; +import java.io.StringWriter; +import java.io.Writer; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -63,6 +70,16 @@ import java.util.Stack; * The reverse operation is {@link #from(XStream, Object)} method, which marshals an object * into {@link XStreamDOM}. * + *

+ * You can also use this class to parse an entire XML document into a DOM like tree with + * {@link #from(HierarchicalStreamReader)} and {@link #writeTo(HierarchicalStreamWriter)}. + * These two methods support variants that accept other forms. + *

+ * Whereas the above methods read from and write to {@link HierarchicalStreamReader} and, + * {@link HierarchicalStreamWriter}, we can also create {@link HierarchicalStreamReader} + * that read from DOM and {@link HierarchicalStreamWriter} that writes to DOM. See + * {@link #newReader()} and {@link #newWriter()} for those operations. + * * @author Kohsuke Kawaguchi * @since 1.473 */ @@ -190,7 +207,15 @@ public class XStreamDOM { * Writes this {@link XStreamDOM} into {@link OutputStream}. */ public void writeTo(OutputStream os) { - new XStream2().toXML(this, os); + writeTo(new XppDriver().createWriter(os)); + } + + public void writeTo(Writer w) { + writeTo(new XppDriver().createWriter(w)); + } + + public void writeTo(HierarchicalStreamWriter w) { + new ConverterImpl().marshal(this,w,null); } /** @@ -202,6 +227,18 @@ public class XStreamDOM { return w.getOutput(); } + public static XStreamDOM from(InputStream in) { + return from(new XppDriver().createReader(in)); + } + + public static XStreamDOM from(Reader in) { + return from(new XppDriver().createReader(in)); + } + + public static XStreamDOM from(HierarchicalStreamReader in) { + return new ConverterImpl().unmarshalElement(in, null); + } + private static class ReaderImpl extends AbstractXmlReader implements DocumentReader { private static class Pointer { final XStreamDOM node; @@ -405,9 +442,17 @@ public class XStreamDOM { w.endNode(); } + /** + * Unmarshals a single child element. + */ public XStreamDOM unmarshal(HierarchicalStreamReader r, UnmarshallingContext context) { r.moveDown(); + XStreamDOM dom = unmarshalElement(r,context); + r.moveUp(); + return dom; + } + public XStreamDOM unmarshalElement(HierarchicalStreamReader r, UnmarshallingContext context) { String name = r.getNodeName(); int c = r.getAttributeCount(); @@ -427,7 +472,6 @@ public class XStreamDOM { } else { value = r.getValue(); } - r.moveUp(); return new XStreamDOM(name,attributes,children,value); } diff --git a/core/src/test/java/jenkins/util/xstream/XStreamDOMTest.java b/core/src/test/java/jenkins/util/xstream/XStreamDOMTest.java index 910d5b0ee5..3bb3e6896d 100644 --- a/core/src/test/java/jenkins/util/xstream/XStreamDOMTest.java +++ b/core/src/test/java/jenkins/util/xstream/XStreamDOMTest.java @@ -23,7 +23,9 @@ */ package jenkins.util.xstream; +import com.thoughtworks.xstream.io.xml.XppDriver; import hudson.util.XStream2; +import jenkins.util.xstream.XStreamDOM.ConverterImpl; import org.apache.commons.io.IOUtils; import org.junit.Before; import org.junit.Test; @@ -32,6 +34,8 @@ import static org.junit.Assert.*; import java.io.IOException; import java.io.InputStream; +import java.io.StringReader; +import java.io.StringWriter; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -151,6 +155,16 @@ public class XStreamDOMTest { assertXStreamDOMEquals(expected.getChildren().get(i), actual.getChildren().get(i)); } } - + } + + @Test + public void readFromInputStream() throws Exception { + for (String name : new String[]{"XStreamDOMTest.data1.xml","XStreamDOMTest.data2.xml"}) { + String input = IOUtils.toString(getClass().getResourceAsStream(name)); + XStreamDOM dom = XStreamDOM.from(new StringReader(input)); + StringWriter sw = new StringWriter(); + dom.writeTo(sw); + assertEquals(input.trim(),sw.toString().trim()); + } } } diff --git a/core/src/test/resources/jenkins/util/xstream/XStreamDOMTest.data2.xml b/core/src/test/resources/jenkins/util/xstream/XStreamDOMTest.data2.xml new file mode 100644 index 0000000000..c860fcf9cf --- /dev/null +++ b/core/src/test/resources/jenkins/util/xstream/XStreamDOMTest.data2.xml @@ -0,0 +1,4 @@ + + + abc + -- GitLab