diff --git a/org.springframework.core/src/main/java/org/springframework/util/xml/StaxUtils.java b/org.springframework.core/src/main/java/org/springframework/util/xml/StaxUtils.java
index b5d4b3297ab..4bd4a7a1eff 100644
--- a/org.springframework.core/src/main/java/org/springframework/util/xml/StaxUtils.java
+++ b/org.springframework.core/src/main/java/org/springframework/util/xml/StaxUtils.java
@@ -16,6 +16,7 @@
package org.springframework.util.xml;
+import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLStreamException;
@@ -308,6 +309,14 @@ public abstract class StaxUtils {
return new XMLEventStreamReader(eventReader);
}
+ /**
+ * Return a {@link XMLStreamWriter} that writes to a {@link XMLEventWriter}.
+ * @return a stream writer that writes to an event writer
+ * @since 3.0.5
+ */
+ public static XMLStreamWriter createEventStreamWriter(XMLEventWriter eventWriter, XMLEventFactory eventFactory) {
+ return new XMLEventStreamWriter(eventWriter, eventFactory);
+ }
/**
* Inner class to avoid a static JAXP 1.4 dependency.
diff --git a/org.springframework.core/src/main/java/org/springframework/util/xml/XMLEventStreamReader.java b/org.springframework.core/src/main/java/org/springframework/util/xml/XMLEventStreamReader.java
index cafbd872361..43f84e2891e 100644
--- a/org.springframework.core/src/main/java/org/springframework/util/xml/XMLEventStreamReader.java
+++ b/org.springframework.core/src/main/java/org/springframework/util/xml/XMLEventStreamReader.java
@@ -29,12 +29,13 @@ import javax.xml.stream.events.StartDocument;
import javax.xml.stream.events.XMLEvent;
/**
- * Implementation of the XMLStreamReader interface that wraps a XMLEventReader. Useful,
- * because the StAX XMLInputFactory allows one to create a event reader from a stream reader, but not
- * vice-versa.
+ * Implementation of the {@link javax.xml.stream.XMLStreamReader} interface that wraps a {@link XMLEventReader}. Useful,
+ * because the StAX {@link javax.xml.stream.XMLInputFactory} allows one to create a event reader from a stream reader,
+ * but not vice-versa.
*
* @author Arjen Poutsma
* @since 3.0
+ * @see StaxUtils#createEventStreamReader(javax.xml.stream.XMLEventReader)
*/
class XMLEventStreamReader extends AbstractXMLStreamReader {
diff --git a/org.springframework.core/src/main/java/org/springframework/util/xml/XMLEventStreamWriter.java b/org.springframework.core/src/main/java/org/springframework/util/xml/XMLEventStreamWriter.java
new file mode 100644
index 00000000000..8e74f7ccb0f
--- /dev/null
+++ b/org.springframework.core/src/main/java/org/springframework/util/xml/XMLEventStreamWriter.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright 2002-2010 the original author or authors.
+ *
+ * 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
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.util.xml;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventFactory;
+import javax.xml.stream.XMLEventWriter;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.stream.events.EndElement;
+import javax.xml.stream.events.Namespace;
+import javax.xml.stream.events.StartElement;
+
+import org.springframework.util.Assert;
+
+/**
+ * Implementation of the {@link javax.xml.stream.XMLStreamWriter} interface that wraps a {@link XMLEventWriter}.
+ *
+ * @author Arjen Poutsma
+ * @since 3.0.5
+ * @see StaxUtils#createEventStreamWriter(javax.xml.stream.XMLEventWriter, javax.xml.stream.XMLEventFactory)
+ */
+class XMLEventStreamWriter implements XMLStreamWriter {
+
+ private static final String DEFAULT_ENCODING = "UTF-8";
+
+ private final XMLEventWriter eventWriter;
+
+ private final XMLEventFactory eventFactory;
+
+ private List endElements = new ArrayList();
+
+ public XMLEventStreamWriter(XMLEventWriter eventWriter, XMLEventFactory eventFactory) {
+ Assert.notNull(eventWriter, "'eventWriter' must not be null");
+ Assert.notNull(eventFactory, "'eventFactory' must not be null");
+
+ this.eventWriter = eventWriter;
+ this.eventFactory = eventFactory;
+ }
+
+ public NamespaceContext getNamespaceContext() {
+ return eventWriter.getNamespaceContext();
+ }
+
+ public String getPrefix(String uri) throws XMLStreamException {
+ return eventWriter.getPrefix(uri);
+ }
+
+ public void setPrefix(String prefix, String uri) throws XMLStreamException {
+ eventWriter.setPrefix(prefix, uri);
+ }
+
+ public void setDefaultNamespace(String uri) throws XMLStreamException {
+ eventWriter.setDefaultNamespace(uri);
+ }
+
+ public void setNamespaceContext(NamespaceContext context) throws XMLStreamException {
+ eventWriter.setNamespaceContext(context);
+ }
+
+ public void writeStartDocument() throws XMLStreamException {
+ eventWriter.add(eventFactory.createStartDocument());
+ }
+
+ public void writeStartDocument(String version) throws XMLStreamException {
+ eventWriter.add(eventFactory.createStartDocument(DEFAULT_ENCODING, version));
+ }
+
+ public void writeStartDocument(String encoding, String version) throws XMLStreamException {
+ eventWriter.add(eventFactory.createStartDocument(encoding, version));
+ }
+
+ public void writeStartElement(String localName) throws XMLStreamException {
+ writeStartElement(eventFactory.createStartElement(new QName(localName), null, null));
+ }
+
+ public void writeStartElement(String namespaceURI, String localName) throws XMLStreamException {
+ writeStartElement(eventFactory.createStartElement(new QName(namespaceURI, localName), null, null));
+ }
+
+ public void writeStartElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
+ writeStartElement(eventFactory.createStartElement(new QName(namespaceURI, localName, prefix), null, null));
+ }
+
+ public void writeEmptyElement(String localName) throws XMLStreamException {
+ writeStartElement(localName);
+ writeEndElement();
+ }
+
+ public void writeEmptyElement(String namespaceURI, String localName) throws XMLStreamException {
+ writeStartElement(namespaceURI, localName);
+ writeEndElement();
+ }
+
+ public void writeEmptyElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
+ writeStartElement(prefix, localName, namespaceURI);
+ writeEndElement();
+ }
+
+ public void writeEndElement() throws XMLStreamException {
+ int last = endElements.size() - 1;
+ EndElement lastEndElement = endElements.get(last);
+ eventWriter.add(lastEndElement);
+ endElements.remove(last);
+ }
+
+ public void writeAttribute(String localName, String value) throws XMLStreamException {
+ eventWriter.add(eventFactory.createAttribute(localName, value));
+ }
+
+ public void writeAttribute(String namespaceURI, String localName, String value) throws XMLStreamException {
+ eventWriter.add(eventFactory.createAttribute(new QName(namespaceURI, localName), value));
+ }
+
+ public void writeAttribute(String prefix, String namespaceURI, String localName, String value)
+ throws XMLStreamException {
+ eventWriter.add(eventFactory.createAttribute(prefix, namespaceURI, localName, value));
+ }
+
+ public void writeNamespace(String prefix, String namespaceURI) throws XMLStreamException {
+ writeNamespace(eventFactory.createNamespace(prefix, namespaceURI));
+ }
+
+ public void writeDefaultNamespace(String namespaceURI) throws XMLStreamException {
+ writeNamespace(eventFactory.createNamespace(namespaceURI));
+ }
+
+ public void writeCharacters(String text) throws XMLStreamException {
+ eventWriter.add(eventFactory.createCharacters(text));
+ }
+
+ public void writeCharacters(char[] text, int start, int len) throws XMLStreamException {
+ eventWriter.add(eventFactory.createCharacters(new String(text, start, len)));
+ }
+
+ public void writeCData(String data) throws XMLStreamException {
+ eventWriter.add(eventFactory.createCData(data));
+ }
+
+ public void writeComment(String data) throws XMLStreamException {
+ eventWriter.add(eventFactory.createComment(data));
+ }
+
+ public void writeProcessingInstruction(String target) throws XMLStreamException {
+ eventWriter.add(eventFactory.createProcessingInstruction(target, ""));
+ }
+
+ public void writeProcessingInstruction(String target, String data) throws XMLStreamException {
+ eventWriter.add(eventFactory.createProcessingInstruction(target, data));
+ }
+
+ public void writeDTD(String dtd) throws XMLStreamException {
+ eventWriter.add(eventFactory.createDTD(dtd));
+ }
+
+ public void writeEntityRef(String name) throws XMLStreamException {
+ eventWriter.add(eventFactory.createEntityReference(name, null));
+ }
+
+ public void writeEndDocument() throws XMLStreamException {
+ eventWriter.add(eventFactory.createEndDocument());
+ }
+
+ public Object getProperty(String name) throws IllegalArgumentException {
+ throw new IllegalArgumentException();
+ }
+
+ public void flush() throws XMLStreamException {
+ eventWriter.flush();
+ }
+
+ public void close() throws XMLStreamException {
+ eventWriter.close();
+ }
+
+ private void writeStartElement(StartElement startElement) throws XMLStreamException {
+ eventWriter.add(startElement);
+ endElements.add(eventFactory.createEndElement(startElement.getName(), null));
+ }
+
+ private void writeNamespace(Namespace namespace) throws XMLStreamException {
+ int last = endElements.size() - 1;
+ EndElement oldEndElement = endElements.get(last);
+ Iterator oldNamespaces = oldEndElement.getNamespaces();
+ List newNamespaces = new ArrayList();
+ while (oldNamespaces.hasNext()) {
+ Namespace oldNamespace = (Namespace) oldNamespaces.next();
+ newNamespaces.add(oldNamespace);
+ }
+ newNamespaces.add(namespace);
+ EndElement newEndElement = eventFactory.createEndElement(oldEndElement.getName(), newNamespaces.iterator());
+ eventWriter.add(namespace);
+ endElements.set(last, newEndElement);
+ }
+}
diff --git a/org.springframework.core/src/test/java/org/springframework/util/xml/XMLEventStreamWriterTest.java b/org.springframework.core/src/test/java/org/springframework/util/xml/XMLEventStreamWriterTest.java
new file mode 100644
index 00000000000..f91fa68234c
--- /dev/null
+++ b/org.springframework.core/src/test/java/org/springframework/util/xml/XMLEventStreamWriterTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2002-2010 the original author or authors.
+ *
+ * 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
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.util.xml;
+
+import java.io.StringWriter;
+import javax.xml.stream.XMLEventFactory;
+import javax.xml.stream.XMLEventWriter;
+import javax.xml.stream.XMLOutputFactory;
+
+import static org.custommonkey.xmlunit.XMLAssert.*;
+import org.junit.Before;
+import org.junit.Test;
+
+public class XMLEventStreamWriterTest {
+
+ private static final String XML =
+ "content"
+ ;
+
+ private XMLEventStreamWriter streamWriter;
+
+ private StringWriter stringWriter;
+
+ @Before
+ public void createStreamReader() throws Exception {
+ stringWriter = new StringWriter();
+ XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
+ XMLEventWriter eventWriter = outputFactory.createXMLEventWriter(stringWriter);
+ streamWriter = new XMLEventStreamWriter(eventWriter, XMLEventFactory.newInstance());
+ }
+
+ @Test
+ public void write() throws Exception {
+ streamWriter.writeStartDocument();
+ streamWriter.writeProcessingInstruction("pi", "content");
+ streamWriter.writeStartElement("namespace", "root");
+ streamWriter.writeDefaultNamespace("namespace");
+ streamWriter.writeStartElement("prefix", "child", "namespace2");
+ streamWriter.writeNamespace("prefix", "namespace2");
+ streamWriter.writeCharacters("content");
+ streamWriter.writeEndElement();
+ streamWriter.writeEndElement();
+ streamWriter.writeEndDocument();
+
+ assertXMLEqual(XML, stringWriter.toString());
+ }
+
+
+}
\ No newline at end of file