FileCodeData.java

/*
 * Copyright (C) 2019 sw4j.org
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.sw4j.tool.barcode.random.codedata;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.sw4j.tool.barcode.random.config.CodeType;
import org.sw4j.tool.barcode.random.config.Config;
import org.sw4j.tool.barcode.random.config.EncodingConfig;

/**
 * <p>
 * This is a concrete implementation of the {@link CodeData} interface that handles files for input and output.
 * </p>
 * <p>
 * <em>This class is not thread safe.</em>
 * </p>
 * @author Uwe Plonus &lt;u.plonus@gmail.com&gt;
 */
public class FileCodeData implements CodeData {

    /**
     * <p>
     * The configuration with the data for the input and output files.
     * </p>
     */
    private final Config config;

    /**
     * <p>
     * Create a new {@code FileCodeData} with the given configuration.
     * </p>
     * @param config the configuration (files and folders) to use for the input and output data.
     */
    public FileCodeData(final Config config) {
        this.config = config;
    }

    /**
     * <p>
     * Create a new {@code FileInputStream} for the input file given in the configuration. The {@code InputStream} must
     * be closed by the caller.
     * </p>
     * @return a new {@code FileInputStream} for reading the input data.
     * @throws IOException if the creation of the {@code FileInputStream} fails.
     */
    @Override
    public InputStream getInput() throws IOException {
        return new FileInputStream(config.getInput().getName());
    }

    /**
     * <p>
     * Create a new {@code FileOutputStream} for writing the csv output file. If the folder for the output file does not
     * exists then it will be created.
     * </p>
     * @return a new {@code FileOutputStream} for writing the csv data.
     * @throws IOException if the creation of the {@code FileOutputStream} or the folder fails.
     */
    @Override
    public OutputStream getOutput() throws IOException {
        File folder = createOutputFolder();
        return new FileOutputStream(new File(folder, config.getOutput().getFile().getName()));
    }

    /**
     * <p>
     * Create a new {@code FileOutputStream} for writing a barcode. If the folder for the output file does not exists
     * then it will be created.
     * </p>
     * <p>
     * This method may be called from different threads as long as the parameters are different.
     * </p>
     * @param type the type to write.
     * @param format the encoding format to write.
     * @param ident the ident of the data.
     * @param suffix the suffix of the file to write.
     * @return a new {@code FileOutputStream} for writing the barcode data.
     * @throws IOException if the creation of the {@code FileOutputStream} or the folder fails.
     */
    @Override
    public OutputStream getOutputForIdent(final CodeType type, final EncodingConfig format, final String ident,
            final String suffix)
            throws IOException {
        File folder = createOutputFolder();
        // TODO Check file name for encoding
        return new FileOutputStream(new File(folder,
                String.format("%s-%s-%s.%s", type.getType(), format.getType(), ident, suffix)));
    }

    /**
     * <p>
     * Create the output folder if it does not already exists.
     * </p>
     * @return the output folder.
     * @throws IOException if the folder cannot be created.
     */
    private File createOutputFolder() throws IOException {
        File folder = new File(config.getOutput().getFolder());
        if (!folder.exists() && !folder.mkdirs()) {
            throw new IOException(
                    String.format("Cannot create output folder '%s'.", folder.getAbsoluteFile()));
        }
        return folder;
    }

}