Skip to content

Commit 73ca736

Browse files
marschallmminella
authored andcommitted
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
1 parent 7a3a72f commit 73ca736

10 files changed

+71
-125
lines changed

spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxEventItemReader.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.batch.item.xml;
1818

19+
import java.io.IOException;
1920
import java.io.InputStream;
2021
import java.util.ArrayList;
2122
import java.util.List;
@@ -217,7 +218,7 @@ protected void doOpen() throws Exception {
217218
* Move to next fragment and map it to item.
218219
*/
219220
@Override
220-
protected T doRead() throws Exception {
221+
protected T doRead() throws IOException, XMLStreamException {
221222

222223
if (noInput) {
223224
return null;

spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxEventItemWriter.java

+2-4
Original file line numberDiff line numberDiff line change
@@ -546,10 +546,8 @@ protected XMLEventFactory createXmlEventFactory() throws FactoryConfigurationErr
546546
* Subclasses can override to customize the STAX result.
547547
*
548548
* @return a result for writing to
549-
*
550-
* @throws Exception thrown if an error occurs curing the creation of the result.
551549
*/
552-
protected Result createStaxResult() throws Exception {
550+
protected Result createStaxResult() {
553551
return StaxUtils.getResult(eventWriter);
554552
}
555553

@@ -757,7 +755,7 @@ private void closeStream() {
757755
* @throws XmlMappingException thrown if error occurs during XML Mapping.
758756
*/
759757
@Override
760-
public void write(List<? extends T> items) throws XmlMappingException, Exception {
758+
public void write(List<? extends T> items) throws XmlMappingException, IOException {
761759

762760
if(!this.initialized) {
763761
throw new WriterNotOpenException("Writer must be open before it can be written to");

spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxUtils.java

+9-110
Original file line numberDiff line numberDiff line change
@@ -16,131 +16,30 @@
1616

1717
package org.springframework.batch.item.xml;
1818

19-
import java.lang.reflect.Constructor;
20-
import java.lang.reflect.Method;
2119
import javax.xml.stream.XMLEventReader;
2220
import javax.xml.stream.XMLEventWriter;
21+
import javax.xml.stream.XMLStreamException;
2322
import javax.xml.transform.Result;
2423
import javax.xml.transform.Source;
24+
import javax.xml.transform.stax.StAXResult;
25+
import javax.xml.transform.stax.StAXSource;
2526

26-
import org.apache.commons.logging.Log;
27-
import org.apache.commons.logging.LogFactory;
28-
29-
import org.springframework.util.Assert;
30-
import org.springframework.util.ClassUtils;
3127

3228
/**
33-
* This class provides a little bit of indirection to avoid ugly conditional object creation. It is unfortunately
34-
* a bit redundant assuming a Spring 3.0 environment, but is necessary to work with Spring WS 1.5.x.
35-
* <br>
36-
* The returned object determines whether the environment has Spring OXM as included in the Spring 3.x series of relies
37-
* or whether it has Spring OXM from Spring WS 1.5x and factories a StaxSource instance appropriately.
29+
* StAX utility methods.
3830
* <br>
39-
* As the only class state maintained is to cache java reflection metadata, which is thread-safe, this class is thread-safe.
31+
* This class is thread-safe.
4032
*
4133
* @author Josh Long
4234
*
4335
*/
4436
public abstract class StaxUtils {
4537

46-
private static final Log logger = LogFactory.getLog(StaxUtils.class);
47-
48-
private static ClassLoader defaultClassLoader = ClassUtils.getDefaultClassLoader();
49-
50-
// regular object.
51-
private static String staxSourceClassNameOnSpringWs15 = "org.springframework.xml.transform.StaxSource";
52-
private static String staxResultClassNameOnSpringOxm15 = "org.springframework.xml.transform.StaxResult";
53-
54-
// in Spring 3, StaxUtils is package private, so use static utility StaxUtils#createStaxSource / StaxUtils#createStaxResult
55-
private static String staxSourceClassNameOnSpringOxm30 = "org.springframework.util.xml.StaxUtils";
56-
57-
private static boolean hasSpringWs15StaxSupport = ClassUtils.isPresent(staxSourceClassNameOnSpringWs15, defaultClassLoader);
58-
59-
private static boolean hasSpring30StaxSupport = ClassUtils.isPresent(staxSourceClassNameOnSpringOxm30, defaultClassLoader);
60-
61-
private static Method staxUtilsSourceMethodOnSpring30, staxUtilsResultMethodOnSpring30;
62-
63-
private static Constructor<?> staxSourceClassCtorOnSpringWs15, staxResultClassCtorOnSpringWs15;
64-
65-
static {
66-
try {
67-
68-
// cache the factory method / constructor so that we spend as little time in reflection as possible
69-
if (hasSpring30StaxSupport) {
70-
Class<?> clzz = ClassUtils.forName(staxSourceClassNameOnSpringOxm30, defaultClassLoader);
71-
72-
// javax.xml.transform.Source
73-
staxUtilsSourceMethodOnSpring30 = ClassUtils.getStaticMethod(clzz, "createStaxSource", XMLEventReader.class);
74-
75-
// javax.xml.transform.Result
76-
staxUtilsResultMethodOnSpring30 = ClassUtils.getStaticMethod(clzz, "createStaxResult", XMLEventWriter.class);
77-
} else if (hasSpringWs15StaxSupport) {
78-
79-
// javax.xml.transform.Source
80-
Class<?> staxSourceClassOnSpringWs15 = ClassUtils.forName(staxSourceClassNameOnSpringWs15, defaultClassLoader);
81-
staxSourceClassCtorOnSpringWs15 = staxSourceClassOnSpringWs15.getConstructor(XMLEventReader.class);
82-
83-
// javax.xml.transform.Result
84-
Class<?> staxResultClassOnSpringWs15 = ClassUtils.forName(staxResultClassNameOnSpringOxm15, defaultClassLoader);
85-
staxResultClassCtorOnSpringWs15 = staxResultClassOnSpringWs15.getConstructor(XMLEventWriter.class);
86-
} else {
87-
88-
if (logger.isDebugEnabled()) {
89-
logger.debug("'StaxSource' was not detected in Spring 3.0's OXM support or Spring WS 1.5's OXM support. " +
90-
"This is a problem if you intend to use the " +StaxEventItemWriter.class.getName() + " or " +
91-
StaxEventItemReader.class.getName()+". Please add the appropriate dependencies.");
92-
}
93-
94-
}
95-
} catch (Exception ex) {
96-
logger.error("Could not precache required class and method metadata in " + StaxUtils.class.getName());
97-
}
98-
}
99-
100-
public static Source getSource(XMLEventReader r) throws Exception {
101-
if (hasSpring30StaxSupport) {
102-
// org.springframework.util.xml.StaxUtils.createStaxSource(r)
103-
Object result = staxUtilsSourceMethodOnSpring30.invoke(null,r);
104-
Assert.isInstanceOf(Source.class, result, "the result should be assignable to " + Source.class.getName());
105-
return (Source) result;
106-
} else if (hasSpringWs15StaxSupport) {
107-
Object result = staxSourceClassCtorOnSpringWs15.newInstance(r);
108-
Assert.isInstanceOf(Source.class, result, "the result should be assignable to " + Source.class.getName());
109-
return (Source) result;
110-
}
111-
// maybe you don't have either environment?
112-
return null;
38+
public static Source getSource(XMLEventReader r) throws XMLStreamException {
39+
return new StAXSource(r);
11340
}
11441

115-
public static Result getResult(XMLEventWriter w) throws Exception {
116-
if (hasSpring30StaxSupport) {
117-
Object result = staxUtilsResultMethodOnSpring30.invoke(null,w);
118-
Assert.isInstanceOf(Result.class, result, "the result should be assignable to " + Result.class.getName());
119-
return (Result) result;
120-
} else if (hasSpringWs15StaxSupport) {
121-
Object result = staxResultClassCtorOnSpringWs15.newInstance(w);
122-
Assert.isInstanceOf(Result.class, result, "the result should be assignable to " + Result.class.getName());
123-
return (Result) result;
124-
}
125-
// maybe you don't have either environment?
126-
return null;
42+
public static Result getResult(XMLEventWriter w) {
43+
return new StAXResult(w);
12744
}
128-
129-
public static XMLEventWriter getXmlEventWriter(Result r) throws Exception {
130-
Method m = r.getClass().getDeclaredMethod("getXMLEventWriter");
131-
boolean accessible = m.isAccessible();
132-
m.setAccessible(true);
133-
Object result = m.invoke(r);
134-
m.setAccessible(accessible);
135-
return (XMLEventWriter) result;
136-
}
137-
138-
public static XMLEventReader getXmlEventReader(Source s) throws Exception {
139-
Method m = s.getClass().getDeclaredMethod("getXMLEventReader");
140-
boolean accessible = m.isAccessible();
141-
m.setAccessible(true);
142-
Object result = m.invoke(s);
143-
m.setAccessible(accessible);
144-
return (XMLEventReader) result;
145-
}
14645
}

spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/MultiResourceItemReaderXmlTests.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
import org.springframework.batch.item.ItemReader;
3333
import org.springframework.batch.item.sample.Foo;
3434
import org.springframework.batch.item.xml.StaxEventItemReader;
35-
import org.springframework.batch.item.xml.StaxUtils;
35+
import org.springframework.batch.item.xml.StaxTestUtils;
3636
import org.springframework.core.io.ByteArrayResource;
3737
import org.springframework.core.io.Resource;
3838
import org.springframework.oxm.Unmarshaller;
@@ -55,7 +55,7 @@ public Object unmarshal(Source source) throws XmlMappingException, IOException {
5555

5656
Attribute attr;
5757
try {
58-
XMLEventReader eventReader = StaxUtils.getXmlEventReader(source );
58+
XMLEventReader eventReader = StaxTestUtils.getXmlEventReader(source );
5959
assertTrue(eventReader.nextEvent().isStartDocument());
6060
StartElement event = eventReader.nextEvent().asStartElement();
6161
attr = (Attribute) event.getAttributes().next();

spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/MultiResourceItemWriterXmlTests.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
import org.junit.Before;
2929
import org.junit.Test;
3030
import org.springframework.batch.item.xml.StaxEventItemWriter;
31-
import org.springframework.batch.item.xml.StaxUtils;
31+
import org.springframework.batch.item.xml.StaxTestUtils;
3232
import org.springframework.oxm.Marshaller;
3333
import org.springframework.oxm.XmlMappingException;
3434
import org.springframework.util.Assert;
@@ -63,7 +63,7 @@ public void marshal(Object graph, Result result) throws XmlMappingException, IOE
6363

6464
try {
6565
XMLEventFactory factory = XMLEventFactory.newInstance();
66-
XMLEventWriter writer = StaxUtils.getXmlEventWriter(result);
66+
XMLEventWriter writer = StaxTestUtils.getXmlEventWriter(result);
6767
writer.add(factory.createStartDocument("UTF-8"));
6868
writer.add(factory.createStartElement("prefix", "namespace", graph.toString()));
6969
writer.add(factory.createEndElement("prefix", "namespace", graph.toString()));

spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemReaderCommonTests.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ protected ItemReader<Foo> getItemReader() throws Exception {
4545
public Object unmarshal(Source source) throws XmlMappingException, IOException {
4646
Attribute attr = null ;
4747
try {
48-
XMLEventReader eventReader = StaxUtils.getXmlEventReader( source);
48+
XMLEventReader eventReader = StaxTestUtils.getXmlEventReader( source);
4949
assertTrue(eventReader.nextEvent().isStartDocument());
5050
StartElement event = eventReader.nextEvent().asStartElement();
5151
attr = (Attribute) event.getAttributes().next();

spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemReaderTests.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,7 @@ public Object unmarshal(Source source) throws XmlMappingException, IOException {
662662

663663
List<XMLEvent> fragmentContent;
664664
try {
665-
XMLEventReader eventReader = StaxUtils.getXmlEventReader(source);
665+
XMLEventReader eventReader = StaxTestUtils.getXmlEventReader(source);
666666

667667
// first event should be StartDocument
668668
XMLEvent event1 = eventReader.nextEvent();

spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemWriterTests.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -772,7 +772,7 @@ public void testMarshallingClosingEventWriter() throws Exception {
772772
public void marshal(Object graph, Result result) throws XmlMappingException, IOException {
773773
super.marshal(graph, result);
774774
try {
775-
StaxUtils.getXmlEventWriter(result).close();
775+
StaxTestUtils.getXmlEventWriter(result).close();
776776
} catch (Exception e) {
777777
throw new RuntimeException("Exception while writing to output file", e);
778778
}
@@ -955,8 +955,8 @@ public void setNamespacePrefix(String namespacePrefix) {
955955
public void marshal(Object graph, Result result) throws XmlMappingException, IOException {
956956
Assert.isInstanceOf( Result.class, result);
957957
try {
958-
StaxUtils.getXmlEventWriter( result ).add( XMLEventFactory.newInstance().createStartElement(namespacePrefix, namespace, graph.toString()));
959-
StaxUtils.getXmlEventWriter( result ).add( XMLEventFactory.newInstance().createEndElement(namespacePrefix, namespace, graph.toString()));
958+
StaxTestUtils.getXmlEventWriter( result ).add( XMLEventFactory.newInstance().createStartElement(namespacePrefix, namespace, graph.toString()));
959+
StaxTestUtils.getXmlEventWriter( result ).add( XMLEventFactory.newInstance().createEndElement(namespacePrefix, namespace, graph.toString()));
960960
}
961961
catch ( Exception e) {
962962
throw new RuntimeException("Exception while writing to output file", e);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright 2015 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.batch.item.xml;
17+
18+
import java.lang.reflect.Method;
19+
20+
import javax.xml.stream.XMLEventReader;
21+
import javax.xml.stream.XMLEventWriter;
22+
import javax.xml.transform.Result;
23+
import javax.xml.transform.Source;
24+
25+
/**
26+
* Utility methods for StAX related tests.
27+
*/
28+
public final class StaxTestUtils {
29+
30+
public static XMLEventWriter getXmlEventWriter(Result r) throws Exception {
31+
Method m = r.getClass().getDeclaredMethod("getXMLEventWriter", new Class[]{});
32+
boolean accessible = m.isAccessible();
33+
m.setAccessible(true);
34+
Object result = m.invoke(r);
35+
m.setAccessible(accessible);
36+
return (XMLEventWriter) result;
37+
}
38+
39+
public static XMLEventReader getXmlEventReader(Source s) throws Exception {
40+
Method m = s.getClass().getDeclaredMethod("getXMLEventReader", new Class[]{});
41+
boolean accessible = m.isAccessible();
42+
m.setAccessible(true);
43+
Object result = m.invoke(s);
44+
m.setAccessible(accessible);
45+
return (XMLEventReader) result;
46+
}
47+
48+
}

spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/TransactionalStaxEventItemWriterTests.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ private static class SimpleMarshaller implements Marshaller {
238238
@Override
239239
public void marshal(Object graph, Result result) throws XmlMappingException, IOException {
240240
try {
241-
StaxUtils.getXmlEventWriter(result).add(XMLEventFactory.newInstance().createComment(graph.toString()));
241+
StaxTestUtils.getXmlEventWriter(result).add(XMLEventFactory.newInstance().createComment(graph.toString()));
242242
}
243243
catch ( Exception e) {
244244
throw new RuntimeException("Exception while writing to output file", e);

0 commit comments

Comments
 (0)