Walid Ammou
Walid Ammou

Reputation: 440

Get current resource name using MultiResourceItemReader Spring batch

I am using MultiResourceItemReader in Spring Batch for reading multiple XML files and I want to get current resource.Here is my configuration:

public class MultiFileResourcePartitioner extends MultiResourceItemReader<MyObject> {
    @Override
    public void update(final ExecutionContext pExecutionContext) throws ItemStreamException {
        super.update(pExecutionContext);
        if (getCurrentResource() != null && getCurrentResource().getFilename() != null) {
            System.out.println("update:" + getCurrentResource().getFilename());
        }
    }
}

And my reader:

<bean id="myMultiSourceReader"
   class="mypackage.MultiFileResourcePartitioner">
   <property name="resources" value="file:${input.directory}/*.xml" />
        
</bean>

The code above read XML files correctly but the method getCurrentResources() return null. By debugging, the batch enter to update method

Please help!

UPDATE: My code bellow is correct. I have just clean my project and now I can get the current resource.

Upvotes: 3

Views: 11498

Answers (3)

mastersunny
mastersunny

Reputation: 1

public class CpsFileItemProcessor implements ItemProcessor<T, T> {

    @Autowired
    MultiResourceItemReader multiResourceItemReader;

    private String fileName;

    @Override
    public FileDetailsEntityTemp process(T item) {
        if(multiResourceItemReader.getCurrentResource()!=null){
            fileName =  multiResourceItemReader.getCurrentResource().getFilename();
        }
    item.setFileName(fileName);
        return item;
    }
}

Upvotes: -2

Luca Basso Ricci
Luca Basso Ricci

Reputation: 18403

There is a specific interface for this problem called ResourceAware: it's purpouse is to inject current resource into objects read from a MultiResourceItemReader.
Check this thread for further information.

Upvotes: 3

Michael Pralow
Michael Pralow

Reputation: 6630

I tried it with a simple Listener for logging the current resource from a injected {@link MultiResourceItemReader}. Saves the value to the StepExecutionContext.

To get it working with a step scoped MultiResourceItemReader i access the proxy directly, see http://forum.springsource.org/showthread.php?120775-Accessing-the-currently-processing-filename, https://gist.github.com/1582202 and https://jira.springsource.org/browse/BATCH-1831.

public class GetCurrentResourceChunkListener implements ChunkListener, StepExecutionListener {

    private StepExecution stepExecution;
    private Object proxy;
    private final List<String> fileNames = new ArrayList<>();

    public void setProxy(Object mrir) {
        this.proxy = mrir;
    }

    @Override
    public void beforeStep(StepExecution stepExecution) {
        this.stepExecution = stepExecution;
    }

    @Override
    public ExitStatus afterStep(StepExecution stepExecution) {
        return stepExecution.getExitStatus();
    }

    @Override
    public void beforeChunk(ChunkContext cc) {
        if (proxy instanceof Advised) {
            try {
                Advised advised = (Advised) proxy;
                Object obj = advised.getTargetSource().getTarget();
                MultiResourceItemReader mrirTarget = (MultiResourceItemReader) obj;
                if (mrirTarget != null
                        && mrirTarget.getCurrentResource() != null
                        && !fileNames.contains(mrirTarget.getCurrentResource().getFilename())) {
                    String fileName = mrirTarget.getCurrentResource().getFilename();
                    fileNames.add(fileName);
                    String index = String.valueOf(fileNames.indexOf(fileName));
                    stepExecution.getExecutionContext().put("current.resource" + index, fileName);
                }
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }
        }
    }

    @Override
    public void afterChunk(ChunkContext cc) {
    }

    @Override
    public void afterChunkError(ChunkContext cc) {
    }
}

see https://github.com/langmi/spring-batch-examples-playground for a working example - look for "GetCurrentResource..."

Upvotes: 0

Related Questions