diff --git a/sandbox/src/main/java/org/springframework/ws/soap/stroap/FaultStroapPayload.java b/sandbox/src/main/java/org/springframework/ws/soap/stroap/FaultStroapPayload.java index 952afb57..a1ade806 100644 --- a/sandbox/src/main/java/org/springframework/ws/soap/stroap/FaultStroapPayload.java +++ b/sandbox/src/main/java/org/springframework/ws/soap/stroap/FaultStroapPayload.java @@ -39,7 +39,7 @@ class FaultStroapPayload extends StroapPayload { @Override public XMLEventReader getEventReader() { - return fault.getEventReader(); + return fault.getEventReader(false); } } diff --git a/sandbox/src/main/java/org/springframework/ws/soap/stroap/Stroap11Body.java b/sandbox/src/main/java/org/springframework/ws/soap/stroap/Stroap11Body.java index b46cf208..dc70d557 100644 --- a/sandbox/src/main/java/org/springframework/ws/soap/stroap/Stroap11Body.java +++ b/sandbox/src/main/java/org/springframework/ws/soap/stroap/Stroap11Body.java @@ -32,13 +32,13 @@ class Stroap11Body extends StroapBody implements Soap11Body { private static final String ENVELOPE_NAMESPACE_URI = "http://schemas.xmlsoap.org/soap/envelope/"; - private QName CLIENT_FAULT_NAME = new QName(ENVELOPE_NAMESPACE_URI, "Client", PREFIX); + private QName CLIENT_FAULT_NAME = new QName(ENVELOPE_NAMESPACE_URI, "Client", DEFAULT_PREFIX); - private QName SERVER_FAULT_NAME = new QName(ENVELOPE_NAMESPACE_URI, "Server", PREFIX); + private QName SERVER_FAULT_NAME = new QName(ENVELOPE_NAMESPACE_URI, "Server", DEFAULT_PREFIX); - private QName MUST_UNDERSTAND_FAULT_NAME = new QName(ENVELOPE_NAMESPACE_URI, "MustUnderstand", PREFIX); + private QName MUST_UNDERSTAND_FAULT_NAME = new QName(ENVELOPE_NAMESPACE_URI, "MustUnderstand", DEFAULT_PREFIX); - private QName VERSION_MISMATCH_FAULT_NAME = new QName(ENVELOPE_NAMESPACE_URI, "VersionMismatch", PREFIX); + private QName VERSION_MISMATCH_FAULT_NAME = new QName(ENVELOPE_NAMESPACE_URI, "VersionMismatch", DEFAULT_PREFIX); Stroap11Body(StroapMessageFactory messageFactory) { super(messageFactory); diff --git a/sandbox/src/main/java/org/springframework/ws/soap/stroap/Stroap11Fault.java b/sandbox/src/main/java/org/springframework/ws/soap/stroap/Stroap11Fault.java index 0576b3c8..0a788331 100644 --- a/sandbox/src/main/java/org/springframework/ws/soap/stroap/Stroap11Fault.java +++ b/sandbox/src/main/java/org/springframework/ws/soap/stroap/Stroap11Fault.java @@ -26,6 +26,7 @@ import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.ws.soap.SoapFaultDetail; import org.springframework.ws.soap.soap11.Soap11Fault; +import org.springframework.xml.stream.CompositeXMLEventReader; import org.springframework.xml.stream.ListBasedXMLEventReader; /** @@ -99,17 +100,17 @@ class Stroap11Fault extends StroapFault implements Soap11Fault { } @Override - protected XMLEventReader[] getChildEventReaders() { - XMLEventReader[] eventReaders = (faultActor != null) ? new XMLEventReader[2] : new XMLEventReader[3]; - eventReaders[0] = faultCode.getEventReader(); - eventReaders[1] = faultString.getEventReader(); + protected XMLEventReader getChildEventReader() { + XMLEventReader[] eventReaders = (faultActor == null) ? new XMLEventReader[2] : new XMLEventReader[3]; + eventReaders[0] = faultCode.getEventReader(false); + eventReaders[1] = faultString.getEventReader(false); if (faultActor != null) { - eventReaders[2] = faultActor.getEventReader(); + eventReaders[2] = faultActor.getEventReader(false); } - return eventReaders; + return new CompositeXMLEventReader(eventReaders); } - private static class FaultElement extends StroapContainer { + private static class FaultElement extends StroapElement { private final Characters characters; @@ -149,8 +150,8 @@ class Stroap11Fault extends StroapFault implements Soap11Fault { } @Override - protected XMLEventReader[] getChildEventReaders() { - return new XMLEventReader[]{new ListBasedXMLEventReader(characters)}; + protected XMLEventReader getChildEventReader() { + return new ListBasedXMLEventReader(characters); } } } diff --git a/sandbox/src/main/java/org/springframework/ws/soap/stroap/StroapBody.java b/sandbox/src/main/java/org/springframework/ws/soap/stroap/StroapBody.java index 5feaf5fc..f7293fa6 100644 --- a/sandbox/src/main/java/org/springframework/ws/soap/stroap/StroapBody.java +++ b/sandbox/src/main/java/org/springframework/ws/soap/stroap/StroapBody.java @@ -33,7 +33,7 @@ import org.springframework.ws.stream.StreamingPayload; /** * @author Arjen Poutsma */ -abstract class StroapBody extends StroapContainer implements SoapBody { +abstract class StroapBody extends StroapElement implements SoapBody { private StroapPayload payload; @@ -105,8 +105,8 @@ abstract class StroapBody extends StroapContainer implements SoapBody { } @Override - protected final XMLEventReader[] getChildEventReaders() { - return new XMLEventReader[]{payload.getEventReader()}; + protected final XMLEventReader getChildEventReader() { + return payload.getEventReader(); } @Override diff --git a/sandbox/src/main/java/org/springframework/ws/soap/stroap/StroapContainer.java b/sandbox/src/main/java/org/springframework/ws/soap/stroap/StroapContainer.java deleted file mode 100644 index d052cb86..00000000 --- a/sandbox/src/main/java/org/springframework/ws/soap/stroap/StroapContainer.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2005-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.ws.soap.stroap; - -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import javax.xml.namespace.QName; -import javax.xml.stream.XMLEventReader; -import javax.xml.stream.events.Attribute; -import javax.xml.stream.events.EndElement; -import javax.xml.stream.events.Namespace; -import javax.xml.stream.events.StartElement; - -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; -import org.springframework.xml.stream.CompositeXMLEventReader; -import org.springframework.xml.stream.ListBasedXMLEventReader; - -/** - * @author Arjen Poutsma - */ -abstract class StroapContainer extends StroapElement { - - static final String PREFIX = "SOAP-ENV"; - - private StartElement startElement; - - private EndElement endElement; - - protected StroapContainer(QName name, StroapMessageFactory messageFactory) { - super(messageFactory); - Assert.notNull(name, "'name' must not be null"); - if (!StringUtils.hasLength(name.getPrefix())) { - name = new QName(name.getNamespaceURI(), name.getLocalPart(), PREFIX); - } - this.startElement = getEventFactory().createStartElement(name, null, null); - this.endElement = getEventFactory().createEndElement(name, null); - } - - protected StroapContainer(StartElement startElement, StroapMessageFactory messageFactory) { - super(messageFactory); - Assert.notNull(startElement, "'startElement' must not be null"); - this.startElement = startElement; - this.endElement = getEventFactory().createEndElement(startElement.getName(), startElement.getNamespaces()); - } - - public final QName getName() { - return getStartElement().getName(); - } - - @Override - protected XMLEventReader getEventReader() { - XMLEventReader[] childEventReaders = getChildEventReaders(); - XMLEventReader[] eventReaders = new XMLEventReader[childEventReaders.length + 2]; - eventReaders[0] = new ListBasedXMLEventReader(startElement); - System.arraycopy(childEventReaders, 0, eventReaders, 1, childEventReaders.length); - eventReaders[eventReaders.length - 1] = new ListBasedXMLEventReader(endElement); - - return new CompositeXMLEventReader(eventReaders); - } - - protected abstract XMLEventReader[] getChildEventReaders(); - - // Attributes - - public final Iterator getAllAttributes() { - List result = new LinkedList(); - for (Iterator iterator = getStartElement().getAttributes(); iterator.hasNext();) { - Attribute attribute = (Attribute) iterator.next(); - result.add(attribute.getName()); - } - return result.iterator(); - } - - public final String getAttributeValue(QName name) { - Attribute attribute = getStartElement().getAttributeByName(name); - return attribute != null ? attribute.getValue() : null; - } - - public final void removeAttribute(QName name) { - List newAttributes = new LinkedList(); - for (Iterator iterator = getStartElement().getAttributes(); iterator.hasNext();) { - Attribute attribute = (Attribute) iterator.next(); - if (!name.equals(attribute.getName())) { - newAttributes.add(attribute); - } - } - StartElement oldStartElement = getStartElement(); - this.startElement = getEventFactory().createStartElement(oldStartElement.getName(), newAttributes.iterator(), - oldStartElement.getNamespaces()); - } - - public final void addAttribute(QName name, String value) { - List newAttributes = new LinkedList(); - for (Iterator iterator = getStartElement().getAttributes(); iterator.hasNext();) { - Attribute attribute = (Attribute) iterator.next(); - newAttributes.add(attribute); - } - Attribute newAttribute = getEventFactory().createAttribute(name, value); - newAttributes.add(newAttribute); - StartElement oldStartElement = getStartElement(); - this.startElement = getEventFactory().createStartElement(oldStartElement.getName(), newAttributes.iterator(), - oldStartElement.getNamespaces()); - } - - // Namespaces - - public final void addNamespaceDeclaration(String prefix, String namespaceUri) { - List newNamespaces = new LinkedList(); - for (Iterator iterator = getStartElement().getNamespaces(); iterator.hasNext();) { - Namespace namespace = (Namespace) iterator.next(); - newNamespaces.add(namespace); - } - Namespace newNamespace; - if (StringUtils.hasLength(prefix)) { - newNamespace = getEventFactory().createNamespace(prefix, namespaceUri); - } - else { - newNamespace = getEventFactory().createNamespace(namespaceUri); - } - newNamespaces.add(newNamespace); - StartElement oldStartElement = getStartElement(); - this.startElement = getEventFactory() - .createStartElement(oldStartElement.getName(), oldStartElement.getAttributes(), - newNamespaces.iterator()); - } - - protected final StartElement getStartElement() { - return startElement; - } - - protected final EndElement getEndElement() { - return endElement; - } - -} diff --git a/sandbox/src/main/java/org/springframework/ws/soap/stroap/StroapElement.java b/sandbox/src/main/java/org/springframework/ws/soap/stroap/StroapElement.java index 148ce948..62b1e724 100644 --- a/sandbox/src/main/java/org/springframework/ws/soap/stroap/StroapElement.java +++ b/sandbox/src/main/java/org/springframework/ws/soap/stroap/StroapElement.java @@ -16,37 +16,71 @@ package org.springframework.ws.soap.stroap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.NoSuchElementException; +import javax.xml.namespace.QName; import javax.xml.stream.XMLEventFactory; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLEventWriter; import javax.xml.stream.XMLStreamException; +import javax.xml.stream.events.Attribute; +import javax.xml.stream.events.EndElement; +import javax.xml.stream.events.Namespace; +import javax.xml.stream.events.StartElement; +import javax.xml.stream.events.XMLEvent; import javax.xml.transform.Source; import org.springframework.util.Assert; +import org.springframework.util.StringUtils; import org.springframework.util.xml.StaxUtils; import org.springframework.ws.soap.SoapElement; import org.springframework.ws.soap.SoapVersion; +import org.springframework.xml.stream.AbstractXMLEventReader; /** * @author Arjen Poutsma */ abstract class StroapElement implements SoapElement { + protected static final String DEFAULT_PREFIX = "SOAP-ENV"; + private final StroapMessageFactory messageFactory; - public StroapElement(StroapMessageFactory messageFactory) { + private StartElement startElement; + + private EndElement endElement; + + protected StroapElement(QName name, StroapMessageFactory messageFactory) { + this(createStartElement(name, messageFactory), messageFactory); + } + + private static StartElement createStartElement(QName name, StroapMessageFactory messageFactory) { + if (!StringUtils.hasLength(name.getPrefix())) { + name = new QName(name.getNamespaceURI(), name.getLocalPart(), DEFAULT_PREFIX); + } + return messageFactory.getEventFactory().createStartElement(name, null, null); + } + + protected StroapElement(StartElement startElement, StroapMessageFactory messageFactory) { + Assert.notNull(startElement, "'startElement' must not be null"); Assert.notNull(messageFactory, "'messageFactory' must not be null"); this.messageFactory = messageFactory; + this.startElement = startElement; + this.endElement = getEventFactory().createEndElement(startElement.getName(), startElement.getNamespaces()); } public final Source getSource() { - return StaxUtils.createCustomStaxSource(getEventReader()); + return StaxUtils.createCustomStaxSource(getEventReader(true)); } - protected abstract XMLEventReader getEventReader(); + protected XMLEventReader getEventReader(boolean documentEvents) { + return new StroapElementEventReader(documentEvents); + } public void writeTo(XMLEventWriter eventWriter) throws XMLStreamException { - eventWriter.add(getEventReader()); + eventWriter.add(getEventReader(false)); } protected StroapMessageFactory getMessageFactory() { @@ -60,4 +94,167 @@ abstract class StroapElement implements SoapElement { protected SoapVersion getSoapVersion() { return getMessageFactory().getSoapVersion(); } + + public final QName getName() { + return getStartElement().getName(); + } + + protected abstract XMLEventReader getChildEventReader(); + + public final Iterator getAllAttributes() { + List result = new LinkedList(); + for (Iterator iterator = getStartElement().getAttributes(); iterator.hasNext();) { + Attribute attribute = (Attribute) iterator.next(); + result.add(attribute.getName()); + } + return result.iterator(); + } + + public final String getAttributeValue(QName name) { + Attribute attribute = getStartElement().getAttributeByName(name); + return attribute != null ? attribute.getValue() : null; + } + + public final void removeAttribute(QName name) { + List newAttributes = new LinkedList(); + for (Iterator iterator = getStartElement().getAttributes(); iterator.hasNext();) { + Attribute attribute = (Attribute) iterator.next(); + if (!name.equals(attribute.getName())) { + newAttributes.add(attribute); + } + } + StartElement oldStartElement = getStartElement(); + this.startElement = getEventFactory().createStartElement(oldStartElement.getName(), newAttributes.iterator(), + oldStartElement.getNamespaces()); + } + + public final void addAttribute(QName name, String value) { + List newAttributes = new LinkedList(); + for (Iterator iterator = getStartElement().getAttributes(); iterator.hasNext();) { + Attribute attribute = (Attribute) iterator.next(); + newAttributes.add(attribute); + } + Attribute newAttribute = getEventFactory().createAttribute(name, value); + newAttributes.add(newAttribute); + StartElement oldStartElement = getStartElement(); + this.startElement = getEventFactory().createStartElement(oldStartElement.getName(), newAttributes.iterator(), + oldStartElement.getNamespaces()); + } + + public final void addNamespaceDeclaration(String prefix, String namespaceUri) { + List newNamespaces = new LinkedList(); + for (Iterator iterator = getStartElement().getNamespaces(); iterator.hasNext();) { + Namespace namespace = (Namespace) iterator.next(); + newNamespaces.add(namespace); + } + Namespace newNamespace; + if (StringUtils.hasLength(prefix)) { + newNamespace = getEventFactory().createNamespace(prefix, namespaceUri); + } + else { + newNamespace = getEventFactory().createNamespace(namespaceUri); + } + newNamespaces.add(newNamespace); + StartElement oldStartElement = getStartElement(); + this.startElement = getEventFactory() + .createStartElement(oldStartElement.getName(), oldStartElement.getAttributes(), + newNamespaces.iterator()); + } + + protected final StartElement getStartElement() { + return startElement; + } + + protected final EndElement getEndElement() { + return endElement; + } + + private enum EVENT_READER_STATE { + + START_DOCUMENT, + START_ELEMENT, + CHILDREN, + END_ELEMENT, + END_DOCUMENT, + DONE + } + + private class StroapElementEventReader extends AbstractXMLEventReader { + + private EVENT_READER_STATE state; + + private boolean documentEvents; + + private final XMLEventReader childEventReader; + + private StroapElementEventReader(boolean documentEvents) { + this.documentEvents = documentEvents; + state = documentEvents ? EVENT_READER_STATE.START_DOCUMENT : EVENT_READER_STATE.START_ELEMENT; + this.childEventReader = getChildEventReader(); + } + + public boolean hasNext() { + if (documentEvents && state == EVENT_READER_STATE.DONE) { + return false; + } + else if (!documentEvents && state == EVENT_READER_STATE.END_DOCUMENT) { + return false; + } + else { + return true; + } + } + + public XMLEvent nextEvent() throws XMLStreamException { + switch (state) { + case START_DOCUMENT: + state = EVENT_READER_STATE.START_ELEMENT; + return getEventFactory().createStartDocument(); + case START_ELEMENT: + state = EVENT_READER_STATE.CHILDREN; + return getStartElement(); + case CHILDREN: + if (!childEventReader.hasNext()) { + state = EVENT_READER_STATE.END_ELEMENT; + return nextEvent(); + } + return childEventReader.nextEvent(); + case END_ELEMENT: + state = EVENT_READER_STATE.END_DOCUMENT; + return getEndElement(); + case END_DOCUMENT: + state = EVENT_READER_STATE.DONE; + return getEventFactory().createEndDocument(); + case DONE: + throw new NoSuchElementException(); + default: + throw new IllegalStateException(); + } + } + + public XMLEvent peek() throws XMLStreamException { + switch (state) { + case START_DOCUMENT: + return getEventFactory().createStartDocument(); + case START_ELEMENT: + return getStartElement(); + case CHILDREN: + XMLEvent event = childEventReader.peek(); + if (event == null) { + state = EVENT_READER_STATE.END_ELEMENT; + event = getEndElement(); + } + return event; + case END_ELEMENT: + return getEndElement(); + case END_DOCUMENT: + return getEventFactory().createEndDocument(); + case DONE: + return null; + default: + throw new IllegalStateException(); + } + + } + } } diff --git a/sandbox/src/main/java/org/springframework/ws/soap/stroap/StroapEnvelope.java b/sandbox/src/main/java/org/springframework/ws/soap/stroap/StroapEnvelope.java index 1fb22179..184e9b84 100644 --- a/sandbox/src/main/java/org/springframework/ws/soap/stroap/StroapEnvelope.java +++ b/sandbox/src/main/java/org/springframework/ws/soap/stroap/StroapEnvelope.java @@ -28,11 +28,12 @@ import org.springframework.ws.soap.SoapEnvelope; import org.springframework.ws.soap.SoapHeader; import org.springframework.ws.soap.SoapHeaderException; import org.springframework.ws.soap.SoapVersion; +import org.springframework.xml.stream.CompositeXMLEventReader; /** * @author Arjen Poutsma */ -class StroapEnvelope extends StroapContainer implements SoapEnvelope { +class StroapEnvelope extends StroapElement implements SoapEnvelope { private static final String LOCAL_NAME = "Envelope"; @@ -112,12 +113,12 @@ class StroapEnvelope extends StroapContainer implements SoapEnvelope { } @Override - protected XMLEventReader[] getChildEventReaders() { + protected XMLEventReader getChildEventReader() { if (header != null) { - return new XMLEventReader[]{header.getEventReader(), body.getEventReader()}; + return new CompositeXMLEventReader(header.getEventReader(false), body.getEventReader(false)); } else { - return new XMLEventReader[]{body.getEventReader()}; + return body.getEventReader(false); } } diff --git a/sandbox/src/main/java/org/springframework/ws/soap/stroap/StroapFault.java b/sandbox/src/main/java/org/springframework/ws/soap/stroap/StroapFault.java index f1747d17..aad4cc87 100644 --- a/sandbox/src/main/java/org/springframework/ws/soap/stroap/StroapFault.java +++ b/sandbox/src/main/java/org/springframework/ws/soap/stroap/StroapFault.java @@ -21,7 +21,7 @@ import org.springframework.ws.soap.SoapFault; /** * @author Arjen Poutsma */ -abstract class StroapFault extends StroapContainer implements SoapFault { +abstract class StroapFault extends StroapElement implements SoapFault { protected StroapFault(StroapMessageFactory messageFactory) { super(messageFactory.getSoapVersion().getFaultName(), messageFactory); diff --git a/sandbox/src/main/java/org/springframework/ws/soap/stroap/StroapHeader.java b/sandbox/src/main/java/org/springframework/ws/soap/stroap/StroapHeader.java index 845dbddc..97a7aaf5 100644 --- a/sandbox/src/main/java/org/springframework/ws/soap/stroap/StroapHeader.java +++ b/sandbox/src/main/java/org/springframework/ws/soap/stroap/StroapHeader.java @@ -34,11 +34,12 @@ import org.springframework.ws.soap.SoapHeaderElement; import org.springframework.ws.soap.SoapHeaderException; import org.springframework.ws.soap.SoapVersion; import org.springframework.xml.stream.AbstractXMLEventWriter; +import org.springframework.xml.stream.CompositeXMLEventReader; /** * @author Arjen Poutsma */ -abstract class StroapHeader extends StroapContainer implements SoapHeader { +abstract class StroapHeader extends StroapElement implements SoapHeader { private List headerElements = new LinkedList(); @@ -107,13 +108,13 @@ abstract class StroapHeader extends StroapContainer implements SoapHeader { } @Override - protected XMLEventReader[] getChildEventReaders() { + protected XMLEventReader getChildEventReader() { XMLEventReader[] eventReaders = new XMLEventReader[headerElements.size()]; for (int i = 0; i < headerElements.size(); i++) { StroapHeaderElement headerElement = headerElements.get(i); - eventReaders[i] = headerElement.getEventReader(); + eventReaders[i] = headerElement.getEventReader(false); } - return eventReaders; + return new CompositeXMLEventReader(eventReaders); } public Result getResult() { diff --git a/sandbox/src/main/java/org/springframework/ws/soap/stroap/StroapHeaderElement.java b/sandbox/src/main/java/org/springframework/ws/soap/stroap/StroapHeaderElement.java index 9ef36267..1c305f73 100644 --- a/sandbox/src/main/java/org/springframework/ws/soap/stroap/StroapHeaderElement.java +++ b/sandbox/src/main/java/org/springframework/ws/soap/stroap/StroapHeaderElement.java @@ -34,7 +34,7 @@ import org.springframework.xml.stream.ListBasedXMLEventReader; /** * @author Arjen Poutsma */ -class StroapHeaderElement extends StroapContainer implements SoapHeaderElement { +class StroapHeaderElement extends StroapElement implements SoapHeaderElement { private final List events = new LinkedList(); @@ -104,8 +104,8 @@ class StroapHeaderElement extends StroapContainer implements SoapHeaderElement { } @Override - protected XMLEventReader[] getChildEventReaders() { - return new XMLEventReader[]{new ListBasedXMLEventReader(events)}; + protected XMLEventReader getChildEventReader() { + return new ListBasedXMLEventReader(events); } diff --git a/sandbox/src/main/java/org/springframework/xml/stream/AbstractXMLEventReader.java b/sandbox/src/main/java/org/springframework/xml/stream/AbstractXMLEventReader.java index 50e6e6cd..4790fb2d 100644 --- a/sandbox/src/main/java/org/springframework/xml/stream/AbstractXMLEventReader.java +++ b/sandbox/src/main/java/org/springframework/xml/stream/AbstractXMLEventReader.java @@ -23,6 +23,8 @@ import javax.xml.stream.XMLStreamException; import javax.xml.stream.events.Characters; import javax.xml.stream.events.XMLEvent; +import org.springframework.util.ClassUtils; + /** * Abstract base class for XMLEventReaders. * @@ -36,7 +38,7 @@ public abstract class AbstractXMLEventReader implements XMLEventReader { try { return nextEvent(); } - catch (XMLStreamException e) { + catch (XMLStreamException ex) { throw new NoSuchElementException(); } } @@ -47,7 +49,7 @@ public abstract class AbstractXMLEventReader implements XMLEventReader { * @throws UnsupportedOperationException when called */ public void remove() { - throw new UnsupportedOperationException("remove not supported on AbstractXmlEventReader"); + throw new UnsupportedOperationException("remove not supported on " + ClassUtils.getShortName(getClass())); } public String getElementText() throws XMLStreamException { diff --git a/sandbox/src/main/java/org/springframework/xml/stream/CompositeXMLEventReader.java b/sandbox/src/main/java/org/springframework/xml/stream/CompositeXMLEventReader.java index b50ec8bc..d2d2849d 100644 --- a/sandbox/src/main/java/org/springframework/xml/stream/CompositeXMLEventReader.java +++ b/sandbox/src/main/java/org/springframework/xml/stream/CompositeXMLEventReader.java @@ -24,6 +24,8 @@ import javax.xml.stream.events.XMLEvent; import org.springframework.util.Assert; /** + * Implementation of {@link XMLEventReader} that combines multiple other {@code XMLEventReader}s. + * * @author Arjen Poutsma */ public class CompositeXMLEventReader extends AbstractXMLEventReader { @@ -47,11 +49,24 @@ public class CompositeXMLEventReader extends AbstractXMLEventReader { this.eventReaders = eventReaders.toArray(new XMLEventReader[eventReaders.size()]); } + public boolean hasNext() { + while (cursor < eventReaders.length) { + if (!atLastEventReader()) { + if (!currentEventReader().hasNext()) { + cursor++; + continue; + } + } + return currentEventReader().hasNext(); + } + return false; + } + public XMLEvent nextEvent() throws XMLStreamException { XMLEvent event = null; while (cursor < eventReaders.length) { - event = eventReaders[cursor].nextEvent(); - if (cursor != eventReaders.length - 1 && event.isEndDocument()) { + event = currentEventReader().nextEvent(); + if (!atLastEventReader() && event.isEndDocument()) { cursor++; } else { @@ -61,24 +76,11 @@ public class CompositeXMLEventReader extends AbstractXMLEventReader { return event; } - public boolean hasNext() { - while (cursor < eventReaders.length) { - if (cursor != eventReaders.length - 1) { - if (!eventReaders[cursor].hasNext()) { - cursor++; - continue; - } - } - return eventReaders[cursor].hasNext(); - } - return false; - } - public XMLEvent peek() throws XMLStreamException { XMLEvent event = null; while (cursor < eventReaders.length) { - event = eventReaders[cursor].peek(); - if (cursor != eventReaders.length - 1 && (event == null || event.isEndDocument())) { + event = currentEventReader().peek(); + if (!atLastEventReader() && (event == null || event.isEndDocument())) { cursor++; } else { @@ -88,4 +90,12 @@ public class CompositeXMLEventReader extends AbstractXMLEventReader { return event; } + private XMLEventReader currentEventReader() { + return eventReaders[cursor]; + } + + private boolean atLastEventReader() { + return cursor == eventReaders.length - 1; + } + }