IN PROGRESS - issue BATCH-145: Move CollectionItemProvider to infrastructure from samples

http://opensource.atlassian.com/projects/spring/browse/BATCH-145
This commit is contained in:
dsyer
2007-10-05 15:02:48 +00:00
parent b6a5bb80e0
commit 51a0c29527
2 changed files with 82 additions and 66 deletions

View File

@@ -21,81 +21,101 @@ import java.util.Collection;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.batch.io.InputSource;
import org.springframework.batch.io.file.FieldSet;
import org.springframework.batch.io.file.FieldSetInputSource;
import org.springframework.batch.io.file.FieldSetMapper;
import org.springframework.batch.item.ItemProvider;
import org.springframework.batch.item.provider.AbstractItemProvider;
/**
* An {@link ItemProvider} that delivers a list as its item, storing up objects
* from the injected {@link InputSource} until they are ready to be packed out
* as a collection.<br/>
*
* This class is thread safe (it can be used concurrently by multiple threads) as
* long as the {@link InputSource} is also thread safe.
*
* @author Dave Syer
*
*/
public class CollectionItemProvider extends AbstractItemProvider {
private static final Log log = LogFactory.getLog(CollectionItemProvider.class);
private FieldSetInputSource inputSource;
//collects simple records
private Collection multiRecord;
private static final Log log = LogFactory
.getLog(CollectionItemProvider.class);
//marks we have finished reading one whole multiRecord
private boolean recordFinished;
private FieldSetInputSource inputSource;
//mapps a sigle line to a simple record
private FieldSetMapper fieldSetMapper;
// maps a single line to a simple record
private FieldSetMapper fieldSetMapper;
public Object next() {
recordFinished = false;
/**
* Get the next list of records.
*
* @see org.springframework.batch.item.ItemProvider#next()
*/
public Object next() {
ResultHolder holder = new ResultHolder();
while (!recordFinished) {
process(inputSource.readFieldSet());
}
while (process(inputSource.readFieldSet(), holder)) {
continue;
}
if (multiRecord != null) {
Collection result = new ArrayList(multiRecord);
multiRecord = null;
if (!holder.exhausted) {
return holder.records;
} else {
return null;
}
}
return result;
} else {
return null;
}
}
private boolean process(FieldSet fieldSet, ResultHolder holder) {
// finish processing if we hit the end of file
if (fieldSet == null) {
log.debug("Exhausted InputSource");
holder.exhausted = true;
return false;
}
private void process(FieldSet fieldSet) {
//finish processing if we hit the end of file
if (fieldSet == null) {
log.debug("FINISHED");
recordFinished = true;
multiRecord = null;
// start a new collection
if (fieldSet.readString(0).equals("BEGIN")) {
log.debug("Start of new record detected");
return true;
}
return;
}
// mark we are finished with current collection
if (fieldSet.readString(0).equals("END")) {
log.debug("End of record detected");
return false;
}
//start a new collection
if (fieldSet.readString(0).equals("BEGIN")) {
log.debug("STARTING NEW RECORD");
multiRecord = new ArrayList();
// add a simple record to the current collection
log.debug("Mapping: " + fieldSet);
holder.records.add(fieldSetMapper.mapLine(fieldSet));
return true;
}
return;
}
/**
* Injection setter for {@link InputSource}.
* @param inputSource an {@link InputSource}.
*/
public void setInputSource(FieldSetInputSource inputSource) {
this.inputSource = inputSource;
}
//mark we are finished with current collection
if (fieldSet.readString(0).equals("END")) {
log.debug("END OF RECORD");
recordFinished = true;
public void setFieldSetMapper(FieldSetMapper mapper) {
this.fieldSetMapper = mapper;
}
return;
}
//add a simple record to the current collection
log.debug("MAPPING: " + fieldSet);
multiRecord.add(fieldSetMapper.mapLine(fieldSet));
}
public void setInputSource(FieldSetInputSource inputTemplate) {
this.inputSource = inputTemplate;
}
public void setFieldSetMapper(FieldSetMapper mapper) {
this.fieldSetMapper = mapper;
}
/**
* Private class for temporary state management while item is being
* collected.
*
* @author Dave Syer
*
*/
private class ResultHolder {
Collection records = new ArrayList();
boolean exhausted = false;
}
}

View File

@@ -11,11 +11,10 @@ import org.springframework.batch.io.file.FieldSetInputSource;
import org.springframework.batch.io.file.FieldSetMapper;
import org.springframework.batch.sample.item.provider.CollectionItemProvider;
public class CollectionItemProviderTest extends TestCase {
public class CollectionItemProviderTests extends TestCase {
private MockControl inputControl;
private FieldSetInputSource input;
private MockControl mapperControl;
private FieldSetMapper mapper;
private CollectionItemProvider provider;
@@ -26,12 +25,9 @@ public class CollectionItemProviderTest extends TestCase {
input = (FieldSetInputSource) inputControl.getMock();
//create mock for mapper
mapperControl = MockControl.createControl(FieldSetMapper.class);
mapper = (FieldSetMapper) mapperControl.getMock();
mapperControl.setDefaultMatcher(MockControl.ALWAYS_MATCHER);
mapper.mapLine(null);
mapperControl.setDefaultReturnValue("line");
mapperControl.replay();
mapper = new FieldSetMapper() {
public Object mapLine(FieldSet fs) { return fs.readString(0); }
};
//create provider
provider = new CollectionItemProvider();
@@ -55,7 +51,7 @@ public class CollectionItemProviderTest extends TestCase {
//read object
Object result = provider.next();
//it should be collection od 3 strings "line"
//it should be collection of 3 strings "line"
assertTrue(result instanceof Collection);
Collection lines = (Collection)result;
assertEquals(3, lines.size());