sleekbyte/tailor

View on GitHub
src/main/java/com/sleekbyte/tailor/output/ViolationMessage.java

Summary

Maintainability
B
4 hrs
Test Coverage
package com.sleekbyte.tailor.output;

import com.sleekbyte.tailor.common.ColorSettings;
import com.sleekbyte.tailor.common.Messages;
import com.sleekbyte.tailor.common.Rules;
import com.sleekbyte.tailor.common.Severity;

/**
 * Note: this class has a natural ordering that is inconsistent with equals.
 */
public class ViolationMessage implements Comparable<ViolationMessage> {

    private String filePath = "";
    private int lineNumber;
    private int columnNumber;
    private Severity severity = null;
    private String violationMessage = "";
    private ColorSettings colorSettings = new ColorSettings(false, false);
    private int lineNumberWidth = 0;
    private int columnNumberWidth = 0;
    private String textColor = "black";
    private Rules rule;

    /**
     * Constructs a ViolationMessage with the specified message components.
     *
     * @param rule             the rule associated with the violation
     * @param filePath         the path of the source file
     * @param lineNumber       the logical line number in the source file
     * @param columnNumber     the logical column number in the source file
     * @param severity         the severity of the violation message
     * @param violationMessage the description of the violation message
     */
    public ViolationMessage(Rules rule, String filePath, int lineNumber, int columnNumber, Severity severity,
                            String violationMessage) {
        this.rule = rule;
        this.filePath = filePath;
        this.lineNumber = lineNumber;
        this.columnNumber = columnNumber;
        this.severity = severity;
        this.violationMessage = violationMessage;
    }

    /**
     * Constructs a ViolationMessage with the specified message components.
     *
     * @param rule             the rule associated with the violation message
     * @param lineNumber       the logical line number in the source file
     * @param columnNumber     the logical column number in the source file
     * @param severity         the severity of the violation message
     * @param violationMessage the description of the violation message
     */
    public ViolationMessage(Rules rule, int lineNumber, int columnNumber, Severity severity, String violationMessage) {
        this.rule = rule;
        this.lineNumber = lineNumber;
        this.columnNumber = columnNumber;
        this.severity = severity;
        this.violationMessage = violationMessage;
    }

    /**
     * Constructs a ViolationMessage where the rule name is replaced by tool name (tailor).
     *
     * @param filePath         the path of the source file
     * @param lineNumber       the logical line number in the source file
     * @param columnNumber     the logical column number in the source file
     * @param severity         the severity of the violation message
     * @param violationMessage the description of the violation message
     */
    public ViolationMessage(String filePath, int lineNumber, int columnNumber, Severity severity,
                            String violationMessage) {
        this.filePath = filePath;
        this.lineNumber = lineNumber;
        this.columnNumber = columnNumber;
        this.severity = severity;
        this.violationMessage = Messages.TAILOR + violationMessage;
    }

    /**
     * Constructs a ViolationMessage where the rule name is replaced by tool name (tailor).
     *
     * @param lineNumber       the logical line number in the source file
     * @param columnNumber     the logical column number in the source file
     * @param severity         the severity of the violation message
     * @param violationMessage the description of the violation message
     */
    public ViolationMessage(int lineNumber, int columnNumber, Severity severity, String violationMessage) {
        this.lineNumber = lineNumber;
        this.columnNumber = columnNumber;
        this.severity = severity;
        this.violationMessage = Messages.TAILOR + violationMessage;
    }

    public Rules getRule() {
        return rule;
    }

    public int getLineNumber() {
        return lineNumber;
    }

    public int getColumnNumber() {
        return columnNumber;
    }

    public Severity getSeverity() {
        return severity;
    }

    public String getMessage() {
        return violationMessage;
    }

    public void setFilePath(String filePath) {
        this.filePath = filePath;
    }

    public void setColorSettings(ColorSettings colorSettings) {
        this.colorSettings = colorSettings;
        textColor = colorSettings.invertColor ? "white" : "black";
    }

    public void setLineNumberWidth(int lineNumberWidth) {
        this.lineNumberWidth = lineNumberWidth;
    }

    public void setColumnNumberWidth(int columnNumberWidth) {
        this.columnNumberWidth = columnNumberWidth;
    }

    @Override
    public int compareTo(final ViolationMessage message) {
        int ret = this.lineNumber - message.lineNumber;
        if (ret == 0) {
            ret = this.columnNumber - message.columnNumber;
        }
        if (ret == 0) {
            ret = this.severity.toString().compareTo(message.severity.toString());
        }
        if (ret == 0) {
            ret = this.violationMessage.compareTo(message.violationMessage);
        }
        if (ret == 0) {
            return this.rule.compareTo(message.rule);
        }
        return ret;
    }

    @Override
    /**
     * Implementation required since equals() is overridden.
     */
    public int hashCode() {
        int result = filePath.hashCode();
        result = 31 * result + lineNumber;
        result = 31 * result + columnNumber;
        result = 31 * result + severity.hashCode();
        result = 31 * result + violationMessage.hashCode();
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (!(obj instanceof ViolationMessage)) {
            return false;
        }

        ViolationMessage candidateObject = (ViolationMessage) obj;

        // Test primitives (int) for equality first, then objects (String)
        return (this.lineNumber == candidateObject.lineNumber)
            && (this.columnNumber == candidateObject.columnNumber)
            && (this.filePath.equals(candidateObject.filePath))
            && (this.severity.equals(candidateObject.severity))
            && (this.violationMessage.equals(candidateObject.violationMessage))
            && (this.rule.equals(candidateObject.rule));
    }

    @Override
    public String toString() {
        // filePath, severity, violationMessage are optional in the output, but at least one must be present
        if (this.filePath.isEmpty() && this.severity == null && this.violationMessage.isEmpty()) {
            return "";
        }

        if (formattedRule().isEmpty()) {
            return String.format("%s%s%s %s %s", formattedFilePath(), formattedLineNumber(), formattedColumnNumber(),
                formattedSeverity(), formattedViolationMessage());
        }

        return String.format("%s%s%s %s %s %s", formattedFilePath(), formattedLineNumber(), formattedColumnNumber(),
            formattedSeverity(), formattedRule(), formattedViolationMessage());
    }

    private String formattedRule() {
        return rule != null ? String.format("[%s]", rule.getName()) : "";
    }

    private String formattedFilePath() {
        return String.format("%s:", filePath);
    }

    private String formattedLineNumber() {
        String res;
        if (lineNumberWidth > 0 && colorSettings.colorOutput) {
            res = String.format("%0" + lineNumberWidth + "d:", lineNumber);
            res = "@|bg_blue," + textColor + " " + res + "|@";
        } else {
            res = String.format("%d:", lineNumber);
        }
        return res;
    }

    private String formattedColumnNumber() {
        String res;
        if (columnNumber == 0) {
            if (columnNumberWidth > 0 && colorSettings.colorOutput) {
                res = String.format("%" + (columnNumberWidth + 1) + "s", "");
                res = "@|bg_blue," + textColor + " " + res + "|@";
            } else {
                res = "";
            }
        } else {
            if (columnNumberWidth > 0 && colorSettings.colorOutput) {
                res = String.format("%0" + columnNumberWidth + "d:", columnNumber);
                res = "@|bg_blue," + textColor + " " + res + "|@";
            } else {
                res = String.format("%d:", columnNumber);
            }
        }
        return res;
    }

    private String formattedSeverity() {
        String res;
        if (colorSettings.colorOutput) {
            res = String.format("%7s:", severity);
            if (severity.equals(Severity.ERROR)) {
                res = "@|bg_red," + textColor + " " + res + "|@";
            } else if (severity.equals(Severity.WARNING)) {
                res = "@|bg_yellow," + textColor + " " + res + "|@";
            } else {
                res = "@|bg_white," + textColor + " " + res + "|@";
            }
        } else {
            res = String.format("%s:", severity);
        }
        return res;
    }

    private String formattedViolationMessage() {
        return violationMessage;
    }

}