An alternative would be to create a class similar to ClassifierCompositeItemProcessor
or ClassifierCompositeItemWriter
. That is to say, it would take a Classifier
, a list of delegated ItemReader
and choose the right ItemReader
depending of the result of the Classifier
.
Problem is, you don't have an input to classify, since the read isn't done yet. That's why I thought about using the resource
property as the element to classify. Here's the result :
public class ResourceClassifierCompositeItemReader<T> implements ItemReader<T> {
private Classifier<String, ItemReader<? extends T>> classifier = new ClassifierSupport<String, ItemReader<? extends T>> (null);
private Resource resource;
public void setClassifier(Classifier<String, ItemReader<? extends T>> classifier) {
this.classifier = classifier;
}
@Override
public T read() throws Exception, UnexpectedInputException, ParseException {
return readItem(classifier.classify(resource.getFilename()));
}
private T readItem(ItemReader<? extends T> reader) throws Exception {
return reader.read();
}
public void setResource(Resource resource) {
this.resource = resource;
}
}
Now for how to use it. First you'll need a MultiResourceItemReader
to read both .PSV and .CSV at the same time. Then you'll have to delegate the read to the ResourceClassifierCompositeItemReader
. You'll have to add a BackToBackPatternClassifier
to classify the String resource.getFilename()
(i.e. the file name) and call an ItemReader
accordingly (via a MatcherMap
). To do that, you'll need to write your own RouterDelegate
(taking the filename, split it to get the extension, and return it as a String to be matched).