IN PROGRESS - issue BATCH-7: Remove transaction synchronization and state management from input/output sources (formerly buffering)
http://jira.springframework.org/browse/BATCH-7 Remove ResourceLifecycle and make existing implementations into ItemStream
This commit is contained in:
@@ -47,15 +47,15 @@ public class RestartableItemOrientedTasklet extends ItemOrientedTasklet implemen
|
||||
StreamContext itemProviderRestartData = null;
|
||||
StreamContext itemProcessorRestartData = null;
|
||||
|
||||
if (itemProvider != null) {
|
||||
itemProviderRestartData = itemProvider.getRestartData();
|
||||
}
|
||||
if (itemWriter != null) {
|
||||
itemProcessorRestartData = itemWriter.getRestartData();
|
||||
if (itemProvider instanceof ItemStream) {
|
||||
itemProviderRestartData = ((ItemStream) itemProvider).getRestartData();
|
||||
}
|
||||
|
||||
RestartableItemOrientedTaskletRestartData restartData = new RestartableItemOrientedTaskletRestartData(
|
||||
itemProviderRestartData, itemProcessorRestartData);
|
||||
if (itemWriter instanceof ItemStream) {
|
||||
itemProcessorRestartData = ((ItemStream) itemWriter).getRestartData();
|
||||
}
|
||||
|
||||
RestartableItemOrientedTaskletRestartData restartData = new RestartableItemOrientedTaskletRestartData(itemProviderRestartData, itemProcessorRestartData);
|
||||
|
||||
return restartData;
|
||||
}
|
||||
@@ -76,11 +76,11 @@ public class RestartableItemOrientedTasklet extends ItemOrientedTasklet implemen
|
||||
moduleRestartData = new RestartableItemOrientedTaskletRestartData(data.getProperties());
|
||||
}
|
||||
|
||||
if (itemProvider != null) {
|
||||
itemProvider.restoreFrom(moduleRestartData.readerData);
|
||||
if (itemProvider instanceof ItemStream) {
|
||||
((ItemStream) itemProvider).restoreFrom(moduleRestartData.readerData);
|
||||
}
|
||||
if (itemWriter != null) {
|
||||
itemWriter.restoreFrom(moduleRestartData.writerData);
|
||||
if (itemWriter instanceof ItemStream) {
|
||||
((ItemStream) itemWriter).restoreFrom(moduleRestartData.writerData);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,8 +100,10 @@ public class RestartableItemOrientedTasklet extends ItemOrientedTasklet implemen
|
||||
}
|
||||
|
||||
public RestartableItemOrientedTaskletRestartData(Properties data) {
|
||||
readerData = new GenericStreamContext(PropertiesConverter.stringToProperties(data.getProperty(READER_KEY)));
|
||||
writerData = new GenericStreamContext(PropertiesConverter.stringToProperties(data.getProperty(WRITER_KEY)));
|
||||
readerData = new GenericStreamContext(PropertiesConverter
|
||||
.stringToProperties(data.getProperty(READER_KEY)));
|
||||
writerData = new GenericStreamContext(PropertiesConverter.stringToProperties(data
|
||||
.getProperty(WRITER_KEY)));
|
||||
}
|
||||
|
||||
public Properties getProperties() {
|
||||
@@ -115,20 +117,18 @@ public class RestartableItemOrientedTasklet extends ItemOrientedTasklet implemen
|
||||
return props;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.batch.item.ItemStream#close()
|
||||
*/
|
||||
public void close() throws Exception {
|
||||
// no-op
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.batch.item.ItemStream#open()
|
||||
*/
|
||||
public void open() throws Exception {
|
||||
// no-op
|
||||
throw new UnsupportedOperationException("Not implemented.");
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.batch.item.ItemStream#close()
|
||||
*/
|
||||
public void close() throws Exception {
|
||||
throw new UnsupportedOperationException("Not implemented.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,11 +21,11 @@ import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.batch.item.writer.AbstractItemWriter;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.support.transaction.TransactionAwareProxyFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
public class EmptyItemWriter extends AbstractItemWriter implements InitializingBean {
|
||||
public class EmptyItemWriter implements ItemWriter, InitializingBean {
|
||||
|
||||
private boolean failed = false;
|
||||
|
||||
|
||||
@@ -25,10 +25,10 @@ import java.util.Properties;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.domain.JobSupport;
|
||||
import org.springframework.batch.core.domain.JobExecution;
|
||||
import org.springframework.batch.core.domain.JobInstance;
|
||||
import org.springframework.batch.core.domain.JobParameters;
|
||||
import org.springframework.batch.core.domain.JobSupport;
|
||||
import org.springframework.batch.core.domain.StepContribution;
|
||||
import org.springframework.batch.core.domain.StepExecution;
|
||||
import org.springframework.batch.core.domain.StepInstance;
|
||||
@@ -40,10 +40,10 @@ import org.springframework.batch.execution.scope.StepScope;
|
||||
import org.springframework.batch.execution.scope.StepSynchronizationManager;
|
||||
import org.springframework.batch.execution.tasklet.ItemOrientedTasklet;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemStream;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.item.StreamContext;
|
||||
import org.springframework.batch.item.reader.ListItemReader;
|
||||
import org.springframework.batch.item.stream.ItemStreamAdapter;
|
||||
import org.springframework.batch.item.writer.AbstractItemWriter;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.batch.repeat.RepeatContext;
|
||||
@@ -455,7 +455,7 @@ public class SimpleStepExecutorTests extends TestCase {
|
||||
assertEquals(0, map.size());
|
||||
}
|
||||
|
||||
private class MockRestartableTasklet extends ItemStreamAdapter implements Tasklet {
|
||||
private class MockRestartableTasklet implements Tasklet, ItemStream {
|
||||
|
||||
private boolean getRestartDataCalled = false;
|
||||
|
||||
@@ -481,6 +481,15 @@ public class SimpleStepExecutorTests extends TestCase {
|
||||
public boolean isRestoreFromCalled() {
|
||||
return restoreFromCalled;
|
||||
}
|
||||
|
||||
public void open() throws Exception {
|
||||
throw new UnsupportedOperationException("Not implemented.");
|
||||
}
|
||||
|
||||
public void close() throws Exception {
|
||||
throw new UnsupportedOperationException("Not implemented.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -273,7 +273,7 @@ public class ItemOrientedTaskletTests extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
private class SkippableItemReader extends AbstractItemReader implements KeyedItemReader,
|
||||
private class SkippableItemReader implements KeyedItemReader,
|
||||
Skippable, StatisticsProvider {
|
||||
public Object read() throws Exception {
|
||||
return itemProvider.read();
|
||||
@@ -287,9 +287,11 @@ public class ItemOrientedTaskletTests extends TestCase {
|
||||
public Properties getStatistics() {
|
||||
return PropertiesConverter.stringToProperties("foo=bar");
|
||||
}
|
||||
public void close() throws Exception {
|
||||
}
|
||||
}
|
||||
|
||||
private class SkippableItemWriter extends AbstractItemWriter implements ItemWriter, Skippable,
|
||||
private class SkippableItemWriter implements ItemWriter, Skippable,
|
||||
StatisticsProvider {
|
||||
String props = "foo=bar";
|
||||
|
||||
|
||||
@@ -21,11 +21,10 @@ import java.util.Properties;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemStream;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.item.StreamContext;
|
||||
import org.springframework.batch.item.reader.AbstractItemReader;
|
||||
import org.springframework.batch.item.stream.GenericStreamContext;
|
||||
import org.springframework.batch.item.writer.AbstractItemWriter;
|
||||
import org.springframework.batch.support.PropertiesConverter;
|
||||
|
||||
/**
|
||||
@@ -33,16 +32,16 @@ import org.springframework.batch.support.PropertiesConverter;
|
||||
*/
|
||||
public class RestartableItemOrientedTaskletTests extends TestCase {
|
||||
|
||||
private static class MockProvider extends AbstractItemReader {
|
||||
private static class MockProvider implements ItemReader, ItemStream {
|
||||
|
||||
StreamContext data = new StreamContext() {
|
||||
|
||||
public Properties getProperties() {
|
||||
return PropertiesConverter.stringToProperties("a=b");
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
public Object read() {
|
||||
return null;
|
||||
}
|
||||
@@ -56,9 +55,21 @@ public class RestartableItemOrientedTaskletTests extends TestCase {
|
||||
assertEquals(this.data.getProperties(), data.getProperties());
|
||||
}
|
||||
|
||||
public boolean recover(Object data, Throwable cause) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void open() throws Exception {
|
||||
throw new UnsupportedOperationException("Not implemented.");
|
||||
}
|
||||
|
||||
public void close() throws Exception {
|
||||
throw new UnsupportedOperationException("Not implemented.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class MockWriter extends AbstractItemWriter {
|
||||
private static class MockWriter implements ItemWriter, ItemStream {
|
||||
|
||||
StreamContext data = new StreamContext() {
|
||||
public Properties getProperties() {
|
||||
@@ -78,7 +89,12 @@ public class RestartableItemOrientedTaskletTests extends TestCase {
|
||||
assertEquals(this.data.getProperties(), data.getProperties());
|
||||
}
|
||||
|
||||
public void open() throws Exception {
|
||||
throw new UnsupportedOperationException("Not implemented.");
|
||||
}
|
||||
|
||||
public void close() throws Exception {
|
||||
throw new UnsupportedOperationException("Not implemented.");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -125,7 +141,7 @@ public class RestartableItemOrientedTaskletTests extends TestCase {
|
||||
// restore from restart data (see asserts in mock classes)
|
||||
module.restoreFrom(data);
|
||||
}
|
||||
|
||||
|
||||
public void testRestartFromNotRestartable() {
|
||||
|
||||
// create and set up module
|
||||
@@ -138,7 +154,7 @@ public class RestartableItemOrientedTaskletTests extends TestCase {
|
||||
assertNotNull(data);
|
||||
// restore from restart data (see asserts in mock classes)
|
||||
module.restoreFrom(data);
|
||||
// System.err.println(data.getProperties());
|
||||
//System.err.println(data.getProperties());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -22,8 +22,8 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.batch.io.exception.FlatFileParsingException;
|
||||
import org.springframework.batch.io.file.mapping.DefaultFieldSet;
|
||||
import org.springframework.batch.io.file.mapping.FieldSetMapper;
|
||||
import org.springframework.batch.io.file.mapping.FieldSet;
|
||||
import org.springframework.batch.io.file.mapping.FieldSetMapper;
|
||||
import org.springframework.batch.io.file.separator.LineReader;
|
||||
import org.springframework.batch.io.file.separator.RecordSeparatorPolicy;
|
||||
import org.springframework.batch.io.file.separator.ResourceLineReader;
|
||||
@@ -170,8 +170,10 @@ public class SimpleFlatFileItemReader extends AbstractItemReader implements Item
|
||||
}
|
||||
|
||||
/**
|
||||
* Close and null out the delegate line reader.
|
||||
* Close and null out the reader.
|
||||
* @throws Exception
|
||||
*
|
||||
* @see ResourceLifecycle
|
||||
*/
|
||||
public void close() throws Exception {
|
||||
try {
|
||||
|
||||
@@ -20,7 +20,6 @@ import java.util.Set;
|
||||
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.item.stream.ItemStreamAdapter;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.batch.repeat.RepeatContext;
|
||||
import org.springframework.batch.repeat.RepeatInterceptor;
|
||||
@@ -45,7 +44,7 @@ import org.springframework.util.Assert;
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class HibernateAwareItemWriter extends ItemStreamAdapter implements ItemWriter, RepeatInterceptor,
|
||||
public class HibernateAwareItemWriter implements ItemWriter, RepeatInterceptor,
|
||||
InitializingBean {
|
||||
|
||||
/**
|
||||
|
||||
@@ -42,7 +42,7 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Robert Kasanicky
|
||||
*/
|
||||
public class StaxEventItemReader extends AbstractItemReader implements ItemReader,
|
||||
public class StaxEventItemReader extends AbstractItemReader implements ItemReader,
|
||||
Skippable, ItemStream, StatisticsProvider, InitializingBean, DisposableBean {
|
||||
|
||||
public static final String READ_COUNT_STATISTICS_NAME = "StaxEventReaderItemReader.readCount";
|
||||
|
||||
@@ -38,7 +38,7 @@ import org.springframework.batch.item.reader.AbstractItemReader;
|
||||
* @author Lucas Ward
|
||||
* @since 1.0
|
||||
*/
|
||||
public interface ItemReader extends ItemStream {
|
||||
public interface ItemReader {
|
||||
|
||||
/**
|
||||
* Reads a piece of input data and advance to the next one. Implementations
|
||||
@@ -51,4 +51,12 @@ public interface ItemReader extends ItemStream {
|
||||
*/
|
||||
Object read() throws Exception;
|
||||
|
||||
/**
|
||||
* Close the reader, freeing any resources that may have been allocated
|
||||
* since the first call to read().
|
||||
*
|
||||
* TODO: this is only used in sandbox?
|
||||
*
|
||||
*/
|
||||
void close() throws Exception;
|
||||
}
|
||||
|
||||
@@ -35,16 +35,6 @@ package org.springframework.batch.item;
|
||||
*
|
||||
*/
|
||||
public interface ItemStream {
|
||||
|
||||
void open() throws Exception;
|
||||
|
||||
/**
|
||||
* Close the reader, freeing any resources that may have been allocated
|
||||
* since the first call to read().
|
||||
*
|
||||
* @throws Exception if an underlying resource is unavailable
|
||||
*/
|
||||
void close() throws Exception;
|
||||
|
||||
/**
|
||||
* Get {@link StreamContext} representing this object's current state.
|
||||
@@ -60,4 +50,16 @@ public interface ItemStream {
|
||||
* @param data
|
||||
*/
|
||||
void restoreFrom(StreamContext data);
|
||||
|
||||
/**
|
||||
* If any resources are needed for the stream to operate they need to be
|
||||
* initialised here.
|
||||
*/
|
||||
void open() throws Exception;
|
||||
|
||||
/**
|
||||
* If any resources are needed for the stream to operate they need to be
|
||||
* destroyed here.
|
||||
*/
|
||||
void close() throws Exception;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ package org.springframework.batch.item;
|
||||
* @author Dave Syer
|
||||
* @author Lucas Ward
|
||||
*/
|
||||
public interface ItemWriter extends ItemStream {
|
||||
public interface ItemWriter {
|
||||
|
||||
/**
|
||||
* Process the supplied data element. Will be called multiple times during a
|
||||
@@ -38,4 +38,10 @@ public interface ItemWriter extends ItemStream {
|
||||
*/
|
||||
public void write(Object item) throws Exception;
|
||||
|
||||
/**
|
||||
* Close the writer, allowing all allocated resources to be cleaned up.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
void close() throws Exception;
|
||||
}
|
||||
|
||||
@@ -17,13 +17,19 @@
|
||||
package org.springframework.batch.item.reader;
|
||||
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.stream.ItemStreamAdapter;
|
||||
|
||||
/**
|
||||
* Base class for {@link ItemReader} implementations.
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractItemReader extends ItemStreamAdapter implements ItemReader {
|
||||
public abstract class AbstractItemReader implements ItemReader {
|
||||
|
||||
/**
|
||||
* Do nothing.
|
||||
* @see org.springframework.batch.item.ItemReader#close()
|
||||
*/
|
||||
public void close() throws Exception {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class DelegatingItemReader extends AbstractItemReader implements ItemStream, Skippable, InitializingBean{
|
||||
public class DelegatingItemReader extends AbstractItemReader implements Skippable, InitializingBean, ItemStream {
|
||||
|
||||
private ItemReader inputSource;
|
||||
|
||||
@@ -87,4 +87,22 @@ public class DelegatingItemReader extends AbstractItemReader implements ItemStre
|
||||
((Skippable)inputSource).skip();
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.batch.item.ItemStream#open()
|
||||
*/
|
||||
public void open() throws Exception {
|
||||
if (inputSource instanceof ItemStream) {
|
||||
((ItemStream) inputSource).open();
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.batch.item.ItemStream#open()
|
||||
*/
|
||||
public void close() throws Exception {
|
||||
if (inputSource instanceof ItemStream) {
|
||||
((ItemStream) inputSource).close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,11 +16,7 @@
|
||||
|
||||
package org.springframework.batch.item.reader;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.StreamContext;
|
||||
import org.springframework.batch.item.stream.GenericStreamContext;
|
||||
import org.springframework.batch.support.AbstractMethodInvokingDelegator;
|
||||
|
||||
/**
|
||||
@@ -39,33 +35,10 @@ public class ItemReaderAdapter extends AbstractMethodInvokingDelegator implement
|
||||
|
||||
/**
|
||||
* Do nothing.
|
||||
* @see org.springframework.batch.item.ItemStream#open()
|
||||
*/
|
||||
public void open() throws Exception {
|
||||
// no-op
|
||||
}
|
||||
|
||||
/**
|
||||
* Do nothing.
|
||||
* @see org.springframework.batch.item.ItemStream#close()
|
||||
*
|
||||
* @see org.springframework.batch.item.ItemReader#close()
|
||||
*/
|
||||
public void close() throws Exception {
|
||||
// no-op
|
||||
}
|
||||
|
||||
/**
|
||||
* Return empty {@link StreamContext}.
|
||||
* @see org.springframework.batch.item.ItemStream#getRestartData()
|
||||
*/
|
||||
public StreamContext getRestartData() {
|
||||
return new GenericStreamContext(new Properties());
|
||||
}
|
||||
|
||||
/**
|
||||
* Do nothing.
|
||||
* @see org.springframework.batch.item.ItemStream#restoreFrom(org.springframework.batch.item.StreamContext)
|
||||
*/
|
||||
public void restoreFrom(StreamContext data) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* 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.item.stream;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemStream;
|
||||
import org.springframework.batch.item.StreamContext;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class CompositeItemStream implements ItemStream {
|
||||
|
||||
private static final String SEPARATOR = "#";
|
||||
|
||||
private List delegates;
|
||||
|
||||
public void setDelegates(List delegates) {
|
||||
this.delegates = delegates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compound restart data of all injected (Restartable) ItemProcessors,
|
||||
* property keys are prefixed with list index of the ItemProcessor.
|
||||
*/
|
||||
public StreamContext getRestartData() {
|
||||
Properties props = createCompoundProperties(new PropertiesExtractor() {
|
||||
public Properties extractProperties(Object o) {
|
||||
if (o instanceof ItemStream) {
|
||||
return ((ItemStream) o).getRestartData().getProperties();
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
return new GenericStreamContext(props);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param data contains values of restart data, property keys are expected
|
||||
* to be prefixed with list index of the ItemProcessor.
|
||||
*/
|
||||
public void restoreFrom(StreamContext data) {
|
||||
if (data == null || data.getProperties() == null) {
|
||||
// do nothing
|
||||
return;
|
||||
}
|
||||
|
||||
List restartDataList = parseProperties(data.getProperties());
|
||||
|
||||
// iterators would make the loop below less readable
|
||||
for (int i = 0; i < delegates.size(); i++) {
|
||||
if (delegates.get(i) instanceof ItemStream) {
|
||||
((ItemStream) delegates.get(i)).restoreFrom((StreamContext) restartDataList.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses compound properties into a list of RestartData.
|
||||
*/
|
||||
private List parseProperties(Properties props) {
|
||||
List restartDataList = new ArrayList(delegates.size());
|
||||
for (int i = 0; i < delegates.size(); i++) {
|
||||
restartDataList.add(new GenericStreamContext(new Properties()));
|
||||
}
|
||||
|
||||
for (Iterator iterator = props.entrySet().iterator(); iterator.hasNext();) {
|
||||
Map.Entry entry = (Map.Entry) iterator.next();
|
||||
String key = (String) entry.getKey();
|
||||
String value = (String) entry.getValue();
|
||||
int separatorIndex = key.indexOf(SEPARATOR);
|
||||
int i = Integer.valueOf(key.substring(0, separatorIndex)).intValue();
|
||||
((StreamContext) restartDataList.get(i)).getProperties().setProperty(key.substring(separatorIndex + 1),
|
||||
value);
|
||||
}
|
||||
return restartDataList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param extractor used to extract Properties from {@link ItemReader}s
|
||||
* @return compound Properties containing all the Properties from injected
|
||||
* delegates with property keys prefixed by list index.
|
||||
*/
|
||||
private Properties createCompoundProperties(PropertiesExtractor extractor) {
|
||||
Properties stats = new Properties();
|
||||
int index = 0;
|
||||
for (Iterator iterator = delegates.listIterator(); iterator.hasNext();) {
|
||||
Properties writerStats = extractor.extractProperties(iterator.next());
|
||||
if (writerStats != null) {
|
||||
for (Iterator iterator2 = writerStats.entrySet().iterator(); iterator2.hasNext();) {
|
||||
Map.Entry entry = (Map.Entry) iterator2.next();
|
||||
stats.setProperty("" + index + SEPARATOR + entry.getKey(), (String) entry.getValue());
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
return stats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts information from given object in the form of {@link Properties}.
|
||||
* If the information is not available (e.g. unexpected object class) return
|
||||
* null.
|
||||
*/
|
||||
private interface PropertiesExtractor {
|
||||
Properties extractProperties(Object o);
|
||||
}
|
||||
|
||||
public void close() throws Exception {
|
||||
for (Iterator iterator = delegates.listIterator(); iterator.hasNext();) {
|
||||
Object delegate = iterator.next();
|
||||
if (delegate instanceof ItemStream) {
|
||||
((ItemStream) delegate).close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void open() throws Exception {
|
||||
for (Iterator iterator = delegates.listIterator(); iterator.hasNext();) {
|
||||
Object delegate = iterator.next();
|
||||
if (delegate instanceof ItemStream) {
|
||||
((ItemStream) delegate).open();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Public getter for the list of delegates.
|
||||
* @return the delegates
|
||||
*/
|
||||
public List getDelegates() {
|
||||
return delegates;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.writer;
|
||||
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
|
||||
/**
|
||||
* Abstract {@link ItemWriter} that allows for base classes to only
|
||||
* implement the close method if they need it.
|
||||
*
|
||||
* @author Lucas Ward
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractItemWriter implements ItemWriter{
|
||||
|
||||
public void close() throws Exception {
|
||||
}
|
||||
}
|
||||
@@ -1,131 +1,24 @@
|
||||
package org.springframework.batch.item.writer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemStream;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.item.StreamContext;
|
||||
import org.springframework.batch.item.stream.GenericStreamContext;
|
||||
import org.springframework.batch.item.stream.ItemStreamAdapter;
|
||||
import org.springframework.batch.item.stream.CompositeItemStream;
|
||||
|
||||
/**
|
||||
* Runs a collection of ItemProcessors in fixed-order sequence.
|
||||
*
|
||||
* @author Robert Kasanicky
|
||||
*/
|
||||
public class CompositeItemWriter extends ItemStreamAdapter implements ItemWriter, ItemStream {
|
||||
|
||||
private static final String SEPARATOR = "#";
|
||||
|
||||
private List delegates;
|
||||
public class CompositeItemWriter extends CompositeItemStream implements ItemWriter {
|
||||
|
||||
/**
|
||||
* Calls injected ItemProcessors in order.
|
||||
*/
|
||||
public void write(Object data) throws Exception {
|
||||
for (Iterator iterator = delegates.listIterator(); iterator.hasNext();) {
|
||||
for (Iterator iterator = getDelegates().listIterator(); iterator.hasNext();) {
|
||||
((ItemWriter) iterator.next()).write(data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compound restart data of all injected (Restartable) ItemProcessors,
|
||||
* property keys are prefixed with list index of the ItemProcessor.
|
||||
*/
|
||||
public StreamContext getRestartData() {
|
||||
Properties props = createCompoundProperties(new PropertiesExtractor() {
|
||||
public Properties extractProperties(ItemStream o) {
|
||||
return o.getRestartData().getProperties();
|
||||
}
|
||||
});
|
||||
return new GenericStreamContext(props);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param data contains values of restart data, property keys are expected
|
||||
* to be prefixed with list index of the ItemProcessor.
|
||||
*/
|
||||
public void restoreFrom(StreamContext data) {
|
||||
if (data == null || data.getProperties() == null) {
|
||||
// do nothing
|
||||
return;
|
||||
}
|
||||
|
||||
List restartDataList = parseProperties(data.getProperties());
|
||||
|
||||
// iterators would make the loop below less readable
|
||||
for (int i = 0; i < delegates.size(); i++) {
|
||||
if (delegates.get(i) instanceof ItemStream) {
|
||||
((ItemStream) delegates.get(i)).restoreFrom((StreamContext) restartDataList.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setItemWriters(List itemProcessors) {
|
||||
this.delegates = itemProcessors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses compound properties into a list of RestartData.
|
||||
*/
|
||||
private List parseProperties(Properties props) {
|
||||
List restartDataList = new ArrayList(delegates.size());
|
||||
for (int i = 0; i < delegates.size(); i++) {
|
||||
restartDataList.add(new GenericStreamContext(new Properties()));
|
||||
}
|
||||
|
||||
for (Iterator iterator = props.entrySet().iterator(); iterator.hasNext();) {
|
||||
Map.Entry entry = (Map.Entry) iterator.next();
|
||||
String key = (String) entry.getKey();
|
||||
String value = (String) entry.getValue();
|
||||
int separatorIndex = key.indexOf(SEPARATOR);
|
||||
int i = Integer.valueOf(key.substring(0, separatorIndex)).intValue();
|
||||
((StreamContext) restartDataList.get(i)).getProperties()
|
||||
.setProperty(key.substring(separatorIndex + 1), value);
|
||||
}
|
||||
return restartDataList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param extractor used to extract Properties from {@link ItemReader}s
|
||||
* @return compound Properties containing all the Properties from injected
|
||||
* {@link ItemWriter}s with property keys prefixed by list index.
|
||||
*/
|
||||
private Properties createCompoundProperties(PropertiesExtractor extractor) {
|
||||
Properties stats = new Properties();
|
||||
int index = 0;
|
||||
for (Iterator iterator = delegates.listIterator(); iterator.hasNext();) {
|
||||
Properties writerStats = extractor.extractProperties((ItemStream) iterator.next());
|
||||
if (writerStats != null) {
|
||||
for (Iterator iterator2 = writerStats.entrySet().iterator(); iterator2.hasNext();) {
|
||||
Map.Entry entry = (Map.Entry) iterator2.next();
|
||||
stats.setProperty("" + index + SEPARATOR + entry.getKey(), (String) entry.getValue());
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
return stats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts information from given object in the form of {@link Properties}.
|
||||
* If the information is not available (e.g. unexpected object class) return
|
||||
* null.
|
||||
*/
|
||||
private interface PropertiesExtractor {
|
||||
Properties extractProperties(ItemStream o);
|
||||
}
|
||||
|
||||
public void close() throws Exception {
|
||||
for (Iterator iterator = delegates.listIterator(); iterator.hasNext();) {
|
||||
((ItemWriter) iterator.next()).close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import org.springframework.batch.item.ItemStream;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.item.StreamContext;
|
||||
import org.springframework.batch.item.stream.GenericStreamContext;
|
||||
import org.springframework.batch.item.stream.ItemStreamAdapter;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -18,7 +17,7 @@ import org.springframework.util.Assert;
|
||||
* @author Dave Syer
|
||||
* @author Robert Kasanicky
|
||||
*/
|
||||
public class DelegatingItemWriter extends ItemStreamAdapter implements ItemWriter, Skippable, InitializingBean {
|
||||
public class DelegatingItemWriter implements ItemWriter, Skippable, InitializingBean {
|
||||
|
||||
private ItemWriter writer;
|
||||
|
||||
@@ -88,6 +87,7 @@ public class DelegatingItemWriter extends ItemStreamAdapter implements ItemWrite
|
||||
Assert.notNull(writer);
|
||||
}
|
||||
|
||||
// YODO: remove
|
||||
public void close() throws Exception {
|
||||
writer.close();
|
||||
}
|
||||
|
||||
@@ -16,11 +16,7 @@
|
||||
|
||||
package org.springframework.batch.item.writer;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.item.StreamContext;
|
||||
import org.springframework.batch.item.stream.GenericStreamContext;
|
||||
import org.springframework.batch.support.AbstractMethodInvokingDelegator;
|
||||
|
||||
|
||||
@@ -38,35 +34,13 @@ public class ItemWriterAdapter extends AbstractMethodInvokingDelegator implement
|
||||
invokeDelegateMethodWithArgument(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Do nothing.
|
||||
* @see org.springframework.batch.item.ItemStream#open()
|
||||
*/
|
||||
public void open() throws Exception {
|
||||
// no-op
|
||||
}
|
||||
|
||||
/**
|
||||
* Do nothing.
|
||||
* @see org.springframework.batch.item.ItemStream#close()
|
||||
*/
|
||||
/*
|
||||
* No-op, can't call more than one method.
|
||||
*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.batch.item.ItemWriter#close()
|
||||
*/
|
||||
public void close() throws Exception {
|
||||
// no-op
|
||||
}
|
||||
|
||||
/**
|
||||
* Return empty {@link StreamContext}.
|
||||
* @see org.springframework.batch.item.ItemStream#getRestartData()
|
||||
*/
|
||||
public StreamContext getRestartData() {
|
||||
return new GenericStreamContext(new Properties());
|
||||
}
|
||||
|
||||
/**
|
||||
* Do nothing.
|
||||
* @see org.springframework.batch.item.ItemStream#restoreFrom(org.springframework.batch.item.StreamContext)
|
||||
*/
|
||||
public void restoreFrom(StreamContext data) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -16,11 +16,7 @@
|
||||
|
||||
package org.springframework.batch.item.writer;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.item.StreamContext;
|
||||
import org.springframework.batch.item.stream.GenericStreamContext;
|
||||
import org.springframework.batch.support.AbstractMethodInvokingDelegator;
|
||||
import org.springframework.beans.BeanWrapper;
|
||||
import org.springframework.beans.BeanWrapperImpl;
|
||||
@@ -70,35 +66,7 @@ public class PropertyExtractingDelegatingItemWriter extends AbstractMethodInvoki
|
||||
this.fieldsUsedAsTargetMethodArguments = fieldsUsedAsMethodArguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do nothing.
|
||||
* @see org.springframework.batch.item.ItemStream#open()
|
||||
*/
|
||||
public void open() throws Exception {
|
||||
// no-op
|
||||
}
|
||||
|
||||
/**
|
||||
* Do nothing.
|
||||
* @see org.springframework.batch.item.ItemStream#close()
|
||||
*/
|
||||
public void close() throws Exception {
|
||||
// no-op
|
||||
}
|
||||
|
||||
/**
|
||||
* Return empty {@link StreamContext}.
|
||||
* @see org.springframework.batch.item.ItemStream#getRestartData()
|
||||
*/
|
||||
public StreamContext getRestartData() {
|
||||
return new GenericStreamContext(new Properties());
|
||||
}
|
||||
|
||||
/**
|
||||
* Do nothing.
|
||||
* @see org.springframework.batch.item.ItemStream#restoreFrom(org.springframework.batch.item.StreamContext)
|
||||
*/
|
||||
public void restoreFrom(StreamContext data) {
|
||||
|
||||
public void close() throws Exception {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
class FooItemReader extends AbstractItemReader implements ItemReader, ItemStream, DisposableBean, InitializingBean{
|
||||
class FooItemReader extends AbstractItemReader implements ItemStream, ItemReader, DisposableBean, InitializingBean{
|
||||
|
||||
DrivingQueryItemReader inputSource;
|
||||
FooDao fooDao = new SingleKeyFooDao();
|
||||
@@ -44,5 +44,8 @@ class FooItemReader extends AbstractItemReader implements ItemReader, ItemStream
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
}
|
||||
|
||||
public void open() throws Exception {
|
||||
};
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import java.util.Map;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.item.writer.AbstractItemWriter;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.batch.repeat.RepeatContext;
|
||||
import org.springframework.batch.repeat.RepeatInterceptor;
|
||||
@@ -41,13 +41,12 @@ public class HibernateAwareItemWriterTests extends TestCase {
|
||||
public void flush() throws DataAccessException {
|
||||
list.add("flush");
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
list.add("clear");
|
||||
list.add("clear");
|
||||
};
|
||||
}
|
||||
|
||||
private class StubItemWriter extends AbstractItemWriter implements RepeatInterceptor {
|
||||
private class StubItemWriter implements ItemWriter, RepeatInterceptor {
|
||||
public void write(Object item) {
|
||||
list.add(item);
|
||||
}
|
||||
@@ -71,10 +70,13 @@ public class HibernateAwareItemWriterTests extends TestCase {
|
||||
public void open(RepeatContext context) {
|
||||
list.add(context);
|
||||
}
|
||||
|
||||
public void close() throws Exception {
|
||||
}
|
||||
}
|
||||
|
||||
HibernateAwareItemWriter writer = new HibernateAwareItemWriter();
|
||||
|
||||
|
||||
final List list = new ArrayList();
|
||||
|
||||
private RepeatContextSupport context;
|
||||
@@ -91,16 +93,15 @@ public class HibernateAwareItemWriterTests extends TestCase {
|
||||
writer.setHibernateTemplate(new HibernateTemplateWrapper());
|
||||
list.clear();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see junit.framework.TestCase#tearDown()
|
||||
*/
|
||||
protected void tearDown() throws Exception {
|
||||
Map map = TransactionSynchronizationManager.getResourceMap();
|
||||
for (Iterator iterator = map.keySet().iterator(); iterator.hasNext();) {
|
||||
String key = (String) iterator.next();
|
||||
TransactionSynchronizationManager.unbindResource(key);
|
||||
TransactionSynchronizationManager.unbindResource(key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,10 +116,10 @@ public class HibernateAwareItemWriterTests extends TestCase {
|
||||
try {
|
||||
writer.afterPropertiesSet();
|
||||
fail("Expected IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
} catch (IllegalArgumentException e) {
|
||||
// expected
|
||||
assertTrue("Wrong message for exception: " + e.getMessage(), e.getMessage().indexOf("delegate") >= 0);
|
||||
assertTrue("Wrong message for exception: " + e.getMessage(), e
|
||||
.getMessage().indexOf("delegate") >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,7 +136,7 @@ public class HibernateAwareItemWriterTests extends TestCase {
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.io.support.HibernateAwareItemWriter#write(java.lang.Object)}.
|
||||
* @throws Exception
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testWrite() throws Exception {
|
||||
writer.write("foo");
|
||||
@@ -157,8 +158,7 @@ public class HibernateAwareItemWriterTests extends TestCase {
|
||||
try {
|
||||
writer.close(context);
|
||||
fail("Expected RuntimeException");
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
} catch (RuntimeException e) {
|
||||
assertEquals("bar", e.getMessage());
|
||||
}
|
||||
assertEquals(2, list.size());
|
||||
@@ -169,7 +169,7 @@ public class HibernateAwareItemWriterTests extends TestCase {
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.io.support.HibernateAwareItemWriter#write(java.lang.Object)}.
|
||||
* @throws Exception
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testWriteAndCloseWithFailure() throws Exception {
|
||||
final RuntimeException ex = new RuntimeException("bar");
|
||||
@@ -182,8 +182,7 @@ public class HibernateAwareItemWriterTests extends TestCase {
|
||||
try {
|
||||
writer.close(context);
|
||||
fail("Expected RuntimeException");
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
} catch (RuntimeException e) {
|
||||
assertEquals("bar", e.getMessage());
|
||||
}
|
||||
assertEquals(3, list.size());
|
||||
|
||||
@@ -8,10 +8,11 @@ import java.util.Properties;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.easymock.MockControl;
|
||||
import org.springframework.batch.item.ItemStream;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.item.StreamContext;
|
||||
import org.springframework.batch.item.stream.GenericStreamContext;
|
||||
import org.springframework.batch.item.stream.ItemStreamAdapter;
|
||||
import org.springframework.batch.item.writer.CompositeItemWriter;
|
||||
import org.springframework.batch.statistics.StatisticsProvider;
|
||||
|
||||
/**
|
||||
@@ -48,7 +49,7 @@ public class CompositeItemWriterTests extends TestCase {
|
||||
controls.add(control);
|
||||
}
|
||||
|
||||
itemProcessor.setItemWriters(processors);
|
||||
itemProcessor.setDelegates(processors);
|
||||
itemProcessor.write(data);
|
||||
|
||||
for (Iterator iterator = controls.iterator(); iterator.hasNext();) {
|
||||
@@ -61,22 +62,27 @@ public class CompositeItemWriterTests extends TestCase {
|
||||
* All Restartable processors should be restarted, not-Restartable processors should be ignored.
|
||||
*/
|
||||
public void testRestart() {
|
||||
final ItemWriter p2 = new ItemWriterStub();
|
||||
final ItemWriter p3 = new ItemWriterStub();
|
||||
//this mock with undefined behaviour makes sure not-Restartable processor is ignored
|
||||
MockControl p1c = MockControl.createStrictControl(ItemWriter.class);
|
||||
final ItemWriter p1 = (ItemWriter) p1c.getMock();
|
||||
|
||||
final ItemWriter p2 = new StubItemWriter();
|
||||
final ItemWriter p3 = new StubItemWriter();
|
||||
List itemProcessors = new ArrayList(){{
|
||||
add(p1);
|
||||
add(p2);
|
||||
add(p3);
|
||||
}};
|
||||
itemProcessor.setItemWriters(itemProcessors);
|
||||
itemProcessor.setDelegates(itemProcessors);
|
||||
|
||||
StreamContext rd = itemProcessor.getRestartData();
|
||||
itemProcessor.restoreFrom(rd);
|
||||
|
||||
for (Iterator iterator = itemProcessors.iterator(); iterator.hasNext();) {
|
||||
ItemWriter processor = (ItemWriter) iterator.next();
|
||||
if (processor instanceof ItemWriterStub) {
|
||||
if (processor instanceof StubItemWriter) {
|
||||
assertTrue("Injected processors are restarted",
|
||||
((ItemWriterStub)processor).restarted);
|
||||
((StubItemWriter)processor).restarted);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,35 +92,34 @@ public class CompositeItemWriterTests extends TestCase {
|
||||
|
||||
final int NUMBER_OF_PROCESSORS = 10;
|
||||
|
||||
List controls = new ArrayList(NUMBER_OF_PROCESSORS);
|
||||
List processors = new ArrayList(NUMBER_OF_PROCESSORS);
|
||||
final List list = new ArrayList(NUMBER_OF_PROCESSORS);
|
||||
|
||||
for (int i = 0; i < NUMBER_OF_PROCESSORS; i++) {
|
||||
MockControl control = MockControl.createStrictControl(ItemWriter.class);
|
||||
ItemWriter processor = (ItemWriter) control.getMock();
|
||||
|
||||
ItemWriter processor = new AbstractItemWriter() {
|
||||
public void write(Object item) throws Exception {
|
||||
throw new IllegalStateException("No way!");
|
||||
}
|
||||
public void close() throws Exception {
|
||||
list.add(this);
|
||||
}
|
||||
};
|
||||
processor.close();
|
||||
control.setVoidCallable();
|
||||
control.replay();
|
||||
|
||||
processors.add(processor);
|
||||
controls.add(control);
|
||||
}
|
||||
|
||||
itemProcessor.setItemWriters(processors);
|
||||
itemProcessor.setDelegates(processors);
|
||||
itemProcessor.close();
|
||||
|
||||
for (Iterator iterator = controls.iterator(); iterator.hasNext();) {
|
||||
MockControl control = (MockControl) iterator.next();
|
||||
control.verify();
|
||||
}
|
||||
assertEquals(NUMBER_OF_PROCESSORS, list.size());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Stub for testing restart. Checks the restart data received is the same that was returned by
|
||||
* <code>getRestartData()</code>
|
||||
*/
|
||||
private static class ItemWriterStub extends ItemStreamAdapter implements ItemWriter, StatisticsProvider {
|
||||
private static class StubItemWriter implements ItemWriter, ItemStream, StatisticsProvider {
|
||||
|
||||
private static final String RESTART_KEY = "restartData";
|
||||
private static final String STATS_KEY = "stats";
|
||||
@@ -149,9 +154,10 @@ public class CompositeItemWriterTests extends TestCase {
|
||||
}
|
||||
|
||||
public void close() throws Exception {
|
||||
|
||||
}
|
||||
|
||||
public void open() throws Exception {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,9 +19,9 @@ package org.springframework.batch.repeat.support;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.batch.repeat.RepeatCallback;
|
||||
import org.springframework.batch.repeat.RepeatContext;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
import org.springframework.batch.repeat.callback.ItemReaderRepeatCallback;
|
||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.batch.sample.dao;
|
||||
|
||||
import org.springframework.batch.item.ItemStream;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.sample.domain.CustomerCredit;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
@@ -56,12 +57,16 @@ public class FlatFileCustomerCreditWriter implements CustomerCreditDao,
|
||||
}
|
||||
|
||||
public void open() throws Exception {
|
||||
outputSource.open();
|
||||
if (outputSource instanceof ItemStream) {
|
||||
((ItemStream) outputSource).open();
|
||||
}
|
||||
opened = true;
|
||||
}
|
||||
|
||||
public void close() throws Exception {
|
||||
outputSource.close();
|
||||
if (outputSource instanceof ItemStream) {
|
||||
((ItemStream) outputSource).close();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
package org.springframework.batch.sample.dao;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.item.StreamContext;
|
||||
import org.springframework.batch.item.stream.GenericStreamContext;
|
||||
import org.springframework.batch.sample.domain.Game;
|
||||
import org.springframework.jdbc.core.support.JdbcDaoSupport;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -38,36 +34,7 @@ public class JdbcGameDao extends JdbcDaoSupport implements ItemWriter {
|
||||
this.getJdbcTemplate().update(INSERT_GAME, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Do nothing.
|
||||
* @see org.springframework.batch.item.ItemStream#open()
|
||||
*/
|
||||
public void open() throws Exception {
|
||||
// no-op
|
||||
}
|
||||
|
||||
/**
|
||||
* Do nothing.
|
||||
* @see org.springframework.batch.item.ItemStream#close()
|
||||
*/
|
||||
public void close() throws Exception {
|
||||
// no-op
|
||||
}
|
||||
|
||||
/**
|
||||
* Return empty {@link StreamContext}.
|
||||
* @see org.springframework.batch.item.ItemStream#getRestartData()
|
||||
*/
|
||||
public StreamContext getRestartData() {
|
||||
return new GenericStreamContext(new Properties());
|
||||
}
|
||||
|
||||
/**
|
||||
* Do nothing.
|
||||
* @see org.springframework.batch.item.ItemStream#restoreFrom(org.springframework.batch.item.StreamContext)
|
||||
*/
|
||||
public void restoreFrom(StreamContext data) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
package org.springframework.batch.sample.dao;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.item.StreamContext;
|
||||
import org.springframework.batch.item.stream.GenericStreamContext;
|
||||
import org.springframework.batch.sample.domain.PlayerSummary;
|
||||
import org.springframework.jdbc.core.support.JdbcDaoSupport;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -32,36 +28,7 @@ public class JdbcPlayerSummaryDao extends JdbcDaoSupport implements ItemWriter {
|
||||
getJdbcTemplate().update(INSERT_SUMMARY, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Do nothing.
|
||||
* @see org.springframework.batch.item.ItemStream#open()
|
||||
*/
|
||||
public void open() throws Exception {
|
||||
// no-op
|
||||
}
|
||||
|
||||
/**
|
||||
* Do nothing.
|
||||
* @see org.springframework.batch.item.ItemStream#close()
|
||||
*/
|
||||
public void close() throws Exception {
|
||||
// no-op
|
||||
}
|
||||
|
||||
/**
|
||||
* Return empty {@link StreamContext}.
|
||||
* @see org.springframework.batch.item.ItemStream#getRestartData()
|
||||
*/
|
||||
public StreamContext getRestartData() {
|
||||
return new GenericStreamContext(new Properties());
|
||||
}
|
||||
|
||||
/**
|
||||
* Do nothing.
|
||||
* @see org.springframework.batch.item.ItemStream#restoreFrom(org.springframework.batch.item.StreamContext)
|
||||
*/
|
||||
public void restoreFrom(StreamContext data) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.commons.lang.SerializationUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
@@ -13,8 +12,6 @@ import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.batch.execution.scope.StepContext;
|
||||
import org.springframework.batch.execution.scope.StepContextAware;
|
||||
import org.springframework.batch.item.KeyedItemReader;
|
||||
import org.springframework.batch.item.StreamContext;
|
||||
import org.springframework.batch.item.stream.GenericStreamContext;
|
||||
import org.springframework.batch.repeat.synch.BatchTransactionSynchronizationManager;
|
||||
import org.springframework.batch.sample.item.writer.StagingItemWriter;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
@@ -252,21 +249,5 @@ public class StagingItemReader extends JdbcDaoSupport implements KeyedItemReader
|
||||
return "list=" + list + "; iter.hasNext()=" + iter.hasNext();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return empty {@link StreamContext}.
|
||||
* @see org.springframework.batch.item.ItemStream#getRestartData()
|
||||
*/
|
||||
public StreamContext getRestartData() {
|
||||
return new GenericStreamContext(new Properties());
|
||||
}
|
||||
|
||||
/**
|
||||
* Do nothing.
|
||||
* @see org.springframework.batch.item.ItemStream#restoreFrom(org.springframework.batch.item.StreamContext)
|
||||
*/
|
||||
public void restoreFrom(StreamContext data) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package org.springframework.batch.sample.item.writer;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.item.writer.AbstractItemWriter;
|
||||
import org.springframework.batch.sample.dao.CustomerCreditDao;
|
||||
import org.springframework.batch.sample.domain.CustomerCredit;
|
||||
|
||||
@@ -12,7 +11,7 @@ import org.springframework.batch.sample.domain.CustomerCredit;
|
||||
*
|
||||
* @author Robert Kasanicky
|
||||
*/
|
||||
public class CustomerCreditIncreaseWriter extends AbstractItemWriter implements ItemWriter {
|
||||
public class CustomerCreditIncreaseWriter implements ItemWriter {
|
||||
|
||||
public static final BigDecimal FIXED_AMOUNT = new BigDecimal(1000);
|
||||
|
||||
@@ -35,9 +34,6 @@ public class CustomerCreditIncreaseWriter extends AbstractItemWriter implements
|
||||
customerCreditDao.writeCredit(customerCredit);
|
||||
}
|
||||
|
||||
public void open() throws Exception {
|
||||
}
|
||||
|
||||
public void close() throws Exception {
|
||||
}
|
||||
|
||||
|
||||
@@ -17,13 +17,12 @@
|
||||
package org.springframework.batch.sample.item.writer;
|
||||
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.item.writer.AbstractItemWriter;
|
||||
import org.springframework.batch.sample.dao.CustomerCreditDao;
|
||||
import org.springframework.batch.sample.domain.CustomerCredit;
|
||||
|
||||
|
||||
|
||||
public class CustomerCreditUpdateWriter extends AbstractItemWriter implements ItemWriter {
|
||||
public class CustomerCreditUpdateWriter implements ItemWriter {
|
||||
private double creditFilter = 800;
|
||||
private CustomerCreditDao dao;
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.springframework.batch.sample.item.writer;
|
||||
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.item.writer.AbstractItemWriter;
|
||||
import org.springframework.batch.sample.dao.JdbcCustomerDebitWriter;
|
||||
import org.springframework.batch.sample.domain.CustomerDebit;
|
||||
import org.springframework.batch.sample.domain.Trade;
|
||||
@@ -28,7 +27,7 @@ import org.springframework.batch.sample.domain.Trade;
|
||||
*
|
||||
* @author Robert Kasanicky
|
||||
*/
|
||||
public class CustomerUpdateWriter extends AbstractItemWriter implements ItemWriter {
|
||||
public class CustomerUpdateWriter implements ItemWriter {
|
||||
private JdbcCustomerDebitWriter dao;
|
||||
|
||||
public void write(Object data) {
|
||||
@@ -43,6 +42,9 @@ public class CustomerUpdateWriter extends AbstractItemWriter implements ItemWrit
|
||||
this.dao = outputSource;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
}
|
||||
|
||||
public void init() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,16 +15,19 @@
|
||||
*/
|
||||
package org.springframework.batch.sample.item.writer;
|
||||
|
||||
import org.springframework.batch.item.writer.AbstractItemWriter;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class DummyItemWriter extends AbstractItemWriter {
|
||||
public class DummyItemWriter implements ItemWriter {
|
||||
|
||||
public void write(Object item) throws Exception {
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
public void close() throws Exception {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,12 +18,12 @@ package org.springframework.batch.sample.item.writer;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.batch.item.writer.AbstractItemWriter;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.sample.domain.Person;
|
||||
|
||||
|
||||
|
||||
public class PersonWriter extends AbstractItemWriter {
|
||||
public class PersonWriter implements ItemWriter {
|
||||
private static Log log = LogFactory.getLog(PersonWriter.class);
|
||||
|
||||
public void write(Object data) {
|
||||
@@ -36,6 +36,9 @@ public class PersonWriter extends AbstractItemWriter {
|
||||
log.debug("Processing: " + data);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
}
|
||||
|
||||
public void init() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package org.springframework.batch.sample.item.writer;
|
||||
|
||||
import org.springframework.batch.item.writer.AbstractItemWriter;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.sample.dao.PlayerDao;
|
||||
import org.springframework.batch.sample.domain.Player;
|
||||
|
||||
public class PlayerItemWriter extends AbstractItemWriter {
|
||||
public class PlayerItemWriter implements ItemWriter {
|
||||
|
||||
PlayerDao playerDao;
|
||||
|
||||
@@ -16,4 +16,6 @@ public class PlayerItemWriter extends AbstractItemWriter {
|
||||
this.playerDao = playerDao;
|
||||
}
|
||||
|
||||
public void close() throws Exception {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,14 +2,11 @@ package org.springframework.batch.sample.item.writer;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.Types;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.commons.lang.SerializationUtils;
|
||||
import org.springframework.batch.execution.scope.StepContext;
|
||||
import org.springframework.batch.execution.scope.StepContextAware;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.item.StreamContext;
|
||||
import org.springframework.batch.item.stream.GenericStreamContext;
|
||||
import org.springframework.jdbc.core.support.JdbcDaoSupport;
|
||||
import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -76,37 +73,7 @@ public class StagingItemWriter extends JdbcDaoSupport implements
|
||||
new int[] { Types.BIGINT, Types.BIGINT, Types.BLOB, Types.CHAR});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Do nothing.
|
||||
* @see org.springframework.batch.item.ItemStream#open()
|
||||
*/
|
||||
public void open() throws Exception {
|
||||
// no-op
|
||||
}
|
||||
|
||||
/**
|
||||
* Do nothing.
|
||||
* @see org.springframework.batch.item.ItemStream#close()
|
||||
*/
|
||||
public void close() throws Exception {
|
||||
// no-op
|
||||
}
|
||||
|
||||
/**
|
||||
* Return empty {@link StreamContext}.
|
||||
* @see org.springframework.batch.item.ItemStream#getRestartData()
|
||||
*/
|
||||
public StreamContext getRestartData() {
|
||||
return new GenericStreamContext(new Properties());
|
||||
}
|
||||
|
||||
/**
|
||||
* Do nothing.
|
||||
* @see org.springframework.batch.item.ItemStream#restoreFrom(org.springframework.batch.item.StreamContext)
|
||||
*/
|
||||
public void restoreFrom(StreamContext data) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,13 +18,13 @@ package org.springframework.batch.sample.item.writer;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.batch.item.writer.AbstractItemWriter;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.sample.dao.TradeDao;
|
||||
import org.springframework.batch.sample.domain.Trade;
|
||||
|
||||
|
||||
|
||||
public class TradeWriter extends AbstractItemWriter {
|
||||
public class TradeWriter implements ItemWriter {
|
||||
private static Log log = LogFactory.getLog(TradeWriter.class);
|
||||
private TradeDao dao;
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
</property>
|
||||
<property name="itemWriter">
|
||||
<bean class="org.springframework.batch.item.writer.CompositeItemWriter" >
|
||||
<property name="itemWriters" >
|
||||
<property name="delegates" >
|
||||
<list>
|
||||
<bean class="org.springframework.batch.sample.item.writer.TradeWriter">
|
||||
<property name="dao" ref="tradeDao" />
|
||||
|
||||
@@ -75,7 +75,8 @@ public class RestartFunctionalTests extends AbstractBatchLauncherTests {
|
||||
}
|
||||
|
||||
int medium = jdbcTemplate.queryForInt("SELECT COUNT(*) FROM TRADE");
|
||||
System.err.println(medium);
|
||||
// assert based on commit inyerval = 2
|
||||
assertEquals(before+2, medium);
|
||||
|
||||
runJob();
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.math.BigDecimal;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.easymock.MockControl;
|
||||
import org.springframework.batch.item.ItemStream;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.sample.domain.CustomerCredit;
|
||||
|
||||
@@ -74,7 +75,7 @@ public class FlatFileCustomerCreditWriterTests extends TestCase {
|
||||
outputControl.verify();
|
||||
}
|
||||
|
||||
private interface ResourceLifecycleItemWriter extends ItemWriter {
|
||||
private interface ResourceLifecycleItemWriter extends ItemWriter, ItemStream{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user