diff --git a/archetypes/simple-cli/src/main/java/example/ExampleItemWriter.java b/archetypes/simple-cli/src/main/java/example/ExampleItemWriter.java index 28e4ae20b..69ec6ee9d 100644 --- a/archetypes/simple-cli/src/main/java/example/ExampleItemWriter.java +++ b/archetypes/simple-cli/src/main/java/example/ExampleItemWriter.java @@ -1,5 +1,7 @@ package example; +import java.util.List; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.batch.item.ItemWriter; @@ -16,7 +18,7 @@ public class ExampleItemWriter extends AbstractItemWriter { /** * @see ItemWriter#write(Object) */ - public void write(Object data) throws Exception { + public void write(List data) throws Exception { log.info(data); } diff --git a/pom.xml b/pom.xml index b50a8ba97..a99043477 100644 --- a/pom.xml +++ b/pom.xml @@ -14,10 +14,10 @@ spring-batch-infrastructure spring-batch-infrastructure-tests spring-batch-core - spring-batch-samples + docs - archetypes + http://www.springframework.org/spring-batch @@ -392,12 +392,6 @@ aspectjweaver 1.5.3 - - backport-util-concurrent - backport-util-concurrent - 3.0 - true - junit junit diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/ItemWriteListener.java b/spring-batch-core/src/main/java/org/springframework/batch/core/ItemWriteListener.java index 69894a12f..7b9ca91b3 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/ItemWriteListener.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/ItemWriteListener.java @@ -26,14 +26,14 @@ import org.springframework.batch.item.ItemWriter; public interface ItemWriteListener extends StepListener { /** - * Called before {@link ItemWriter#write(Object)} + * Called before {@link ItemWriter#write(java.util.List)} * * @param item to be written */ void beforeWrite(Object item); /** - * Called after {@link ItemWriter#write(Object)} If the item is last in a + * Called after {@link ItemWriter#write(java.util.List)} If the item is last in a * chunk, this will be called before any transaction is committed, and * before {@link ChunkListener#afterChunk()} * @param item written item diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/BatchListenerFactoryHelper.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/BatchListenerFactoryHelper.java index d6350ae24..7a3e7dfc3 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/BatchListenerFactoryHelper.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/BatchListenerFactoryHelper.java @@ -16,6 +16,7 @@ package org.springframework.batch.core.step.item; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import org.springframework.batch.core.ChunkListener; @@ -94,15 +95,18 @@ abstract class BatchListenerFactoryHelper { } return new ItemWriter() { - public void write(T item) throws Exception { - try { - multicaster.beforeWrite(item); - itemWriter.write(item); - multicaster.afterWrite(item); - } - catch (Exception e) { - multicaster.onWriteError(e, item); - throw e; + public void write(List items) throws Exception { + + for (T item : items) { + try { + multicaster.beforeWrite(item); + itemWriter.write(Collections.singletonList(item)); + multicaster.afterWrite(item); + } + catch (Exception e) { + multicaster.onWriteError(e, item); + throw e; + } } } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/ItemOrientedStepHandler.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/ItemOrientedStepHandler.java index daebc50f2..e665f01cc 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/ItemOrientedStepHandler.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/ItemOrientedStepHandler.java @@ -15,6 +15,8 @@ */ package org.springframework.batch.core.step.item; +import java.util.Collections; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.batch.core.StepContribution; @@ -118,7 +120,7 @@ public class ItemOrientedStepHandler implements StepHandler { S processed = itemProcessor.process(item); if (processed != null) { // TODO: increment filtered item count - itemWriter.write(processed); + itemWriter.write(Collections.singletonList(processed)); return true; } return false; diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/launch/EmptyItemWriter.java b/spring-batch-core/src/test/java/org/springframework/batch/core/launch/EmptyItemWriter.java index 06be29e80..78ccc9c53 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/launch/EmptyItemWriter.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/launch/EmptyItemWriter.java @@ -28,8 +28,8 @@ import org.springframework.batch.support.transaction.TransactionAwareProxyFactor import org.springframework.beans.factory.InitializingBean; /** - * Mock {@link ItemWriter} that will throw an exception when a certain - * number of items have been written. + * Mock {@link ItemWriter} that will throw an exception when a certain number of + * items have been written. */ public class EmptyItemWriter implements ItemWriter, InitializingBean { @@ -43,7 +43,8 @@ public class EmptyItemWriter implements ItemWriter, InitializingBean { List list; public void afterPropertiesSet() throws Exception { - TransactionAwareProxyFactory> factory = new TransactionAwareProxyFactory>(new ArrayList()); + TransactionAwareProxyFactory> factory = new TransactionAwareProxyFactory>( + new ArrayList()); list = factory.createInstance(); } @@ -51,13 +52,15 @@ public class EmptyItemWriter implements ItemWriter, InitializingBean { this.failurePoint = failurePoint; } - public void write(T data) { - if (!failed && list.size() == failurePoint) { - failed = true; - throw new RuntimeException("Failed processing: [" + data + "]"); + public void write(List items) { + for (T data : items) { + if (!failed && list.size() == failurePoint) { + failed = true; + throw new RuntimeException("Failed processing: [" + data + "]"); + } + logger.info("Processing: [" + data + "]"); + list.add(data); } - logger.info("Processing: [" + data + "]"); - list.add(data); } public List getList() { @@ -65,11 +68,11 @@ public class EmptyItemWriter implements ItemWriter, InitializingBean { } public void clear() throws ClearFailedException { - //no-op + // no-op } public void flush() throws FlushFailedException { - //no-op + // no-op } } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/ItemOrientedStepHandlerTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/ItemOrientedStepHandlerTests.java index 52798eec0..f5d840f6d 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/ItemOrientedStepHandlerTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/ItemOrientedStepHandlerTests.java @@ -17,6 +17,8 @@ package org.springframework.batch.core.step.item; import static org.junit.Assert.assertEquals; +import java.util.List; + import org.junit.Test; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobInstance; @@ -91,8 +93,10 @@ public class ItemOrientedStepHandlerTests { private final class StubItemWriter extends AbstractItemWriter { private String values = ""; - public void write(String item) throws Exception { - values += item; + public void write(List items) throws Exception { + for (String item : items) { + values += item; + } } } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SimpleStepFactoryBeanTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SimpleStepFactoryBeanTests.java index be73f6758..d319339ac 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SimpleStepFactoryBeanTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SimpleStepFactoryBeanTests.java @@ -64,8 +64,8 @@ public class SimpleStepFactoryBeanTests extends TestCase { private List written = new ArrayList(); private ItemWriter writer = new AbstractItemWriter() { - public void write(String data) throws Exception { - written.add(data); + public void write(List data) throws Exception { + written.addAll(data); } }; @@ -166,7 +166,7 @@ public class SimpleStepFactoryBeanTests extends TestCase { SimpleStepFactoryBean factory = getStepFactory(new String[] { "foo", "bar", "spam" }); factory.setItemWriter(new AbstractItemWriter() { - public void write(String data) throws Exception { + public void write(List data) throws Exception { throw new RuntimeException("Error!"); } }); @@ -199,7 +199,7 @@ public class SimpleStepFactoryBeanTests extends TestCase { SimpleStepFactoryBean factory = getStepFactory(new String[] { "foo", "bar", "spam" }); factory.setBeanName("exceptionStep"); factory.setItemWriter(new AbstractItemWriter() { - public void write(String data) throws Exception { + public void write(List data) throws Exception { throw new RuntimeException("Foo"); } }); @@ -225,7 +225,7 @@ public class SimpleStepFactoryBeanTests extends TestCase { factory.setItemWriter(new AbstractItemWriter() { int count = 0; - public void write(String data) throws Exception { + public void write(List data) throws Exception { if (count++ == 0) { throw new RuntimeException("Foo"); } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SkipLimitStepFactoryBeanTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SkipLimitStepFactoryBeanTests.java index 935ba0ada..99e2b937b 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SkipLimitStepFactoryBeanTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/SkipLimitStepFactoryBeanTests.java @@ -42,7 +42,7 @@ public class SkipLimitStepFactoryBeanTests extends TestCase { protected final Log logger = LogFactory.getLog(getClass()); - private SkipLimitStepFactoryBean factory = new SkipLimitStepFactoryBean(); + private SkipLimitStepFactoryBean factory = new SkipLimitStepFactoryBean(); private Class[] skippableExceptions = new Class[] { SkippableException.class, SkippableRuntimeException.class }; @@ -132,7 +132,7 @@ public class SkipLimitStepFactoryBeanTests extends TestCase { public void testFatalException() throws Exception { factory.setFatalExceptionClasses(new Class[] { FatalRuntimeException.class }); factory.setItemWriter(new SkipWriterStub() { - public void write(String item) { + public void write(List items) { throw new FatalRuntimeException("Ouch!"); } }); @@ -255,7 +255,7 @@ public class SkipLimitStepFactoryBeanTests extends TestCase { assertEquals(1, stepExecution.getSkipCount()); assertEquals(1, stepExecution.getReadSkipCount()); assertEquals(0, stepExecution.getWriteSkipCount()); - + } /** @@ -292,7 +292,7 @@ public class SkipLimitStepFactoryBeanTests extends TestCase { assertEquals(1, stepExecution.getSkipCount()); assertEquals(0, stepExecution.getReadSkipCount()); assertEquals(1, stepExecution.getWriteSkipCount()); - + } /** @@ -470,12 +470,14 @@ public class SkipLimitStepFactoryBeanTests extends TestCase { flushIndex = written.size() - 1; } - public void write(String item) throws Exception { - if (failures.contains(item)) { - logger.debug("Throwing write exception on [" + item + "]"); - throw new SkippableRuntimeException("exception in writer"); + public void write(List items) throws Exception { + for (String item : items) { + if (failures.contains(item)) { + logger.debug("Throwing write exception on [" + item + "]"); + throw new SkippableRuntimeException("exception in writer"); + } + written.add(item); } - written.add(item); } } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StatefulRetryStepFactoryBeanTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StatefulRetryStepFactoryBeanTests.java index 2243fdc59..2573949d7 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StatefulRetryStepFactoryBeanTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StatefulRetryStepFactoryBeanTests.java @@ -73,8 +73,8 @@ public class StatefulRetryStepFactoryBeanTests extends TestCase { JobExecution jobExecution; private ItemWriter processor = new AbstractItemWriter() { - public void write(Object data) throws Exception { - processed.add(data); + public void write(List data) throws Exception { + processed.addAll(data); } }; @@ -199,9 +199,9 @@ public class StatefulRetryStepFactoryBeanTests extends TestCase { }; ItemWriter itemWriter = new AbstractItemWriter() { - public void write(Object item) throws Exception { + public void write(List item) throws Exception { logger.debug("Write Called! Item: [" + item + "]"); - if ("b".equals(item) || "d".equals(item)) { + if (item.contains("b") || item.contains("d")) { throw new RuntimeException("Read error - planned but skippable."); } } @@ -237,7 +237,7 @@ public class StatefulRetryStepFactoryBeanTests extends TestCase { } }; ItemWriter itemWriter = new AbstractItemWriter() { - public void write(Object item) throws Exception { + public void write(List item) throws Exception { logger.debug("Write Called! Item: [" + item + "]"); throw new RuntimeException("Write error - planned but retryable."); } @@ -274,7 +274,7 @@ public class StatefulRetryStepFactoryBeanTests extends TestCase { } }; ItemWriter itemWriter = new AbstractItemWriter() { - public void write(Object item) throws Exception { + public void write(List item) throws Exception { logger.debug("Write Called! Item: [" + item + "]"); throw new RuntimeException("Write error - planned but retryable."); } @@ -312,7 +312,7 @@ public class StatefulRetryStepFactoryBeanTests extends TestCase { } }; ItemWriter itemWriter = new AbstractItemWriter() { - public void write(Object item) throws Exception { + public void write(List item) throws Exception { logger.debug("Write Called! Item: [" + item + "]"); throw new RuntimeException("Write error - planned but retryable."); } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StepExecutorInterruptionTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StepExecutorInterruptionTests.java index 6c60221ae..0c665fba2 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StepExecutorInterruptionTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StepExecutorInterruptionTests.java @@ -16,6 +16,8 @@ package org.springframework.batch.core.step.item; +import java.util.List; + import junit.framework.TestCase; import org.springframework.batch.core.BatchStatus; @@ -63,7 +65,7 @@ public class StepExecutorInterruptionTests extends TestCase { step.setJobRepository(jobRepository); step.setTransactionManager(new ResourcelessTransactionManager()); itemWriter = new AbstractItemWriter() { - public void write(Object item) throws Exception { + public void write(List item) throws Exception { } }; step.setItemHandler(new SimpleStepHandler(new AbstractItemReader() { diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StepHandlerStepIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StepHandlerStepIntegrationTests.java index 7a71bd15e..49b918679 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StepHandlerStepIntegrationTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StepHandlerStepIntegrationTests.java @@ -21,6 +21,7 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.Arrays; +import java.util.List; import javax.sql.DataSource; @@ -112,7 +113,7 @@ public class StepHandlerStepIntegrationTests { step.setItemHandler(new SimpleStepHandler(getReader(new String[] { "a", "b", "c" }), new AbstractItemWriter() { - public void write(String data) throws Exception { + public void write(List data) throws Exception { TransactionSynchronizationManager .registerSynchronization(new TransactionSynchronizationAdapter() { public void beforeCommit(boolean readOnly) { diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StepHandlerStepTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StepHandlerStepTests.java index 635ce91f3..9e85b02cd 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StepHandlerStepTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/StepHandlerStepTests.java @@ -71,8 +71,8 @@ public class StepHandlerStepTests extends TestCase { private List list = new ArrayList(); ItemWriter itemWriter = new AbstractItemWriter() { - public void write(String data) throws Exception { - processed.add(data); + public void write(List data) throws Exception { + processed.addAll(data); } }; 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 065c02645..a5ead4598 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 @@ -4,7 +4,6 @@ import java.io.File; import java.io.FileReader; import java.math.BigDecimal; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; import junit.framework.TestCase; @@ -43,9 +42,7 @@ public abstract class AbstractStaxEventWriterItemWriterTests extends TestCase { * Write list of domain objects and check the output file. */ public void testWrite() throws Exception { - for (Iterator iterator = objects.listIterator(); iterator.hasNext();) { - writer.write(iterator.next()); - } + writer.write(objects); writer.close(null); XMLUnit.setIgnoreWhitespace(true); XMLAssert.assertXMLEqual(new FileReader(expected.getFile()), new FileReader(resource.getFile())); @@ -53,7 +50,9 @@ public abstract class AbstractStaxEventWriterItemWriterTests extends TestCase { } protected void setUp() throws Exception { - // File outputFile = File.createTempFile("AbstractStaxStreamWriterOutputSourceTests", "xml"); + // File outputFile = + // File.createTempFile("AbstractStaxStreamWriterOutputSourceTests", + // "xml"); outputFile = File.createTempFile(ClassUtils.getShortName(this.getClass()), ".xml"); resource = new FileSystemResource(outputFile); writer.setResource(resource); diff --git a/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/retry/jms/ExternalRetryTests.java b/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/retry/jms/ExternalRetryTests.java index 11b8d2d70..19716e7dc 100644 --- a/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/retry/jms/ExternalRetryTests.java +++ b/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/retry/jms/ExternalRetryTests.java @@ -16,13 +16,18 @@ package org.springframework.batch.retry.jms; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import javax.sql.DataSource; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; import org.springframework.batch.item.ItemRecoverer; import org.springframework.batch.item.support.AbstractItemReader; import org.springframework.batch.item.support.AbstractItemWriter; @@ -32,18 +37,15 @@ import org.springframework.batch.retry.RetryContext; import org.springframework.batch.retry.callback.RecoveryRetryCallback; import org.springframework.batch.retry.policy.RecoveryCallbackRetryPolicy; import org.springframework.batch.retry.support.RetryTemplate; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; import org.springframework.jms.core.JmsTemplate; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionTemplate; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.ContextConfiguration; -import org.junit.runner.RunWith; -import org.junit.Before; -import org.junit.Test; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "/org/springframework/batch/jms/jms-context.xml") @@ -107,10 +109,16 @@ public class ExternalRetryTests { retryTemplate.setRetryPolicy(new RecoveryCallbackRetryPolicy()); final AbstractItemWriter writer = new AbstractItemWriter() { - public void write(final Object text) { - simpleJdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", list.size(), text); - if (list.size() == 1) { - throw new RuntimeException("Rollback!"); + public void write(final List texts) { + + for (Object text : texts) { + + simpleJdbcTemplate.update("INSERT into T_FOOS (id,name,foo_date) values (?,?,null)", list.size(), + text); + if (list.size() == 1) { + throw new RuntimeException("Rollback!"); + } + } } @@ -123,7 +131,7 @@ public class ExternalRetryTests { final Object item = provider.read(); RecoveryRetryCallback callback = new RecoveryRetryCallback(item, new RetryCallback() { public Object doWithRetry(RetryContext context) throws Throwable { - writer.write(item); + writer.write(Collections.singletonList(item)); return null; } }); @@ -151,7 +159,7 @@ public class ExternalRetryTests { final Object item = provider.read(); RecoveryRetryCallback callback = new RecoveryRetryCallback(item, new RetryCallback() { public Object doWithRetry(RetryContext context) throws Throwable { - writer.write(item); + writer.write(Collections.singletonList(item)); return null; } }); @@ -190,7 +198,7 @@ public class ExternalRetryTests { throw new RuntimeException("Rollback!"); } }); - + callback.setRecoveryCallback(new RecoveryCallback() { public Object recover(RetryContext context) { return provider.recover(item, context.getLastThrowable()); diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemWriter.java index 4c467f5cd..fd330c9c6 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemWriter.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemWriter.java @@ -16,6 +16,8 @@ package org.springframework.batch.item; +import java.util.List; + /** *

* Basic interface for generic output operations. Class implementing this @@ -46,7 +48,7 @@ public interface ItemWriter { * retry or a batch the framework will catch the exception and convert or * rethrow it as appropriate. */ - void write(T item) throws Exception; + void write(List items) throws Exception; /** * Flush any buffers that are being held. This will usually be performed diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/adapter/ItemWriterAdapter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/adapter/ItemWriterAdapter.java index 46bfe0b9c..b76391d18 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/adapter/ItemWriterAdapter.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/adapter/ItemWriterAdapter.java @@ -16,6 +16,8 @@ package org.springframework.batch.item.adapter; +import java.util.List; + import org.springframework.batch.item.ClearFailedException; import org.springframework.batch.item.FlushFailedException; import org.springframework.batch.item.ItemWriter; @@ -31,8 +33,10 @@ import org.springframework.batch.item.ItemWriter; */ public class ItemWriterAdapter extends AbstractMethodInvokingDelegator implements ItemWriter { - public void write(T item) throws Exception { - invokeDelegateMethodWithArgument(item); + public void write(List items) throws Exception { + for (T item : items) { + invokeDelegateMethodWithArgument(item); + } } /* diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/adapter/PropertyExtractingDelegatingItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/adapter/PropertyExtractingDelegatingItemWriter.java index cdbb62a10..9741ccf16 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/adapter/PropertyExtractingDelegatingItemWriter.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/adapter/PropertyExtractingDelegatingItemWriter.java @@ -16,6 +16,8 @@ package org.springframework.batch.item.adapter; +import java.util.List; + import org.springframework.batch.item.ClearFailedException; import org.springframework.batch.item.FlushFailedException; import org.springframework.batch.item.ItemWriter; @@ -24,33 +26,38 @@ import org.springframework.beans.BeanWrapperImpl; import org.springframework.util.Assert; /** - * Delegates processing to a custom method - extracts property values - * from item object and uses them as arguments for the delegate method. + * Delegates processing to a custom method - extracts property values from item + * object and uses them as arguments for the delegate method. * * @see ItemWriterAdapter * * @author Robert Kasanicky */ -public class PropertyExtractingDelegatingItemWriter extends AbstractMethodInvokingDelegator implements ItemWriter { - +public class PropertyExtractingDelegatingItemWriter extends AbstractMethodInvokingDelegator implements + ItemWriter { + private String[] fieldsUsedAsTargetMethodArguments; - + /** - * Extracts values from item's fields named in fieldsUsedAsTargetMethodArguments - * and passes them as arguments to the delegate method. + * Extracts values from item's fields named in + * fieldsUsedAsTargetMethodArguments and passes them as arguments to the + * delegate method. */ - public void write(T item) throws Exception { - // helper for extracting property values from a bean - BeanWrapper beanWrapper = new BeanWrapperImpl(item); - - Object[] methodArguments = new Object[fieldsUsedAsTargetMethodArguments.length]; - for (int i = 0; i < fieldsUsedAsTargetMethodArguments.length; i++) { - methodArguments[i] = beanWrapper.getPropertyValue(fieldsUsedAsTargetMethodArguments[i]); + public void write(List items) throws Exception { + for (T item : items) { + + // helper for extracting property values from a bean + BeanWrapper beanWrapper = new BeanWrapperImpl(item); + + Object[] methodArguments = new Object[fieldsUsedAsTargetMethodArguments.length]; + for (int i = 0; i < fieldsUsedAsTargetMethodArguments.length; i++) { + methodArguments[i] = beanWrapper.getPropertyValue(fieldsUsedAsTargetMethodArguments[i]); + } + + invokeDelegateMethodWithArguments(methodArguments); + } - - invokeDelegateMethodWithArguments(methodArguments); } - public void afterPropertiesSet() throws Exception { super.afterPropertiesSet(); @@ -59,18 +66,16 @@ public class PropertyExtractingDelegatingItemWriter extends AbstractMethodInv /** * @param fieldsUsedAsMethodArguments the values of the these item's fields - * will be used as arguments for the delegate method. Nested property values are - * supported, e.g. address.city + * will be used as arguments for the delegate method. Nested property values + * are supported, e.g. address.city */ public void setFieldsUsedAsTargetMethodArguments(String[] fieldsUsedAsMethodArguments) { this.fieldsUsedAsTargetMethodArguments = fieldsUsedAsMethodArguments; } - public void clear() throws ClearFailedException { } - public void flush() throws FlushFailedException { } } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/AbstractTransactionalResourceItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/AbstractTransactionalResourceItemWriter.java index e6dbc7570..ecbc75318 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/AbstractTransactionalResourceItemWriter.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/AbstractTransactionalResourceItemWriter.java @@ -16,6 +16,7 @@ package org.springframework.batch.item.database; import java.util.HashSet; +import java.util.List; import java.util.Set; import org.springframework.batch.item.ClearFailedException; @@ -71,11 +72,11 @@ public abstract class AbstractTransactionalResourceItemWriter implements Item * * @throws Exception * - * @see org.springframework.batch.item.ItemWriter#write(Object) + * @see org.springframework.batch.item.ItemWriter#write(java.util.List) */ - public final void write(T output) throws Exception { + public final void write(List output) throws Exception { bindTransactionResources(); - getProcessed().add(output); + getProcessed().addAll(output); doWrite(output); flushIfNecessary(output); } @@ -104,9 +105,9 @@ public abstract class AbstractTransactionalResourceItemWriter implements Item protected abstract void doClear() throws ClearFailedException; /** - * Callback method of {@link #write(Object)}. + * Callback method of {@link #write(List)}. */ - protected abstract void doWrite(T item) throws Exception; + protected abstract void doWrite(List output) throws Exception; /** * @return Key for items processed in the current transaction @@ -114,19 +115,23 @@ public abstract class AbstractTransactionalResourceItemWriter implements Item */ protected abstract String getResourceKey(); - private void flushIfNecessary(Object output) { - boolean flush; + private void flushIfNecessary(List outputs) { + Set flush = new HashSet(); synchronized (failed) { - flush = failed.contains(output); + for (T output : outputs) { + if (failed.contains(output)) { + flush.add(output); + } + } } - if (flush) { + if (!flush.isEmpty()) { // Force early completion to commit aggressively if we encounter a // failed item (from a failed chunk but we don't know which one was // the problem). RepeatSynchronizationManager.setCompleteOnly(); // Remove the failed item from the cache, otherwise it could grow // unnecessarily large. - failed.remove(output); + failed.removeAll(flush); // Flush now, so that if there is a failure this record can be // skipped. flush(); diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/BatchSqlUpdateItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/BatchSqlUpdateItemWriter.java index 33f6682bf..45ab98fd3 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/BatchSqlUpdateItemWriter.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/BatchSqlUpdateItemWriter.java @@ -42,7 +42,7 @@ import org.springframework.util.Assert; * {@link ItemPreparedStatementSetter}, which is responsible for mapping the * item to a PreparedStatement.
* - * It is expected that {@link #write(Object)} is called inside a transaction, + * It is expected that {@link #write(List)} is called inside a transaction, * and that {@link #flush()} is then subsequently called before the transaction * commits, or {@link #clear()} before it rolls back.
* @@ -158,7 +158,7 @@ public class BatchSqlUpdateItemWriter extends AbstractTransactionalResourceIt /** * No-op. */ - protected void doWrite(T item) { + protected void doWrite(List item) { } /** diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/HibernateAwareItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/HibernateAwareItemWriter.java index 8a41fc3ba..035ee6bd4 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/HibernateAwareItemWriter.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/HibernateAwareItemWriter.java @@ -15,6 +15,8 @@ */ package org.springframework.batch.item.database; +import java.util.List; + import org.hibernate.SessionFactory; import org.springframework.batch.item.ClearFailedException; import org.springframework.batch.item.ItemWriter; @@ -30,7 +32,7 @@ import org.springframework.util.Assert; * {@link ItemWriter} (the delegate). A delegate is required, and will be used * to do the actual writing of the item.
* - * It is expected that {@link #write(Object)} is called inside a transaction, + * It is expected that {@link #write(List)} is called inside a transaction, * and that {@link #flush()} is then subsequently called before the transaction * commits, or {@link #clear()} before it rolls back.
* @@ -114,7 +116,7 @@ public class HibernateAwareItemWriter extends AbstractTransactionalResourceIt return ITEMS_PROCESSED; } - protected void doWrite(T item) throws Exception { + protected void doWrite(List item) throws Exception { delegate.write(item); } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JpaAwareItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JpaAwareItemWriter.java index 8ecadd2ae..c89277ee3 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JpaAwareItemWriter.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JpaAwareItemWriter.java @@ -1,22 +1,24 @@ package org.springframework.batch.item.database; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.batch.item.ItemWriter; -import org.springframework.batch.item.ClearFailedException; -import org.springframework.util.Assert; -import org.springframework.orm.jpa.EntityManagerFactoryUtils; -import org.springframework.dao.DataAccessResourceFailureException; +import java.util.List; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; +import org.springframework.batch.item.ClearFailedException; +import org.springframework.batch.item.ItemWriter; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.dao.DataAccessResourceFailureException; +import org.springframework.orm.jpa.EntityManagerFactoryUtils; +import org.springframework.util.Assert; + /** * {@link org.springframework.batch.item.ItemWriter} that is aware of the JPA EntityManagerFactory and can * take some responsibilities to do with chunk boundaries away from a less smart * {@link org.springframework.batch.item.ItemWriter} (the delegate). A delegate is required, and will be used * to do the actual writing of the item.
* - * It is required that {@link #write(Object)} is called inside a transaction, + * It is required that {@link #write(List)} is called inside a transaction, * and that {@link #flush()} is then subsequently called before the transaction * commits, or {@link #clear()} before it rolls back.
* @@ -102,7 +104,7 @@ public class JpaAwareItemWriter extends AbstractTransactionalResourceItemWrit return ITEMS_PROCESSED; } - protected void doWrite(T item) throws Exception { + protected void doWrite(List item) throws Exception { delegate.write(item); } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/FlatFileItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/FlatFileItemWriter.java index 85dbc3908..3245333cc 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/FlatFileItemWriter.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/FlatFileItemWriter.java @@ -161,7 +161,7 @@ public class FlatFileItemWriter extends ExecutionContextUserSupport implement /** * Public setter for the header lines. These will be output at the head of - * the file before any calls to {@link #write(Object)} (and not on restart + * the file before any calls to {@link #write(List)} (and not on restart * unless the restart is after a failure before the first flush). * * @param headerLines the header lines to set @@ -179,17 +179,21 @@ public class FlatFileItemWriter extends ExecutionContextUserSupport implement * line (recursively calling this method for each value). If no converter is * supplied the input object's toString method will be used.
* - * @param item Object (a String or Object that can be converted) to be - * written to output stream + * @param items list of items to be written to output stream * @throws Exception if the transformer or file output fail, * WriterNotOpenException if the writer has not been initialized. */ - public void write(T item) throws Exception { - if (getOutputState().isInitialized()) { - lineBuffer.add(lineAggregator.aggregate(item) + lineSeparator); - } - else { - throw new WriterNotOpenException("Writer must be open before it can be written to"); + public void write(List items) throws Exception { + + for (T item : items) { + + if (getOutputState().isInitialized()) { + lineBuffer.add(lineAggregator.aggregate(item) + lineSeparator); + } + else { + 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/support/CompositeItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/CompositeItemWriter.java index 79592091b..6d75ae691 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/CompositeItemWriter.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/CompositeItemWriter.java @@ -1,5 +1,8 @@ package org.springframework.batch.item.support; +import java.util.Arrays; +import java.util.List; + import org.springframework.batch.item.ClearFailedException; import org.springframework.batch.item.FlushFailedException; import org.springframework.batch.item.ItemWriter; @@ -10,19 +13,20 @@ import org.springframework.batch.item.ItemWriter; * The implementation is thread-safe if all delegates are thread-safe. * * @author Robert Kasanicky + * @author Dave Syer */ public class CompositeItemWriter implements ItemWriter { - private ItemWriter[] delegates; + private List> delegates; public void setDelegates(ItemWriter[] delegates) { - this.delegates = delegates; + this.delegates = Arrays.asList(delegates); } /** * Calls injected ItemProcessors in order. */ - public void write(T item) throws Exception { + public void write(List item) throws Exception { for (ItemWriter writer : delegates) { writer.write(item); } @@ -35,7 +39,7 @@ public class CompositeItemWriter implements ItemWriter { } public void flush() throws FlushFailedException { - for (ItemWriter writer : delegates) { + for (ItemWriter writer : delegates) { writer.flush(); } } 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 8f1aee32f..a0ddfc537 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 @@ -9,7 +9,6 @@ import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.Arrays; -import java.util.Iterator; import java.util.List; import java.util.Map; @@ -231,7 +230,7 @@ public class StaxEventItemWriter extends ExecutionContextUserSupport implemen /** * Setter for the headers. This list will be marshalled and output before - * any calls to {@link #write(Object)}. + * any calls to {@link #write(List)}. * @param headers */ public void setHeaderItems(T[] headers) { @@ -271,9 +270,7 @@ public class StaxEventItemWriter extends ExecutionContextUserSupport implemen open(startAtPosition); if (startAtPosition == 0) { - for (Iterator iterator = headers.listIterator(); iterator.hasNext();) { - write(iterator.next()); - } + write(headers); } } @@ -407,10 +404,10 @@ public class StaxEventItemWriter extends ExecutionContextUserSupport implemen * @param item the value object * @see #flush() */ - public void write(T item) { + public void write(List item) { - currentRecordCount++; - buffer.add(item); + currentRecordCount+=item.size(); + buffer.addAll(item); } /** diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/callback/ItemReaderRepeatCallback.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/callback/ItemReaderRepeatCallback.java deleted file mode 100644 index d623cc250..000000000 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/repeat/callback/ItemReaderRepeatCallback.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2006-2007 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.repeat.callback; - -import org.springframework.batch.item.ItemReader; -import org.springframework.batch.item.ItemWriter; -import org.springframework.batch.repeat.ExitStatus; -import org.springframework.batch.repeat.RepeatCallback; -import org.springframework.batch.repeat.RepeatContext; - -/** - * Simple wrapper for two business interfaces: get the next item from a - * reader and apply the given writer to the result (if not null). - * - * @author Dave Syer - * - */ -public class ItemReaderRepeatCallback implements RepeatCallback { - - ItemReader reader; - - ItemWriter writer; - - public ItemReaderRepeatCallback(ItemReader reader, ItemWriter writer) { - super(); - this.reader = reader; - this.writer = writer; - } - - /** - * Default writer is null, in which case we do nothing - subclasses can - * extend this behaviour, but must be careful to actually exhaust the - * provider by calling next(). - * @param provider - */ - public ItemReaderRepeatCallback(ItemReader provider) { - this(provider, null); - } - - /** - * Use the writer to process the next item if there is one. Return the - * item processed, or null if nothing was available. - * @see org.springframework.batch.repeat.RepeatCallback#doInIteration(RepeatContext) - * @param context the current context. - * @return null if the data provider is exhausted. - */ - public ExitStatus doInIteration(RepeatContext context) throws Exception { - - ExitStatus result = ExitStatus.FINISHED; - T item = reader.read(); - - if (writer != null) { - if (item != null) { - writer.write(item); - result = ExitStatus.CONTINUABLE; - } - item = null; - } - - return result; - } - -} diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/adapter/ItemWriterAdapterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/adapter/ItemWriterAdapterTests.java index f2f4c9f8a..ccc68398e 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/adapter/ItemWriterAdapterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/adapter/ItemWriterAdapterTests.java @@ -1,17 +1,20 @@ package org.springframework.batch.item.adapter; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertSame; +import java.util.ArrayList; import java.util.List; +import org.junit.Test; +import org.junit.runner.RunWith; import org.springframework.batch.item.ItemWriter; import org.springframework.batch.item.sample.Foo; import org.springframework.batch.item.sample.FooService; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.ContextConfiguration; import org.springframework.beans.factory.annotation.Autowired; -import org.junit.runner.RunWith; -import org.junit.Test; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * Tests for {@link ItemWriterAdapter}. @@ -34,9 +37,11 @@ public class ItemWriterAdapterTests { @Test public void testProcess() throws Exception { Foo foo; + List foos = new ArrayList(); while ((foo = fooService.generateFoo()) != null) { - processor.write(foo); + foos.add(foo); } + processor.write(foos); List input = fooService.getGeneratedFoos(); List processed = fooService.getProcessedFoos(); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/adapter/PropertyExtractingDelegatingItemProccessorIntegrationTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/adapter/PropertyExtractingDelegatingItemProccessorIntegrationTests.java index 9e6b4fbbe..8551ef018 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/adapter/PropertyExtractingDelegatingItemProccessorIntegrationTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/adapter/PropertyExtractingDelegatingItemProccessorIntegrationTests.java @@ -4,6 +4,7 @@ import static org.junit.Assert.*; import org.junit.runner.RunWith; import org.junit.Test; +import java.util.Collections; import java.util.List; import org.springframework.batch.item.sample.Foo; @@ -34,7 +35,7 @@ public class PropertyExtractingDelegatingItemProccessorIntegrationTests { public void testProcess() throws Exception { Foo foo; while ((foo = fooService.generateFoo()) != null) { - processor.write(foo); + processor.write(Collections.singletonList(foo)); } List input = fooService.getGeneratedFoos(); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/BatchSqlUpdateItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/BatchSqlUpdateItemWriterTests.java index 3a64757b9..45dfa6bb0 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/BatchSqlUpdateItemWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/BatchSqlUpdateItemWriterTests.java @@ -109,12 +109,12 @@ public class BatchSqlUpdateItemWriterTests extends TestCase { /** * Test method for - * {@link org.springframework.batch.item.database.BatchSqlUpdateItemWriter#write(java.lang.Object)}. + * {@link org.springframework.batch.item.database.BatchSqlUpdateItemWriter#write(List)}. * @throws Exception */ public void testWrite() throws Exception { writer.setSql("foo"); - writer.write("bar"); + writer.write(Collections.singletonList("bar")); // Nothing happens till we flush assertEquals(0, list.size()); } @@ -157,7 +157,7 @@ public class BatchSqlUpdateItemWriterTests extends TestCase { expectLastCall().times(2); expect(ps.executeBatch()).andReturn(new int[] { 123 }); replay(ps); - writer.write("bar"); + writer.write(Collections.singletonList("bar")); writer.flush(); assertFalse(TransactionSynchronizationManager.hasResource(writer.getResourceKey())); assertEquals(3, list.size()); @@ -175,7 +175,7 @@ public class BatchSqlUpdateItemWriterTests extends TestCase { expectLastCall().times(2); expect(ps.executeBatch()).andReturn(new int[] {0}); replay(ps); - writer.write("bar"); + writer.write(Collections.singletonList("bar")); try { writer.flush(); fail("Expected EmptyResultDataAccessException"); @@ -201,7 +201,7 @@ public class BatchSqlUpdateItemWriterTests extends TestCase { expectLastCall().times(1); expect(ps.executeBatch()).andReturn(new int[] {123}); replay(ps); - writer.write("foo"); + writer.write(Collections.singletonList("foo")); try { writer.flush(); fail("Expected RuntimeException"); @@ -216,7 +216,7 @@ public class BatchSqlUpdateItemWriterTests extends TestCase { list.add(item); } }); - writer.write("foo"); + writer.write(Collections.singletonList("foo")); writer.flush(); verify(ps); assertEquals(4, list.size()); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateAwareItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateAwareItemWriterTests.java index b274b1b9c..1987efe00 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateAwareItemWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/HibernateAwareItemWriterTests.java @@ -16,6 +16,7 @@ package org.springframework.batch.item.database; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import junit.framework.TestCase; @@ -45,8 +46,8 @@ public class HibernateAwareItemWriterTests extends TestCase { } private class StubItemWriter implements ItemWriter { - public void write(Object item) { - list.add(item); + public void write(List items) { + list.addAll(items); } public void clear() throws ClearFailedException { @@ -116,21 +117,12 @@ public class HibernateAwareItemWriterTests extends TestCase { writer.afterPropertiesSet(); } - /** - * Test method for - * {@link org.springframework.batch.item.database.HibernateAwareItemWriter#write(java.lang.Object)}. - * @throws Exception - */ public void testWrite() throws Exception { - writer.write("foo"); + writer.write(Collections.singletonList("foo")); assertEquals(1, list.size()); assertTrue(list.contains("foo")); } - /** - * Test method for - * {@link org.springframework.batch.item.database.HibernateAwareItemWriter#write(java.lang.Object)}. - */ public void testFlushWithFailure() throws Exception{ final RuntimeException ex = new RuntimeException("bar"); writer.setHibernateTemplate(new HibernateTemplate() { @@ -146,11 +138,6 @@ public class HibernateAwareItemWriterTests extends TestCase { } } - /** - * Test method for - * {@link org.springframework.batch.item.database.HibernateAwareItemWriter#write(java.lang.Object)}. - * @throws Exception - */ public void testWriteAndFlushWithFailure() throws Exception { final RuntimeException ex = new RuntimeException("bar"); writer.setHibernateTemplate(new HibernateTemplateWrapper() { @@ -158,7 +145,7 @@ public class HibernateAwareItemWriterTests extends TestCase { throw ex; } }); - writer.write("foo"); + writer.write(Collections.singletonList("foo")); try { writer.flush(); fail("Expected RuntimeException"); @@ -173,11 +160,10 @@ public class HibernateAwareItemWriterTests extends TestCase { list.add("flush"); } }); - writer.write("foo"); + writer.write(Collections.singletonList("foo")); assertEquals(6, list.size()); assertTrue(list.contains("flush")); assertTrue(list.contains("clear")); - assertTrue(list.contains("delegateFlush")); assertTrue(context.isCompleteOnly()); } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JpaAwareItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JpaAwareItemWriterTests.java index cb89c162b..324d2062c 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JpaAwareItemWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JpaAwareItemWriterTests.java @@ -27,6 +27,8 @@ import org.springframework.transaction.support.TransactionSynchronizationManager import javax.persistence.EntityManagerFactory; import javax.persistence.EntityManager; + +import java.util.Collections; import java.util.List; import java.util.ArrayList; @@ -80,9 +82,9 @@ public class JpaAwareItemWriterTests { @Test public void testWrite() throws Exception { - delegate.write("foo"); + delegate.write(Collections.singletonList("foo")); replay(delegate); - writer.write("foo"); + writer.write(Collections.singletonList("foo")); verify(delegate); } @@ -119,13 +121,13 @@ public class JpaAwareItemWriterTests { replay(em); replay(emf); TransactionSynchronizationManager.bindResource(emf, new EntityManagerHolder(em)); - delegate.write("foo"); + delegate.write(Collections.singletonList("foo")); delegate.flush(); - delegate.write("spam"); + delegate.write(Collections.singletonList("spam")); delegate.flush(); replay(delegate); - writer.write("foo"); + writer.write(Collections.singletonList("foo")); try { writer.flush(); fail("Expected RuntimeException"); @@ -133,7 +135,7 @@ public class JpaAwareItemWriterTests { assertEquals("bar", e.getMessage()); } - writer.write("spam"); + writer.write(Collections.singletonList("spam")); writer.flush(); verify(delegate); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/FlatFileItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/FlatFileItemWriterTests.java index 0a4b98a76..00b23e7fc 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/FlatFileItemWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/FlatFileItemWriterTests.java @@ -21,6 +21,8 @@ import java.io.File; import java.io.FileReader; import java.io.IOException; import java.nio.charset.UnsupportedCharsetException; +import java.util.Arrays; +import java.util.Collections; import junit.framework.TestCase; @@ -106,10 +108,10 @@ public class FlatFileItemWriterTests extends TestCase { public void testWriteWithMultipleOpen() throws Exception { writer.open(executionContext); - writer.write("test1"); + writer.write(Collections.singletonList("test1")); writer.flush(); writer.open(executionContext); - writer.write("test2"); + writer.write(Collections.singletonList("test2")); writer.flush(); assertEquals("test1", readLine()); assertEquals("test2", readLine()); @@ -128,7 +130,7 @@ public class FlatFileItemWriterTests extends TestCase { */ public void testWriteString() throws Exception { writer.open(executionContext); - writer.write(TEST_STRING); + writer.write(Collections.singletonList(TEST_STRING)); writer.flush(); writer.close(null); String lineFromFile = readLine(); @@ -149,7 +151,7 @@ public class FlatFileItemWriterTests extends TestCase { }); String data = "string"; writer.open(executionContext); - writer.write(data); + writer.write(Collections.singletonList(data)); writer.flush(); String lineFromFile = readLine(); // converter not used if input is String @@ -168,7 +170,7 @@ public class FlatFileItemWriterTests extends TestCase { } }); writer.open(executionContext); - writer.write(TEST_STRING); + writer.write(Collections.singletonList(TEST_STRING)); writer.flush(); String lineFromFile = readLine(); assertEquals("FOO:" + TEST_STRING, lineFromFile); @@ -180,19 +182,17 @@ public class FlatFileItemWriterTests extends TestCase { * @throws Exception */ public void testWriteRecord() throws Exception { - String args = "1"; writer.open(executionContext); - writer.write(args); + writer.write(Collections.singletonList("1")); writer.flush(); String lineFromFile = readLine(); - assertEquals(args, lineFromFile); + assertEquals("1", lineFromFile); } public void testWriteRecordWithrecordSeparator() throws Exception { writer.setLineSeparator("|"); writer.open(executionContext); - writer.write("1"); - writer.write("2"); + writer.write(Arrays.asList(new String[] { "1", "2" })); writer.flush(); String lineFromFile = readLine(); assertEquals("1|2|", lineFromFile); @@ -200,7 +200,7 @@ public class FlatFileItemWriterTests extends TestCase { public void testRollback() throws Exception { writer.open(executionContext); - writer.write("testLine1"); + writer.write(Collections.singletonList("testLine1")); // rollback rollback(); writer.flush(); @@ -211,7 +211,7 @@ public class FlatFileItemWriterTests extends TestCase { public void testCommit() throws Exception { writer.open(executionContext); - writer.write("testLine1"); + writer.write(Collections.singletonList("testLine1")); // rollback commit(); writer.close(null); @@ -224,22 +224,19 @@ public class FlatFileItemWriterTests extends TestCase { writer.open(executionContext); // write some lines - writer.write("testLine1"); - writer.write("testLine2"); - writer.write("testLine3"); + writer.write(Arrays.asList(new String[] { "testLine1", "testLine2", "testLine3" })); // commit commit(); // this will be rolled back... - writer.write("this will be rolled back"); + writer.write(Collections.singletonList("this will be rolled back")); // rollback rollback(); // write more lines - writer.write("testLine4"); - writer.write("testLine5"); + writer.write(Arrays.asList(new String[] {"testLine4", "testLine5"})); // commit commit(); @@ -253,9 +250,7 @@ public class FlatFileItemWriterTests extends TestCase { writer.open(executionContext); // write more lines - writer.write("testLine6"); - writer.write("testLine7"); - writer.write("testLine8"); + writer.write(Arrays.asList(new String[] {"testLine6","testLine7","testLine8"})); commit(); @@ -344,7 +339,7 @@ public class FlatFileItemWriterTests extends TestCase { testWriteStringWithBogusEncoding(); writer.setEncoding("UTF-8"); writer.open(executionContext); - writer.write(TEST_STRING); + writer.write(Collections.singletonList(TEST_STRING)); writer.flush(); String lineFromFile = readLine(); @@ -354,7 +349,7 @@ public class FlatFileItemWriterTests extends TestCase { public void testWriteHeader() throws Exception { writer.setHeaderLines(new String[] { "a", "b" }); writer.open(executionContext); - writer.write(TEST_STRING); + writer.write(Collections.singletonList(TEST_STRING)); writer.flush(); writer.close(null); String lineFromFile = readLine(); @@ -368,11 +363,11 @@ public class FlatFileItemWriterTests extends TestCase { public void testWriteHeaderAfterRestartOnFirstChunk() throws Exception { writer.setHeaderLines(new String[] { "a", "b" }); writer.open(executionContext); - writer.write(TEST_STRING); + writer.write(Collections.singletonList(TEST_STRING)); writer.clear(); writer.close(executionContext); writer.open(executionContext); - writer.write(TEST_STRING); + writer.write(Collections.singletonList(TEST_STRING)); writer.flush(); writer.close(executionContext); String lineFromFile = readLine(); @@ -388,10 +383,10 @@ public class FlatFileItemWriterTests extends TestCase { public void testWriteHeaderAfterRestartOnSecondChunk() throws Exception { writer.setHeaderLines(new String[] { "a", "b" }); writer.open(executionContext); - writer.write(TEST_STRING); + writer.write(Collections.singletonList(TEST_STRING)); writer.flush(); writer.update(executionContext); - writer.write(TEST_STRING); + writer.write(Collections.singletonList(TEST_STRING)); writer.clear(); writer.close(executionContext); String lineFromFile = readLine(); @@ -401,7 +396,7 @@ public class FlatFileItemWriterTests extends TestCase { lineFromFile = readLine(); assertEquals(TEST_STRING, lineFromFile); writer.open(executionContext); - writer.write(TEST_STRING); + writer.write(Collections.singletonList(TEST_STRING)); writer.flush(); writer.close(executionContext); reader = null; diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/CompositeItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/CompositeItemWriterTests.java index 4e30a7d0f..db6d874e1 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/CompositeItemWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/CompositeItemWriterTests.java @@ -4,6 +4,10 @@ import static org.easymock.EasyMock.createStrictMock; import static org.easymock.EasyMock.expectLastCall; import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.verify; + +import java.util.Collections; +import java.util.List; + import junit.framework.TestCase; import org.springframework.batch.item.ItemWriter; @@ -26,7 +30,7 @@ public class CompositeItemWriterTests extends TestCase { public void testProcess() throws Exception { final int NUMBER_OF_WRITERS = 10; - Object data = new Object(); + List data = Collections.singletonList(new Object()); @SuppressWarnings("unchecked") ItemWriter[] writers = new ItemWriter[NUMBER_OF_WRITERS]; 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 035946f3f..09ed87032 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 @@ -11,7 +11,10 @@ import static org.junit.Assert.fail; import java.io.File; import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; +import java.util.List; import javax.xml.stream.XMLEventFactory; import javax.xml.stream.XMLStreamException; @@ -50,6 +53,8 @@ public class StaxEventItemWriterTests { } }; + private List items = Collections.singletonList(item); + private static final String TEST_STRING = ""; @@ -73,7 +78,7 @@ public class StaxEventItemWriterTests { writer.setSerializer(serializer); // see asserts in the marshaller - writer.write(item); + writer.write(items); assertFalse(marshaller.wasCalled); writer.flush(); @@ -84,8 +89,7 @@ public class StaxEventItemWriterTests { @Test public void testClear() throws Exception { writer.open(executionContext); - writer.write(item); - writer.write(item); + writer.write(Arrays.asList(new Object[] {item, item})); writer.clear(); // writer.write(item); writer.flush(); @@ -98,7 +102,7 @@ public class StaxEventItemWriterTests { @Test public void testRollback() throws Exception { writer.open(executionContext); - writer.write(item); + writer.write(items); // rollback writer.clear(); assertFalse(outputFileContent().contains(TEST_STRING)); @@ -110,7 +114,7 @@ public class StaxEventItemWriterTests { @Test public void testWriteAndFlush() throws Exception { writer.open(executionContext); - writer.write(item); + writer.write(items); String content = outputFileContent(); assertFalse(content.contains(TEST_STRING)); writer.flush(); @@ -125,7 +129,7 @@ public class StaxEventItemWriterTests { public void testRestart() throws Exception { writer.open(executionContext); // write item - writer.write(item); + writer.write(items); writer.flush(); writer.update(executionContext); writer.close(executionContext); @@ -133,7 +137,7 @@ public class StaxEventItemWriterTests { // create new writer from saved restart data and continue writing writer = createItemWriter(); writer.open(executionContext); - writer.write(item); + writer.write(items); writer.close(executionContext); // check the output is concatenation of 'before restart' and 'after @@ -158,7 +162,7 @@ public class StaxEventItemWriterTests { Object header2 = new Object(); writer.setHeaderItems(new Object[] {header1, header2}); writer.open(executionContext); - writer.write(item); + writer.write(items); writer.flush(); String content = outputFileContent(); assertTrue("Wrong content: "+content, contains(content, "")); @@ -174,10 +178,10 @@ public class StaxEventItemWriterTests { Object header = new Object(); writer.setHeaderItems(new Object[] {header}); writer.open(executionContext); - writer.write(item); + writer.write(items); writer.clear(); writer.open(executionContext); - writer.write(item); + writer.write(items); writer.flush(); String content = outputFileContent(); assertEquals("Wrong content: "+content, 1, countContains(content, "")); @@ -192,12 +196,12 @@ public class StaxEventItemWriterTests { Object header = new Object(); writer.setHeaderItems(new Object[] {header}); writer.open(executionContext); - writer.write(item); + writer.write(items); writer.flush(); writer.update(executionContext); writer.close(executionContext); writer.open(executionContext); - writer.write(item); + writer.write(items); writer.clear(); writer.flush(); String content = outputFileContent(); @@ -212,8 +216,10 @@ public class StaxEventItemWriterTests { public void testStreamContext() throws Exception { writer.open(executionContext); final int NUMBER_OF_RECORDS = 10; + assertFalse(executionContext.containsKey(ClassUtils.getShortName(StaxEventItemWriter.class) + + ".record.count")); for (int i = 1; i <= NUMBER_OF_RECORDS; i++) { - writer.write(item); + writer.write(items); writer.update(executionContext); long writeStatistics = executionContext.getLong(ClassUtils.getShortName(StaxEventItemWriter.class) + ".record.count"); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/callback/ItemReaderRepeatCallbackTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/callback/ItemReaderRepeatCallbackTests.java deleted file mode 100644 index ffd281b91..000000000 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/callback/ItemReaderRepeatCallbackTests.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2006-2007 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.repeat.callback; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import junit.framework.TestCase; - -import org.springframework.batch.item.support.AbstractItemWriter; -import org.springframework.batch.item.support.ListItemReader; - -public class ItemReaderRepeatCallbackTests extends TestCase { - - ItemReaderRepeatCallback callback; - - List list = new ArrayList(); - - public void testDoWithRepeat() throws Exception { - callback = new ItemReaderRepeatCallback(new ListItemReader(Arrays.asList(new String[] { "foo", "bar" })), - new AbstractItemWriter() { - public void write(String data) { - list.add(data); - } - }); - callback.doInIteration(null); - assertEquals(1, list.size()); - assertEquals("foo", list.get(0)); - } - - public void testDoWithRepeatNullProcessor() throws Exception { - ListItemReader provider = new ListItemReader(Arrays.asList(new String[] { "foo", "bar" })); - callback = new ItemReaderRepeatCallback(provider); - callback.doInIteration(null); - assertEquals(0, list.size()); - assertEquals("bar", provider.read()); - } - -} diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/AbstractTradeBatchTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/AbstractTradeBatchTests.java index 57fadb9f3..6484c756e 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/AbstractTradeBatchTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/AbstractTradeBatchTests.java @@ -16,6 +16,8 @@ package org.springframework.batch.repeat.support; +import java.util.List; + import junit.framework.TestCase; import org.springframework.batch.item.ExecutionContext; @@ -70,7 +72,7 @@ public abstract class AbstractTradeBatchTests extends TestCase { // This has to be synchronized because we are going to test the state // (count) at the end of a concurrent batch run. - public synchronized void write(Trade data) { + public synchronized void write(List data) { count++; System.out.println("Executing trade '" + data + "'"); } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/AsynchronousRepeatTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/AsynchronousRepeatTests.java index 8386b7a36..7affd43f8 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/AsynchronousRepeatTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/AsynchronousRepeatTests.java @@ -16,13 +16,13 @@ package org.springframework.batch.repeat.support; +import java.util.Collections; import java.util.HashSet; import java.util.Set; import org.springframework.batch.repeat.ExitStatus; import org.springframework.batch.repeat.RepeatCallback; import org.springframework.batch.repeat.RepeatContext; -import org.springframework.batch.repeat.callback.ItemReaderRepeatCallback; import org.springframework.core.task.SimpleAsyncTaskExecutor; public class AsynchronousRepeatTests extends AbstractTradeBatchTests { @@ -48,7 +48,7 @@ public class AsynchronousRepeatTests extends AbstractTradeBatchTests { Thread.sleep(100); Trade item = provider.read(); if (item!=null) { - processor.write(item); + processor.write(Collections.singletonList(item)); } return new ExitStatus(item!=null); } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/ChunkedRepeatTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/ChunkedRepeatTests.java index 923064dd8..288c67eb1 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/ChunkedRepeatTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/ChunkedRepeatTests.java @@ -21,7 +21,6 @@ import org.springframework.batch.item.support.AbstractItemReader; import org.springframework.batch.repeat.ExitStatus; import org.springframework.batch.repeat.RepeatCallback; import org.springframework.batch.repeat.RepeatContext; -import org.springframework.batch.repeat.callback.ItemReaderRepeatCallback; import org.springframework.batch.repeat.callback.NestedRepeatCallback; import org.springframework.batch.repeat.policy.SimpleCompletionPolicy; import org.springframework.core.task.SimpleAsyncTaskExecutor; diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/SimpleRepeatTemplateTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/SimpleRepeatTemplateTests.java index 72c970d0a..4ec5d2514 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/SimpleRepeatTemplateTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/repeat/support/SimpleRepeatTemplateTests.java @@ -24,7 +24,6 @@ import org.springframework.batch.repeat.RepeatCallback; import org.springframework.batch.repeat.RepeatContext; import org.springframework.batch.repeat.RepeatException; import org.springframework.batch.repeat.RepeatListener; -import org.springframework.batch.repeat.callback.ItemReaderRepeatCallback; import org.springframework.batch.repeat.callback.NestedRepeatCallback; import org.springframework.batch.repeat.context.RepeatContextSupport; import org.springframework.batch.repeat.exception.ExceptionHandler;