koraktor/mavanagaiata

View on GitHub
src/main/java/com/github/koraktor/mavanagaiata/mojo/AbstractGitOutputMojo.java

Summary

Maintainability
A
25 mins
Test Coverage
A
90%
/*
 * This code is free software; you can redistribute it and/or modify it under
 * the terms of the new BSD License.
 *
 * Copyright (c) 2011-2019, Sebastian Staudt
 */

package com.github.koraktor.mavanagaiata.mojo;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.maven.plugins.annotations.Parameter;

import com.github.koraktor.mavanagaiata.git.GitRepository;

import static java.nio.file.Files.*;

/**
 * This abstract Mojo implements writing output to a {@code PrintStream}
 *
 * This is either {@code System.out} by default, but maybe another
 * {@code PrintStream} object wrapped around a file given by {@code outputFile}.
 *
 * @author Sebastian Staudt
 * @see File
 * @see PrintStream
 * @since 0.2.2
 */
abstract class AbstractGitOutputMojo extends AbstractGitMojo {

    /**
     * The encoding to use for generated output
     */
    @Parameter(property = "mavanagaiata.encoding",
               defaultValue = "UTF-8")
    String encoding;

    /**
     * The footer to print below the output
     */
    @Parameter(property = "mavanagaiata.footer",
               defaultValue = "\nGenerated by Mavanagaiata %s at %s")
    String footer;

    PrintStream printStream;

    /**
     * Unescapes newlines for format strings
     *
     * @param format The escaped format string
     * @return The unescaped format string
     */
    static String unescapeFormatNewlines(String format) {
        return format.replaceAll("([^\\\\]?)\\\\n", "$1\n");
    }

    protected void initConfiguration() {
        footer = unescapeFormatNewlines(footer);
    }

    /**
     * Initializes the output stream for the generated content
     *
     * @throws MavanagaiataMojoException if the output file can not be opened
     */
    @Override
    protected GitRepository init() throws MavanagaiataMojoException {
        initConfiguration();

        return super.init();
    }

    /**
     * Returns the output file for the generated content
     * <p>
     * Has to be implemented by subclassing mojos, so that the output file
     * can be easily configured.
     *
     * @return The output file for the generated content
     */
    public abstract File getOutputFile();

    /**
     * Initializes the {@code PrintStream} to use
     *
     * This is {@code System.out} if no output file is given (default).
     * Otherwise the parent directories of {@code outputFile} are created and a
     * new {@code PrintStream} for that file is created.
     *
     * @throws MavanagaiataMojoException if the file specified by
     *         {@code outputFile} cannot be opened for writing or the target
     *         directory cannot be created
     */
    @Override
    protected final void run(GitRepository repository) throws MavanagaiataMojoException {
        if (getOutputFile() == null) {
            printStream = System.out;
            generateOutput(repository);
        } else {
            File parentDirectory = getOutputFile().getParentFile();

            try {
                createDirectories(parentDirectory.toPath());
            } catch (IOException e) {
                throw MavanagaiataMojoException.create("Could not create directory \"%s\" for output file.",
                    e,
                    parentDirectory.getAbsolutePath());
            }

            try (PrintStream filePrintStream = createPrintStream()) {
                printStream = filePrintStream;
                generateOutput(repository);
            } catch (FileNotFoundException | UnsupportedEncodingException e) {
                throw MavanagaiataMojoException.create(
                                        "Could not open output file \"%s\" for writing.",
                                        e,
                                        getOutputFile().getAbsolutePath());
            }
        }
    }

    /**
     * Creates a new print stream for the configured output file and encoding
     *
     * @return A new print stream
     * @throws FileNotFoundException if the output file could not be found
     * @throws UnsupportedEncodingException if the encoding is not supported
     */
    PrintStream createPrintStream()
            throws FileNotFoundException, UnsupportedEncodingException {
        return new PrintStream(getOutputFile(), encoding);
    }

    /**
     * Sets the output file for the generated content
     *
     * @param outputFile The output file for the generated content
     */
    public abstract void setOutputFile(File outputFile);

    /**
     * This must be implemented by mojos for writing their output
     *
     * @param repository The repository the mojo is running in
     * @throws MavanagaiataMojoException if the output cannot be generated
     */
    protected abstract void writeOutput(GitRepository repository)
            throws MavanagaiataMojoException;

    /**
     * Writes the (optional) footer and flushes the {@code PrintStream} after
     * calling the main mojo implementation
     *
     * @param repository The repository the mojo is running in
     * @see #writeOutput
     * @throws MavanagaiataMojoException if the output cannot be generated
     */
    void generateOutput(GitRepository repository)
            throws MavanagaiataMojoException {
        writeOutput(repository);

        if (footer.length() > 0) {
            SimpleDateFormat baseDateFormat = new SimpleDateFormat(dateFormat);
            printStream.println(String.format(footer,
                    VersionHelper.getVersion(),
                    baseDateFormat.format(new Date())));
        }

        printStream.flush();
    }

}