Permalink
Browse files

STXM-1 Collapse tags with no content

STXM-2 Automatic namespace application
STXM-3 Trim getElementText by default
  • Loading branch information...
1 parent d7669ad commit d3d6d6080499675af2c1f5e79bb05ab1a0bbfe37 @n1hility n1hility committed Oct 1, 2010
@@ -22,6 +22,8 @@
package org.jboss.staxmapper;
+import java.lang.reflect.UndeclaredThrowableException;
+import java.util.ArrayDeque;
import java.util.Iterator;
import javax.xml.namespace.NamespaceContext;
@@ -35,12 +37,17 @@
* @author <a href="mailto:david.lloyd@redhat.com">David M. Lloyd</a>
*/
final class FormattingXMLStreamWriter implements XMLExtendedStreamWriter, XMLStreamConstants {
+ private static final String NO_NAMESPACE = new String();
private final XMLStreamWriter delegate;
+ private final ArrayDeque<ArgRunnable> attrQueue = new ArrayDeque<ArgRunnable>();
private int level;
private int state = START_DOCUMENT;
+ private ArrayDeque<String> unspecifiedNamespaces = new ArrayDeque<String>();
+
public FormattingXMLStreamWriter(final XMLStreamWriter delegate) {
this.delegate = delegate;
+ unspecifiedNamespaces.push(NO_NAMESPACE);
}
private void nl() throws XMLStreamException {
@@ -55,45 +62,116 @@ private void indent() throws XMLStreamException {
}
}
+ public interface ArgRunnable {
+ public void run(int arg) throws XMLStreamException;
+ }
+
+ @Override
+ public void setUnspecifiedElementNamespace(final String namespace) {
+ ArrayDeque<String> namespaces = this.unspecifiedNamespaces;
+ namespaces.pop();
+ namespaces.push(namespace == null ? NO_NAMESPACE : namespace);
+ }
+
+ private String nestUnspecifiedNamespace() {
+ ArrayDeque<String> namespaces = unspecifiedNamespaces;
+ String clone = namespaces.getFirst();
+ namespaces.push(clone);
+ return clone;
+ }
+
public void writeStartElement(final String localName) throws XMLStreamException {
+ ArrayDeque<String> namespaces = unspecifiedNamespaces;
+ String namespace = namespaces.getFirst();
+ if (namespace != NO_NAMESPACE) {
+ writeStartElement(namespace, localName);
+ return;
+ }
+
+ unspecifiedNamespaces.push(namespace);
+
+ // If this is a nested element flush the outer
+ runAttrQueue();
nl();
indent();
- delegate.writeStartElement(localName);
+ attrQueue.add(new ArgRunnable() {
+ public void run(int arg) throws XMLStreamException {
+ if (arg == 0) {
+ delegate.writeStartElement(localName);
+ } else {
+ delegate.writeEmptyElement(localName);
+ }
+ }
+ });
+
level++;
state = START_ELEMENT;
}
public void writeStartElement(final String namespaceURI, final String localName) throws XMLStreamException {
+ nestUnspecifiedNamespace();
+
+ // If this is a nested element flush the outer
+ runAttrQueue();
nl();
indent();
- delegate.writeStartElement(namespaceURI, localName);
+ attrQueue.add(new ArgRunnable() {
+ public void run(int arg) throws XMLStreamException {
+ if (arg == 0) {
+ delegate.writeStartElement(namespaceURI, localName);
+ } else {
+ delegate.writeEmptyElement(namespaceURI, localName);
+ }
+ }
+ });
level++;
state = START_ELEMENT;
}
public void writeStartElement(final String prefix, final String localName, final String namespaceURI) throws XMLStreamException {
+ nestUnspecifiedNamespace();
+
+ // If this is a nested element flush the outer
+ runAttrQueue();
nl();
indent();
- delegate.writeStartElement(prefix, namespaceURI, localName);
+ attrQueue.add(new ArgRunnable() {
+ public void run(int arg) throws XMLStreamException {
+ if (arg == 0) {
+ delegate.writeStartElement(prefix, namespaceURI, localName);
+ } else {
+ delegate.writeEmptyElement(prefix, namespaceURI, localName);
+ }
+ }
+ });
level++;
state = START_ELEMENT;
}
public void writeEmptyElement(final String namespaceURI, final String localName) throws XMLStreamException {
+ runAttrQueue();
nl();
indent();
delegate.writeEmptyElement(namespaceURI, localName);
state = END_ELEMENT;
}
public void writeEmptyElement(final String prefix, final String localName, final String namespaceURI) throws XMLStreamException {
+ runAttrQueue();
nl();
indent();
delegate.writeEmptyElement(prefix, namespaceURI, localName);
state = END_ELEMENT;
}
public void writeEmptyElement(final String localName) throws XMLStreamException {
+ String namespace = unspecifiedNamespaces.getFirst();
+ if (namespace != NO_NAMESPACE) {
+ writeEmptyElement(namespace, localName);
+ return;
+ }
+
+ runAttrQueue();
nl();
indent();
delegate.writeEmptyElement(localName);
@@ -105,11 +183,26 @@ public void writeEndElement() throws XMLStreamException {
if (state != START_ELEMENT) {
nl();
indent();
+ delegate.writeEndElement();
+ } else {
+ // Change the start element to an empty element
+ ArgRunnable start = attrQueue.poll();
+ start.run(1);
+ // Write everything else
+ runAttrQueue();
}
- delegate.writeEndElement();
+
+ unspecifiedNamespaces.pop();
state = END_ELEMENT;
}
+ private void runAttrQueue() throws XMLStreamException {
+ ArgRunnable attr;
+ while ((attr = attrQueue.poll()) != null) {
+ attr.run(0);
+ }
+ }
+
public void writeEndDocument() throws XMLStreamException {
delegate.writeEndDocument();
state = END_DOCUMENT;
@@ -125,50 +218,99 @@ public void flush() throws XMLStreamException {
}
public void writeAttribute(final String localName, final String value) throws XMLStreamException {
- delegate.writeAttribute(localName, value);
+ attrQueue.add(new ArgRunnable() {
+ public void run(int arg) throws XMLStreamException {
+ try {
+ delegate.writeAttribute(localName, value);
+ } catch (XMLStreamException e) {
+ throw new UndeclaredThrowableException(e);
+ }
+ }
+ });
}
public void writeAttribute(final String prefix, final String namespaceURI, final String localName, final String value) throws XMLStreamException {
- delegate.writeAttribute(prefix, namespaceURI, localName, value);
+ attrQueue.add(new ArgRunnable() {
+ public void run(int arg) throws XMLStreamException {
+ delegate.writeAttribute(prefix, namespaceURI, localName, value);
+ }
+ });
}
public void writeAttribute(final String namespaceURI, final String localName, final String value) throws XMLStreamException {
- delegate.writeAttribute(namespaceURI, localName, value);
+ attrQueue.add(new ArgRunnable() {
+ public void run(int arg) throws XMLStreamException {
+ delegate.writeAttribute(namespaceURI, localName, value);
+ }
+ });
}
public void writeAttribute(final String localName, final String[] values) throws XMLStreamException {
- delegate.writeAttribute(localName, join(values));
+ attrQueue.add(new ArgRunnable() {
+ public void run(int arg) throws XMLStreamException {
+ delegate.writeAttribute(localName, join(values));
+ }
+ });
}
public void writeAttribute(final String prefix, final String namespaceURI, final String localName, final String[] values) throws XMLStreamException {
- delegate.writeAttribute(prefix, namespaceURI, localName, join(values));
+ attrQueue.add(new ArgRunnable() {
+ public void run(int arg) throws XMLStreamException {
+ delegate.writeAttribute(prefix, namespaceURI, localName, join(values));
+ }
+ });
}
public void writeAttribute(final String namespaceURI, final String localName, final String[] values) throws XMLStreamException {
- delegate.writeAttribute(namespaceURI, localName, join(values));
+ attrQueue.add(new ArgRunnable() {
+ public void run(int arg) throws XMLStreamException {
+ delegate.writeAttribute(namespaceURI, localName, join(values));
+ }
+ });
}
public void writeAttribute(final String localName, final Iterable<String> values) throws XMLStreamException {
- delegate.writeAttribute(localName, join(values));
+ attrQueue.add(new ArgRunnable() {
+ public void run(int arg) throws XMLStreamException {
+ delegate.writeAttribute(localName, join(values));
+ }
+ });
}
public void writeAttribute(final String prefix, final String namespaceURI, final String localName, final Iterable<String> values) throws XMLStreamException {
- delegate.writeAttribute(prefix, namespaceURI, localName, join(values));
+ attrQueue.add(new ArgRunnable() {
+ public void run(int arg) throws XMLStreamException {
+ delegate.writeAttribute(prefix, namespaceURI, localName, join(values));
+ }
+ });
}
public void writeAttribute(final String namespaceURI, final String localName, final Iterable<String> values) throws XMLStreamException {
- delegate.writeAttribute(localName, join(values));
+ attrQueue.add(new ArgRunnable() {
+ public void run(int arg) throws XMLStreamException {
+ delegate.writeAttribute(namespaceURI, localName, join(values));
+ }
+ });
}
public void writeNamespace(final String prefix, final String namespaceURI) throws XMLStreamException {
- delegate.writeNamespace(prefix, namespaceURI);
+ attrQueue.add(new ArgRunnable() {
+ public void run(int arg) throws XMLStreamException {
+ delegate.writeNamespace(prefix, namespaceURI);
+ }
+ });
}
public void writeDefaultNamespace(final String namespaceURI) throws XMLStreamException {
- delegate.writeDefaultNamespace(namespaceURI);
+ attrQueue.add(new ArgRunnable() {
+ public void run(int arg) throws XMLStreamException {
+ delegate.writeDefaultNamespace(namespaceURI);
+ }
+ });
}
public void writeComment(final String data) throws XMLStreamException {
+ runAttrQueue();
nl();
nl();
indent();
@@ -209,20 +351,23 @@ public void writeComment(final String data) throws XMLStreamException {
}
public void writeProcessingInstruction(final String target) throws XMLStreamException {
+ runAttrQueue();
nl();
indent();
delegate.writeProcessingInstruction(target);
state = PROCESSING_INSTRUCTION;
}
public void writeProcessingInstruction(final String target, final String data) throws XMLStreamException {
+ runAttrQueue();
nl();
indent();
delegate.writeProcessingInstruction(target, data);
state = PROCESSING_INSTRUCTION;
}
public void writeCData(final String data) throws XMLStreamException {
+ runAttrQueue();
delegate.writeCData(data);
state = CDATA;
}
@@ -235,6 +380,7 @@ public void writeDTD(final String dtd) throws XMLStreamException {
}
public void writeEntityRef(final String name) throws XMLStreamException {
+ runAttrQueue();
delegate.writeEntityRef(name);
state = ENTITY_REFERENCE;
}
@@ -258,6 +404,7 @@ public void writeStartDocument(final String encoding, final String version) thro
}
public void writeCharacters(final String text) throws XMLStreamException {
+ runAttrQueue();
if (state != CHARACTERS) {
nl();
indent();
@@ -275,6 +422,7 @@ public void writeCharacters(final String text) throws XMLStreamException {
}
public void writeCharacters(final char[] text, final int start, final int len) throws XMLStreamException {
+ runAttrQueue();
delegate.writeCharacters(text, start, len);
state = CHARACTERS;
}
@@ -33,7 +33,6 @@
* @author <a href="mailto:david.lloyd@redhat.com">David M. Lloyd</a>
*/
public interface XMLExtendedStreamReader extends XMLStreamReader {
-
/**
* Handle an {@code <xs:any>}-type nested element, passing in the given value, returning after the end of the element.
* Must be positioned on a {@code START_ELEMENT} or an exception will occur. On return the cursor will be positioned
@@ -141,13 +140,21 @@
* @throws XMLStreamException if an error occurs
*/
String getId() throws XMLStreamException;
-
+
/**
- * Gets the {@link XMLMapper} used to handle
+ * Gets the {@link XMLMapper} used to handle
* {@link #handleAttribute(Object, int) extended attributes} and
* {@link #handleAny(Object) xs:any-type nested elements}.
- *
+ *
* @return the XMLMapper. Will not return {@code null}
*/
XMLMapper getXMLMapper();
+
+ /**
+ * Whether or not {@link #getElementText} should trim content.
+ * The default is true.
+ *
+ * @param trim trim if true, don't if false
+ */
+ void setTrimElementText(boolean trim);
}
@@ -44,6 +44,7 @@
private final XMLStreamReader streamReader;
private final XMLStreamReader fixedStreamReader;
private final Deque<Context> stack = new ArrayDeque<Context>();
+ private boolean trimElementText = true;
XMLExtendedStreamReaderImpl(final XMLMapperImpl xmlMapper, final XMLStreamReader streamReader) {
this.xmlMapper = xmlMapper;
@@ -52,6 +53,10 @@
stack.push(new Context());
}
+ public void setTrimElementText(boolean trim) {
+ this.trimElementText = trim;
+ }
+
public void handleAny(final Object value) throws XMLStreamException {
require(START_ELEMENT, null, null);
boolean ok = false;
@@ -127,7 +132,8 @@ public void require(final int type, final String namespaceURI, final String loca
}
public String getElementText() throws XMLStreamException {
- return streamReader.getElementText();
+ String text = streamReader.getElementText();
+ return trimElementText ? text.trim() : text;
}
public int nextTag() throws XMLStreamException {
Oops, something went wrong.

0 comments on commit d3d6d60

Please sign in to comment.