BATCH-2417 Drop JAXP 1.3 support
Spring 4 requires JDK 6 which includes JAXP 1.4. In Spring 4 `org.springframework.util.xml.StaxUtils` is public and directly delegates to `javax.xml.transform.stax.StAXSource`. This means that `org.springframework.batch.item.xml.StaxUtils#hasSpring30StaxSupport` will always be true. Therefore a lot of code an be simplified by calling the constructors directly instead of through reflection. - remove reflection no longer needed in Spring 4 - move methods only used in tests to custom test class Issue: BATCH-2417
This commit is contained in:
committed by
Michael Minella
parent
7a3a72f5ca
commit
73ca73688d
@@ -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<T>, 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;
|
||||
|
||||
@@ -546,10 +546,8 @@ ResourceAwareItemWriterItemStream<T>, 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<T>, InitializingBean {
|
||||
* @throws XmlMappingException thrown if error occurs during XML Mapping.
|
||||
*/
|
||||
@Override
|
||||
public void write(List<? extends T> items) throws XmlMappingException, Exception {
|
||||
public void write(List<? extends T> items) throws XmlMappingException, IOException {
|
||||
|
||||
if(!this.initialized) {
|
||||
throw new WriterNotOpenException("Writer must be open before it can be written to");
|
||||
|
||||
@@ -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.
|
||||
* <br>
|
||||
* 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.
|
||||
* <br>
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user