CsvClientImpl.java

/*
 * CSVeed (https://github.com/42BV/CSVeed)
 *
 * Copyright 2013-2023 CSVeed.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of The Apache Software License,
 * Version 2.0 which accompanies this distribution, and is available at
 * https://www.apache.org/licenses/LICENSE-2.0.txt
 */
package org.csveed.api;

import java.io.Reader;
import java.io.Writer;
import java.util.Collection;
import java.util.List;
import java.util.Locale;

import org.csveed.bean.AbstractMapper;
import org.csveed.bean.BeanInstructions;
import org.csveed.bean.BeanParser;
import org.csveed.bean.BeanReader;
import org.csveed.bean.BeanReaderImpl;
import org.csveed.bean.BeanWriter;
import org.csveed.bean.BeanWriterImpl;
import org.csveed.bean.conversion.Converter;
import org.csveed.report.CsvException;
import org.csveed.report.GeneralError;
import org.csveed.row.RowInstructions;
import org.csveed.row.RowReader;
import org.csveed.row.RowReaderImpl;
import org.csveed.row.RowWriter;
import org.csveed.row.RowWriterImpl;

/**
 * The Class CsvClientImpl.
 *
 * @param <T>
 *            the generic type
 */
public class CsvClientImpl<T> implements CsvClient<T> {

    /** The bean reader. */
    private BeanReader<T> beanReader;

    /** The bean writer. */
    private BeanWriter<T> beanWriter;

    /** The row reader. */
    private RowReader rowReader;

    /** The row writer. */
    private RowWriter rowWriter;

    /** The row instructions. */
    private final RowInstructions rowInstructions;

    /** The bean instructions. */
    private BeanInstructions beanInstructions;

    /**
     * Instantiates a new csv client impl.
     *
     * @param writer
     *            the writer
     */
    public CsvClientImpl(Writer writer) {
        this.rowWriter = new RowWriterImpl(writer);
        this.rowInstructions = getRowWriter().getRowInstructions();
    }

    /**
     * Instantiates a new csv client impl.
     *
     * @param writer
     *            the writer
     * @param beanClass
     *            the bean class
     */
    public CsvClientImpl(Writer writer, Class<T> beanClass) {
        this(writer, new BeanParser().getBeanInstructions(beanClass));
    }

    /**
     * Instantiates a new csv client impl.
     *
     * @param writer
     *            the writer
     * @param beanInstructions
     *            the bean instructions
     */
    public CsvClientImpl(Writer writer, BeanInstructions beanInstructions) {
        this.beanWriter = new BeanWriterImpl<>(writer, beanInstructions);
        this.rowWriter = getBeanWriter().getRowWriter();
        this.rowInstructions = getRowWriter().getRowInstructions();
        this.beanInstructions = beanInstructions;
    }

    /**
     * Instantiates a new csv client impl.
     *
     * @param reader
     *            the reader
     */
    public CsvClientImpl(Reader reader) {
        this.rowReader = new RowReaderImpl(reader);
        this.rowInstructions = getRowReader().getRowInstructions();
    }

    /**
     * Instantiates a new csv client impl.
     *
     * @param reader
     *            the reader
     * @param beanClass
     *            the bean class
     */
    public CsvClientImpl(Reader reader, Class<T> beanClass) {
        this(reader, new BeanParser().getBeanInstructions(beanClass));
    }

    /**
     * Instantiates a new csv client impl.
     *
     * @param reader
     *            the reader
     * @param beanInstructions
     *            the bean instructions
     */
    public CsvClientImpl(Reader reader, BeanInstructions beanInstructions) {
        this.beanReader = new BeanReaderImpl<>(reader, beanInstructions);
        this.rowReader = getBeanReader().getRowReader();
        this.rowInstructions = getRowReader().getRowInstructions();
        this.beanInstructions = beanInstructions;
    }

    @Override
    public void writeBeans(Collection<T> beans) {
        getBeanWriter().writeBeans(beans);
    }

    @Override
    public void writeBean(T bean) {
        getBeanWriter().writeBean(bean);
    }

    @Override
    public void writeRow(Row row) {
        getRowWriter().writeRow(row);
    }

    @Override
    public Row writeRow(String[] row) {
        return getRowWriter().writeRow(row);
    }

    @Override
    public void writeRows(Collection<Row> rows) {
        getRowWriter().writeRows(rows);
    }

    @Override
    public void writeRows(String[][] rows) {
        getRowWriter().writeRows(rows);
    }

    @Override
    public Header writeHeader(String[] header) {
        return getRowWriter().writeHeader(header);
    }

    @Override
    public void writeHeader(Header header) {
        getRowWriter().writeHeader(header);
    }

    @Override
    public void writeHeader() {
        getBeanWriter().writeHeader();
    }

    @Override
    public List<T> readBeans() {
        return getBeanReader().readBeans();
    }

    @Override
    public T readBean() {
        return getBeanReader().readBean();
    }

    @Override
    public List<Row> readRows() {
        return getRowReader().readRows();
    }

    @Override
    public Row readRow() {
        return getRowReader().readRow();
    }

    @Override
    public Header readHeader() {
        return getRowReader().readHeader();
    }

    @Override
    public int getCurrentLine() {
        return getRowReader().getCurrentLine();
    }

    @Override
    public boolean isFinished() {
        return getRowReader().isFinished();
    }

    @Override
    public CsvClient<T> setUseHeader(boolean useHeader) {
        rowInstructions.setUseHeader(useHeader);
        return this;
    }

    @Override
    public CsvClient<T> setStartRow(int startRow) {
        rowInstructions.setStartRow(startRow);
        return this;
    }

    @Override
    public CsvClient<T> setEscape(char symbol) {
        rowInstructions.setEscape(symbol);
        return this;
    }

    @Override
    public CsvClient<T> setQuote(char symbol) {
        rowInstructions.setQuote(symbol);
        return this;
    }

    @Override
    public CsvClient<T> setSeparator(char symbol) {
        rowInstructions.setSeparator(symbol);
        return this;
    }

    @Override
    public CsvClient<T> setComment(char symbol) {
        rowInstructions.setComment(symbol);
        return this;
    }

    @Override
    public CsvClient<T> setEndOfLine(char[] symbols) {
        rowInstructions.setEndOfLine(symbols);
        return this;
    }

    @Override
    public CsvClient<T> skipEmptyLines(boolean skip) {
        rowInstructions.skipEmptyLines(skip);
        return this;
    }

    @Override
    public CsvClient<T> skipCommentLines(boolean skip) {
        rowInstructions.skipCommentLines(skip);
        return this;
    }

    @Override
    public CsvClient<T> setMapper(Class<? extends AbstractMapper> mapper) {
        getBeanInstructions().setMapper(mapper);
        return this;
    }

    @Override
    public CsvClient<T> setDate(String propertyName, String dateFormat) {
        getBeanInstructions().setDate(propertyName, dateFormat);
        return this;
    }

    @Override
    public CsvClient<T> setLocalizedNumber(String propertyName, Locale locale) {
        getBeanInstructions().setLocalizedNumber(propertyName, locale);
        return this;
    }

    @Override
    public CsvClient<T> setRequired(String propertyName, boolean required) {
        getBeanInstructions().setRequired(propertyName, required);
        return this;
    }

    @Override
    public CsvClient<T> setConverter(String propertyName, Converter converter) {
        getBeanInstructions().setConverter(propertyName, converter);
        return this;
    }

    @Override
    public CsvClient<T> ignoreProperty(String propertyName) {
        getBeanInstructions().ignoreProperty(propertyName);
        return this;
    }

    @Override
    public CsvClient<T> mapColumnIndexToProperty(int columnIndex, String propertyName) {
        getBeanInstructions().mapColumnIndexToProperty(columnIndex, propertyName);
        return this;
    }

    @Override
    public CsvClient<T> mapColumnNameToProperty(String columnName, String propertyName) {
        getBeanInstructions().mapColumnNameToProperty(columnName, propertyName);
        return this;
    }

    @Override
    public CsvClient<T> setStartIndexDynamicColumns(int startIndex) {
        getBeanInstructions().setStartIndexDynamicColumns(startIndex);
        return this;
    }

    @Override
    public CsvClient<T> setHeaderNameToProperty(String propertyName) {
        getBeanInstructions().setHeaderNameToProperty(propertyName);
        return this;
    }

    @Override
    public CsvClient<T> setHeaderValueToProperty(String propertyName) {
        getBeanInstructions().setHeaderValueToProperty(propertyName);
        return this;
    }

    /**
     * Gets the bean instructions.
     *
     * @return the bean instructions
     */
    private BeanInstructions getBeanInstructions() {
        if (this.beanInstructions == null) {
            throw new CsvException(new GeneralError(
                    "BeanInstructions have not been initialized. Make sure to pass BeanInstructions or the bean class"
                            + " to CsvClient."));
        }
        return this.beanInstructions;
    }

    /**
     * Gets the bean reader.
     *
     * @return the bean reader
     */
    private BeanReader<T> getBeanReader() {
        if (this.beanReader == null) {
            throw new CsvException(new GeneralError(
                    "BeanReader has not been initialized. Make sure to pass BeanInstructions or the bean class to CsvClient."));
        }
        return this.beanReader;
    }

    /**
     * Gets the bean writer.
     *
     * @return the bean writer
     */
    private BeanWriter<T> getBeanWriter() {
        if (this.beanWriter == null) {
            throw new CsvException(new GeneralError(
                    "BeanWriter has not been initialized. Make sure to pass BeanInstructions or the bean class to CsvClient."));
        }
        return this.beanWriter;
    }

    /**
     * Gets the row reader.
     *
     * @return the row reader
     */
    private RowReader getRowReader() {
        if (this.rowReader == null) {
            throw new CsvException(new GeneralError(
                    "RowReader has not been initialized. Make sure to pass a Reader to the constructor."));
        }
        return this.rowReader;
    }

    /**
     * Gets the row writer.
     *
     * @return the row writer
     */
    public RowWriter getRowWriter() {
        if (this.rowWriter == null) {
            throw new CsvException(new GeneralError(
                    "RowWriter has not been initialized. Make sure to pass a Writer to the constructor."));
        }
        return rowWriter;
    }

}