Skip to content

Instantly share code, notes, and snippets.

@trmsmy
Created May 23, 2017 02:48
Show Gist options
  • Save trmsmy/63002ee2a47a3acb3e1f4f7cd59ec007 to your computer and use it in GitHub Desktop.
Save trmsmy/63002ee2a47a3acb3e1f4f7cd59ec007 to your computer and use it in GitHub Desktop.
Multi line record reader using PeekableItemReader
package com.trmsmy.spring.boot.batch.springbootbatch;
import java.util.ArrayList;
import java.util.List;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.ItemStreamException;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.support.SingleItemPeekableItemReader;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
public class MultiLineTradeItemReader implements ItemReader<String>, ItemStream {
private SingleItemPeekableItemReader<String> delegate;
@Override
public String read() throws Exception {
List<String> record = null;
for (String line; (line = this.delegate.read()) != null;) {
if (isRecordStart(line)) {
record = new ArrayList<>();
record.add(line);
}
else {
record.add(line);
String nextLine = this.delegate.peek();
if (nextLine == null || isRecordStart(nextLine)) {
return StringUtils.collectionToDelimitedString(record, "\n");
}
}
}
Assert.isNull(record, "No 'END' was found.");
return null;
}
private boolean isRecordStart(String line) {
return line != null && line.equals("START");
}
public void setDelegate(FlatFileItemReader<String> delegate) {
this.delegate = new SingleItemPeekableItemReader<>();
this.delegate.setDelegate(delegate);
}
@Override
public void close() throws ItemStreamException {
this.delegate.close();
}
@Override
public void open(ExecutionContext executionContext) throws ItemStreamException {
this.delegate.open(executionContext);
}
@Override
public void update(ExecutionContext executionContext) throws ItemStreamException {
this.delegate.update(executionContext);
}
}
@Gregordy
Copy link

This is so useful, thanks a lot!

@bhavasar
Copy link

great

@dimio
Copy link

dimio commented Nov 27, 2020

Can you suggest how to use this to read a file (instead of or in conjunction with FlatFileTemReader)?

@robinsomarajv
Copy link

Can the read method return the collection and processor receive the same? Can you please share how the step configuration would look like. I am having hard time the generics.

My usecase needs the delegate to read a book(item) and group by authors and pass the collection of books of an author to processor and then build a different aggregation object from processor to be send to writer

@xenogew
Copy link

xenogew commented Sep 27, 2021

Can this be used in MultiResourceItemReader?
I found it was thrown with this exception message Input resource must be set.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment