From d4d35cd6683b2ffc12b22c7f281c963e86a313b2 Mon Sep 17 00:00:00 2001 From: dsyer Date: Mon, 11 Aug 2008 08:48:41 +0000 Subject: [PATCH] OPEN - issue BATCH-770: Make ItemTransformer a first class citizen and rename as ItemProcessor Done first pass. Some tests needed. --- .../step/item/AbstractStepFactoryBean.java | 45 ++++-- .../step/item/ItemOrientedStepHandler.java | 150 ++++++++++++++++++ .../item/RepeatOperationsStepFactoryBean.java | 2 +- .../core/step/item/SimpleItemHandler.java | 117 +------------- .../core/step/item/SimpleStepFactoryBean.java | 2 +- .../step/item/SkipLimitStepFactoryBean.java | 13 +- .../ItemOrientedStepIntegrationTests.java | 33 ++-- .../RepeatOperationsStepFactoryBeanTests.java | 2 +- .../step/item/SimpleStepFactoryBeanTests.java | 26 +-- .../item/SkipLimitStepFactoryBeanTests.java | 2 +- .../StatefulRetryStepFactoryBeanTests.java | 2 +- .../item/StepExecutorInterruptionTests.java | 4 +- .../batch/item/ItemProcessor.java | 13 ++ .../CompositeItemProcessor.java} | 19 +-- .../support/PassthroughItemProcessor.java | 13 ++ .../batch/item/transform/ItemTransformer.java | 11 -- .../transform/ItemTransformerItemWriter.java | 36 ----- .../batch/item/transform/package.html | 7 - .../CompositeItemProcessorTests.java} | 30 ++-- ...mTransformerItemWriterFunctionalTests.java | 113 ------------- .../ItemTransformerItemWriterTests.java | 68 -------- .../file/FileToMessagesJobFactoryBean.java | 10 +- ...hunkMessageItemWriterIntegrationTests.java | 4 +- ...org.springframework.ide.eclipse.core.prefs | 67 ++++++++ ...erTransformer.java => OrderProcessor.java} | 9 +- .../main/resources/jobs/multilineOrderJob.xml | 63 +++----- .../order/FlatFileOrderAggregatorTests.java | 6 +- 27 files changed, 394 insertions(+), 473 deletions(-) create mode 100644 spring-batch-core/src/main/java/org/springframework/batch/core/step/item/ItemOrientedStepHandler.java create mode 100644 spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemProcessor.java rename spring-batch-infrastructure/src/main/java/org/springframework/batch/item/{transform/CompositeItemTransformer.java => support/CompositeItemProcessor.java} (57%) create mode 100644 spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/PassthroughItemProcessor.java delete mode 100644 spring-batch-infrastructure/src/main/java/org/springframework/batch/item/transform/ItemTransformer.java delete mode 100644 spring-batch-infrastructure/src/main/java/org/springframework/batch/item/transform/ItemTransformerItemWriter.java delete mode 100644 spring-batch-infrastructure/src/main/java/org/springframework/batch/item/transform/package.html rename spring-batch-infrastructure/src/test/java/org/springframework/batch/item/{transform/CompositeItemTransformerTests.java => support/CompositeItemProcessorTests.java} (60%) delete mode 100644 spring-batch-infrastructure/src/test/java/org/springframework/batch/item/transform/ItemTransformerItemWriterFunctionalTests.java delete mode 100644 spring-batch-infrastructure/src/test/java/org/springframework/batch/item/transform/ItemTransformerItemWriterTests.java create mode 100644 spring-batch-samples/.settings/org.springframework.ide.eclipse.core.prefs rename spring-batch-samples/src/main/java/org/springframework/batch/sample/domain/order/internal/{OrderTransformer.java => OrderProcessor.java} (93%) diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/AbstractStepFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/AbstractStepFactoryBean.java index 7f2cde993..63c22f1a5 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/AbstractStepFactoryBean.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/AbstractStepFactoryBean.java @@ -19,6 +19,7 @@ import org.springframework.batch.core.Step; import org.springframework.batch.core.StepExecutionListener; import org.springframework.batch.core.StepListener; import org.springframework.batch.core.repository.JobRepository; +import org.springframework.batch.item.ItemProcessor; import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.ItemStream; import org.springframework.batch.item.ItemWriter; @@ -42,7 +43,7 @@ import org.springframework.util.Assert; * @author Dave Syer * */ -public abstract class AbstractStepFactoryBean implements FactoryBean, BeanNameAware { +public abstract class AbstractStepFactoryBean implements FactoryBean, BeanNameAware { private String name; @@ -52,7 +53,7 @@ public abstract class AbstractStepFactoryBean implements FactoryBean, BeanNam private ItemReader itemReader; - private ItemWriter itemWriter; + private ItemWriter itemWriter; private PlatformTransactionManager transactionManager; @@ -68,6 +69,11 @@ public abstract class AbstractStepFactoryBean implements FactoryBean, BeanNam private StepListener[] listeners = new StepListener[0]; + private ItemProcessor itemProcessor = new ItemProcessor() { + @SuppressWarnings("unchecked") + public S process(T item) throws Exception {return (S)item;} + }; + /** * */ @@ -121,10 +127,17 @@ public abstract class AbstractStepFactoryBean implements FactoryBean, BeanNam /** * @param itemWriter the itemWriter to set */ - public void setItemWriter(ItemWriter itemWriter) { + public void setItemWriter(ItemWriter itemWriter) { this.itemWriter = itemWriter; } + /** + * @param itemProcessor the itemProcessor to set + */ + public void setItemProcessor(ItemProcessor itemProcessor) { + this.itemProcessor = itemProcessor; + } + /** * The streams to inject into the {@link Step}. Any instance of * {@link ItemStream} can be used, and will then receive callbacks at the @@ -167,10 +180,18 @@ public abstract class AbstractStepFactoryBean implements FactoryBean, BeanNam * Protected getter for the {@link ItemWriter} for subclasses to use * @return the itemWriter */ - protected ItemWriter getItemWriter() { + protected ItemWriter getItemWriter() { return itemWriter; } + /** + * Protected getter for the {@link ItemProcessor} for subclasses to use + * @return the itemProcessor + */ + protected ItemProcessor getItemProcessor() { + return itemProcessor; + } + /** * Public setter for {@link JobRepository}. * @@ -198,7 +219,8 @@ public abstract class AbstractStepFactoryBean implements FactoryBean, BeanNam } /** - * Protected getter for the {@link TransactionAttribute} for subclasses only. + * Protected getter for the {@link TransactionAttribute} for subclasses + * only. * @return the transactionAttribute */ protected TransactionAttribute getTransactionAttribute() { @@ -227,7 +249,6 @@ public abstract class AbstractStepFactoryBean implements FactoryBean, BeanNam Assert.notNull(transactionManager, "TransactionManager must be provided"); jobRepositoryValidator.validate(jobRepository); - step.setItemHandler(new SimpleItemHandler(itemReader, itemWriter)); step.setTransactionManager(transactionManager); if (transactionAttribute!=null) { step.setTransactionAttribute(transactionAttribute); @@ -239,7 +260,8 @@ public abstract class AbstractStepFactoryBean implements FactoryBean, BeanNam step.setStreams(streams); ItemReader itemReader = getItemReader(); - ItemWriter itemWriter = getItemWriter(); + ItemWriter itemWriter = getItemWriter(); + ItemProcessor itemProcessor = getItemProcessor(); // Since we are going to wrap these things with listener callbacks we // need to register them here because the step will not know we did @@ -250,6 +272,12 @@ public abstract class AbstractStepFactoryBean implements FactoryBean, BeanNam if (itemReader instanceof StepExecutionListener) { step.registerStepExecutionListener((StepExecutionListener) itemReader); } + if (itemProcessor instanceof ItemStream) { + step.registerStream((ItemStream) itemProcessor); + } + if (itemProcessor instanceof StepExecutionListener) { + step.registerStepExecutionListener((StepExecutionListener) itemProcessor); + } if (itemWriter instanceof ItemStream) { step.registerStream((ItemStream) itemWriter); } @@ -266,8 +294,7 @@ public abstract class AbstractStepFactoryBean implements FactoryBean, BeanNam setItemWriter(itemWriter); step.setStepExecutionListeners(stepListeners); - //TODO: Why is setItemHandler called twice? - step.setItemHandler(new SimpleItemHandler(itemReader, itemWriter)); + step.setItemHandler(new ItemOrientedStepHandler(itemReader, itemProcessor, itemWriter)); } 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 new file mode 100644 index 000000000..dc1c58209 --- /dev/null +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/ItemOrientedStepHandler.java @@ -0,0 +1,150 @@ +/* + * 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.core.step.item; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.batch.core.StepContribution; +import org.springframework.batch.item.ClearFailedException; +import org.springframework.batch.item.FlushFailedException; +import org.springframework.batch.item.ItemProcessor; +import org.springframework.batch.item.ItemReader; +import org.springframework.batch.item.ItemWriter; +import org.springframework.batch.item.MarkFailedException; +import org.springframework.batch.item.ResetFailedException; +import org.springframework.batch.repeat.ExitStatus; + +/** + * Simplest possible implementation of {@link ItemHandler} with no skipping or + * recovering. Just delegates all calls to the provided {@link ItemReader} and + * {@link ItemWriter}. + * + * Provides extension points by protected {@link #read(StepContribution)} and + * {@link #write(Object, StepContribution)} methods that can be overriden to + * provide more sophisticated behavior (e.g. skipping). + * + * @author Dave Syer + * @author Robert Kasanicky + */ +public class ItemOrientedStepHandler implements ItemHandler { + + protected final Log logger = LogFactory.getLog(getClass()); + + private ItemReader itemReader; + + private ItemProcessor itemProcessor; + + private ItemWriter itemWriter; + + /** + * @param itemReader + * @param itemProcessor + * @param itemWriter + */ + public ItemOrientedStepHandler(ItemReader itemReader, ItemProcessor itemProcessor, + ItemWriter itemWriter) { + super(); + this.itemReader = itemReader; + this.itemProcessor = itemProcessor; + this.itemWriter = itemWriter; + } + + /** + * Get the next item from {@link #read(StepContribution)} and if not null + * pass the item to {@link #write(Object, StepContribution)}. + * + * @see org.springframework.batch.core.step.item.ItemHandler#handle(org.springframework.batch.core.StepContribution) + */ + public ExitStatus handle(StepContribution contribution) throws Exception { + T item = read(contribution); + if (item == null) { + return ExitStatus.FINISHED; + } + contribution.incrementItemCount(); + write(item, contribution); + return ExitStatus.CONTINUABLE; + } + + /** + * @param contribution current context + * @return next item for writing + */ + protected T read(StepContribution contribution) throws Exception { + return doRead(); + } + + /** + * @return item + * @throws Exception + */ + protected final T doRead() throws Exception { + return itemReader.read(); + } + + /** + * + * @param item the item to write + * @param contribution current context + */ + protected void write(T item, StepContribution contribution) throws Exception { + doWrite(item); + } + + /** + * @param item + * @throws Exception + */ + protected final void doWrite(T item) throws Exception { + S processed = itemProcessor.process(item); + if (processed != null) { + // TODO: increment filtered item count + itemWriter.write(processed); + } + } + + /** + * @throws MarkFailedException + * @see org.springframework.batch.item.ItemReader#mark() + */ + public void mark() throws MarkFailedException { + itemReader.mark(); + } + + /** + * @throws ResetFailedException + * @see org.springframework.batch.item.ItemReader#reset() + */ + public void reset() throws ResetFailedException { + itemReader.reset(); + } + + /** + * @throws ClearFailedException + * @see org.springframework.batch.item.ItemWriter#clear() + */ + public void clear() throws ClearFailedException { + itemWriter.clear(); + } + + /** + * @throws FlushFailedException + * @see org.springframework.batch.item.ItemWriter#flush() + */ + public void flush() throws FlushFailedException { + itemWriter.flush(); + } + +} diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/RepeatOperationsStepFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/RepeatOperationsStepFactoryBean.java index 559e01556..d2100db7f 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/RepeatOperationsStepFactoryBean.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/RepeatOperationsStepFactoryBean.java @@ -27,7 +27,7 @@ import org.springframework.batch.repeat.support.RepeatTemplate; * @author Dave Syer * */ -public class RepeatOperationsStepFactoryBean extends AbstractStepFactoryBean { +public class RepeatOperationsStepFactoryBean extends AbstractStepFactoryBean { private RepeatOperations chunkOperations = new RepeatTemplate(); diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SimpleItemHandler.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SimpleItemHandler.java index 5f16c69f3..8fef7f62b 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SimpleItemHandler.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SimpleItemHandler.java @@ -15,126 +15,25 @@ */ package org.springframework.batch.core.step.item; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.batch.core.StepContribution; -import org.springframework.batch.item.ClearFailedException; -import org.springframework.batch.item.FlushFailedException; import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.ItemWriter; -import org.springframework.batch.item.MarkFailedException; -import org.springframework.batch.item.ResetFailedException; -import org.springframework.batch.repeat.ExitStatus; +import org.springframework.batch.item.support.PassthroughItemProcessor; /** * Simplest possible implementation of {@link ItemHandler} with no skipping or - * recovering. Just delegates all calls to the provided {@link ItemReader} and - * {@link ItemWriter}. - * - * Provides extension points by protected {@link #read(StepContribution)} and - * {@link #write(Object, StepContribution)} methods that can be overriden to - * provide more sophisticated behavior (e.g. skipping). + * recovering or processing. Just delegates all calls to the provided + * {@link ItemReader} and {@link ItemWriter}. * * @author Dave Syer - * @author Robert Kasanicky */ -public class SimpleItemHandler implements ItemHandler { - - protected final Log logger = LogFactory.getLog(getClass()); - - private ItemReader itemReader; - - private ItemWriter itemWriter; +public class SimpleItemHandler extends ItemOrientedStepHandler { /** - * @param itemReader - * @param itemWriter + * Creates a {@link PassthroughItemProcessor} and uses it to create an + * instance of {@link ItemOrientedStepHandler}. */ - public SimpleItemHandler(ItemReader itemReader, ItemWriter itemWriter) { - super(); - this.itemReader = itemReader; - this.itemWriter = itemWriter; - } - - /** - * Get the next item from {@link #read(StepContribution)} and if not null - * pass the item to {@link #write(Object, StepContribution)}. - * - * @see org.springframework.batch.core.step.item.ItemHandler#handle(org.springframework.batch.core.StepContribution) - */ - public ExitStatus handle(StepContribution contribution) throws Exception { - T item = read(contribution); - if (item == null) { - return ExitStatus.FINISHED; - } - contribution.incrementItemCount(); - write(item, contribution); - return ExitStatus.CONTINUABLE; - } - - /** - * @param contribution current context - * @return next item for writing - */ - protected T read(StepContribution contribution) throws Exception { - return doRead(); - } - - /** - * @return item - * @throws Exception - */ - protected final T doRead() throws Exception { - return itemReader.read(); - } - - /** - * - * @param item the item to write - * @param contribution current context - */ - protected void write(T item, StepContribution contribution) throws Exception { - doWrite(item); - } - - /** - * @param item - * @throws Exception - */ - protected final void doWrite(T item) throws Exception { - itemWriter.write(item); - } - - /** - * @throws MarkFailedException - * @see org.springframework.batch.item.ItemReader#mark() - */ - public void mark() throws MarkFailedException { - itemReader.mark(); - } - - /** - * @throws ResetFailedException - * @see org.springframework.batch.item.ItemReader#reset() - */ - public void reset() throws ResetFailedException { - itemReader.reset(); - } - - /** - * @throws ClearFailedException - * @see org.springframework.batch.item.ItemWriter#clear() - */ - public void clear() throws ClearFailedException { - itemWriter.clear(); - } - - /** - * @throws FlushFailedException - * @see org.springframework.batch.item.ItemWriter#flush() - */ - public void flush() throws FlushFailedException { - itemWriter.flush(); + public SimpleItemHandler(ItemReader itemReader, ItemWriter itemWriter) { + super(itemReader, new PassthroughItemProcessor(), itemWriter); } } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SimpleStepFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SimpleStepFactoryBean.java index 8d449434c..cdf7e7292 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SimpleStepFactoryBean.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SimpleStepFactoryBean.java @@ -39,7 +39,7 @@ import org.springframework.util.Assert; * @author Dave Syer * */ -public class SimpleStepFactoryBean extends AbstractStepFactoryBean { +public class SimpleStepFactoryBean extends AbstractStepFactoryBean { protected final Log logger = LogFactory.getLog(getClass()); diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SkipLimitStepFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SkipLimitStepFactoryBean.java index fa8804b12..343fd7c9d 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SkipLimitStepFactoryBean.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SkipLimitStepFactoryBean.java @@ -13,6 +13,7 @@ import org.springframework.batch.core.step.skip.LimitCheckingItemSkipPolicy; import org.springframework.batch.core.step.skip.SkipLimitExceededException; import org.springframework.batch.core.step.skip.SkipListenerFailedException; import org.springframework.batch.item.ItemKeyGenerator; +import org.springframework.batch.item.ItemProcessor; import org.springframework.batch.item.ItemReader; import org.springframework.batch.item.ItemWriter; import org.springframework.batch.retry.RecoveryCallback; @@ -51,7 +52,7 @@ import org.springframework.batch.support.SubclassExceptionClassifier; * @author Robert Kasanicky * */ -public class SkipLimitStepFactoryBean extends SimpleStepFactoryBean { +public class SkipLimitStepFactoryBean extends SimpleStepFactoryBean { private int skipLimit = 0; @@ -267,7 +268,7 @@ public class SkipLimitStepFactoryBean extends SimpleStepFactoryBean { } } }); - StatefulRetryItemHandler itemHandler = new StatefulRetryItemHandler(getItemReader(), getItemWriter(), + StatefulRetryItemHandler itemHandler = new StatefulRetryItemHandler(getItemReader(), getItemProcessor(), getItemWriter(), retryTemplate, itemKeyGenerator, readSkipPolicy, writeSkipPolicy); itemHandler.setSkipListeners(BatchListenerFactoryHelper.getSkipListeners(getListeners())); @@ -276,7 +277,7 @@ public class SkipLimitStepFactoryBean extends SimpleStepFactoryBean { } else { // This is the default in ItemOrientedStep anyway... - step.setItemHandler(new SimpleItemHandler(getItemReader(), getItemWriter())); + step.setItemHandler(new ItemOrientedStepHandler(getItemReader(), getItemProcessor(), getItemWriter())); } } @@ -305,7 +306,7 @@ public class SkipLimitStepFactoryBean extends SimpleStepFactoryBean { * @author Dave Syer * */ - private static class StatefulRetryItemHandler extends SimpleItemHandler { + private static class StatefulRetryItemHandler extends ItemOrientedStepHandler { final private RetryOperations retryOperations; @@ -323,10 +324,10 @@ public class SkipLimitStepFactoryBean extends SimpleStepFactoryBean { * @param retryTemplate * @param itemKeyGenerator */ - public StatefulRetryItemHandler(ItemReader itemReader, ItemWriter itemWriter, + public StatefulRetryItemHandler(ItemReader itemReader, ItemProcessor itemProcessor, ItemWriter itemWriter, RetryOperations retryTemplate, ItemKeyGenerator itemKeyGenerator, ItemSkipPolicy readSkipPolicy, ItemSkipPolicy writeSkipPolicy) { - super(itemReader, itemWriter); + super(itemReader, itemProcessor, itemWriter); this.retryOperations = retryTemplate; this.itemKeyGenerator = itemKeyGenerator; this.readSkipPolicy = readSkipPolicy; diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/ItemOrientedStepIntegrationTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/ItemOrientedStepIntegrationTests.java index 4709e468e..528fa98fa 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/ItemOrientedStepIntegrationTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/ItemOrientedStepIntegrationTests.java @@ -15,12 +15,18 @@ */ package org.springframework.batch.core.step.item; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import java.util.Arrays; import javax.sql.DataSource; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; import org.springframework.batch.core.BatchStatus; import org.springframework.batch.core.Job; import org.springframework.batch.core.JobExecution; @@ -38,15 +44,12 @@ import org.springframework.batch.item.support.AbstractItemWriter; import org.springframework.batch.item.support.ListItemReader; import org.springframework.batch.repeat.policy.SimpleCompletionPolicy; import org.springframework.batch.repeat.support.RepeatTemplate; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.support.TransactionSynchronizationAdapter; import org.springframework.transaction.support.TransactionSynchronizationManager; -import org.springframework.beans.factory.annotation.Autowired; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; /** * @author Dave Syer @@ -107,15 +110,17 @@ public class ItemOrientedStepIntegrationTests { @Test public void testStatusForCommitFailedException() throws Exception { - step.setItemHandler(new SimpleItemHandler(getReader(new String[] { "a", "b", "c" }), new AbstractItemWriter() { - public void write(String data) throws Exception { - TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() { - public void beforeCommit(boolean readOnly) { - throw new RuntimeException("Simulate commit failure"); + step.setItemHandler(new SimpleItemHandler(getReader(new String[] { "a", "b", "c" }), + new AbstractItemWriter() { + public void write(String data) throws Exception { + TransactionSynchronizationManager + .registerSynchronization(new TransactionSynchronizationAdapter() { + public void beforeCommit(boolean readOnly) { + throw new RuntimeException("Simulate commit failure"); + } + }); } - }); - } - })); + })); JobExecution jobExecution = jobRepository.createJobExecution(job, new JobParameters()); StepExecution stepExecution = new StepExecution(step.getName(), jobExecution); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/RepeatOperationsStepFactoryBeanTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/RepeatOperationsStepFactoryBeanTests.java index 5563a8736..a401b2a4c 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/RepeatOperationsStepFactoryBeanTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/RepeatOperationsStepFactoryBeanTests.java @@ -39,7 +39,7 @@ import org.springframework.batch.support.transaction.ResourcelessTransactionMana */ public class RepeatOperationsStepFactoryBeanTests extends TestCase { - private RepeatOperationsStepFactoryBean factory = new RepeatOperationsStepFactoryBean(); + private RepeatOperationsStepFactoryBean factory = new RepeatOperationsStepFactoryBean(); private List list; 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 49c932d6d..a5c843d30 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 @@ -23,12 +23,12 @@ import java.util.List; import junit.framework.TestCase; -import org.springframework.batch.core.Step; -import org.springframework.batch.core.StepListener; import org.springframework.batch.core.BatchStatus; import org.springframework.batch.core.ChunkListener; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobParameters; +import org.springframework.batch.core.Step; +import org.springframework.batch.core.StepListener; import org.springframework.batch.core.job.AbstractJob; import org.springframework.batch.core.job.SimpleJob; import org.springframework.batch.core.listener.ItemListenerSupport; @@ -85,16 +85,16 @@ public class SimpleStepFactoryBeanTests extends TestCase { MapStepExecutionDao.clear(); } - private SimpleStepFactoryBean getStepFactory(String arg) throws Exception { + private SimpleStepFactoryBean getStepFactory(String arg) throws Exception { return getStepFactory(new String[] { arg }); } - private SimpleStepFactoryBean getStepFactory(String arg0, String arg1) throws Exception { + private SimpleStepFactoryBean getStepFactory(String arg0, String arg1) throws Exception { return getStepFactory(new String[] { arg0, arg1 }); } - private SimpleStepFactoryBean getStepFactory(String[] args) throws Exception { - SimpleStepFactoryBean factory = new SimpleStepFactoryBean(); + private SimpleStepFactoryBean getStepFactory(String[] args) throws Exception { + SimpleStepFactoryBean factory = new SimpleStepFactoryBean(); List items = TransactionAwareProxyFactory.createTransactionalList(); items.addAll(Arrays.asList(args)); @@ -129,7 +129,7 @@ public class SimpleStepFactoryBeanTests extends TestCase { public void testSimpleConcurrentJob() throws Exception { job.setSteps(new ArrayList()); - SimpleStepFactoryBean factory = getStepFactory("foo", "bar"); + SimpleStepFactoryBean factory = getStepFactory("foo", "bar"); factory.setTaskExecutor(new SimpleAsyncTaskExecutor()); factory.setThrottleLimit(1); @@ -163,7 +163,7 @@ public class SimpleStepFactoryBeanTests extends TestCase { * is recovered ("skipped") on the second attempt (see retry policy * definition above)... */ - SimpleStepFactoryBean factory = getStepFactory(new String[] { "foo", "bar", "spam" }); + SimpleStepFactoryBean factory = getStepFactory(new String[] { "foo", "bar", "spam" }); factory.setItemWriter(new AbstractItemWriter() { public void write(String data) throws Exception { @@ -196,7 +196,7 @@ public class SimpleStepFactoryBeanTests extends TestCase { } public void testExceptionTerminates() throws Exception { - SimpleStepFactoryBean factory = getStepFactory(new String[] { "foo", "bar", "spam" }); + SimpleStepFactoryBean factory = getStepFactory(new String[] { "foo", "bar", "spam" }); factory.setBeanName("exceptionStep"); factory.setItemWriter(new AbstractItemWriter() { public void write(String data) throws Exception { @@ -219,7 +219,7 @@ public class SimpleStepFactoryBeanTests extends TestCase { } public void testExceptionHandler() throws Exception { - SimpleStepFactoryBean factory = getStepFactory(new String[] { "foo", "bar", "spam" }); + SimpleStepFactoryBean factory = getStepFactory(new String[] { "foo", "bar", "spam" }); factory.setBeanName("exceptionStep"); factory.setExceptionHandler(new SimpleLimitExceptionHandler(1)); factory.setItemWriter(new AbstractItemWriter() { @@ -245,7 +245,7 @@ public class SimpleStepFactoryBeanTests extends TestCase { String[] items = new String[] { "1", "2", "3", "4", "5", "6", "7" }; int commitInterval = 3; - SimpleStepFactoryBean factory = getStepFactory(items); + SimpleStepFactoryBean factory = getStepFactory(items); class CountingChunkListener implements ChunkListener { int beforeCount = 0; @@ -284,7 +284,7 @@ public class SimpleStepFactoryBeanTests extends TestCase { * @throws Exception */ public void testCommitIntervalMustBeGreaterThanZero() throws Exception { - SimpleStepFactoryBean factory = getStepFactory("foo"); + SimpleStepFactoryBean factory = getStepFactory("foo"); // nothing wrong here factory.getObject(); @@ -304,7 +304,7 @@ public class SimpleStepFactoryBeanTests extends TestCase { * @throws Exception */ public void testCommitIntervalAndCompletionPolicyBothSet() throws Exception { - SimpleStepFactoryBean factory = getStepFactory("foo"); + SimpleStepFactoryBean factory = getStepFactory("foo"); // but exception expected after setting commit interval and completion // policy 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 d6b06a037..1217e42db 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 }; 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 5af693388..bb703d6a7 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 @@ -59,7 +59,7 @@ public class StatefulRetryStepFactoryBeanTests extends TestCase { protected final Log logger = LogFactory.getLog(getClass()); - private SkipLimitStepFactoryBean factory = new SkipLimitStepFactoryBean(); + private SkipLimitStepFactoryBean factory = new SkipLimitStepFactoryBean(); private List recovered = new ArrayList(); 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 3de0d93ca..a2a219c3d 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 @@ -31,8 +31,6 @@ import org.springframework.batch.core.repository.dao.MapJobInstanceDao; import org.springframework.batch.core.repository.dao.MapStepExecutionDao; import org.springframework.batch.core.repository.support.SimpleJobRepository; import org.springframework.batch.core.step.StepExecutionSynchronizer; -import org.springframework.batch.core.step.item.ItemOrientedStep; -import org.springframework.batch.core.step.item.SimpleItemHandler; import org.springframework.batch.item.support.AbstractItemReader; import org.springframework.batch.item.support.AbstractItemWriter; import org.springframework.batch.repeat.policy.SimpleCompletionPolicy; @@ -46,7 +44,7 @@ public class StepExecutorInterruptionTests extends TestCase { private JobExecution jobExecution; private AbstractItemWriter itemWriter; - + private StepExecution stepExecution; public void setUp() throws Exception { diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemProcessor.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemProcessor.java new file mode 100644 index 000000000..1f2544e92 --- /dev/null +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/ItemProcessor.java @@ -0,0 +1,13 @@ +package org.springframework.batch.item; + +/** + * Interface for item transformations. If the return value is null it may be + * ignored, so this interface is also able to act as a filter. + * + * @author Robert Kasanicky + * @author Dave Syer + */ +public interface ItemProcessor { + + O process(I item) throws Exception; +} diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/transform/CompositeItemTransformer.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/CompositeItemProcessor.java similarity index 57% rename from spring-batch-infrastructure/src/main/java/org/springframework/batch/item/transform/CompositeItemTransformer.java rename to spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/CompositeItemProcessor.java index 7188894ea..13dee854a 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/transform/CompositeItemTransformer.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/CompositeItemProcessor.java @@ -1,30 +1,31 @@ -package org.springframework.batch.item.transform; +package org.springframework.batch.item.support; import java.util.List; +import org.springframework.batch.item.ItemProcessor; import org.springframework.beans.factory.InitializingBean; import org.springframework.util.Assert; /** - * Composite {@link ItemTransformer} that passes the item through a sequence of + * Composite {@link ItemProcessor} that passes the item through a sequence of * injected ItemTransformers (return value of previous * transformation is the entry value of the next). * - * Note the user is responsible for injecting a chain of {@link ItemTransformer} + * Note the user is responsible for injecting a chain of {@link ItemProcessor} * s that conforms to declared input and output types. * * @author Robert Kasanicky */ @SuppressWarnings("unchecked") -public class CompositeItemTransformer implements ItemTransformer, InitializingBean { +public class CompositeItemProcessor implements ItemProcessor, InitializingBean { - private List itemTransformers; + private List itemTransformers; - public O transform(I item) throws Exception { + public O process(I item) throws Exception { Object result = item; - for(ItemTransformer transformer: itemTransformers){ - result = transformer.transform(result); + for(ItemProcessor transformer: itemTransformers){ + result = transformer.process(result); } return (O) result; } @@ -37,7 +38,7 @@ public class CompositeItemTransformer implements ItemTransformer, In * @param itemTransformers will be chained to produce a composite * transformation. */ - public void setItemTransformers(List itemTransformers) { + public void setItemTransformers(List itemTransformers) { this.itemTransformers = itemTransformers; } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/PassthroughItemProcessor.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/PassthroughItemProcessor.java new file mode 100644 index 000000000..8c84f6a33 --- /dev/null +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/support/PassthroughItemProcessor.java @@ -0,0 +1,13 @@ +package org.springframework.batch.item.support; + +import org.springframework.batch.item.ItemProcessor; + +/** + * @author Dave Syer + * + */ +public class PassthroughItemProcessor implements ItemProcessor { + public T process(T item) throws Exception { + return item; + } +} \ No newline at end of file diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/transform/ItemTransformer.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/transform/ItemTransformer.java deleted file mode 100644 index 190c7f662..000000000 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/transform/ItemTransformer.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.springframework.batch.item.transform; - -/** - * Interface for item transformations during processing phase. - * - * @author Robert Kasanicky - */ -public interface ItemTransformer { - - O transform(I item) throws Exception; -} diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/transform/ItemTransformerItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/transform/ItemTransformerItemWriter.java deleted file mode 100644 index e9fd0b80d..000000000 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/transform/ItemTransformerItemWriter.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.springframework.batch.item.transform; - -import org.springframework.batch.item.ItemWriter; -import org.springframework.batch.item.support.DelegatingItemWriter; -import org.springframework.util.Assert; - -/** - * Transforms the item using injected {@link ItemTransformer} - * before it is written to output by {@link ItemWriter}. - * - * @author Robert Kasanicky - */ -public class ItemTransformerItemWriter extends DelegatingItemWriter { - - private ItemTransformer itemTransformer; - - /** - * Transform the item using the {@link #setItemTransformer(ItemTransformer)}. - */ - protected O doProcess(I item) throws Exception { - return itemTransformer.transform(item); - } - - /** - * @param itemTransformer will transform the item before - * it is passed to {@link ItemWriter}. - */ - public void setItemTransformer(ItemTransformer itemTransformer) { - this.itemTransformer = itemTransformer; - } - - public void afterPropertiesSet() throws Exception { - super.afterPropertiesSet(); - Assert.notNull(itemTransformer); - } -} diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/transform/package.html b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/transform/package.html deleted file mode 100644 index a07f60145..000000000 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/transform/package.html +++ /dev/null @@ -1,7 +0,0 @@ - - -

-Writer implementation concerned with item transformation before writing. -

- - diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/transform/CompositeItemTransformerTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/CompositeItemProcessorTests.java similarity index 60% rename from spring-batch-infrastructure/src/test/java/org/springframework/batch/item/transform/CompositeItemTransformerTests.java rename to spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/CompositeItemProcessorTests.java index 40835719e..401ce9d35 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/transform/CompositeItemTransformerTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/support/CompositeItemProcessorTests.java @@ -1,4 +1,4 @@ -package org.springframework.batch.item.transform; +package org.springframework.batch.item.support; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.expect; @@ -11,26 +11,28 @@ import java.util.ArrayList; import org.junit.Before; import org.junit.Test; +import org.springframework.batch.item.ItemProcessor; +import org.springframework.batch.item.support.CompositeItemProcessor; /** - * Tests for {@link CompositeItemTransformer}. + * Tests for {@link CompositeItemProcessor}. * * @author Robert Kasanicky */ -public class CompositeItemTransformerTests { +public class CompositeItemProcessorTests { - private CompositeItemTransformer composite = new CompositeItemTransformer(); + private CompositeItemProcessor composite = new CompositeItemProcessor(); - private ItemTransformer transformer1; - private ItemTransformer transformer2; + private ItemProcessor transformer1; + private ItemProcessor transformer2; @SuppressWarnings("unchecked") @Before public void setUp() throws Exception { - transformer1 = createMock(ItemTransformer.class); - transformer2 = createMock(ItemTransformer.class); + transformer1 = createMock(ItemProcessor.class); + transformer2 = createMock(ItemProcessor.class); - composite.setItemTransformers(new ArrayList() {{ + composite.setItemTransformers(new ArrayList() {{ add(transformer1); add(transformer2); }}); @@ -47,14 +49,14 @@ public class CompositeItemTransformerTests { Object itemAfterFirstTransfromation = new Object(); Object itemAfterSecondTransformation = new Object(); - expect(transformer1.transform(item)).andReturn(itemAfterFirstTransfromation); + expect(transformer1.process(item)).andReturn(itemAfterFirstTransfromation); - expect(transformer2.transform(itemAfterFirstTransfromation)).andReturn(itemAfterSecondTransformation); + expect(transformer2.process(itemAfterFirstTransfromation)).andReturn(itemAfterSecondTransformation); replay(transformer1); replay(transformer2); - assertSame(itemAfterSecondTransformation, composite.transform(item)); + assertSame(itemAfterSecondTransformation, composite.process(item)); verify(transformer1); verify(transformer2); @@ -62,7 +64,7 @@ public class CompositeItemTransformerTests { /** * The list of transformers must not be null or empty and - * can contain only instances of {@link ItemTransformer}. + * can contain only instances of {@link ItemProcessor}. */ @SuppressWarnings("unchecked") @Test @@ -79,7 +81,7 @@ public class CompositeItemTransformerTests { } // empty list - composite.setItemTransformers(new ArrayList()); + composite.setItemTransformers(new ArrayList()); try { composite.afterPropertiesSet(); fail(); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/transform/ItemTransformerItemWriterFunctionalTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/transform/ItemTransformerItemWriterFunctionalTests.java deleted file mode 100644 index dc299ca14..000000000 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/transform/ItemTransformerItemWriterFunctionalTests.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2006-2008 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.batch.item.transform; - -import java.util.ArrayList; -import java.util.List; - -import org.springframework.batch.item.ClearFailedException; -import org.springframework.batch.item.FlushFailedException; -import org.springframework.batch.item.ItemWriter; - -import junit.framework.TestCase; - -/** - * These functional tests were created for the Reference Documentation and show how various - * combinations of ItemTransformer can be used with an ItemTransformerItemWriter. - * - * @author Lucas Ward - * - */ -public class ItemTransformerItemWriterFunctionalTests extends TestCase { - - public void testTransform() throws Exception{ - - ItemTransformerItemWriter itemTransformerItemWriter = new ItemTransformerItemWriter(); - itemTransformerItemWriter.setItemTransformer(new FooTransformer()); - itemTransformerItemWriter.setDelegate(new BarWriter()); - itemTransformerItemWriter.write(new Foo()); - } - - - public void testComposite() throws Exception{ - - CompositeItemTransformer compositeTransformer = new CompositeItemTransformer(); - - @SuppressWarnings("unchecked") List itemTransformers = new ArrayList(); - itemTransformers.add(new FooTransformer()); - itemTransformers.add(new BarTransformer()); - compositeTransformer.setItemTransformers(itemTransformers); - ItemTransformerItemWriter itemTransformerItemWriter = new ItemTransformerItemWriter(); - itemTransformerItemWriter.setItemTransformer(compositeTransformer); - itemTransformerItemWriter.setDelegate(new FoobarWriter()); - itemTransformerItemWriter.write(new Foo()); - } - - private static class Foo { - - } - - private static class Bar { - public Bar(Foo foo) { - } - } - - private static class Foobar{ - public Foobar(Bar bar){} - } - - public class FooTransformer implements ItemTransformer{ - - //Preform simple transformation, convert a Foo to a Barr - public Bar transform(Foo foo) throws Exception { - return new Bar(foo); - } - } - - public class BarTransformer implements ItemTransformer{ - - public Foobar transform(Bar bar) throws Exception { - return new Foobar(bar); - } - } - - private static class BarWriter implements ItemWriter{ - - public void write(Bar item) throws Exception { - assertTrue(item instanceof Bar); - } - - public void clear() throws ClearFailedException { - } - - public void flush() throws FlushFailedException { - } - - } - - private static class FoobarWriter implements ItemWriter{ - - public void write(Foobar item) throws Exception { - assertTrue(item instanceof Foobar); - } - - public void clear() throws ClearFailedException { - } - - public void flush() throws FlushFailedException { - } - } -} diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/transform/ItemTransformerItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/transform/ItemTransformerItemWriterTests.java deleted file mode 100644 index cabaca8b0..000000000 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/transform/ItemTransformerItemWriterTests.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.springframework.batch.item.transform; - -import static org.junit.Assert.fail; - -import org.easymock.EasyMock; -import org.junit.Before; -import org.junit.Test; -import org.springframework.batch.item.ItemWriter; - -/** - * Tests for {@link ItemTransformerItemWriter}. - * - * @author Robert Kasanicky - */ -public class ItemTransformerItemWriterTests { - - private ItemTransformerItemWriter processor = new ItemTransformerItemWriter(); - - @SuppressWarnings("unchecked") - private ItemTransformer transformer = EasyMock.createMock(ItemTransformer.class); - @SuppressWarnings("unchecked") - private ItemWriter itemWriter = EasyMock.createMock(ItemWriter.class); - - @Before - public void setUp() throws Exception { - processor.setItemTransformer(transformer); - processor.setDelegate(itemWriter); - processor.afterPropertiesSet(); - } - - /** - * Regular usage scenario - item is passed to transformer - * and the result of transformation is passed to output source. - */ - @Test - public void testProcess() throws Exception { - Object item = new Object(); - Object itemAfterTransformation = new Object(); - - EasyMock.expect(transformer.transform(item)).andReturn(itemAfterTransformation); - - itemWriter.write(itemAfterTransformation); - EasyMock.expectLastCall(); - - EasyMock.replay(itemWriter, transformer); - - processor.write(item); - - EasyMock.verify(itemWriter, transformer); - } - - /** - * Item transformer must be set. - */ - @Test - public void testAfterPropertiesSet() throws Exception { - - // value not set - processor.setItemTransformer(null); - try { - processor.afterPropertiesSet(); - fail(); - } - catch (IllegalArgumentException e) { - // expected - } - } -} diff --git a/spring-batch-integration/src/main/java/org/springframework/batch/integration/file/FileToMessagesJobFactoryBean.java b/spring-batch-integration/src/main/java/org/springframework/batch/integration/file/FileToMessagesJobFactoryBean.java index 8cc3ffcfc..4e9050a0c 100644 --- a/spring-batch-integration/src/main/java/org/springframework/batch/integration/file/FileToMessagesJobFactoryBean.java +++ b/spring-batch-integration/src/main/java/org/springframework/batch/integration/file/FileToMessagesJobFactoryBean.java @@ -39,10 +39,10 @@ import org.springframework.util.Assert; /** * A FactoryBean for a {@link Job} with a single step which just pumps messages - * from a file into a channel. The channel has to be a - * {@link DirectChannel} to ensure that failures propagate up to the step - * and fail the job execution. Normally this job will be used in conjunction - * with a {@link JobLaunchingMessageHandler} and a + * from a file into a channel. The channel has to be a {@link DirectChannel} to + * ensure that failures propagate up to the step and fail the job execution. + * Normally this job will be used in conjunction with a + * {@link JobLaunchingMessageHandler} and a * {@link ResourcePayloadAsJobParameterStrategy}, so that the user can just * send a message to a request channel listing the files to be processed, and * everything else just happens by magic. After a failure the job will be @@ -125,7 +125,7 @@ public class FileToMessagesJobFactoryBean implements FactoryBean, BeanNameAwa job.setName(name); job.setJobRepository(jobRepository); - SimpleStepFactoryBean stepFactory = new SimpleStepFactoryBean(); + SimpleStepFactoryBean stepFactory = new SimpleStepFactoryBean(); stepFactory.setBeanName("step"); Assert.state((itemReader instanceof FlatFileItemReader) || (itemReader instanceof StaxEventItemReader), diff --git a/spring-batch-integration/src/test/java/org/springframework/batch/integration/chunk/ChunkMessageItemWriterIntegrationTests.java b/spring-batch-integration/src/test/java/org/springframework/batch/integration/chunk/ChunkMessageItemWriterIntegrationTests.java index 9d9b6ae12..13dc786af 100644 --- a/spring-batch-integration/src/test/java/org/springframework/batch/integration/chunk/ChunkMessageItemWriterIntegrationTests.java +++ b/spring-batch-integration/src/test/java/org/springframework/batch/integration/chunk/ChunkMessageItemWriterIntegrationTests.java @@ -53,7 +53,7 @@ public class ChunkMessageItemWriterIntegrationTests { @Qualifier("replies") private PollableChannel replies; - private SimpleStepFactoryBean factory; + private SimpleStepFactoryBean factory; private SimpleJobRepository jobRepository; @@ -63,7 +63,7 @@ public class ChunkMessageItemWriterIntegrationTests { @Before public void setUp() { - factory = new SimpleStepFactoryBean(); + factory = new SimpleStepFactoryBean(); jobRepository = new SimpleJobRepository(new MapJobInstanceDao(), new MapJobExecutionDao(), new MapStepExecutionDao(), new MapExecutionContextDao()); factory.setJobRepository(jobRepository); diff --git a/spring-batch-samples/.settings/org.springframework.ide.eclipse.core.prefs b/spring-batch-samples/.settings/org.springframework.ide.eclipse.core.prefs new file mode 100644 index 000000000..1058cc07e --- /dev/null +++ b/spring-batch-samples/.settings/org.springframework.ide.eclipse.core.prefs @@ -0,0 +1,67 @@ +#Mon Aug 11 02:58:58 EDT 2008 +eclipse.preferences.version=1 +org.springframework.ide.eclipse.core.builders.enable.aopreferencemodelbuilder=true +org.springframework.ide.eclipse.core.builders.enable.beanmetadatabuilder=true +org.springframework.ide.eclipse.core.builders.enable.osgibundleupdater=true +org.springframework.ide.eclipse.core.enable.project.preferences=false +org.springframework.ide.eclipse.core.validator.enable.com.springsource.platform.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.enable.com.springsource.sts.ap.quickfix.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.enable.com.springsource.sts.bestpractices.beansvalidator=true +org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.core.springvalidator=true +org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.platform.ide.manifest.core.applicationSymbolicNameRule-com.springsource.platform.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.platform.ide.manifest.core.applicationVersionRule-com.springsource.platform.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.platform.ide.manifest.core.bundleActivationPolicyRule-com.springsource.platform.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.platform.ide.manifest.core.bundleActivatorRule-com.springsource.platform.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.platform.ide.manifest.core.bundleManifestVersionRule-com.springsource.platform.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.platform.ide.manifest.core.bundleNameRule-com.springsource.platform.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.platform.ide.manifest.core.bundleSymbolicNameRule-com.springsource.platform.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.platform.ide.manifest.core.bundleVersionRule-com.springsource.platform.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.platform.ide.manifest.core.exportPackageRule-com.springsource.platform.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.platform.ide.manifest.core.importRule-com.springsource.platform.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.platform.ide.manifest.core.parsingProblemsRule-com.springsource.platform.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.platform.ide.manifest.core.requireBundleRule-com.springsource.platform.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.ap.quickfix.importBundleVersionRule-com.springsource.sts.ap.quickfix.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.ap.quickfix.importLibraryVersionRule-com.springsource.sts.ap.quickfix.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.ap.quickfix.importPackageVersionRule-com.springsource.sts.ap.quickfix.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.ap.quickfix.requireBundleVersionRule-com.springsource.sts.ap.quickfix.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.AvoidDriverManagerDataSource-com.springsource.sts.bestpractices.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.ImportElementsAtTopRulee-com.springsource.sts.bestpractices.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.ParentBeanSpecifiesAbstractClassRule-com.springsource.sts.bestpractices.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.RefElementRule-com.springsource.sts.bestpractices.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.TooManyBeansInFileRule-com.springsource.sts.bestpractices.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.UnnecessaryValueElementRule-com.springsource.sts.bestpractices.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.UseBeanInheritance-com.springsource.sts.bestpractices.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.legacyxmlusage.jndiobjectfactory-com.springsource.sts.bestpractices.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanAlias-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanClass-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanConstructorArgument-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanDefinition-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanDefinitionHolder-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanFactory-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanInitDestroyMethod-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanProperty-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanReference-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.methodOverride-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.parsingProblems-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.requiredProperty-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.core.springClasspath-org.springframework.ide.eclipse.core.springvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.action-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.actionstate-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.attribute-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.attributemapper-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.beanaction-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.evaluationaction-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.evaluationresult-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.exceptionhandler-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.import-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.inputattribute-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.mapping-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.outputattribute-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.set-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.state-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.subflowstate-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.transition-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.variable-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.webflowstate-org.springframework.ide.eclipse.webflow.core.validator=true diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/sample/domain/order/internal/OrderTransformer.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/domain/order/internal/OrderProcessor.java similarity index 93% rename from spring-batch-samples/src/main/java/org/springframework/batch/sample/domain/order/internal/OrderTransformer.java rename to spring-batch-samples/src/main/java/org/springframework/batch/sample/domain/order/internal/OrderProcessor.java index ed0b20c83..4cfa643e7 100644 --- a/spring-batch-samples/src/main/java/org/springframework/batch/sample/domain/order/internal/OrderTransformer.java +++ b/spring-batch-samples/src/main/java/org/springframework/batch/sample/domain/order/internal/OrderProcessor.java @@ -21,8 +21,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import org.springframework.batch.item.ItemProcessor; import org.springframework.batch.item.file.transform.LineAggregator; -import org.springframework.batch.item.transform.ItemTransformer; import org.springframework.batch.sample.domain.order.Address; import org.springframework.batch.sample.domain.order.BillingInfo; import org.springframework.batch.sample.domain.order.Customer; @@ -30,10 +30,11 @@ import org.springframework.batch.sample.domain.order.LineItem; import org.springframework.batch.sample.domain.order.Order; /** - * Converts Order object to a String. + * Converts Order object to a list of strings. + * * @author Dave Syer */ -public class OrderTransformer implements ItemTransformer> { +public class OrderProcessor implements ItemProcessor> { /** * Aggregators for all types of lines in the output file @@ -44,7 +45,7 @@ public class OrderTransformer implements ItemTransformer> { * Converts information from an Order object to a collection of Strings for * output. */ - public List transform(Order order) { + public List process(Order order) { List result = new ArrayList(); diff --git a/spring-batch-samples/src/main/resources/jobs/multilineOrderJob.xml b/spring-batch-samples/src/main/resources/jobs/multilineOrderJob.xml index f5d1c8a55..c9fc93dc5 100644 --- a/spring-batch-samples/src/main/resources/jobs/multilineOrderJob.xml +++ b/spring-batch-samples/src/main/resources/jobs/multilineOrderJob.xml @@ -1,6 +1,5 @@ - - + - - - - - - - - + + + + + + + + - + + + + + + - - - - - - - - - - + - + - + - + - + diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/order/FlatFileOrderAggregatorTests.java b/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/order/FlatFileOrderAggregatorTests.java index b0c2d4e4c..92152ef02 100644 --- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/order/FlatFileOrderAggregatorTests.java +++ b/spring-batch-samples/src/test/java/org/springframework/batch/sample/domain/order/FlatFileOrderAggregatorTests.java @@ -27,7 +27,7 @@ import java.util.Map; import org.junit.Test; import org.springframework.batch.item.file.transform.DelimitedLineAggregator; import org.springframework.batch.item.file.transform.LineAggregator; -import org.springframework.batch.sample.domain.order.internal.OrderTransformer; +import org.springframework.batch.sample.domain.order.internal.OrderProcessor; public class FlatFileOrderAggregatorTests { @@ -55,7 +55,7 @@ public class FlatFileOrderAggregatorTests { // create map of aggregators and set it to writer Map> aggregators = new HashMap>(); - OrderTransformer converter = new OrderTransformer(); + OrderProcessor converter = new OrderProcessor(); aggregators.put("header", aggregator); aggregators.put("customer", aggregator); aggregators.put("address", aggregator); @@ -65,7 +65,7 @@ public class FlatFileOrderAggregatorTests { converter.setAggregators(aggregators); // call tested method - List list = converter.transform(order); + List list = converter.process(order); // verify method calls assertEquals(7, list.size());