sleekbyte/tailor

View on GitHub
src/main/java/com/sleekbyte/tailor/format/HTMLFormatter.java

Summary

Maintainability
A
35 mins
Test Coverage
package com.sleekbyte.tailor.format;

import com.github.mustachejava.DefaultMustacheFactory;
import com.github.mustachejava.Mustache;
import com.sleekbyte.tailor.common.ColorSettings;
import com.sleekbyte.tailor.common.ConfigProperties;
import com.sleekbyte.tailor.common.Messages;
import com.sleekbyte.tailor.output.ViolationMessage;

import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Formatter that displays violation messages in valid HTML output.
 */
public final class HTMLFormatter extends Formatter {

    protected static final String TEMPLATE_PATH = "index.html";
    private static final String NEWLINE_PATTERN = "\n";
    private static final List<Map<String, Object>> FILES = new ArrayList<>();

    public HTMLFormatter(ColorSettings colorSettings) {
        super(colorSettings);
    }

    protected static List<Map<String, Object>> getFiles() {
        return FILES;
    }

    protected static void clearFiles() {
        FILES.clear();
    }

    @Override
    public void displayViolationMessages(List<ViolationMessage> violationMessages, File inputFile) throws IOException {
        List<Map<String, Object>> violations = new ArrayList<>();
        for (ViolationMessage msg : violationMessages) {
            Map<String, Object> violation = new HashMap<>();
            Map<String, Integer> location = new HashMap<>();

            location.put(Messages.LINE_KEY, msg.getLineNumber());
            if (msg.getColumnNumber() != 0) {
                location.put(Messages.COLUMN_KEY, msg.getColumnNumber());
            }
            violation.put(Messages.LOCATION_KEY, location);
            switch (msg.getSeverity()) {
                case ERROR:
                    violation.put(Messages.ERROR, true);
                    break;
                case WARNING:
                    violation.put(Messages.WARNING, true);
                    break;
                default:
                    break;
            }
            violation.put(Messages.RULE_KEY, msg.getRule().getName());
            violation.put(Messages.MESSAGE_KEY, msg.getMessage());

            violations.add(violation);
        }
        storeMessages(violations, true, inputFile.getCanonicalPath());
    }

    @Override
    public void displayParseErrorMessage(File inputFile) throws IOException {
        storeMessages(new ArrayList<>(), false, inputFile.getCanonicalPath());
    }

    @Override
    public void displaySummary(long numFiles, long numSkipped, long numErrors, long numWarnings) throws IOException {
        Map<String, Object> output = new HashMap<>();
        output.put(Messages.SUMMARY_KEY,
            Formatter.formatSummary(numFiles, numSkipped, numErrors, numWarnings).replace(NEWLINE_PATTERN, ""));
        // Sort files by descending order of the number of violations
        FILES.sort((o1, o2) ->
            ((List) o2.get(Messages.VIOLATIONS_KEY)).size() - ((List) o1.get(Messages.VIOLATIONS_KEY)).size());
        output.put(Messages.FILES_KEY, FILES);
        output.put(Messages.VERSION_LONG_OPT, new ConfigProperties().getVersion());

        InputStreamReader inputStreamReader = new InputStreamReader(
            HTMLFormatter.class.getResourceAsStream(TEMPLATE_PATH),
            Charset.defaultCharset());
        Mustache mustache = new DefaultMustacheFactory().compile(inputStreamReader, TEMPLATE_PATH);
        mustache.execute(new OutputStreamWriter(System.out, Charset.defaultCharset()), output).flush();
        inputStreamReader.close();
    }

    @Override
    public void printProgressInfo(String str) {
        // Not Applicable to this formatter
    }

    private void storeMessages(List<Map<String, Object>> violations, boolean parsed, String filePath)
        throws IOException {
        Map<String, Object> output = new HashMap<>();
        output.put(Messages.PATH_KEY, filePath);
        output.put(Messages.VIOLATIONS_KEY, violations);
        final int numViolations = violations.size();
        output.put(Messages.NUM_VIOLATIONS_KEY,
            Formatter.pluralize(numViolations, Messages.SINGLE_VIOLATION_KEY, Messages.MULTI_VIOLATIONS_KEY)
        );
        output.put(Messages.PARSED_KEY, parsed);
        FILES.add(output);
    }

}