Polishing
This commit is contained in:
@@ -40,6 +40,7 @@ import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.MimeType;
|
||||
import org.springframework.util.MimeTypeUtils;
|
||||
import org.springframework.util.xml.StaxUtils2;
|
||||
|
||||
/**
|
||||
* Decode from a bytes stream of XML elements to a stream of {@code Object} (POJO).
|
||||
@@ -193,10 +194,10 @@ public class Jaxb2Decoder extends AbstractDecoder<Object> {
|
||||
});
|
||||
}
|
||||
|
||||
private Object unmarshal(List<XMLEvent> eventFlux, Class<?> outputClass) {
|
||||
private Object unmarshal(List<XMLEvent> events, Class<?> outputClass) {
|
||||
try {
|
||||
Unmarshaller unmarshaller = this.jaxbContexts.createUnmarshaller(outputClass);
|
||||
XMLEventReader eventReader = new ListBasedXMLEventReader(eventFlux);
|
||||
XMLEventReader eventReader = StaxUtils2.createXMLEventReader(events);
|
||||
if (outputClass.isAnnotationPresent(XmlRootElement.class)) {
|
||||
return unmarshaller.unmarshal(eventReader);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import java.io.SequenceInputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@@ -36,6 +35,7 @@ import reactor.core.subscriber.SubscriberWithContext;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.core.io.buffer.DataBufferAllocator;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils2;
|
||||
|
||||
/**i
|
||||
* Utility class for working with {@link DataBuffer}s.
|
||||
@@ -67,7 +67,7 @@ public abstract class DataBufferUtils {
|
||||
toIterable(1);
|
||||
|
||||
Enumeration<InputStream> enumeration =
|
||||
new IteratorEnumeration<InputStream>(streams.iterator());
|
||||
CollectionUtils2.toEnumeration(streams.iterator());
|
||||
|
||||
return new SequenceInputStream(enumeration);
|
||||
}
|
||||
@@ -169,29 +169,6 @@ public abstract class DataBufferUtils {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumeration wrapping an Iterator.
|
||||
*/
|
||||
// TODO: move to CollectionUtils when we merge with Spring Framework?
|
||||
private static class IteratorEnumeration<T> implements Enumeration<T> {
|
||||
|
||||
private final Iterator<T> iterator;
|
||||
|
||||
public IteratorEnumeration(Iterator<T> iterator) {
|
||||
this.iterator = iterator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMoreElements() {
|
||||
return this.iterator.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T nextElement() {
|
||||
return this.iterator.next();
|
||||
}
|
||||
}
|
||||
|
||||
private static class ReadableByteChannelConsumer
|
||||
implements Consumer<SubscriberWithContext<DataBuffer, ReadableByteChannel>> {
|
||||
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2002-2016 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;
|
||||
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* TODO: to be merged with {@link CollectionUtils}
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public abstract class CollectionUtils2 {
|
||||
|
||||
/**
|
||||
* Adapt an iterator to an enumeration.
|
||||
* @param iterator the iterator
|
||||
* @return the enumeration
|
||||
*/
|
||||
public static <E> Enumeration<E> toEnumeration(Iterator<E> iterator) {
|
||||
return new IteratorEnumeration<E>(iterator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumeration wrapping an Iterator.
|
||||
*/
|
||||
private static class IteratorEnumeration<T> implements Enumeration<T> {
|
||||
|
||||
private final Iterator<T> iterator;
|
||||
|
||||
public IteratorEnumeration(Iterator<T> iterator) {
|
||||
this.iterator = iterator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMoreElements() {
|
||||
return this.iterator.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T nextElement() {
|
||||
return this.iterator.next();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -14,9 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.core.codec.support;
|
||||
package org.springframework.util.xml;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
import javax.xml.stream.XMLEventReader;
|
||||
import javax.xml.stream.XMLStreamConstants;
|
||||
@@ -24,60 +23,26 @@ import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.events.Characters;
|
||||
import javax.xml.stream.events.XMLEvent;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* TODO: move to org.springframework.util.xml when merging, hidden behind StaxUtils
|
||||
*
|
||||
* Abstract base class for {@code XMLEventReader}s.
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
class ListBasedXMLEventReader implements XMLEventReader {
|
||||
abstract class AbstractXMLEventReader implements XMLEventReader {
|
||||
|
||||
private final XMLEvent[] events;
|
||||
|
||||
private int cursor = 0;
|
||||
|
||||
public ListBasedXMLEventReader(List<XMLEvent> events) {
|
||||
Assert.notNull(events, "'events' must not be null");
|
||||
this.events = events.toArray(new XMLEvent[events.size()]);
|
||||
}
|
||||
private boolean closed;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
Assert.notNull(events, "'events' must not be null");
|
||||
return cursor != events.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XMLEvent nextEvent() {
|
||||
if (cursor < events.length) {
|
||||
return events[cursor++];
|
||||
public Object next() {
|
||||
try {
|
||||
return nextEvent();
|
||||
}
|
||||
else {
|
||||
catch (XMLStreamException ex) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public XMLEvent peek() {
|
||||
if (cursor < events.length) {
|
||||
return events[cursor];
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object next() {
|
||||
return nextEvent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an {@code UnsupportedOperationException} when called.
|
||||
* @throws UnsupportedOperationException when called
|
||||
*/
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException(
|
||||
@@ -86,6 +51,7 @@ class ListBasedXMLEventReader implements XMLEventReader {
|
||||
|
||||
@Override
|
||||
public String getElementText() throws XMLStreamException {
|
||||
checkIfClosed();
|
||||
if (!peek().isStartElement()) {
|
||||
throw new XMLStreamException("Not at START_ELEMENT");
|
||||
}
|
||||
@@ -110,6 +76,7 @@ class ListBasedXMLEventReader implements XMLEventReader {
|
||||
|
||||
@Override
|
||||
public XMLEvent nextTag() throws XMLStreamException {
|
||||
checkIfClosed();
|
||||
while (true) {
|
||||
XMLEvent event = nextEvent();
|
||||
switch (event.getEventType()) {
|
||||
@@ -145,7 +112,28 @@ class ListBasedXMLEventReader implements XMLEventReader {
|
||||
throw new IllegalArgumentException("Property not supported: [" + name + "]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if closed; {@code false} otherwise.
|
||||
* @see #close()
|
||||
*/
|
||||
protected boolean isClosed() {
|
||||
return closed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the reader is closed, and throws a {@code XMLStreamException} if so.
|
||||
* @throws XMLStreamException if the reader is closed
|
||||
* @see #close()
|
||||
* @see #isClosed()
|
||||
*/
|
||||
protected void checkIfClosed() throws XMLStreamException {
|
||||
if (isClosed()) {
|
||||
throw new XMLStreamException("XMLEventReader has been closed");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
closed = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2002-2016 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.Collections;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
import javax.xml.stream.events.XMLEvent;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Implementation of {@code XMLEventReader} based on a list of {@link XMLEvent}s.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
class ListBasedXMLEventReader extends AbstractXMLEventReader {
|
||||
|
||||
private final List<XMLEvent> events;
|
||||
|
||||
private int cursor = 0;
|
||||
|
||||
public ListBasedXMLEventReader(List<XMLEvent> events) {
|
||||
Assert.notNull(events, "'events' must not be null");
|
||||
this.events = Collections.unmodifiableList(events);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return cursor != events.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public XMLEvent nextEvent() {
|
||||
if (cursor < events.size()) {
|
||||
return events.get(cursor++);
|
||||
}
|
||||
else {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public XMLEvent peek() {
|
||||
if (cursor < events.size()) {
|
||||
return events.get(cursor);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
super.close();
|
||||
this.events.clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2002-2016 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.List;
|
||||
import javax.xml.stream.XMLEventReader;
|
||||
import javax.xml.stream.events.XMLEvent;
|
||||
|
||||
/**
|
||||
* TODO: to be merged with {@link StaxUtils}.
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public abstract class StaxUtils2 {
|
||||
|
||||
/**
|
||||
* Create a {@link XMLEventReader} from the given list of {@link XMLEvent}.
|
||||
* @param events the list of {@link XMLEvent}s.
|
||||
* @return an {@code XMLEventReader} that reads from the given events
|
||||
*/
|
||||
public static XMLEventReader createXMLEventReader(List<XMLEvent> events) {
|
||||
return new ListBasedXMLEventReader(events);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2002-2016 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.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.xml.stream.XMLEventReader;
|
||||
import javax.xml.stream.XMLEventWriter;
|
||||
import javax.xml.stream.XMLInputFactory;
|
||||
import javax.xml.stream.XMLOutputFactory;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.events.XMLEvent;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class ListBasedXMLEventReaderTests {
|
||||
|
||||
private final XMLInputFactory inputFactory = XMLInputFactory.newFactory();
|
||||
|
||||
private final XMLOutputFactory outputFactory = XMLOutputFactory.newFactory();
|
||||
|
||||
@Test
|
||||
public void standard() throws Exception {
|
||||
String xml = "<foo><bar>baz</bar></foo>";
|
||||
List<XMLEvent> events = readEvents(xml);
|
||||
|
||||
ListBasedXMLEventReader reader = new ListBasedXMLEventReader(events);
|
||||
|
||||
StringWriter resultWriter = new StringWriter();
|
||||
XMLEventWriter writer = this.outputFactory.createXMLEventWriter(resultWriter);
|
||||
writer.add(reader);
|
||||
|
||||
assertXMLEqual(xml, resultWriter.toString());
|
||||
}
|
||||
|
||||
private List<XMLEvent> readEvents(String xml) throws XMLStreamException {
|
||||
XMLEventReader reader =
|
||||
this.inputFactory.createXMLEventReader(new StringReader(xml));
|
||||
List<XMLEvent> events = new ArrayList<>();
|
||||
while (reader.hasNext()) {
|
||||
events.add(reader.nextEvent());
|
||||
}
|
||||
return events;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user