DocAsCodeAntLogger.java

package org.docascode.ant;

import org.apache.log4j.Logger;
import org.apache.tools.ant.*;
import org.apache.tools.ant.util.StringUtils;
import org.docascode.cli.CLIEventListener;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintStream;
import java.io.StringReader;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.tools.ant.util.DateUtils;

public class DocAsCodeAntLogger extends CLIEventListener implements BuildLogger {
    /**
     * Time of the start of the build
     */
    private long startBuildTime = System.currentTimeMillis();

    private static final int LEFT_COLUMN_SIZE = 12;

    private int msgOutputLevel = Project.MSG_ERR;

    protected void log(String message) {
        Logger logger = Logger.getLogger(DocAsCodeAntLogger.class);
        logger.info(message);
    }

    @Override
    public void buildStarted(BuildEvent buildEvent) {
        startBuildTime = System.currentTimeMillis();
    }

    private static void throwableMessage(StringBuilder m, Throwable error, boolean verbose) {
        while (error instanceof BuildException) { // #43398
            Throwable cause = error.getCause();
            if (cause != null) {
                String msg1 = error.toString();
                String msg2 = cause.toString();
                if (msg1.endsWith(msg2)) {
                    m.append(msg1, 0, msg1.length() - msg2.length());
                    error = cause;
                } else {
                    break;
                }
            }
        }
        if (verbose || !(error instanceof BuildException)) {
            m.append(StringUtils.getStackTrace(error));
        } else {
            m.append(String.format("%s%n", error));
        }
    }

    @Override
    public void setMessageOutputLevel(int level) {
        this.msgOutputLevel = level;
    }

    /**
     * No-op implementation.
     *
     * @param printStream Ignored.
     */
    @Override
    public void setOutputPrintStream(PrintStream printStream) {
        throw new UnsupportedOperationException();
    }

    /**
     * No-op implementation.
     *
     * @param b Ignored.
     */
    @Override
    public void setEmacsMode(boolean b) {
        throw new UnsupportedOperationException();
    }

    /**
     * No-op implementation.
     *
     * @param printStream Ignored.
     */
    @Override
    public void setErrorPrintStream(PrintStream printStream) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void buildFinished(BuildEvent event) {
        Throwable error = event.getException();
        StringBuilder message = new StringBuilder();
        if (error == null) {
            message.append(String.format("%n%s", "BUILD SUCCESSFULL"));
        } else {
            message.append(String.format("%n%s%n", "BUILD FAILED"));
            throwableMessage(message, error, Project.MSG_VERBOSE <= msgOutputLevel);
        }
        message.append(String.format("%nTotal time: %s",
                DateUtils.formatElapsedTime(System.currentTimeMillis() - startBuildTime)));

        String msg = message.toString();
        printMessage(msg, Project.MSG_VERBOSE);
    }

    private void printMessage(String msg, int msgVerbose) {
        switch (msgVerbose) {
            case Project.MSG_ERR:
                error(msg+"\n");
                break;
            case Project.MSG_WARN:
                warn(msg+"\n");
                break;
            case Project.MSG_INFO:
                info(msg+"\n");
                break;
            case Project.MSG_VERBOSE:
                debug(msg+"\n");
                break;
            case Project.MSG_DEBUG:
                debug(msg+"\n");
                break;
            default:
                error(msg);
                break;
        }
    }

    @Override
    public void targetStarted(BuildEvent event) {
        if (Project.MSG_INFO <= msgOutputLevel
                && !event.getTarget().getName().isEmpty()) {
            String msg = String.format("%n%s:", event.getTarget().getName());
            printMessage(msg, event.getPriority());
        }
    }

    /**
     * No-op implementation.
     *
     * @param event Ignored.
     */
    @Override
    public void targetFinished(BuildEvent event) {
        //Nothing to display
    }

    /**
     * No-op implementation.
     *
     * @param event Ignored.
     */
    @Override
    public void taskStarted(BuildEvent event) {
        //Nothing to display
    }

    /**
     * No-op implementation.
     *
     * @param event Ignored.
     */
    @Override
    public void taskFinished(BuildEvent event) {
        //Nothing to display
    }

    @Override
    public void messageLogged(BuildEvent event) {
        int priority = event.getPriority();
        // Filter out messages based on priority
        if (priority <= msgOutputLevel) {

            StringBuilder message = new StringBuilder();
            if (event.getTask() == null) {
                message.append(event.getMessage());
            } else {
                String name = event.getTask().getTaskName();
                String label = "[" + name + "] ";
                int size = LEFT_COLUMN_SIZE - label.length();
                final String prefix = size > 0 ? Stream.generate(() -> " ")
                        .limit(size).collect(Collectors.joining()) + label : label;

                try (BufferedReader r =
                             new BufferedReader(new StringReader(event.getMessage()))) {
                    message.append(r.lines()
                            .collect(Collectors.joining(System.lineSeparator() + prefix, prefix, "")));
                } catch (IOException e) {
                    // shouldn't be possible
                    message.append(label).append(event.getMessage());
                }
            }
            Throwable ex = event.getException();
            if (Project.MSG_DEBUG <= msgOutputLevel && ex != null) {
                message.append(String.format("%n%s: ", ex.getClass().getSimpleName()))
                        .append(StringUtils.getStackTrace(ex));
            }

            String msg = message.toString();
            printMessage(msg, priority);
        }
    }
}