diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxEventItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxEventItemReader.java index d4091e41a..27df9f19e 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxEventItemReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxEventItemReader.java @@ -16,6 +16,7 @@ package org.springframework.batch.item.xml; +import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; @@ -217,7 +218,7 @@ ResourceAwareItemReaderItemStream, InitializingBean { * Move to next fragment and map it to item. */ @Override - protected T doRead() throws Exception { + protected T doRead() throws IOException, XMLStreamException { if (noInput) { return null; diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxEventItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxEventItemWriter.java index 66d70167e..a47d9d854 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxEventItemWriter.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxEventItemWriter.java @@ -546,10 +546,8 @@ ResourceAwareItemWriterItemStream, InitializingBean { * Subclasses can override to customize the STAX result. * * @return a result for writing to - * - * @throws Exception thrown if an error occurs curing the creation of the result. */ - protected Result createStaxResult() throws Exception { + protected Result createStaxResult() { return StaxUtils.getResult(eventWriter); } @@ -757,7 +755,7 @@ ResourceAwareItemWriterItemStream, InitializingBean { * @throws XmlMappingException thrown if error occurs during XML Mapping. */ @Override - public void write(List items) throws XmlMappingException, Exception { + public void write(List items) throws XmlMappingException, IOException { if(!this.initialized) { throw new WriterNotOpenException("Writer must be open before it can be written to"); diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxUtils.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxUtils.java index 2cd9e0bf6..c274f0b3a 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxUtils.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxUtils.java @@ -16,131 +16,30 @@ package org.springframework.batch.item.xml; -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLEventWriter; +import javax.xml.stream.XMLStreamException; import javax.xml.transform.Result; import javax.xml.transform.Source; +import javax.xml.transform.stax.StAXResult; +import javax.xml.transform.stax.StAXSource; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; /** - * This class provides a little bit of indirection to avoid ugly conditional object creation. It is unfortunately - * a bit redundant assuming a Spring 3.0 environment, but is necessary to work with Spring WS 1.5.x. + * StAX utility methods. *
- * The returned object determines whether the environment has Spring OXM as included in the Spring 3.x series of relies - * or whether it has Spring OXM from Spring WS 1.5x and factories a StaxSource instance appropriately. - *
- * As the only class state maintained is to cache java reflection metadata, which is thread-safe, this class is thread-safe. + * This class is thread-safe. * * @author Josh Long * */ public abstract class StaxUtils { - private static final Log logger = LogFactory.getLog(StaxUtils.class); - - private static ClassLoader defaultClassLoader = ClassUtils.getDefaultClassLoader(); - - // regular object. - private static String staxSourceClassNameOnSpringWs15 = "org.springframework.xml.transform.StaxSource"; - private static String staxResultClassNameOnSpringOxm15 = "org.springframework.xml.transform.StaxResult"; - - // in Spring 3, StaxUtils is package private, so use static utility StaxUtils#createStaxSource / StaxUtils#createStaxResult - private static String staxSourceClassNameOnSpringOxm30 = "org.springframework.util.xml.StaxUtils"; - - private static boolean hasSpringWs15StaxSupport = ClassUtils.isPresent(staxSourceClassNameOnSpringWs15, defaultClassLoader); - - private static boolean hasSpring30StaxSupport = ClassUtils.isPresent(staxSourceClassNameOnSpringOxm30, defaultClassLoader); - - private static Method staxUtilsSourceMethodOnSpring30, staxUtilsResultMethodOnSpring30; - - private static Constructor staxSourceClassCtorOnSpringWs15, staxResultClassCtorOnSpringWs15; - - static { - try { - - // cache the factory method / constructor so that we spend as little time in reflection as possible - if (hasSpring30StaxSupport) { - Class clzz = ClassUtils.forName(staxSourceClassNameOnSpringOxm30, defaultClassLoader); - - // javax.xml.transform.Source - staxUtilsSourceMethodOnSpring30 = ClassUtils.getStaticMethod(clzz, "createStaxSource", XMLEventReader.class); - - // javax.xml.transform.Result - staxUtilsResultMethodOnSpring30 = ClassUtils.getStaticMethod(clzz, "createStaxResult", XMLEventWriter.class); - } else if (hasSpringWs15StaxSupport) { - - // javax.xml.transform.Source - Class staxSourceClassOnSpringWs15 = ClassUtils.forName(staxSourceClassNameOnSpringWs15, defaultClassLoader); - staxSourceClassCtorOnSpringWs15 = staxSourceClassOnSpringWs15.getConstructor(XMLEventReader.class); - - // javax.xml.transform.Result - Class staxResultClassOnSpringWs15 = ClassUtils.forName(staxResultClassNameOnSpringOxm15, defaultClassLoader); - staxResultClassCtorOnSpringWs15 = staxResultClassOnSpringWs15.getConstructor(XMLEventWriter.class); - } else { - - if (logger.isDebugEnabled()) { - logger.debug("'StaxSource' was not detected in Spring 3.0's OXM support or Spring WS 1.5's OXM support. " + - "This is a problem if you intend to use the " +StaxEventItemWriter.class.getName() + " or " + - StaxEventItemReader.class.getName()+". Please add the appropriate dependencies."); - } - - } - } catch (Exception ex) { - logger.error("Could not precache required class and method metadata in " + StaxUtils.class.getName()); - } + public static Source getSource(XMLEventReader r) throws XMLStreamException { + return new StAXSource(r); } - public static Source getSource(XMLEventReader r) throws Exception { - if (hasSpring30StaxSupport) { - // org.springframework.util.xml.StaxUtils.createStaxSource(r) - Object result = staxUtilsSourceMethodOnSpring30.invoke(null,r); - Assert.isInstanceOf(Source.class, result, "the result should be assignable to " + Source.class.getName()); - return (Source) result; - } else if (hasSpringWs15StaxSupport) { - Object result = staxSourceClassCtorOnSpringWs15.newInstance(r); - Assert.isInstanceOf(Source.class, result, "the result should be assignable to " + Source.class.getName()); - return (Source) result; - } - // maybe you don't have either environment? - return null; + public static Result getResult(XMLEventWriter w) { + return new StAXResult(w); } - - public static Result getResult(XMLEventWriter w) throws Exception { - if (hasSpring30StaxSupport) { - Object result = staxUtilsResultMethodOnSpring30.invoke(null,w); - Assert.isInstanceOf(Result.class, result, "the result should be assignable to " + Result.class.getName()); - return (Result) result; - } else if (hasSpringWs15StaxSupport) { - Object result = staxResultClassCtorOnSpringWs15.newInstance(w); - Assert.isInstanceOf(Result.class, result, "the result should be assignable to " + Result.class.getName()); - return (Result) result; - } - // maybe you don't have either environment? - return null; - } - - public static XMLEventWriter getXmlEventWriter(Result r) throws Exception { - Method m = r.getClass().getDeclaredMethod("getXMLEventWriter"); - boolean accessible = m.isAccessible(); - m.setAccessible(true); - Object result = m.invoke(r); - m.setAccessible(accessible); - return (XMLEventWriter) result; - } - - public static XMLEventReader getXmlEventReader(Source s) throws Exception { - Method m = s.getClass().getDeclaredMethod("getXMLEventReader"); - boolean accessible = m.isAccessible(); - m.setAccessible(true); - Object result = m.invoke(s); - m.setAccessible(accessible); - return (XMLEventReader) result; - } } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/MultiResourceItemReaderXmlTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/MultiResourceItemReaderXmlTests.java index 4eeba4f9d..20dda9a4a 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/MultiResourceItemReaderXmlTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/MultiResourceItemReaderXmlTests.java @@ -32,7 +32,7 @@ import org.springframework.batch.item.ExecutionContext; import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.sample.Foo; import org.springframework.batch.item.xml.StaxEventItemReader; -import org.springframework.batch.item.xml.StaxUtils; +import org.springframework.batch.item.xml.StaxTestUtils; import org.springframework.core.io.ByteArrayResource; import org.springframework.core.io.Resource; import org.springframework.oxm.Unmarshaller; @@ -55,7 +55,7 @@ public class MultiResourceItemReaderXmlTests extends AbstractItemStreamItemReade Attribute attr; try { - XMLEventReader eventReader = StaxUtils.getXmlEventReader(source ); + XMLEventReader eventReader = StaxTestUtils.getXmlEventReader(source ); assertTrue(eventReader.nextEvent().isStartDocument()); StartElement event = eventReader.nextEvent().asStartElement(); attr = (Attribute) event.getAttributes().next(); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/MultiResourceItemWriterXmlTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/MultiResourceItemWriterXmlTests.java index 8b7fe910c..d25889b5e 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/MultiResourceItemWriterXmlTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/MultiResourceItemWriterXmlTests.java @@ -28,7 +28,7 @@ import javax.xml.transform.Result; import org.junit.Before; import org.junit.Test; import org.springframework.batch.item.xml.StaxEventItemWriter; -import org.springframework.batch.item.xml.StaxUtils; +import org.springframework.batch.item.xml.StaxTestUtils; import org.springframework.oxm.Marshaller; import org.springframework.oxm.XmlMappingException; import org.springframework.util.Assert; @@ -63,7 +63,7 @@ public class MultiResourceItemWriterXmlTests extends AbstractMultiResourceItemWr try { XMLEventFactory factory = XMLEventFactory.newInstance(); - XMLEventWriter writer = StaxUtils.getXmlEventWriter(result); + XMLEventWriter writer = StaxTestUtils.getXmlEventWriter(result); writer.add(factory.createStartDocument("UTF-8")); writer.add(factory.createStartElement("prefix", "namespace", graph.toString())); writer.add(factory.createEndElement("prefix", "namespace", graph.toString())); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemReaderCommonTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemReaderCommonTests.java index d4d51e2fc..2979cef99 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemReaderCommonTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemReaderCommonTests.java @@ -45,7 +45,7 @@ public class StaxEventItemReaderCommonTests extends AbstractItemStreamItemReader public Object unmarshal(Source source) throws XmlMappingException, IOException { Attribute attr = null ; try { - XMLEventReader eventReader = StaxUtils.getXmlEventReader( source); + XMLEventReader eventReader = StaxTestUtils.getXmlEventReader( source); assertTrue(eventReader.nextEvent().isStartDocument()); StartElement event = eventReader.nextEvent().asStartElement(); attr = (Attribute) event.getAttributes().next(); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemReaderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemReaderTests.java index c0921475b..cabc4a2d4 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemReaderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemReaderTests.java @@ -662,7 +662,7 @@ public class StaxEventItemReaderTests { List fragmentContent; try { - XMLEventReader eventReader = StaxUtils.getXmlEventReader(source); + XMLEventReader eventReader = StaxTestUtils.getXmlEventReader(source); // first event should be StartDocument XMLEvent event1 = eventReader.nextEvent(); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemWriterTests.java index 31cdd9168..39d3628d0 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemWriterTests.java @@ -772,7 +772,7 @@ public class StaxEventItemWriterTests { public void marshal(Object graph, Result result) throws XmlMappingException, IOException { super.marshal(graph, result); try { - StaxUtils.getXmlEventWriter(result).close(); + StaxTestUtils.getXmlEventWriter(result).close(); } catch (Exception e) { throw new RuntimeException("Exception while writing to output file", e); } @@ -955,8 +955,8 @@ public class StaxEventItemWriterTests { public void marshal(Object graph, Result result) throws XmlMappingException, IOException { Assert.isInstanceOf( Result.class, result); try { - StaxUtils.getXmlEventWriter( result ).add( XMLEventFactory.newInstance().createStartElement(namespacePrefix, namespace, graph.toString())); - StaxUtils.getXmlEventWriter( result ).add( XMLEventFactory.newInstance().createEndElement(namespacePrefix, namespace, graph.toString())); + StaxTestUtils.getXmlEventWriter( result ).add( XMLEventFactory.newInstance().createStartElement(namespacePrefix, namespace, graph.toString())); + StaxTestUtils.getXmlEventWriter( result ).add( XMLEventFactory.newInstance().createEndElement(namespacePrefix, namespace, graph.toString())); } catch ( Exception e) { throw new RuntimeException("Exception while writing to output file", e); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxTestUtils.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxTestUtils.java new file mode 100644 index 000000000..a85d6b1c1 --- /dev/null +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxTestUtils.java @@ -0,0 +1,48 @@ +/* + * Copyright 2015 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.batch.item.xml; + +import java.lang.reflect.Method; + +import javax.xml.stream.XMLEventReader; +import javax.xml.stream.XMLEventWriter; +import javax.xml.transform.Result; +import javax.xml.transform.Source; + +/** + * Utility methods for StAX related tests. + */ +public final class StaxTestUtils { + + public static XMLEventWriter getXmlEventWriter(Result r) throws Exception { + Method m = r.getClass().getDeclaredMethod("getXMLEventWriter", new Class[]{}); + boolean accessible = m.isAccessible(); + m.setAccessible(true); + Object result = m.invoke(r); + m.setAccessible(accessible); + return (XMLEventWriter) result; + } + + public static XMLEventReader getXmlEventReader(Source s) throws Exception { + Method m = s.getClass().getDeclaredMethod("getXMLEventReader", new Class[]{}); + boolean accessible = m.isAccessible(); + m.setAccessible(true); + Object result = m.invoke(s); + m.setAccessible(accessible); + return (XMLEventReader) result; + } + +} diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/TransactionalStaxEventItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/TransactionalStaxEventItemWriterTests.java index 74ced537d..67bee745d 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/TransactionalStaxEventItemWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/TransactionalStaxEventItemWriterTests.java @@ -238,7 +238,7 @@ public class TransactionalStaxEventItemWriterTests { @Override public void marshal(Object graph, Result result) throws XmlMappingException, IOException { try { - StaxUtils.getXmlEventWriter(result).add(XMLEventFactory.newInstance().createComment(graph.toString())); + StaxTestUtils.getXmlEventWriter(result).add(XMLEventFactory.newInstance().createComment(graph.toString())); } catch ( Exception e) { throw new RuntimeException("Exception while writing to output file", e);