OPEN - issue BATCH-770: Make ItemTransformer a first class citizen and rename as ItemProcessor

Done first pass.  Some tests needed.
This commit is contained in:
dsyer
2008-08-11 08:48:41 +00:00
parent 8c12cd8b10
commit d4d35cd668
27 changed files with 394 additions and 473 deletions

View File

@@ -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<T> implements FactoryBean, BeanNameAware {
public abstract class AbstractStepFactoryBean<T,S> implements FactoryBean, BeanNameAware {
private String name;
@@ -52,7 +53,7 @@ public abstract class AbstractStepFactoryBean<T> implements FactoryBean, BeanNam
private ItemReader<? extends T> itemReader;
private ItemWriter<? super T> itemWriter;
private ItemWriter<? super S> itemWriter;
private PlatformTransactionManager transactionManager;
@@ -68,6 +69,11 @@ public abstract class AbstractStepFactoryBean<T> implements FactoryBean, BeanNam
private StepListener[] listeners = new StepListener[0];
private ItemProcessor<? super T, ? extends S> itemProcessor = new ItemProcessor<T, S>() {
@SuppressWarnings("unchecked")
public S process(T item) throws Exception {return (S)item;}
};
/**
*
*/
@@ -121,10 +127,17 @@ public abstract class AbstractStepFactoryBean<T> implements FactoryBean, BeanNam
/**
* @param itemWriter the itemWriter to set
*/
public void setItemWriter(ItemWriter<? super T> itemWriter) {
public void setItemWriter(ItemWriter<? super S> itemWriter) {
this.itemWriter = itemWriter;
}
/**
* @param itemProcessor the itemProcessor to set
*/
public void setItemProcessor(ItemProcessor<? super T, ? extends S> 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<T> implements FactoryBean, BeanNam
* Protected getter for the {@link ItemWriter} for subclasses to use
* @return the itemWriter
*/
protected ItemWriter<? super T> getItemWriter() {
protected ItemWriter<? super S> getItemWriter() {
return itemWriter;
}
/**
* Protected getter for the {@link ItemProcessor} for subclasses to use
* @return the itemProcessor
*/
protected ItemProcessor<? super T, ? extends S> getItemProcessor() {
return itemProcessor;
}
/**
* Public setter for {@link JobRepository}.
*
@@ -198,7 +219,8 @@ public abstract class AbstractStepFactoryBean<T> 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<T> implements FactoryBean, BeanNam
Assert.notNull(transactionManager, "TransactionManager must be provided");
jobRepositoryValidator.validate(jobRepository);
step.setItemHandler(new SimpleItemHandler<T>(itemReader, itemWriter));
step.setTransactionManager(transactionManager);
if (transactionAttribute!=null) {
step.setTransactionAttribute(transactionAttribute);
@@ -239,7 +260,8 @@ public abstract class AbstractStepFactoryBean<T> implements FactoryBean, BeanNam
step.setStreams(streams);
ItemReader<? extends T> itemReader = getItemReader();
ItemWriter<? super T> itemWriter = getItemWriter();
ItemWriter<? super S> itemWriter = getItemWriter();
ItemProcessor<? super T, ? extends S> 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<T> 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<T> implements FactoryBean, BeanNam
setItemWriter(itemWriter);
step.setStepExecutionListeners(stepListeners);
//TODO: Why is setItemHandler called twice?
step.setItemHandler(new SimpleItemHandler<T>(itemReader, itemWriter));
step.setItemHandler(new ItemOrientedStepHandler<T,S>(itemReader, itemProcessor, itemWriter));
}

View File

@@ -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<T, S> implements ItemHandler {
protected final Log logger = LogFactory.getLog(getClass());
private ItemReader<? extends T> itemReader;
private ItemProcessor<? super T, ? extends S> itemProcessor;
private ItemWriter<? super S> itemWriter;
/**
* @param itemReader
* @param itemProcessor
* @param itemWriter
*/
public ItemOrientedStepHandler(ItemReader<? extends T> itemReader, ItemProcessor<? super T, ? extends S> itemProcessor,
ItemWriter<? super S> 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();
}
}

View File

@@ -27,7 +27,7 @@ import org.springframework.batch.repeat.support.RepeatTemplate;
* @author Dave Syer
*
*/
public class RepeatOperationsStepFactoryBean<T> extends AbstractStepFactoryBean<T> {
public class RepeatOperationsStepFactoryBean<T,S> extends AbstractStepFactoryBean<T,S> {
private RepeatOperations chunkOperations = new RepeatTemplate();

View File

@@ -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<T> implements ItemHandler {
protected final Log logger = LogFactory.getLog(getClass());
private ItemReader<? extends T> itemReader;
private ItemWriter<? super T> itemWriter;
public class SimpleItemHandler<T> extends ItemOrientedStepHandler<T, T> {
/**
* @param itemReader
* @param itemWriter
* Creates a {@link PassthroughItemProcessor} and uses it to create an
* instance of {@link ItemOrientedStepHandler}.
*/
public SimpleItemHandler(ItemReader<? extends T> itemReader, ItemWriter<? super T> 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<T> itemReader, ItemWriter<T> itemWriter) {
super(itemReader, new PassthroughItemProcessor<T>(), itemWriter);
}
}

View File

@@ -39,7 +39,7 @@ import org.springframework.util.Assert;
* @author Dave Syer
*
*/
public class SimpleStepFactoryBean<T> extends AbstractStepFactoryBean<T> {
public class SimpleStepFactoryBean<T,S> extends AbstractStepFactoryBean<T,S> {
protected final Log logger = LogFactory.getLog(getClass());

View File

@@ -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<T> extends SimpleStepFactoryBean<T> {
public class SkipLimitStepFactoryBean<T,S> extends SimpleStepFactoryBean<T,S> {
private int skipLimit = 0;
@@ -267,7 +268,7 @@ public class SkipLimitStepFactoryBean<T> extends SimpleStepFactoryBean<T> {
}
}
});
StatefulRetryItemHandler<T> itemHandler = new StatefulRetryItemHandler<T>(getItemReader(), getItemWriter(),
StatefulRetryItemHandler<T,S> itemHandler = new StatefulRetryItemHandler<T,S>(getItemReader(), getItemProcessor(), getItemWriter(),
retryTemplate, itemKeyGenerator, readSkipPolicy, writeSkipPolicy);
itemHandler.setSkipListeners(BatchListenerFactoryHelper.getSkipListeners(getListeners()));
@@ -276,7 +277,7 @@ public class SkipLimitStepFactoryBean<T> extends SimpleStepFactoryBean<T> {
}
else {
// This is the default in ItemOrientedStep anyway...
step.setItemHandler(new SimpleItemHandler<T>(getItemReader(), getItemWriter()));
step.setItemHandler(new ItemOrientedStepHandler<T,S>(getItemReader(), getItemProcessor(), getItemWriter()));
}
}
@@ -305,7 +306,7 @@ public class SkipLimitStepFactoryBean<T> extends SimpleStepFactoryBean<T> {
* @author Dave Syer
*
*/
private static class StatefulRetryItemHandler<T> extends SimpleItemHandler<T> {
private static class StatefulRetryItemHandler<T,S> extends ItemOrientedStepHandler<T,S> {
final private RetryOperations retryOperations;
@@ -323,10 +324,10 @@ public class SkipLimitStepFactoryBean<T> extends SimpleStepFactoryBean<T> {
* @param retryTemplate
* @param itemKeyGenerator
*/
public StatefulRetryItemHandler(ItemReader<? extends T> itemReader, ItemWriter<? super T> itemWriter,
public StatefulRetryItemHandler(ItemReader<? extends T> itemReader, ItemProcessor<? super T, ? extends S> itemProcessor, ItemWriter<? super S> 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;

View File

@@ -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<String>(getReader(new String[] { "a", "b", "c" }), new AbstractItemWriter<String>() {
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<String>(getReader(new String[] { "a", "b", "c" }),
new AbstractItemWriter<String>() {
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);

View File

@@ -39,7 +39,7 @@ import org.springframework.batch.support.transaction.ResourcelessTransactionMana
*/
public class RepeatOperationsStepFactoryBeanTests extends TestCase {
private RepeatOperationsStepFactoryBean<String> factory = new RepeatOperationsStepFactoryBean<String>();
private RepeatOperationsStepFactoryBean<String,String> factory = new RepeatOperationsStepFactoryBean<String,String>();
private List<String> list;

View File

@@ -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<String> getStepFactory(String arg) throws Exception {
private SimpleStepFactoryBean<String,String> getStepFactory(String arg) throws Exception {
return getStepFactory(new String[] { arg });
}
private SimpleStepFactoryBean<String> getStepFactory(String arg0, String arg1) throws Exception {
private SimpleStepFactoryBean<String,String> getStepFactory(String arg0, String arg1) throws Exception {
return getStepFactory(new String[] { arg0, arg1 });
}
private SimpleStepFactoryBean<String> getStepFactory(String[] args) throws Exception {
SimpleStepFactoryBean<String> factory = new SimpleStepFactoryBean<String>();
private SimpleStepFactoryBean<String,String> getStepFactory(String[] args) throws Exception {
SimpleStepFactoryBean<String,String> factory = new SimpleStepFactoryBean<String,String>();
List<String> 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<Step>());
SimpleStepFactoryBean<String> factory = getStepFactory("foo", "bar");
SimpleStepFactoryBean<String,String> 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<String> factory = getStepFactory(new String[] { "foo", "bar", "spam" });
SimpleStepFactoryBean<String,String> factory = getStepFactory(new String[] { "foo", "bar", "spam" });
factory.setItemWriter(new AbstractItemWriter<String>() {
public void write(String data) throws Exception {
@@ -196,7 +196,7 @@ public class SimpleStepFactoryBeanTests extends TestCase {
}
public void testExceptionTerminates() throws Exception {
SimpleStepFactoryBean<String> factory = getStepFactory(new String[] { "foo", "bar", "spam" });
SimpleStepFactoryBean<String,String> factory = getStepFactory(new String[] { "foo", "bar", "spam" });
factory.setBeanName("exceptionStep");
factory.setItemWriter(new AbstractItemWriter<String>() {
public void write(String data) throws Exception {
@@ -219,7 +219,7 @@ public class SimpleStepFactoryBeanTests extends TestCase {
}
public void testExceptionHandler() throws Exception {
SimpleStepFactoryBean<String> factory = getStepFactory(new String[] { "foo", "bar", "spam" });
SimpleStepFactoryBean<String,String> factory = getStepFactory(new String[] { "foo", "bar", "spam" });
factory.setBeanName("exceptionStep");
factory.setExceptionHandler(new SimpleLimitExceptionHandler(1));
factory.setItemWriter(new AbstractItemWriter<String>() {
@@ -245,7 +245,7 @@ public class SimpleStepFactoryBeanTests extends TestCase {
String[] items = new String[] { "1", "2", "3", "4", "5", "6", "7" };
int commitInterval = 3;
SimpleStepFactoryBean<String> factory = getStepFactory(items);
SimpleStepFactoryBean<String,String> 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<String> factory = getStepFactory("foo");
SimpleStepFactoryBean<String,String> 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<String> factory = getStepFactory("foo");
SimpleStepFactoryBean<String,String> factory = getStepFactory("foo");
// but exception expected after setting commit interval and completion
// policy

View File

@@ -42,7 +42,7 @@ public class SkipLimitStepFactoryBeanTests extends TestCase {
protected final Log logger = LogFactory.getLog(getClass());
private SkipLimitStepFactoryBean<String> factory = new SkipLimitStepFactoryBean<String>();
private SkipLimitStepFactoryBean<String,String> factory = new SkipLimitStepFactoryBean<String,String>();
private Class<?>[] skippableExceptions = new Class[] { SkippableException.class, SkippableRuntimeException.class };

View File

@@ -59,7 +59,7 @@ public class StatefulRetryStepFactoryBeanTests extends TestCase {
protected final Log logger = LogFactory.getLog(getClass());
private SkipLimitStepFactoryBean<Object> factory = new SkipLimitStepFactoryBean<Object>();
private SkipLimitStepFactoryBean<Object,Object> factory = new SkipLimitStepFactoryBean<Object,Object>();
private List<Object> recovered = new ArrayList<Object>();

View File

@@ -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<Object> itemWriter;
private StepExecution stepExecution;
public void setUp() throws Exception {

View File

@@ -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<I, O> {
O process(I item) throws Exception;
}

View File

@@ -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 <code>ItemTransformer</code>s (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<I, O> implements ItemTransformer<I, O>, InitializingBean {
public class CompositeItemProcessor<I, O> implements ItemProcessor<I, O>, InitializingBean {
private List<ItemTransformer> itemTransformers;
private List<ItemProcessor> 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<I, O> implements ItemTransformer<I, O>, In
* @param itemTransformers will be chained to produce a composite
* transformation.
*/
public void setItemTransformers(List<ItemTransformer> itemTransformers) {
public void setItemTransformers(List<ItemProcessor> itemTransformers) {
this.itemTransformers = itemTransformers;
}

View File

@@ -0,0 +1,13 @@
package org.springframework.batch.item.support;
import org.springframework.batch.item.ItemProcessor;
/**
* @author Dave Syer
*
*/
public class PassthroughItemProcessor<T> implements ItemProcessor<T, T> {
public T process(T item) throws Exception {
return item;
}
}

View File

@@ -1,11 +0,0 @@
package org.springframework.batch.item.transform;
/**
* Interface for item transformations during processing phase.
*
* @author Robert Kasanicky
*/
public interface ItemTransformer<I,O> {
O transform(I item) throws Exception;
}

View File

@@ -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<I,O> extends DelegatingItemWriter<I,O> {
private ItemTransformer<? super I,? extends O> 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<? super I,? extends O> itemTransformer) {
this.itemTransformer = itemTransformer;
}
public void afterPropertiesSet() throws Exception {
super.afterPropertiesSet();
Assert.notNull(itemTransformer);
}
}

View File

@@ -1,7 +0,0 @@
<html>
<body>
<p>
Writer implementation concerned with item transformation before writing.
</p>
</body>
</html>

View File

@@ -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<Object, Object> composite = new CompositeItemTransformer<Object, Object>();
private CompositeItemProcessor<Object, Object> composite = new CompositeItemProcessor<Object, Object>();
private ItemTransformer<Object, Object> transformer1;
private ItemTransformer<Object, Object> transformer2;
private ItemProcessor<Object, Object> transformer1;
private ItemProcessor<Object, Object> 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<ItemTransformer>() {{
composite.setItemTransformers(new ArrayList<ItemProcessor>() {{
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<ItemTransformer>());
composite.setItemTransformers(new ArrayList<ItemProcessor>());
try {
composite.afterPropertiesSet();
fail();

View File

@@ -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<Foo, Bar> itemTransformerItemWriter = new ItemTransformerItemWriter<Foo, Bar>();
itemTransformerItemWriter.setItemTransformer(new FooTransformer());
itemTransformerItemWriter.setDelegate(new BarWriter());
itemTransformerItemWriter.write(new Foo());
}
public void testComposite() throws Exception{
CompositeItemTransformer<Foo, Foobar> compositeTransformer = new CompositeItemTransformer<Foo, Foobar>();
@SuppressWarnings("unchecked") List<ItemTransformer> itemTransformers = new ArrayList<ItemTransformer>();
itemTransformers.add(new FooTransformer());
itemTransformers.add(new BarTransformer());
compositeTransformer.setItemTransformers(itemTransformers);
ItemTransformerItemWriter<Foo, Foobar> itemTransformerItemWriter = new ItemTransformerItemWriter<Foo, Foobar>();
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<Foo, Bar>{
//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<Bar, Foobar>{
public Foobar transform(Bar bar) throws Exception {
return new Foobar(bar);
}
}
private static class BarWriter implements ItemWriter<Bar>{
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<Foobar>{
public void write(Foobar item) throws Exception {
assertTrue(item instanceof Foobar);
}
public void clear() throws ClearFailedException {
}
public void flush() throws FlushFailedException {
}
}
}

View File

@@ -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<Object, Object> processor = new ItemTransformerItemWriter<Object, Object>();
@SuppressWarnings("unchecked")
private ItemTransformer<Object, Object> transformer = EasyMock.createMock(ItemTransformer.class);
@SuppressWarnings("unchecked")
private ItemWriter<Object> 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
}
}
}

View File

@@ -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<T> implements FactoryBean, BeanNameAwa
job.setName(name);
job.setJobRepository(jobRepository);
SimpleStepFactoryBean<T> stepFactory = new SimpleStepFactoryBean<T>();
SimpleStepFactoryBean<T, T> stepFactory = new SimpleStepFactoryBean<T, T>();
stepFactory.setBeanName("step");
Assert.state((itemReader instanceof FlatFileItemReader) || (itemReader instanceof StaxEventItemReader),

View File

@@ -53,7 +53,7 @@ public class ChunkMessageItemWriterIntegrationTests {
@Qualifier("replies")
private PollableChannel replies;
private SimpleStepFactoryBean<Object> factory;
private SimpleStepFactoryBean<Object,Object> factory;
private SimpleJobRepository jobRepository;
@@ -63,7 +63,7 @@ public class ChunkMessageItemWriterIntegrationTests {
@Before
public void setUp() {
factory = new SimpleStepFactoryBean<Object>();
factory = new SimpleStepFactoryBean<Object,Object>();
jobRepository = new SimpleJobRepository(new MapJobInstanceDao(),
new MapJobExecutionDao(), new MapStepExecutionDao(), new MapExecutionContextDao());
factory.setJobRepository(jobRepository);

View File

@@ -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

View File

@@ -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 <code>Order</code> object to a String.
* Converts <code>Order</code> object to a list of strings.
*
* @author Dave Syer
*/
public class OrderTransformer implements ItemTransformer<Order, List<String>> {
public class OrderProcessor implements ItemProcessor<Order, List<String>> {
/**
* Aggregators for all types of lines in the output file
@@ -44,7 +45,7 @@ public class OrderTransformer implements ItemTransformer<Order, List<String>> {
* Converts information from an Order object to a collection of Strings for
* output.
*/
public List<String> transform(Order order) {
public List<String> process(Order order) {
List<String> result = new ArrayList<String>();

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
@@ -21,48 +20,32 @@
</list>
</property>
<property name="itemReader">
<bean
class="org.springframework.batch.item.validator.ValidatingItemReader">
<bean class="org.springframework.batch.item.validator.ValidatingItemReader">
<property name="itemReader">
<bean
class="org.springframework.batch.sample.domain.order.internal.OrderItemReader">
<property name="fieldSetReader"
ref="fileItemReader" />
<property name="headerMapper"
ref="headerFieldSetMapper" />
<property name="customerMapper"
ref="customerFieldSetMapper" />
<property name="addressMapper"
ref="addressFieldSetMapper" />
<property name="billingMapper"
ref="billingFieldSetMapper" />
<property name="itemMapper"
ref="orderItemFieldSetMapper" />
<property name="shippingMapper"
ref="shippingFieldSetMapper" />
<bean class="org.springframework.batch.sample.domain.order.internal.OrderItemReader">
<property name="fieldSetReader" ref="fileItemReader" />
<property name="headerMapper" ref="headerFieldSetMapper" />
<property name="customerMapper" ref="customerFieldSetMapper" />
<property name="addressMapper" ref="addressFieldSetMapper" />
<property name="billingMapper" ref="billingFieldSetMapper" />
<property name="itemMapper" ref="orderItemFieldSetMapper" />
<property name="shippingMapper" ref="shippingFieldSetMapper" />
</bean>
</property>
<property name="validator" ref="validator" />
</bean>
</property>
<property name="itemWriter" ref="orderWriter" />
<property name="itemWriter" ref="fileItemWriter" />
<property name="itemProcessor">
<bean class="org.springframework.batch.sample.domain.order.internal.OrderProcessor">
<property name="aggregators" ref="outputAggregators" />
</bean>
</property>
</bean>
</property>
</bean>
<bean id="orderWriter"
class="org.springframework.batch.item.transform.ItemTransformerItemWriter">
<property name="delegate" ref="fileItemWriter" />
<property name="itemTransformer">
<bean
class="org.springframework.batch.sample.domain.order.internal.OrderTransformer">
<property name="aggregators" ref="outputAggregators" />
</bean>
</property>
</bean>
<bean id="headerFieldSetMapper"
class="org.springframework.batch.sample.domain.order.internal.HeaderFieldSetMapper" />
<bean id="headerFieldSetMapper" class="org.springframework.batch.sample.domain.order.internal.HeaderFieldSetMapper" />
<bean id="customerFieldSetMapper"
class="org.springframework.batch.sample.domain.order.internal.CustomerFieldSetMapper" />
<bean id="addressFieldSetMapper"
@@ -74,11 +57,9 @@
<bean id="shippingFieldSetMapper"
class="org.springframework.batch.sample.domain.order.internal.ShippingFieldSetMapper" />
<bean id="validator"
class="org.springframework.batch.item.validator.SpringValidator">
<bean id="validator" class="org.springframework.batch.item.validator.SpringValidator">
<property name="validator">
<bean id="orderValidator"
class="org.springmodules.validation.valang.ValangValidator">
<bean id="orderValidator" class="org.springmodules.validation.valang.ValangValidator">
<property name="valang">
<value>
<![CDATA[
@@ -155,14 +136,12 @@
</bean>
<!-- "{" <key> : <rule> : <message> : [ <error_code> [ : <error_parameters> ] ] "}" -->
<bean id="fileInputLocator"
class="org.springframework.core.io.ClassPathResource">
<bean id="fileInputLocator" class="org.springframework.core.io.ClassPathResource">
<constructor-arg type="java.lang.String"
value="data/multilineOrderJob/input/20070122.teststream.multilineOrderStep.txt" />
</bean>
<bean id="fileOutputLocator"
class="org.springframework.core.io.FileSystemResource">
<bean id="fileOutputLocator" class="org.springframework.core.io.FileSystemResource">
<constructor-arg type="java.lang.String"
value="target/test-outputs/20070122.teststream.multilineOrderStep.TEMP.txt" />
</bean>

View File

@@ -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<String, LineAggregator<Object[]>> aggregators = new HashMap<String, LineAggregator<Object[]>>();
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<String> list = converter.transform(order);
List<String> list = converter.process(order);
// verify method calls
assertEquals(7, list.size());