RESOLVED - BATCH-708: merge MultiResourceItemReader and SortedMultiResourceItemReader
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package org.springframework.batch.item.file;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
@@ -24,10 +26,11 @@ import org.springframework.util.ClassUtils;
|
||||
* {@link #setResources(Resource[])}, the actual reading is delegated to
|
||||
* {@link #setDelegate(ResourceAwareItemReaderItemStream)}.
|
||||
*
|
||||
* Reset (rollback) capability is implemented by item buffering. To restart
|
||||
* correctly resource ordering needs to be preserved between runs.
|
||||
* Input resources are ordered using {@link #setComparator(Comparator)} to make
|
||||
* sure resource ordering is preserved between job runs in restart scenario.
|
||||
*
|
||||
* Reset (rollback) capability is implemented by item buffering.
|
||||
*
|
||||
* @see SortedMultiResourceItemReader
|
||||
*
|
||||
* @author Robert Kasanicky
|
||||
*/
|
||||
@@ -53,6 +56,19 @@ public class MultiResourceItemReader extends ExecutionContextUserSupport impleme
|
||||
|
||||
private boolean saveState = false;
|
||||
|
||||
private Comparator comparator = new Comparator() {
|
||||
|
||||
/**
|
||||
* Compares resource filenames.
|
||||
*/
|
||||
public int compare(Object o1, Object o2) {
|
||||
Resource r1 = (Resource) o1;
|
||||
Resource r2 = (Resource) o2;
|
||||
return r1.getFilename().compareTo(r2.getFilename());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
public MultiResourceItemReader() {
|
||||
setName(ClassUtils.getShortName(MultiResourceItemReader.class));
|
||||
}
|
||||
@@ -126,6 +142,10 @@ public class MultiResourceItemReader extends ExecutionContextUserSupport impleme
|
||||
return buffered;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the longer needed items from buffer, mark the index position and
|
||||
* call mark() on delegate so that it clears its buffers.
|
||||
*/
|
||||
public void mark() throws MarkFailedException {
|
||||
emptyBuffer();
|
||||
|
||||
@@ -179,6 +199,8 @@ public class MultiResourceItemReader extends ExecutionContextUserSupport impleme
|
||||
*/
|
||||
public void open(ExecutionContext executionContext) throws ItemStreamException {
|
||||
|
||||
Arrays.sort(resources, comparator);
|
||||
|
||||
index.open(executionContext);
|
||||
|
||||
delegate.setResource(resources[index.currentResource]);
|
||||
@@ -216,13 +238,6 @@ public class MultiResourceItemReader extends ExecutionContextUserSupport impleme
|
||||
Assert.notEmpty(resources, "There must be at least one input resource");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resources input resources
|
||||
*/
|
||||
public void setResources(Resource[] resources) {
|
||||
this.resources = resources;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the boolean indicating whether or not state should be saved in the
|
||||
* provided {@link ExecutionContext} during the {@link ItemStream} call to
|
||||
@@ -234,6 +249,21 @@ public class MultiResourceItemReader extends ExecutionContextUserSupport impleme
|
||||
this.saveState = saveState;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param comparator used to order the injected resources, by default
|
||||
* compares {@link Resource#getFilename()} values.
|
||||
*/
|
||||
public void setComparator(Comparator comparator) {
|
||||
this.comparator = comparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resources input resources
|
||||
*/
|
||||
public void setResources(Resource[] resources) {
|
||||
this.resources = resources;
|
||||
}
|
||||
|
||||
/**
|
||||
* Facilitates keeping track of the position within multi-resource input.
|
||||
*/
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
package org.springframework.batch.item.file;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* {@link MultiResourceItemReader} which orders the injected resources using
|
||||
* {@link #setComparator(Comparator)} to avoid potential problems caused by
|
||||
* resource re-ordering on restart.
|
||||
*
|
||||
* @see MultiResourceItemReader
|
||||
*
|
||||
* @author Robert Kasanicky
|
||||
*/
|
||||
public class SortedMultiResourceItemReader extends MultiResourceItemReader {
|
||||
|
||||
private Comparator comparator = new Comparator() {
|
||||
|
||||
/**
|
||||
* Compares resource filenames.
|
||||
*/
|
||||
public int compare(Object o1, Object o2) {
|
||||
Resource r1 = (Resource) o1;
|
||||
Resource r2 = (Resource) o2;
|
||||
return r1.getFilename().compareTo(r2.getFilename());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
public SortedMultiResourceItemReader() {
|
||||
setName(ClassUtils.getShortName(SortedMultiResourceItemReader.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param comparator used to order the injected resources, by default
|
||||
* compares {@link Resource#getFilename()} values.
|
||||
*/
|
||||
public void setComparator(Comparator comparator) {
|
||||
this.comparator = comparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Orders the resources using {@link #setComparator(Comparator)} before
|
||||
* setting them.
|
||||
*/
|
||||
public void setResources(Resource[] resources) {
|
||||
Arrays.sort(resources, comparator);
|
||||
super.setResources(resources);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.springframework.batch.item.file;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import org.springframework.batch.item.CommonItemStreamItemReaderTests;
|
||||
import org.springframework.batch.item.ExecutionContext;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
@@ -35,6 +37,12 @@ public class MultiResourceItemReaderFlatFileTests extends
|
||||
|
||||
multiReader.setResources(new Resource[] { r1, r2, r3, r4 });
|
||||
multiReader.setSaveState(true);
|
||||
multiReader.setComparator(new Comparator() {
|
||||
public int compare(Object arg0, Object arg1) {
|
||||
return 0; // preserve original ordering
|
||||
}
|
||||
|
||||
});
|
||||
multiReader.afterPropertiesSet();
|
||||
|
||||
return multiReader;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.springframework.batch.item.file;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.item.ExecutionContext;
|
||||
@@ -38,6 +40,10 @@ public class MultiResourceItemReaderIntegrationTests extends TestCase {
|
||||
itemReader.setFieldSetMapper(new PassThroughFieldSetMapper());
|
||||
|
||||
tested.setDelegate(itemReader);
|
||||
tested.setComparator(new Comparator() {
|
||||
public int compare(Object o1, Object o2) {
|
||||
return 0; // do not change ordering
|
||||
}});
|
||||
tested.setResources(new Resource[] { r1, r2, r3, r4, r5 });
|
||||
tested.afterPropertiesSet();
|
||||
}
|
||||
@@ -137,6 +143,40 @@ public class MultiResourceItemReaderIntegrationTests extends TestCase {
|
||||
assertEquals(null, readItem());
|
||||
}
|
||||
|
||||
/**
|
||||
* Resources are ordered according to injected comparator.
|
||||
*/
|
||||
public void testResourceOrderingWithCustomComparator() {
|
||||
|
||||
Resource r1 = new ByteArrayResource("".getBytes(), "b");
|
||||
Resource r2 = new ByteArrayResource("".getBytes(), "a");
|
||||
Resource r3 = new ByteArrayResource("".getBytes(), "c");
|
||||
|
||||
|
||||
Resource[] resources = new Resource[] {r1, r2, r3};
|
||||
|
||||
Comparator comp = new Comparator() {
|
||||
|
||||
/**
|
||||
* Reversed ordering by filename.
|
||||
*/
|
||||
public int compare(Object o1, Object o2) {
|
||||
Resource r1 = (Resource) o1;
|
||||
Resource r2 = (Resource) o2;
|
||||
return -r1.getDescription().compareTo(r2.getDescription());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
tested.setComparator(comp);
|
||||
tested.setResources(resources);
|
||||
tested.open(ctx);
|
||||
|
||||
assertSame(r3, resources[0]);
|
||||
assertSame(r1, resources[1]);
|
||||
assertSame(r2, resources[2]);
|
||||
}
|
||||
|
||||
private String readItem() throws Exception {
|
||||
Object result = tested.read();
|
||||
return result == null ? null : ((FieldSet) result).readString(0);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.springframework.batch.item.file;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import javax.xml.stream.XMLEventReader;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.events.Attribute;
|
||||
@@ -49,6 +51,11 @@ public class MultiResourceItemReaderXmlTests extends CommonItemStreamItemReaderT
|
||||
multiReader.setDelegate(reader);
|
||||
multiReader.setResources(new Resource[] { r1, r2, r3, r4 });
|
||||
multiReader.setSaveState(true);
|
||||
multiReader.setComparator(new Comparator() {
|
||||
public int compare(Object arg0, Object arg1) {
|
||||
return 0; // preserve original ordering
|
||||
}
|
||||
});
|
||||
multiReader.afterPropertiesSet();
|
||||
|
||||
return multiReader;
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
package org.springframework.batch.item.file;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
/**
|
||||
* Tests for {@link SortedMultiResourceItemReader}.
|
||||
*/
|
||||
public class SortedMultiResourceItemReaderTests extends TestCase {
|
||||
|
||||
private SortedMultiResourceItemReader tested = new SortedMultiResourceItemReader();
|
||||
|
||||
private Resource r1 = new FileSystemResource("b");
|
||||
|
||||
private Resource r2 = new FileSystemResource("a");
|
||||
|
||||
private Resource r3 = new FileSystemResource("c");
|
||||
|
||||
private Resource[] resources = { r1, r2, r3 };
|
||||
|
||||
/**
|
||||
* Resources are ordered according to filename by default.
|
||||
*/
|
||||
public void testResourceOrdering() {
|
||||
|
||||
tested.setResources(resources);
|
||||
|
||||
assertSame(r2, resources[0]);
|
||||
assertSame(r1, resources[1]);
|
||||
assertSame(r3, resources[2]);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Resources are ordered according to injected comparator.
|
||||
*/
|
||||
public void testResourceOrderingWithCustomComparator() {
|
||||
Comparator comp = new Comparator() {
|
||||
|
||||
/**
|
||||
* Reversed ordering by filename.
|
||||
*/
|
||||
public int compare(Object o1, Object o2) {
|
||||
Resource r1 = (Resource) o1;
|
||||
Resource r2 = (Resource) o2;
|
||||
return -r1.getFilename().compareTo(r2.getFilename());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
tested.setComparator(comp);
|
||||
tested.setResources(resources);
|
||||
|
||||
assertSame(r3, resources[0]);
|
||||
assertSame(r1, resources[1]);
|
||||
assertSame(r2, resources[2]);
|
||||
}
|
||||
}
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
<!-- This input source is injected into the test case to verify the output - not used by the job at all -->
|
||||
<bean id="testItemReader"
|
||||
class="org.springframework.batch.item.file.SortedMultiResourceItemReader">
|
||||
class="org.springframework.batch.item.file.MultiResourceItemReader">
|
||||
<property name="resources"
|
||||
value="classpath:data/multiResourceJob/input/file-*.txt" />
|
||||
<property name="delegate" ref="flatFileItemReader" />
|
||||
|
||||
Reference in New Issue
Block a user