All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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