1
votes

I have very large txt file that I'm parsing with PatternMatchingCompositeLineMapper because each row have different number of columns.
In this file I have data from multiple periods, each period in this file is represented by header DATA with date of this period. After this header there are lines with data related to this period and they end with header STOP.
The problem is that I need to save data for all periods that start before and end after specific date, to another file.
Is there some way to do this in Spring Batch?
Sample file looks like this:

DATA|20121113-20121212
STRT|33|20121213|123425654|123
ASD|asd|asd|asd
QWE|qwe|qwe
ZXC|zxc|zxc|zxc|zxc
STOP

DATA|20121213-20130112
STRT|33|20130113|65465463546|123
ASD|asd|asd|asd
QWE|qwe|qwe
ZXC|zxc|zxc|zxc|zxc
STOP

DATA|20121113-20121212
STRT|33|20121213|34653465546|123.10
ASD|asd|asd|asd
QWE|qwe|qwe
ZXC|zxc|zxc|zxc|zxc
STOP

DATA|20120713-20120812
STRT|33|20121213|34654356546|123.10
STOP

DATA|20121213-20130112
STRT|33|20130113|345646345|123.10
ASD|asd|asd|asd
QWE|qwe|qwe
ZXC|zxc|zxc|zxc|zxc
STOP
1

1 Answers

1
votes

You can probably do this via a ClassifierCompositeItemWriter. I will assume that you have a domain object (say, MyDomainObject) that has both the start and end dates as shown in your same input.

You will first need to create a class that declares a classify method and annotate it with @Classifier. This is what will effectively route the item to one of the underyling item writers (in your case, based on whether the record's start and end date span a reference date).

import org.springframework.batch.support.annotation.Classifier;
public class MyDateClassifierDelegate {
    //set this via Spring, or whatever
    private final Date referenceDate;

    @Classifier
    public String classify(MyDomainObject classifiable) {
        if(classifiable.startDate.compareTo(referenceDate) < 0
                && classifiable.endDate.compareTo(referenceDate) >= 0) {
            return "FILE1";
        }
        else {
            return "FILE2";
        }
    }
}

Next, you will need to configure the ClassifierCompositeItemWriter to delegate to one of the two underlying item writers based on the value that was set by the classifier. In this case, you will set up file1Writer and file2Writer however you need, which I gather will just be flat file item writers.

<beans:bean id="dateRangeBasedFileWriter" class="org.springframework.batch.item.support.ClassifierCompositeItemWriter">
    <beans:property name="classifier">
        <beans:bean class="org.springframework.batch.classify.BackToBackPatternClassifier">
            <beans:property name="routerDelegate">
                <!-- this is where you specify the classifier that is to be used -->
                <beans:bean class="MyDateClassifierDelegate" />
            </beans:property>
            <beans:property name="matcherMap">
                <beans:map>
                    <!-- this will contain your "spanning reference date" items -->
                    <beans:entry key="FILE1" value-ref="file1Writer" />
                    <!-- this will contain your "not spanning reference date" items -->
                    <beans:entry key="FILE2" value-ref="file2Writer" />
                </beans:map>
            </beans:property>
        </beans:bean>
    </beans:property>
</beans:bean>