OPEN - issue BATCH-385: Merge user attributes in StepContext with ExecutionContext

http://jira.springframework.org/browse/BATCH-385
OPEN - issue BATCH-378: RepeatListener is confusing and too generic to use for 'intercepting' a step 
http://jira.springframework.org/browse/BATCH-378

Javadocs plus new setter.
This commit is contained in:
dsyer
2008-02-29 10:40:54 +00:00
parent c41d38c684
commit f4f3adac86
3 changed files with 86 additions and 19 deletions

View File

@@ -25,7 +25,6 @@ import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.core.domain.JobInterruptedException;
import org.springframework.batch.core.domain.StepContribution;
import org.springframework.batch.core.domain.StepExecution;
import org.springframework.batch.core.domain.StepListener;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.runtime.ExitStatusExceptionClassifier;
import org.springframework.batch.core.tasklet.Tasklet;
@@ -102,8 +101,13 @@ public class ItemOrientedStep extends AbstractStep implements InitializingBean {
/**
* Register each of the objects as listeners. The {@link ItemOrientedStep}
* accepts listeners of type {@link ItemStream}, {@link StepListener},
* TODO: complete the list.
* accepts listeners of type {@link ItemStream} and {@link BatchListener}.
* The {@link ItemReader} and {@link ItemWriter} are automatically
* registered, but it doesn't hurt to also register them here. Injected
* dependencies of the reader and writer are not automatically registered,
* so if you implement {@link ItemWriter} using delegation to another object
* which itself is a {@link BatchListener}, you need to register the
* delegate here.
*
* @param listeners an array of listener objects of known types.
*/
@@ -112,6 +116,15 @@ public class ItemOrientedStep extends AbstractStep implements InitializingBean {
listener.register(listeners[i]);
}
}
/**
* Register the objects as a listener.
* @see #setListeners(Object[])
* @param listener the listener to set
*/
public void setListener(Object listener) {
this.listener.register(listener);
}
/**
* The {@link RepeatOperations} to use for the outer loop of the batch
@@ -232,9 +245,10 @@ public class ItemOrientedStep extends AbstractStep implements InitializingBean {
ExitStatus status = ExitStatus.FAILED;
final ExceptionHolder fatalException = new ExceptionHolder();
// This could go in applyConfiguration(), but some unit tests do not call that
possiblyRegisterStreams();
// This could go in applyConfiguration(), but some unit tests do not
// call that
possiblyRegisterStreams();
try {
@@ -300,7 +314,7 @@ public class ItemOrientedStep extends AbstractStep implements InitializingBean {
}
}
try {
result = result.and(listener.afterStep());
}
@@ -334,7 +348,7 @@ public class ItemOrientedStep extends AbstractStep implements InitializingBean {
synchronized (stepExecution) {
stepExecution.rollback();
}
try {
itemReader.reset();
itemWriter.clear();

View File

@@ -119,12 +119,26 @@ public class TaskletStep implements Step, InitializingBean, BeanNameAware {
private CompositeStepListener listener = new CompositeStepListener();
/**
* Register each of the objects as listeners. The {@link TaskletStep}
* accepts listeners of type {@link StepListener}. If the {@link Tasklet}
* itself implements this interface it will be registered automatically, but
* its injected dependencies will not be. This is a good way to get access
* to job parameters and execution context if the tasklet is parameterised.
*
* @param listeners an array of listener objects of known types.
*/
public void setListeners(StepListener[] listeners) {
for (int i = 0; i < listeners.length; i++) {
this.listener.register(listeners[i]);
}
}
/**
* Register the objects as a listener.
* @see #setListeners(Object[])
* @param listener the listener to set
*/
public void setListener(StepListener listener) {
this.listener.register(listener);
}
@@ -136,6 +150,9 @@ public class TaskletStep implements Step, InitializingBean, BeanNameAware {
public void afterPropertiesSet() throws Exception {
Assert.notNull(jobRepository, "JobRepository is mandatory for TaskletStep");
Assert.notNull(tasklet, "Tasklet is mandatory for TaskletStep");
if (tasklet instanceof StepListener) {
listener.register((StepListener) tasklet);
}
}
/**

View File

@@ -35,16 +35,17 @@ import org.springframework.batch.repeat.ExitStatus;
* @author Dave Syer
*
*/
public class ListenerMulticaster implements ItemStream, StepListener, ChunkListener, ItemReadListener, ItemWriteListener {
public class ListenerMulticaster implements ItemStream, StepListener, ChunkListener, ItemReadListener,
ItemWriteListener {
private CompositeItemStream stream = new CompositeItemStream();
private CompositeStepListener stepListener = new CompositeStepListener();
private CompositeChunkListener chunkListener = new CompositeChunkListener();
private CompositeItemReadListener itemReadListener = new CompositeItemReadListener();
private CompositeItemWriteListener itemWriteListener = new CompositeItemWriteListener();
/**
@@ -62,7 +63,8 @@ public class ListenerMulticaster implements ItemStream, StepListener, ChunkListe
/**
* Register the listener for callbacks on the appropriate interfaces
* implemented.
* implemented. Any {@link BatchListener} can be provided, or an
* {@link ItemStream}. Other types will be ignored.
*/
public void register(Object listener) {
if (listener instanceof StepListener) {
@@ -71,14 +73,14 @@ public class ListenerMulticaster implements ItemStream, StepListener, ChunkListe
if (listener instanceof ItemStream) {
this.stream.register((ItemStream) listener);
}
if(listener instanceof ChunkListener){
this.chunkListener.register((ChunkListener)listener);
if (listener instanceof ChunkListener) {
this.chunkListener.register((ChunkListener) listener);
}
if(listener instanceof ItemReadListener){
this.itemReadListener.register((ItemReadListener)listener);
if (listener instanceof ItemReadListener) {
this.itemReadListener.register((ItemReadListener) listener);
}
if(listener instanceof ItemWriteListener){
this.itemWriteListener.register((ItemWriteListener)listener);
if (listener instanceof ItemWriteListener) {
this.itemWriteListener.register((ItemWriteListener) listener);
}
}
@@ -133,34 +135,68 @@ public class ListenerMulticaster implements ItemStream, StepListener, ChunkListe
stream.update(executionContext);
}
/**
*
* @see org.springframework.batch.execution.listener.CompositeChunkListener#afterChunk()
*/
public void afterChunk() {
chunkListener.afterChunk();
}
/**
*
* @see org.springframework.batch.execution.listener.CompositeChunkListener#beforeChunk()
*/
public void beforeChunk() {
chunkListener.beforeChunk();
}
/**
* @param item
* @see org.springframework.batch.execution.listener.CompositeItemReadListener#afterRead(java.lang.Object)
*/
public void afterRead(Object item) {
itemReadListener.afterRead(item);
}
/**
*
* @see org.springframework.batch.execution.listener.CompositeItemReadListener#beforeRead()
*/
public void beforeRead() {
itemReadListener.beforeRead();
}
/**
* @param ex
* @see org.springframework.batch.execution.listener.CompositeItemReadListener#onReadError(java.lang.Exception)
*/
public void onReadError(Exception ex) {
itemReadListener.onReadError(ex);
}
/**
*
* @see org.springframework.batch.execution.listener.CompositeItemWriteListener#afterWrite()
*/
public void afterWrite() {
itemWriteListener.afterWrite();
}
/**
* @param item
* @see org.springframework.batch.execution.listener.CompositeItemWriteListener#beforeWrite(java.lang.Object)
*/
public void beforeWrite(Object item) {
itemWriteListener.beforeWrite(item);
}
/**
* @param ex
* @param item
* @see org.springframework.batch.execution.listener.CompositeItemWriteListener#onWriteError(java.lang.Exception,
* java.lang.Object)
*/
public void onWriteError(Exception ex, Object item) {
itemWriteListener.onWriteError(ex, item);
}