diff --git a/spring-batch-infrastructure-tests/pom.xml b/spring-batch-infrastructure-tests/pom.xml index d78211da6..a98bba9e5 100644 --- a/spring-batch-infrastructure-tests/pom.xml +++ b/spring-batch-infrastructure-tests/pom.xml @@ -123,7 +123,7 @@ org.springframework.ws - spring-oxm + spring-oxm-tiger test diff --git a/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/io/oxm/AbstractStaxEventReaderItemReaderTests.java b/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/io/oxm/AbstractStaxEventReaderItemReaderTests.java index 41e5d7559..d6df61511 100644 --- a/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/io/oxm/AbstractStaxEventReaderItemReaderTests.java +++ b/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/io/oxm/AbstractStaxEventReaderItemReaderTests.java @@ -1,11 +1,14 @@ package org.springframework.batch.io.oxm; +import static org.junit.Assert.assertEquals; + import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; -import junit.framework.TestCase; - +import org.junit.After; +import org.junit.Before; +import org.junit.Test; import org.springframework.batch.io.oxm.domain.Trade; import org.springframework.batch.item.ExecutionContext; import org.springframework.batch.item.xml.StaxEventItemReader; @@ -13,28 +16,32 @@ import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.oxm.Unmarshaller; -public abstract class AbstractStaxEventReaderItemReaderTests extends TestCase { +public abstract class AbstractStaxEventReaderItemReaderTests { - private StaxEventItemReader source = new StaxEventItemReader(); + protected StaxEventItemReader reader = new StaxEventItemReader(); protected Resource resource = new ClassPathResource("org/springframework/batch/io/oxm/input.xml"); - protected void setUp() throws Exception { + @Before + public void setUp() throws Exception { - source.setResource(resource); + reader.setResource(resource); - source.setFragmentRootElementName("trade"); + reader.setFragmentRootElementName("trade"); - source.setUnmarshaller(getUnmarshaller()); + reader.setUnmarshaller(getUnmarshaller()); - source.open(new ExecutionContext()); + reader.afterPropertiesSet(); + + reader.open(new ExecutionContext()); } + @Test public void testRead() throws Exception { Trade result; List results = new ArrayList(); - while ((result = source.read()) != null) { + while ((result = reader.read()) != null) { results.add(result); } checkResults(results); @@ -71,8 +78,9 @@ public abstract class AbstractStaxEventReaderItemReaderTests extends TestCase { assertEquals("Customer3", trade3.getCustomer()); } - protected void tearDown() throws Exception { - source.close(); + @After + public void tearDown() throws Exception { + reader.close(); } public void setResource(Resource resource) { diff --git a/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/io/oxm/AbstractStaxEventWriterItemWriterTests.java b/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/io/oxm/AbstractStaxEventWriterItemWriterTests.java index 746fd20b5..c48c76ea2 100644 --- a/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/io/oxm/AbstractStaxEventWriterItemWriterTests.java +++ b/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/io/oxm/AbstractStaxEventWriterItemWriterTests.java @@ -33,11 +33,11 @@ public abstract class AbstractStaxEventWriterItemWriterTests { private static final int MAX_WRITE = 100; - private StaxEventItemWriter writer = new StaxEventItemWriter(); + protected StaxEventItemWriter writer = new StaxEventItemWriter(); private Resource resource; - File outputFile; + private File outputFile; protected Resource expected = new ClassPathResource("expected-output.xml", getClass()); @@ -62,8 +62,11 @@ public abstract class AbstractStaxEventWriterItemWriterTests { try { writer.write(objects); } + catch (RuntimeException e) { + throw e; + } catch (Exception e) { - status.setRollbackOnly(); + throw new IllegalStateException("Exception encountered on write", e); } return null; } @@ -73,22 +76,26 @@ public abstract class AbstractStaxEventWriterItemWriterTests { stopWatch.stop(); logger.info("Timing for XML writer: " + stopWatch); XMLUnit.setIgnoreWhitespace(true); + // String content = FileUtils.readFileToString(resource.getFile()); + // System.err.println(content); XMLAssert.assertXMLEqual(new FileReader(expected.getFile()), new FileReader(resource.getFile())); } @Before public void setUp() throws Exception { - // File outputFile = - // File.createTempFile("AbstractStaxStreamWriterOutputSourceTests", - // "xml"); - outputFile = File.createTempFile(ClassUtils.getShortName(this.getClass()), ".xml"); + + File directory = new File("target/data"); + directory.mkdirs(); + outputFile = File.createTempFile(ClassUtils.getShortName(this.getClass()), ".xml", directory); resource = new FileSystemResource(outputFile); writer.setResource(resource); writer.setMarshaller(getMarshaller()); + writer.afterPropertiesSet(); writer.open(new ExecutionContext()); + } @After diff --git a/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/io/oxm/Jaxb2MarshallingTests.java b/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/io/oxm/Jaxb2MarshallingTests.java new file mode 100644 index 000000000..d5ba94a9e --- /dev/null +++ b/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/io/oxm/Jaxb2MarshallingTests.java @@ -0,0 +1,45 @@ +package org.springframework.batch.io.oxm; + +import static org.junit.Assert.assertTrue; + +import java.io.StringWriter; +import java.math.BigDecimal; + +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.stream.StreamResult; + +import org.springframework.batch.io.oxm.domain.Trade; +import org.springframework.oxm.Marshaller; +import org.springframework.oxm.jaxb.Jaxb2Marshaller; + +public class Jaxb2MarshallingTests extends AbstractStaxEventWriterItemWriterTests { + + protected Marshaller getMarshaller() throws Exception { + + Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); + marshaller.setClassesToBeBound(new Class[] { Trade.class }); + marshaller.afterPropertiesSet(); + + StringWriter string = new StringWriter(); + marshaller.marshal(new Trade("FOO", 100, BigDecimal.valueOf(10.), "bar"), new StreamResult(string)); + String content = string.toString(); + assertTrue("Wrong content: "+content, content.contains("bar")); + return marshaller; + } + + public static String getTextFromSource(Source source) { + try { + Transformer transformer = TransformerFactory.newInstance().newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + StreamResult stream = new StreamResult(new StringWriter()); + transformer.transform(source, stream); + return stream.getWriter().toString(); + } + catch (Exception e) { + throw new IllegalStateException(e); + } + } +} diff --git a/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/io/oxm/Jaxb2NamespaceMarshallingTests.java b/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/io/oxm/Jaxb2NamespaceMarshallingTests.java new file mode 100644 index 000000000..6603c8a59 --- /dev/null +++ b/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/io/oxm/Jaxb2NamespaceMarshallingTests.java @@ -0,0 +1,128 @@ +package org.springframework.batch.io.oxm; + +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.FileReader; +import java.io.StringWriter; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.transform.stream.StreamResult; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.custommonkey.xmlunit.XMLAssert; +import org.custommonkey.xmlunit.XMLUnit; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.batch.io.oxm.domain.QualifiedTrade; +import org.springframework.batch.item.ExecutionContext; +import org.springframework.batch.item.xml.StaxEventItemWriter; +import org.springframework.batch.support.transaction.ResourcelessTransactionManager; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.FileSystemResource; +import org.springframework.core.io.Resource; +import org.springframework.oxm.Marshaller; +import org.springframework.oxm.jaxb.Jaxb2Marshaller; +import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.support.TransactionCallback; +import org.springframework.transaction.support.TransactionTemplate; +import org.springframework.util.ClassUtils; +import org.springframework.util.StopWatch; + +public class Jaxb2NamespaceMarshallingTests { + + private Log logger = LogFactory.getLog(getClass()); + + private static final int MAX_WRITE = 100; + + private StaxEventItemWriter writer = new StaxEventItemWriter(); + + private Resource resource; + + private File outputFile; + + private Resource expected = new ClassPathResource("expected-qualified-output.xml", getClass()); + + private List objects = new ArrayList() { + { + add(new QualifiedTrade("isin1", 1, new BigDecimal(1.0), "customer1")); + add(new QualifiedTrade("isin2", 2, new BigDecimal(2.0), "customer2")); + add(new QualifiedTrade("isin3", 3, new BigDecimal(3.0), "customer3")); + } + }; + + /** + * Write list of domain objects and check the output file. + */ + @Test + public void testWrite() throws Exception { + StopWatch stopWatch = new StopWatch(getClass().getSimpleName()); + stopWatch.start(); + for (int i = 0; i < MAX_WRITE; i++) { + new TransactionTemplate(new ResourcelessTransactionManager()).execute(new TransactionCallback() { + public Object doInTransaction(TransactionStatus status) { + try { + writer.write(objects); + } + catch (RuntimeException e) { + throw e; + } + catch (Exception e) { + throw new IllegalStateException("Exception encountered on write", e); + } + return null; + } + }); + } + writer.close(); + stopWatch.stop(); + logger.info("Timing for XML writer: " + stopWatch); + XMLUnit.setIgnoreWhitespace(true); + // String content = FileUtils.readFileToString(resource.getFile()); + // System.err.println(content); + XMLAssert.assertXMLEqual(new FileReader(expected.getFile()), new FileReader(resource.getFile())); + + } + + @Before + public void setUp() throws Exception { + + File directory = new File("target/data"); + directory.mkdirs(); + outputFile = File.createTempFile(ClassUtils.getShortName(this.getClass()), ".xml", directory); + resource = new FileSystemResource(outputFile); + + writer.setResource(resource); + + writer.setMarshaller(getMarshaller()); + writer.setRootTagName("{urn:org.springframework.batch.io.oxm.domain}trades"); + + writer.afterPropertiesSet(); + + writer.open(new ExecutionContext()); + + } + + @After + public void tearDown() throws Exception { + outputFile.delete(); + } + + protected Marshaller getMarshaller() throws Exception { + + Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); + marshaller.setClassesToBeBound(new Class[] { QualifiedTrade.class }); + marshaller.afterPropertiesSet(); + + StringWriter string = new StringWriter(); + marshaller.marshal(new QualifiedTrade("FOO", 100, BigDecimal.valueOf(10.), "bar"), new StreamResult(string)); + String content = string.toString(); + assertTrue("Wrong content: "+content, content.contains("bar")); + return marshaller; + } + +} diff --git a/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/io/oxm/Jaxb2NamespaceUnmarshallingTests.java b/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/io/oxm/Jaxb2NamespaceUnmarshallingTests.java new file mode 100644 index 000000000..0ab69cff5 --- /dev/null +++ b/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/io/oxm/Jaxb2NamespaceUnmarshallingTests.java @@ -0,0 +1,108 @@ +package org.springframework.batch.io.oxm; + +import static org.junit.Assert.assertEquals; + +import java.io.StringReader; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.transform.stream.StreamSource; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.batch.io.oxm.domain.QualifiedTrade; +import org.springframework.batch.io.oxm.domain.Trade; +import org.springframework.batch.item.ExecutionContext; +import org.springframework.batch.item.xml.StaxEventItemReader; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.oxm.Unmarshaller; +import org.springframework.oxm.jaxb.Jaxb2Marshaller; + +public class Jaxb2NamespaceUnmarshallingTests { + + private StaxEventItemReader reader = new StaxEventItemReader(); + + private Resource resource = new ClassPathResource("org/springframework/batch/io/oxm/domain/trades.xml"); + + @Before + public void setUp() throws Exception { + + reader.setResource(resource); + + reader.setFragmentRootElementName("{urn:org.springframework.batch.io.oxm.domain}trade"); + + reader.setUnmarshaller(getUnmarshaller()); + + reader.afterPropertiesSet(); + + reader.open(new ExecutionContext()); + + } + + @Test + public void testUnmarshal() throws Exception { + QualifiedTrade trade = (QualifiedTrade) getUnmarshaller().unmarshal(new StreamSource(new StringReader(TRADE_XML))); + assertEquals("XYZ0001", trade.getIsin()); + assertEquals(5, trade.getQuantity()); + assertEquals(new BigDecimal("11.39"), trade.getPrice()); + assertEquals("Customer1", trade.getCustomer()); + } + + @Test + public void testRead() throws Exception { + QualifiedTrade result; + List results = new ArrayList(); + while ((result = reader.read()) != null) { + results.add(result); + } + checkResults(results); + + } + + protected Unmarshaller getUnmarshaller() throws Exception { + + Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); + marshaller.setClassesToBeBound(new Class[] { QualifiedTrade.class }); + marshaller.setSchema(new ClassPathResource("trade.xsd", Trade.class)); + marshaller.afterPropertiesSet(); + + return marshaller; + } + + /** + * @param results list of domain objects returned by input source + */ + protected void checkResults(List results) { + assertEquals(3, results.size()); + + QualifiedTrade trade1 = results.get(0); + assertEquals("XYZ0001", trade1.getIsin()); + assertEquals(5, trade1.getQuantity()); + assertEquals(new BigDecimal("11.39"), trade1.getPrice()); + assertEquals("Customer1", trade1.getCustomer()); + + QualifiedTrade trade2 = results.get(1); + assertEquals("XYZ0002", trade2.getIsin()); + assertEquals(2, trade2.getQuantity()); + assertEquals(new BigDecimal("72.99"), trade2.getPrice()); + assertEquals("Customer2", trade2.getCustomer()); + + QualifiedTrade trade3 = results.get(2); + assertEquals("XYZ0003", trade3.getIsin()); + assertEquals(9, trade3.getQuantity()); + assertEquals(new BigDecimal("99.99"), trade3.getPrice()); + assertEquals("Customer3", trade3.getCustomer()); + } + + @After + public void tearDown() throws Exception { + reader.close(); + } + + private static String TRADE_XML = "" + + "Customer1XYZ000111.395" + + ""; +} diff --git a/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/io/oxm/Jaxb2UnmarshallingTests.java b/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/io/oxm/Jaxb2UnmarshallingTests.java new file mode 100644 index 000000000..2fe7af670 --- /dev/null +++ b/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/io/oxm/Jaxb2UnmarshallingTests.java @@ -0,0 +1,20 @@ +package org.springframework.batch.io.oxm; + +import org.springframework.batch.io.oxm.domain.Trade; +import org.springframework.oxm.Unmarshaller; +import org.springframework.oxm.jaxb.Jaxb2Marshaller; + +public class Jaxb2UnmarshallingTests extends AbstractStaxEventReaderItemReaderTests { + + protected Unmarshaller getUnmarshaller() throws Exception { + reader.setFragmentRootElementName("trade"); + + Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); + marshaller.setClassesToBeBound(new Class[] { Trade.class }); + // marshaller.setSchema(new ClassPathResource("trade.xsd", Trade.class)); + marshaller.afterPropertiesSet(); + + return marshaller; + } + +} diff --git a/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/io/oxm/domain/QualifiedTrade.java b/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/io/oxm/domain/QualifiedTrade.java new file mode 100644 index 000000000..061628253 --- /dev/null +++ b/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/io/oxm/domain/QualifiedTrade.java @@ -0,0 +1,121 @@ +package org.springframework.batch.io.oxm.domain; + +import java.math.BigDecimal; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * @author Rob Harrop + */ +@XmlRootElement(name="trade", namespace="urn:org.springframework.batch.io.oxm.domain") +@XmlType +@XmlAccessorType(XmlAccessType.FIELD) +public class QualifiedTrade { + + @XmlElement(namespace="urn:org.springframework.batch.io.oxm.domain") + private String isin = ""; + + @XmlElement(namespace="urn:org.springframework.batch.io.oxm.domain") + private long quantity = 0; + + @XmlElement(namespace="urn:org.springframework.batch.io.oxm.domain") + private BigDecimal price = new BigDecimal(0); + + @XmlElement(namespace="urn:org.springframework.batch.io.oxm.domain") + private String customer = ""; + + public QualifiedTrade() { + } + + public QualifiedTrade(String isin, long quantity, BigDecimal price, String customer) { + this.isin = isin; + this.quantity = quantity; + this.price = price; + this.customer = customer; + } + + public void setCustomer(String customer) { + this.customer = customer; + } + + public void setIsin(String isin) { + this.isin = isin; + } + + public void setPrice(BigDecimal price) { + this.price = price; + } + + public void setQuantity(long quantity) { + this.quantity = quantity; + } + + public String getIsin() { + return isin; + } + + public BigDecimal getPrice() { + return price; + } + + public long getQuantity() { + return quantity; + } + + public String getCustomer() { + return customer; + } + + public String toString() { + return "Trade: [isin=" + this.isin + ",quantity=" + this.quantity + ",price=" + this.price + ",customer=" + + this.customer + "]"; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((customer == null) ? 0 : customer.hashCode()); + result = prime * result + ((isin == null) ? 0 : isin.hashCode()); + result = prime * result + ((price == null) ? 0 : price.hashCode()); + result = prime * result + (int) (quantity ^ (quantity >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + QualifiedTrade other = (QualifiedTrade) obj; + if (customer == null) { + if (other.customer != null) + return false; + } + else if (!customer.equals(other.customer)) + return false; + if (isin == null) { + if (other.isin != null) + return false; + } + else if (!isin.equals(other.isin)) + return false; + if (price == null) { + if (other.price != null) + return false; + } + else if (!price.equals(other.price)) + return false; + if (quantity != other.quantity) + return false; + return true; + } + +} diff --git a/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/io/oxm/domain/Trade.java b/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/io/oxm/domain/Trade.java index 6fc755b58..84df42a7a 100644 --- a/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/io/oxm/domain/Trade.java +++ b/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/io/oxm/domain/Trade.java @@ -2,9 +2,14 @@ package org.springframework.batch.io.oxm.domain; import java.math.BigDecimal; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + /** * @author Rob Harrop */ +@XmlRootElement(name="trade") +@XmlType public class Trade { private String isin = ""; diff --git a/spring-batch-infrastructure-tests/src/test/resources/log4j.properties b/spring-batch-infrastructure-tests/src/test/resources/log4j.properties index f8c8855eb..0a1da5901 100644 --- a/spring-batch-infrastructure-tests/src/test/resources/log4j.properties +++ b/spring-batch-infrastructure-tests/src/test/resources/log4j.properties @@ -9,4 +9,5 @@ log4j.category.org.apache.activemq=ERROR log4j.category.org.springframework.jdbc=DEBUG log4j.category.org.springframework.jms=DEBUG log4j.category.org.springframework.batch=DEBUG +log4j.category.org.springframework.batch.support=INFO log4j.category.org.springframework.retry=DEBUG diff --git a/spring-batch-infrastructure-tests/src/test/resources/org/springframework/batch/io/oxm/domain/trade.xsd b/spring-batch-infrastructure-tests/src/test/resources/org/springframework/batch/io/oxm/domain/trade.xsd new file mode 100644 index 000000000..902fbba34 --- /dev/null +++ b/spring-batch-infrastructure-tests/src/test/resources/org/springframework/batch/io/oxm/domain/trade.xsd @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/spring-batch-infrastructure-tests/src/test/resources/org/springframework/batch/io/oxm/domain/trades.xml b/spring-batch-infrastructure-tests/src/test/resources/org/springframework/batch/io/oxm/domain/trades.xml new file mode 100644 index 000000000..a2bcfa41a --- /dev/null +++ b/spring-batch-infrastructure-tests/src/test/resources/org/springframework/batch/io/oxm/domain/trades.xml @@ -0,0 +1,22 @@ + + + + Customer1 + XYZ0001 + 11.39 + 5 + + + Customer2 + XYZ0002 + 72.99 + 2 + + + Customer3 + XYZ0003 + 99.99 + 9 + + diff --git a/spring-batch-infrastructure-tests/src/test/resources/org/springframework/batch/io/oxm/expected-qualified-output.xml b/spring-batch-infrastructure-tests/src/test/resources/org/springframework/batch/io/oxm/expected-qualified-output.xml new file mode 100644 index 000000000..af6707505 --- /dev/null +++ b/spring-batch-infrastructure-tests/src/test/resources/org/springframework/batch/io/oxm/expected-qualified-output.xml @@ -0,0 +1,1803 @@ + + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + + isin1 + 1 + 1 + customer1 + + + isin2 + 2 + 2 + customer2 + + + isin3 + 3 + 3 + customer3 + + \ No newline at end of file diff --git a/spring-batch-infrastructure/pom.xml b/spring-batch-infrastructure/pom.xml index ee304fb8d..e6e7a2339 100644 --- a/spring-batch-infrastructure/pom.xml +++ b/spring-batch-infrastructure/pom.xml @@ -141,7 +141,7 @@ org.springframework.ws - spring-oxm + spring-oxm-tiger true 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 f41cf93d3..e2b77a899 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 @@ -232,15 +232,17 @@ public class StaxEventItemWriter extends ExecutionContextUserSupport implemen /** * Set the tag name of the root element. If not set, default name is used - * ("root"). Namespace URI and prefix can also be set optionally using the + * ("root"). Namespace URI and prefix can also be set optionally using the * notation: * *
 	 * {uri}prefix:root
 	 * 
* - * The prefix is optional (defaults to empty), but if it is specified then the - * uri must be provided. + * The prefix is optional (defaults to empty), but if it is specified then + * the uri must be provided. In addition you might want to declare other + * namespaces using the {@link #setRootElementAttributes(Map) root + * attributes}. * * @param rootTagName the tag name to be used for the root element */ @@ -276,7 +278,8 @@ public class StaxEventItemWriter extends ExecutionContextUserSupport implemen } /** - * Set the root element attributes to be written. + * Set the root element attributes to be written. If any of the key names + * begin with "xmlns:" then they are treated as namespace declarations. * * @param rootElementAttributes attributes of the root element */ @@ -307,8 +310,7 @@ public class StaxEventItemWriter extends ExecutionContextUserSupport implemen if (rootTagName.contains("{")) { rootTagNamespace = rootTagName.replaceAll("\\{(.*)\\}.*", "$1"); rootTagName = rootTagName.replaceAll("\\{.*\\}(.*)", "$1"); - if (rootTagName.contains(":")) - { + if (rootTagName.contains(":")) { rootTagNamespacePrefix = rootTagName.replaceAll("(.*):.*", "$1"); rootTagName = rootTagName.replaceAll(".*:(.*)", "$1"); } @@ -430,14 +432,29 @@ public class StaxEventItemWriter extends ExecutionContextUserSupport implemen // write root tag writer.add(factory.createStartElement(getRootTagNamespacePrefix(), getRootTagNamespace(), getRootTagName())); if (StringUtils.hasText(getRootTagNamespace())) { - writer.add(factory.createNamespace(getRootTagNamespacePrefix(), getRootTagNamespace())); + if (StringUtils.hasText(getRootTagNamespacePrefix())) { + writer.add(factory.createNamespace(getRootTagNamespacePrefix(), getRootTagNamespace())); + } + else { + writer.add(factory.createNamespace(getRootTagNamespace())); + } } // write root tag attributes if (!CollectionUtils.isEmpty(getRootElementAttributes())) { for (Map.Entry entry : getRootElementAttributes().entrySet()) { - writer.add(factory.createAttribute(entry.getKey(), entry.getValue())); + String key = entry.getKey(); + if (key.startsWith("xmlns")) { + String prefix = ""; + if (key.contains(":")) { + prefix = key.substring(key.indexOf(":") + 1); + } + writer.add(factory.createNamespace(prefix, entry.getValue())); + } + else { + writer.add(factory.createAttribute(key, entry.getValue())); + } } } 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 df698d7b9..59ab20962 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 @@ -62,9 +62,19 @@ public class StaxEventItemWriterTests { private static final String TEST_STRING = "<" + ClassUtils.getShortName(StaxEventItemWriter.class) + "-testString/>"; + private static final String NS_TEST_STRING = ""; + + private static final String FOO_TEST_STRING = ""; + + private SimpleMarshaller marshaller; + @Before public void setUp() throws Exception { - resource = new FileSystemResource(File.createTempFile("StaxEventWriterOutputSourceTests", ".xml")); + File directory = new File("target/data"); + directory.mkdirs(); + resource = new FileSystemResource(File.createTempFile("StaxEventWriterOutputSourceTests", ".xml", directory)); writer = createItemWriter(); executionContext = new ExecutionContext(); } @@ -287,29 +297,68 @@ public class StaxEventItemWriterTests { public void testWriteRootTagWithNamespaceAndPrefix() throws Exception { writer.setRootTagName("{http://www.springframework.org/test}ns:root"); writer.afterPropertiesSet(); + marshaller.setNamespace(writer.getRootTagNamespace()); + marshaller.setNamespacePrefix(writer.getRootTagNamespacePrefix()); writer.open(executionContext); writer.write(items); writer.close(); String content = getOutputFileContent(); assertTrue("Wrong content: " + content, content .contains((""))); - assertTrue("Wrong content: " + content, content.contains(TEST_STRING)); + assertTrue("Wrong content: " + content, content.contains(NS_TEST_STRING)); assertTrue("Wrong content: " + content, content.contains((""))); + assertTrue("Wrong content: " + content, content.contains((""))); + assertTrue("Wrong content: " + content, content.contains(FOO_TEST_STRING)); + assertTrue("Wrong content: " + content, content.contains((""))); + assertTrue("Wrong content: " + content, content.contains((" source = new StaxEventItemWriter(); source.setResource(resource); - Marshaller marshaller = new SimpleMarshaller(); + marshaller = new SimpleMarshaller(); source.setMarshaller(marshaller); source.setEncoding("UTF-8"); @@ -351,5 +400,5 @@ public class StaxEventItemWriterTests { return source; } - + } diff --git a/spring-batch-parent/pom.xml b/spring-batch-parent/pom.xml index bb313483c..b4e9b49a4 100644 --- a/spring-batch-parent/pom.xml +++ b/spring-batch-parent/pom.xml @@ -546,7 +546,13 @@ org.springframework.ws spring-oxm - 1.5.5 + 1.5.8 + true + + + org.springframework.ws + spring-oxm-tiger + 1.5.8 true