OPEN - issue BATCH-771: Refactor Listeners for chunk changes

Favour collections over arrays in the composite listeners
This commit is contained in:
dsyer
2008-08-26 16:21:33 +00:00
parent 894c9dc2cf
commit b55fc3b475
18 changed files with 92 additions and 89 deletions

View File

@@ -24,7 +24,7 @@ import org.springframework.batch.item.ItemWriter;
* @author Lucas Ward
*
*/
public interface ItemReadListener extends StepListener {
public interface ItemReadListener<T> extends StepListener {
/**
* Called before {@link ItemReader#read()}
@@ -36,7 +36,7 @@ public interface ItemReadListener extends StepListener {
*
* @param item returned from read()
*/
void afterRead(Object item);
void afterRead(T item);
/**
* Called if an error occurs while trying to read.

View File

@@ -23,7 +23,7 @@ package org.springframework.batch.core;
* @author Robert Kasanicky
*
*/
public interface SkipListener extends StepListener {
public interface SkipListener<S> extends StepListener {
/**
* Callback for a failure on read that is legal, so is not going to be
@@ -44,6 +44,6 @@ public interface SkipListener extends StepListener {
* @param item the failed item
* @param t the cause of the failure
*/
void onSkipInWrite(Object item, Throwable t);
void onSkipInWrite(S item, Throwable t);
}

View File

@@ -15,8 +15,8 @@
*/
package org.springframework.batch.core.listener;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.springframework.batch.core.ChunkListener;
import org.springframework.core.Ordered;
@@ -34,8 +34,8 @@ public class CompositeChunkListener implements ChunkListener {
*
* @param listeners
*/
public void setListeners(ChunkListener[] listeners) {
this.listeners.setItems(Arrays.asList(listeners));
public void setListeners(List<? extends ChunkListener> listeners) {
this.listeners.setItems(listeners);
}
/**
@@ -55,7 +55,7 @@ public class CompositeChunkListener implements ChunkListener {
*/
public void afterChunk() {
for (Iterator<ChunkListener> iterator = listeners.iterator(); iterator.hasNext();) {
ChunkListener listener = (ChunkListener) iterator.next();
ChunkListener listener = iterator.next();
listener.afterChunk();
}
}
@@ -67,7 +67,7 @@ public class CompositeChunkListener implements ChunkListener {
*/
public void beforeChunk() {
for (Iterator<ChunkListener> iterator = listeners.reverse(); iterator.hasNext();) {
ChunkListener listener = (ChunkListener) iterator.next();
ChunkListener listener = iterator.next();
listener.beforeChunk();
}
}

View File

@@ -15,8 +15,8 @@
*/
package org.springframework.batch.core.listener;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobExecutionListener;
@@ -35,8 +35,8 @@ public class CompositeExecutionJobListener implements JobExecutionListener {
*
* @param listeners
*/
public void setListeners(JobExecutionListener[] listeners) {
this.listeners.setItems(Arrays.asList(listeners));
public void setListeners(List<? extends JobExecutionListener> listeners) {
this.listeners.setItems(listeners);
}
/**
@@ -55,7 +55,7 @@ public class CompositeExecutionJobListener implements JobExecutionListener {
*/
public void afterJob(JobExecution jobExecution) {
for (Iterator<JobExecutionListener> iterator = listeners.reverse(); iterator.hasNext();) {
JobExecutionListener listener = (JobExecutionListener) iterator.next();
JobExecutionListener listener = iterator.next();
listener.afterJob(jobExecution);
}
}
@@ -67,7 +67,7 @@ public class CompositeExecutionJobListener implements JobExecutionListener {
*/
public void beforeJob(JobExecution jobExecution) {
for (Iterator<JobExecutionListener> iterator = listeners.iterator(); iterator.hasNext();) {
JobExecutionListener listener = (JobExecutionListener) iterator.next();
JobExecutionListener listener = iterator.next();
listener.beforeJob(jobExecution);
}
}
@@ -80,7 +80,7 @@ public class CompositeExecutionJobListener implements JobExecutionListener {
*/
public void onError(JobExecution jobExecution, Throwable e) {
for (Iterator<JobExecutionListener> iterator = listeners.reverse(); iterator.hasNext();) {
JobExecutionListener listener = (JobExecutionListener) iterator.next();
JobExecutionListener listener = iterator.next();
listener.onError(jobExecution, e);
}
@@ -93,7 +93,7 @@ public class CompositeExecutionJobListener implements JobExecutionListener {
*/
public void onInterrupt(JobExecution jobExecution) {
for (Iterator<JobExecutionListener> iterator = listeners.reverse(); iterator.hasNext();) {
JobExecutionListener listener = (JobExecutionListener) iterator.next();
JobExecutionListener listener = iterator.next();
listener.onInterrupt(jobExecution);
}

View File

@@ -15,8 +15,8 @@
*/
package org.springframework.batch.core.listener;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.springframework.batch.core.ItemReadListener;
import org.springframework.core.Ordered;
@@ -26,17 +26,17 @@ import org.springframework.core.Ordered;
* @author Dave Syer
*
*/
public class CompositeItemReadListener implements ItemReadListener {
public class CompositeItemReadListener<T> implements ItemReadListener<T> {
private OrderedComposite<ItemReadListener> listeners = new OrderedComposite<ItemReadListener>();
private OrderedComposite<ItemReadListener<? super T>> listeners = new OrderedComposite<ItemReadListener<? super T>>();
/**
* Public setter for the listeners.
*
* @param itemReadListeners
*/
public void setListeners(ItemReadListener[] itemReadListeners) {
this.listeners.setItems(Arrays.asList(itemReadListeners));
public void setListeners(List<? extends ItemReadListener<? super T>> itemReadListeners) {
this.listeners.setItems(itemReadListeners);
}
/**
@@ -44,7 +44,7 @@ public class CompositeItemReadListener implements ItemReadListener {
*
* @param itemReaderListener
*/
public void register(ItemReadListener itemReaderListener) {
public void register(ItemReadListener<? super T> itemReaderListener) {
listeners.add(itemReaderListener);
}
@@ -53,9 +53,9 @@ public class CompositeItemReadListener implements ItemReadListener {
* prioritising those that implement {@link Ordered}.
* @see org.springframework.batch.core.ItemReadListener#afterRead(java.lang.Object)
*/
public void afterRead(Object item) {
for (Iterator<ItemReadListener> iterator = listeners.reverse(); iterator.hasNext();) {
ItemReadListener listener = (ItemReadListener) iterator.next();
public void afterRead(T item) {
for (Iterator<ItemReadListener<? super T>> iterator = listeners.reverse(); iterator.hasNext();) {
ItemReadListener<? super T> listener = iterator.next();
listener.afterRead(item);
}
}
@@ -66,8 +66,8 @@ public class CompositeItemReadListener implements ItemReadListener {
* @see org.springframework.batch.core.ItemReadListener#beforeRead()
*/
public void beforeRead() {
for (Iterator<ItemReadListener> iterator = listeners.iterator(); iterator.hasNext();) {
ItemReadListener listener = (ItemReadListener) iterator.next();
for (Iterator<ItemReadListener<? super T>> iterator = listeners.iterator(); iterator.hasNext();) {
ItemReadListener<? super T> listener = iterator.next();
listener.beforeRead();
}
}
@@ -78,8 +78,8 @@ public class CompositeItemReadListener implements ItemReadListener {
* @see org.springframework.batch.core.ItemReadListener#onReadError(java.lang.Exception)
*/
public void onReadError(Exception ex) {
for (Iterator<ItemReadListener> iterator = listeners.iterator(); iterator.hasNext();) {
ItemReadListener listener = (ItemReadListener) iterator.next();
for (Iterator<ItemReadListener<? super T>> iterator = listeners.iterator(); iterator.hasNext();) {
ItemReadListener<? super T> listener = iterator.next();
listener.onReadError(ex);
}
}

View File

@@ -35,7 +35,7 @@ public class CompositeItemWriteListener<S> implements ItemWriteListener<S> {
*
* @param itemWriteListeners
*/
public void setListeners(List<ItemWriteListener<? super S>> itemWriteListeners) {
public void setListeners(List<? extends ItemWriteListener<? super S>> itemWriteListeners) {
this.listeners.setItems(itemWriteListeners);
}

View File

@@ -15,8 +15,8 @@
*/
package org.springframework.batch.core.listener;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.springframework.batch.core.SkipListener;
import org.springframework.core.Ordered;
@@ -25,17 +25,17 @@ import org.springframework.core.Ordered;
* @author Dave Syer
*
*/
public class CompositeSkipListener implements SkipListener {
public class CompositeSkipListener<S> implements SkipListener<S> {
private OrderedComposite<SkipListener> listeners = new OrderedComposite<SkipListener>();
private OrderedComposite<SkipListener<? super S>> listeners = new OrderedComposite<SkipListener<? super S>>();
/**
* Public setter for the listeners.
*
* @param listeners
*/
public void setListeners(SkipListener[] listeners) {
this.listeners.setItems(Arrays.asList(listeners));
public void setListeners(List<? extends SkipListener<? super S>> listeners) {
this.listeners.setItems(listeners);
}
/**
@@ -43,7 +43,7 @@ public class CompositeSkipListener implements SkipListener {
*
* @param listener
*/
public void register(SkipListener listener) {
public void register(SkipListener<? super S> listener) {
listeners.add(listener);
}
@@ -53,8 +53,8 @@ public class CompositeSkipListener implements SkipListener {
* @see org.springframework.batch.core.SkipListener#onSkipInRead(java.lang.Throwable)
*/
public void onSkipInRead(Throwable t) {
for (Iterator<SkipListener> iterator = listeners.iterator(); iterator.hasNext();) {
SkipListener listener = (SkipListener) iterator.next();
for (Iterator<SkipListener<? super S>> iterator = listeners.iterator(); iterator.hasNext();) {
SkipListener<? super S> listener = iterator.next();
listener.onSkipInRead(t);
}
}
@@ -65,9 +65,9 @@ public class CompositeSkipListener implements SkipListener {
* @see org.springframework.batch.core.SkipListener#onSkipInWrite(java.lang.Object,
* java.lang.Throwable)
*/
public void onSkipInWrite(Object item, Throwable t) {
for (Iterator<SkipListener> iterator = listeners.iterator(); iterator.hasNext();) {
SkipListener listener = (SkipListener) iterator.next();
public void onSkipInWrite(S item, Throwable t) {
for (Iterator<SkipListener<? super S>> iterator = listeners.iterator(); iterator.hasNext();) {
SkipListener<? super S> listener = iterator.next();
listener.onSkipInWrite(item, t);
}
}

View File

@@ -28,7 +28,7 @@ import org.springframework.batch.core.ItemWriteListener;
* @author Lucas Ward
*
*/
public class ItemListenerSupport<S> implements ItemWriteListener<S>, ItemReadListener {
public class ItemListenerSupport<T,S> implements ItemWriteListener<S>, ItemReadListener<T> {
/* (non-Javadoc)
* @see org.springframework.batch.core.domain.ItemWriteListener#afterWrite()
@@ -51,7 +51,7 @@ public class ItemListenerSupport<S> implements ItemWriteListener<S>, ItemReadLis
/* (non-Javadoc)
* @see org.springframework.batch.core.domain.ItemReadListener#afterRead(java.lang.Object)
*/
public void afterRead(Object item) {
public void afterRead(T item) {
}
/* (non-Javadoc)

View File

@@ -31,18 +31,18 @@ import org.springframework.batch.repeat.ExitStatus;
* @author Dave Syer
*
*/
public class MulticasterBatchListener<S> implements StepExecutionListener, ChunkListener, ItemReadListener,
ItemWriteListener<S>, SkipListener {
public class MulticasterBatchListener<T, S> implements StepExecutionListener, ChunkListener, ItemReadListener<T>,
ItemWriteListener<S>, SkipListener<S> {
private CompositeStepExecutionListener stepListener = new CompositeStepExecutionListener();
private CompositeChunkListener chunkListener = new CompositeChunkListener();
private CompositeItemReadListener itemReadListener = new CompositeItemReadListener();
private CompositeItemReadListener<T> itemReadListener = new CompositeItemReadListener<T>();
private CompositeItemWriteListener<S> itemWriteListener = new CompositeItemWriteListener<S>();
private CompositeSkipListener skipListener = new CompositeSkipListener();
private CompositeSkipListener<S> skipListener = new CompositeSkipListener<S>();
/**
* Initialise the listener instance.
@@ -55,12 +55,11 @@ public class MulticasterBatchListener<S> implements StepExecutionListener, Chunk
* Register each of the objects as listeners. Once registered, calls to the
* {@link MulticasterBatchListener} broadcast to the individual listeners.
*
* @param listeners an array of listener objects of types known to the
* multicaster.
* @param listeners listener objects of types known to the multicaster.
*/
public void setListeners(StepListener[] listeners) {
for (int i = 0; i < listeners.length; i++) {
register(listeners[i]);
public void setListeners(List<? extends StepListener> listeners) {
for (StepListener stepListener : listeners) {
register(stepListener);
}
}
@@ -157,7 +156,7 @@ public class MulticasterBatchListener<S> implements StepExecutionListener, Chunk
* @param item
* @see org.springframework.batch.core.listener.CompositeItemReadListener#afterRead(java.lang.Object)
*/
public void afterRead(Object item) {
public void afterRead(T item) {
try {
itemReadListener.afterRead(item);
}
@@ -246,7 +245,7 @@ public class MulticasterBatchListener<S> implements StepExecutionListener, Chunk
* @see org.springframework.batch.core.listener.CompositeSkipListener#onSkipInWrite(java.lang.Object,
* java.lang.Throwable)
*/
public void onSkipInWrite(Object item, Throwable t) {
public void onSkipInWrite(S item, Throwable t) {
skipListener.onSkipInWrite(item, t);
}

View File

@@ -43,7 +43,7 @@ class OrderedComposite<S> {
*
* @param items
*/
public void setItems(List<S> items) {
public void setItems(List<? extends S> items) {
unordered.clear();
ordered.clear();
for (S s : items) {

View File

@@ -31,8 +31,8 @@ import org.springframework.batch.repeat.ExitStatus;
* @author Lucas Ward
*
*/
public class StepListenerSupport<S> implements StepExecutionListener, ChunkListener,
ItemReadListener, ItemWriteListener<S> {
public class StepListenerSupport<T,S> implements StepExecutionListener, ChunkListener,
ItemReadListener<T>, ItemWriteListener<S> {
/* (non-Javadoc)
* @see org.springframework.batch.core.domain.StepListener#afterStep(StepExecution stepExecution)
@@ -69,7 +69,7 @@ public class StepListenerSupport<S> implements StepExecutionListener, ChunkListe
/* (non-Javadoc)
* @see org.springframework.batch.core.domain.ItemReadListener#afterRead(java.lang.Object)
*/
public void afterRead(Object item) {
public void afterRead(T item) {
}
/* (non-Javadoc)

View File

@@ -30,7 +30,7 @@ import org.springframework.batch.core.listener.ItemListenerSupport;
* @author Lucas Ward
*
*/
public class DefaultItemFailureHandler extends ItemListenerSupport<Object> {
public class DefaultItemFailureHandler extends ItemListenerSupport<Object,Object> {
protected static final Log logger = LogFactory
.getLog(DefaultItemFailureHandler.class);

View File

@@ -60,7 +60,7 @@ public class ItemOrientedStepHandler<T, S> implements StepHandler {
private final RepeatOperations repeatOperations;
final private MulticasterBatchListener<S> listener = new MulticasterBatchListener<S>();
final private MulticasterBatchListener<T,S> listener = new MulticasterBatchListener<T,S>();
/**
* @param itemReader
@@ -291,7 +291,7 @@ public class ItemOrientedStepHandler<T, S> implements StepHandler {
* Public getter for the listener.
* @return the listener
*/
protected MulticasterBatchListener<S> getListener() {
protected MulticasterBatchListener<T,S> getListener() {
return listener;
}

View File

@@ -15,12 +15,15 @@
*/
package org.springframework.batch.core.listener;
import static org.easymock.EasyMock.*;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import java.util.ArrayList;
import org.junit.Before;
import org.junit.Test;
import org.springframework.batch.core.ItemReadListener;
import org.springframework.batch.core.listener.CompositeItemReadListener;
/**
* @author Lucas Ward
@@ -28,14 +31,14 @@ import org.springframework.batch.core.listener.CompositeItemReadListener;
*/
public class CompositeItemReadListenerTests {
ItemReadListener listener;
CompositeItemReadListener compositeListener;
ItemReadListener<Object> listener;
CompositeItemReadListener<Object> compositeListener;
@SuppressWarnings("unchecked")
@Before
public void setUp() throws Exception {
listener = createMock(ItemReadListener.class);
compositeListener = new CompositeItemReadListener();
compositeListener = new CompositeItemReadListener<Object>();
compositeListener.register(listener);
}
@@ -68,8 +71,12 @@ public class CompositeItemReadListenerTests {
}
@Test
public void testSetListners() throws Exception {
compositeListener.setListeners(new ItemReadListener[] {listener});
public void testSetListeners() throws Exception {
compositeListener.setListeners(new ArrayList<ItemReadListener<? super Object>>() {
{
add(listener);
}
});
listener.beforeRead();
replay(listener);
compositeListener.beforeRead();

View File

@@ -74,7 +74,7 @@ public class CompositeItemWriteListenerTests {
}
@Test
public void testSetListners() throws Exception {
public void testSetListeners() throws Exception {
compositeListener.setListeners(new ArrayList<ItemWriteListener<? super Object>>() {
{
add(listener);

View File

@@ -16,12 +16,12 @@
package org.springframework.batch.core.listener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import junit.framework.TestCase;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobExecutionListener;
import org.springframework.batch.core.JobInstance;
/**
@@ -36,10 +36,10 @@ public class CompositeJobExecutionListenerTests extends TestCase {
/**
* Test method for
* {@link org.springframework.batch.core.listener.CompositeExecutionJobListener#setListeners(org.springframework.batch.core.JobExecutionListener[])}.
* {@link org.springframework.batch.core.listener.CompositeExecutionJobListener#setListeners(List)}
*/
public void testSetListeners() {
listener.setListeners(new JobExecutionListener[] { new JobExecutionListenerSupport() {
listener.setListeners(Arrays.asList(new JobExecutionListenerSupport() {
public void afterJob(JobExecution jobExecution) {
list.add("fail");
}
@@ -47,14 +47,15 @@ public class CompositeJobExecutionListenerTests extends TestCase {
public void afterJob(JobExecution jobExecution) {
list.add("continue");
}
} });
}));
listener.afterJob(null);
assertEquals(2, list.size());
}
/**
* Test method for
* {@link org.springframework.batch.core.listener.CompositeExecutionJobListener#register(org.springframework.batch.core.JobExecutionListener)}.
* {@link org.springframework.batch.core.listener.CompositeExecutionJobListener#register(org.springframework.batch.core.JobExecutionListener)}
* .
*/
public void testSetListener() {
listener.register(new JobExecutionListenerSupport() {
@@ -68,7 +69,8 @@ public class CompositeJobExecutionListenerTests extends TestCase {
/**
* Test method for
* {@link org.springframework.batch.core.listener.CompositeExecutionJobListener#beforeJob(JobExecution)}.
* {@link org.springframework.batch.core.listener.CompositeExecutionJobListener#beforeJob(JobExecution)}
* .
*/
public void testOpen() {
listener.register(new JobExecutionListenerSupport() {

View File

@@ -18,12 +18,12 @@ package org.springframework.batch.core.listener;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.util.Arrays;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.StepListener;
import org.springframework.batch.repeat.ExitStatus;
/**
@@ -32,7 +32,7 @@ import org.springframework.batch.repeat.ExitStatus;
*/
public class MulticasterBatchListenerTests {
private MulticasterBatchListener<String> multicast = new MulticasterBatchListener<String>();
private MulticasterBatchListener<Integer, String> multicast = new MulticasterBatchListener<Integer, String>();
private int count = 0;
@@ -43,20 +43,15 @@ public class MulticasterBatchListenerTests {
multicast.register(new CountingStepListenerSupport());
}
/**
* Test method for
* {@link org.springframework.batch.core.listener.MulticasterBatchListener#setListeners(org.springframework.batch.core.StepListener[])}
* .
*/
@Test
public void testSetListeners() {
multicast.setListeners(new StepListener[] { new StepListenerSupport<String>() {
multicast.setListeners(Arrays.asList(new StepListenerSupport<Integer, String>() {
@Override
public ExitStatus afterStep(StepExecution stepExecution) {
count++;
return super.afterStep(stepExecution);
}
} });
}));
multicast.afterStep(null);
// setListeners is cumulative (should be OK if used for DI)
assertEquals(2, count);
@@ -69,7 +64,7 @@ public class MulticasterBatchListenerTests {
*/
@Test
public void testRegister() {
multicast.register(new StepListenerSupport<String>() {
multicast.register(new StepListenerSupport<Integer, String>() {
@Override
public ExitStatus afterStep(StepExecution stepExecution) {
count++;
@@ -502,7 +497,7 @@ public class MulticasterBatchListenerTests {
* @author Dave Syer
*
*/
private final class CountingStepListenerSupport extends StepListenerSupport<String> {
private final class CountingStepListenerSupport extends StepListenerSupport<Integer, String> {
@Override
public void onReadError(Exception ex) {
count++;
@@ -536,7 +531,7 @@ public class MulticasterBatchListenerTests {
* (java.lang.Object)
*/
@Override
public void afterRead(Object item) {
public void afterRead(Integer item) {
count++;
if (error) {
throw new RuntimeException("listener error");

View File

@@ -134,7 +134,7 @@ public class SimpleStepFactoryBeanTests {
throw new RuntimeException("Error!");
}
});
factory.setListeners(new StepListener[] { new ItemListenerSupport<String>() {
factory.setListeners(new StepListener[] { new ItemListenerSupport<String,String>() {
@Override
public void onReadError(Exception ex) {
listened.add(ex);