RESOLVED - issue BATCH-1520: Allow null ItemWriter as long as ItemProcessor is provided

This commit is contained in:
dsyer
2010-03-01 11:37:32 +00:00
parent b6aca5fa05
commit 3d6036b93e
5 changed files with 86 additions and 16 deletions

View File

@@ -183,6 +183,9 @@ public abstract class AbstractListenerFactoryBean implements FactoryBean, Initia
* interface, or contains the marker annotations
*/
public static boolean isListener(Object target, Class<?> listenerType, ListenerMetaData[] metaDataValues) {
if (target == null) {
return false;
}
if (listenerType.isInstance(target)) {
return true;
}

View File

@@ -113,6 +113,13 @@ public class SimpleChunkProcessor<I, O> implements ChunkProcessor<I>, Initializi
* @throws Exception
*/
protected final O doProcess(I item) throws Exception {
if (itemProcessor==null) {
@SuppressWarnings("unchecked")
O result = (O) item;
return result;
}
try {
listener.beforeProcess(item);
O result = itemProcessor.process(item);
@@ -123,6 +130,7 @@ public class SimpleChunkProcessor<I, O> implements ChunkProcessor<I>, Initializi
listener.onProcessError(item, e);
throw e;
}
}
/**
@@ -132,6 +140,11 @@ public class SimpleChunkProcessor<I, O> implements ChunkProcessor<I>, Initializi
* @throws Exception
*/
protected final void doWrite(List<O> items) throws Exception {
if (itemWriter==null) {
return;
}
try {
listener.beforeWrite(items);
writeItems(items);
@@ -141,6 +154,7 @@ public class SimpleChunkProcessor<I, O> implements ChunkProcessor<I>, Initializi
listener.onWriteError(e, items);
throw e;
}
}
/**
@@ -153,7 +167,9 @@ public class SimpleChunkProcessor<I, O> implements ChunkProcessor<I>, Initializi
}
protected void writeItems(List<O> items) throws Exception {
itemWriter.write(items);
if (itemWriter!=null) {
itemWriter.write(items);
}
}
public final void process(StepContribution contribution, Chunk<I> inputs) throws Exception {

View File

@@ -77,6 +77,8 @@ public class SimpleStepFactoryBean<T, S> implements FactoryBean, BeanNameAware {
private ItemReader<? extends T> itemReader;
private ItemProcessor<? super T, ? extends S> itemProcessor;
private ItemWriter<? super S> itemWriter;
private PlatformTransactionManager transactionManager;
@@ -97,13 +99,6 @@ public class SimpleStepFactoryBean<T, S> implements FactoryBean, BeanNameAware {
protected final Log logger = LogFactory.getLog(getClass());
private ItemProcessor<? super T, ? extends S> itemProcessor = new ItemProcessor<T, S>() {
@SuppressWarnings("unchecked")
public S process(T item) throws Exception {
return (S) item;
}
};
private int commitInterval = 0;
private TaskExecutor taskExecutor;
@@ -469,9 +464,9 @@ public class SimpleStepFactoryBean<T, S> implements FactoryBean, BeanNameAware {
*/
protected void applyConfiguration(TaskletStep step) {
Assert.notNull(getItemReader(), "ItemReader must be provided");
Assert.notNull(getItemWriter(), "ItemWriter must be provided");
Assert.notNull(transactionManager, "TransactionManager must be provided");
Assert.state(getItemReader()!=null, "ItemReader must be provided");
Assert.state(getItemWriter()!=null || getItemProcessor()!=null, "ItemWriter or ItemProcessor must be provided");
Assert.state(transactionManager!=null, "TransactionManager must be provided");
step.setTransactionManager(transactionManager);
step.setTransactionAttribute(getTransactionAttribute());

View File

@@ -296,6 +296,30 @@ public class FaultTolerantStepFactoryBeanTests {
.getName()));
}
@Test
public void testNullWriter() throws Exception {
factory.setItemWriter(null);
Step step = (Step) factory.getObject();
step.execute(stepExecution);
assertEquals(0, stepExecution.getSkipCount());
assertEquals(0, stepExecution.getReadSkipCount());
assertEquals(5, stepExecution.getReadCount());
// Write count is incremented even if nothing happens
assertEquals(5, stepExecution.getWriteCount());
assertEquals(0, stepExecution.getFilterCount());
assertEquals(0, stepExecution.getRollbackCount());
// writer skips "4"
assertTrue(reader.getRead().contains("4"));
assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus());
assertStepExecutionsAreEqual(stepExecution, repository.getLastStepExecution(jobExecution.getJobInstance(), step
.getName()));
}
/**
* Check items causing errors are skipped as expected.
*/

View File

@@ -47,6 +47,7 @@ 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.AbstractStep;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.support.ListItemReader;
@@ -83,7 +84,7 @@ public class SimpleStepFactoryBeanTests {
job.setBeanName("simpleJob");
}
@Test(expected = IllegalArgumentException.class)
@Test(expected = IllegalStateException.class)
public void testMandatoryProperties() throws Exception {
new SimpleStepFactoryBean<String, String>().getObject();
}
@@ -325,11 +326,15 @@ public class SimpleStepFactoryBeanTests {
final List<String> listenerCalls = new ArrayList<String>();
class TestItemListenerWriter implements ItemWriter<String>, ItemReadListener<String>,
ItemWriteListener<String>, ItemProcessListener<String, String>, ChunkListener {
class TestItemListenerWriter implements ItemWriter<String>, ItemProcessor<String, String>,
ItemReadListener<String>, ItemWriteListener<String>, ItemProcessListener<String, String>, ChunkListener {
public void write(List<? extends String> items) throws Exception {
}
public String process(String item) throws Exception {
return item;
}
public void afterRead(String item) {
listenerCalls.add("read");
}
@@ -369,7 +374,9 @@ public class SimpleStepFactoryBeanTests {
}
factory.setItemWriter(new TestItemListenerWriter());
TestItemListenerWriter itemWriter = new TestItemListenerWriter();
factory.setItemWriter(itemWriter);
factory.setItemProcessor(itemWriter);
Step step = (Step) factory.getObject();
@@ -409,7 +416,7 @@ public class SimpleStepFactoryBeanTests {
}
TestItemListenerWriter itemWriter = new TestItemListenerWriter();
factory.setListeners(new StepListener[] {itemWriter});
factory.setListeners(new StepListener[] { itemWriter });
factory.setItemWriter(itemWriter);
Step step = (Step) factory.getObject();
@@ -425,6 +432,31 @@ public class SimpleStepFactoryBeanTests {
}
@Test
public void testNullWriter() throws Exception {
SimpleStepFactoryBean<String, String> factory = getStepFactory(new String[] { "foo", "bar", "spam" });
factory.setItemWriter(null);
factory.setItemProcessor(new ItemProcessor<String, String>() {
public String process(String item) throws Exception {
written.add(item);
return null;
}
});
Step step = (Step) factory.getObject();
job.setSteps(Collections.singletonList(step));
JobExecution jobExecution = repository.createJobExecution(job.getName(), new JobParameters());
job.execute(jobExecution);
assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus());
assertEquals("[foo, bar, spam]", written.toString());
}
private SimpleStepFactoryBean<String, String> getStepFactory(String... args) throws Exception {
SimpleStepFactoryBean<String, String> factory = new SimpleStepFactoryBean<String, String>();