
org.jberet.support.io.BeanIOItemReader Maven / Gradle / Ivy
The newest version!
/*
* Copyright (c) 2014-2018 Red Hat, Inc. and/or its affiliates.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.jberet.support.io;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.Serializable;
import org.beanio.BeanReader;
import org.beanio.BeanReaderErrorHandler;
import org.beanio.StreamFactory;
import org.beanio.internal.util.LocaleUtil;
import org.jberet.support._private.SupportMessages;
import jakarta.batch.api.BatchProperty;
import jakarta.batch.api.chunk.ItemReader;
import jakarta.enterprise.context.Dependent;
import jakarta.inject.Inject;
import jakarta.inject.Named;
/**
* An implementation of {@code jakarta.batch.api.chunk.ItemReader} based on BeanIO. This reader class handles all
* data formats that are supported by BeanIO, e.g., fixed length file, CSV file, XML, etc. It supports restart,
* ranged reading, custom error handler, and dynamic BeanIO mapping properties. {@link org.jberet.support.io.BeanIOItemReader}
* configurations are specified as reader properties in job xml, and BeanIO mapping xml file.
*
* @see BeanIOItemReaderWriterBase
* @see BeanIOItemWriter
* @since 1.1.0
*/
@Named
@Dependent
public class BeanIOItemReader extends BeanIOItemReaderWriterBase implements ItemReader {
/**
* A positive integer indicating the start position in the input resource. It is optional and defaults to 1
* (starting from the 1st data item).
*/
@Inject
@BatchProperty
protected int start;
/**
* A positive integer indicating the end position in the input resource. It is optional and defaults to
* {@code Integer.MAX_VALUE}.
*/
@Inject
@BatchProperty
protected int end;
/**
* A class implementing {@link org.beanio.BeanReaderErrorHandler} for handling exceptions thrown by a
* {@link BeanReader}.
*/
@Inject
@BatchProperty
protected Class errorHandler;
/**
* The locale name for this {@code BeanIOItemReader}
*/
@Inject
@BatchProperty
protected String locale;
private BeanReader beanReader;
protected int currentPosition;
@Override
public void open(final Serializable checkpoint) throws Exception {
/**
* The row number to start reading. It may be different from the injected field start. During a restart,
* we would start reading from where it ended during the last run.
*/
if (this.end == 0) {
this.end = Integer.MAX_VALUE;
}
if (this.start == 0) {
this.start = 1;
}
final int startRowNumber = checkpoint == null ? this.start : (Integer) checkpoint;
if (startRowNumber < this.start || startRowNumber > this.end || startRowNumber < 0) {
throw SupportMessages.MESSAGES.invalidStartPosition(startRowNumber, this.start, this.end);
}
mappingFileKey = new StreamFactoryKey(jobContext, streamMapping);
final StreamFactory streamFactory = getStreamFactory(streamFactoryLookup, mappingFileKey, mappingProperties);
final InputStream inputStream = getInputStream(resource, false);
final Reader inputReader = charset == null ? new InputStreamReader(inputStream) :
new InputStreamReader(inputStream, charset);
beanReader = streamFactory.createReader(streamName, new BufferedReader(inputReader), LocaleUtil.parseLocale(locale));
if (errorHandler != null) {
beanReader.setErrorHandler((BeanReaderErrorHandler) errorHandler.getDeclaredConstructor().newInstance());
}
if (startRowNumber > 1) {
beanReader.skip(startRowNumber - 1);
currentPosition += startRowNumber - 1;
}
}
@Override
public Object readItem() throws Exception {
if (++currentPosition > end) {
return null;
}
final Object readValue = beanReader.read();
if (!skipBeanValidation) {
ItemReaderWriterBase.validate(readValue);
}
return readValue;
}
@Override
public Serializable checkpointInfo() throws Exception {
return currentPosition;
}
@Override
public void close() throws Exception {
if (beanReader != null) {
beanReader.close();
beanReader = null;
mappingFileKey = null;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy