All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.tzemp.parser.Command Maven / Gradle / Ivy

package com.github.tzemp.parser;

import com.github.tzemp.parser.hints.Hint;
import org.reflections.Reflections;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * This represents a command which is created during
 * the parsing of the whole log. It contains multiple modules
 * and an (optional) BuildSection (there might be commands
 * without any building)
 */
public class Command {
    private String name;
    private List lines;
    private List modules;
    private BuildSection buildSection;
    private Hint hint;

    public Command() {
        this.modules = new ArrayList<>();
    }

    /*
     * This parsers the log lines assigned to the commands and tries to find
     * the reactor if available. If he is present, it parsers the reactor and
     * creates the Modules. If not, the whole logsection is treated as one Module
     * Afterwards, ech log line is assigned to its Module for further parsing.
     */
    public void parseModules() {
        boolean foundStart = false;
        boolean foundEnd = false;
        for (String logLine : this.getLines()) {
            if (foundStart && !foundEnd) {
                Pattern pattern = Pattern.compile(Parser.config.getReactor().get("extractRegex"));
                Matcher matcher = pattern.matcher(logLine.substring(7));
                String name, status = "";
                if (matcher.find()) {
                    name = matcher.group(1).trim();
                    status = matcher.group(2).trim();
                    if (name.length() > 0 && status.length() > 0) {
                        this.getModules().add(new Module(name, status));
                    }
                }

                if (logLine.contains(Parser.config.getReactor().get("summaryEnd"))) {
                    foundEnd = true;
                }
            } else {
                if (logLine.contains(Parser.config.getReactor().get("summaryStart"))) {
                    foundStart = true;
                }
            }
            if (foundStart && foundEnd) {
                break;
            }
        }

        boolean foundModule = false;
        Module foundedModule = null;

        // assign lines to each module
        for (String logLine : this.getLines()) {

            for (Module module : this.getModules()) {
                if (logLine.contains("Building") && logLine.contains(module.getName())) {
                    foundModule = true;
                    foundedModule = module;
                }
            }

            if (logLine.contains("BUILD FAILURE") || logLine.contains("BUILD SUCCESS") || logLine.contains("Reactor Summary")) {
                break;
            }

            if (foundModule) {
                foundedModule.getLines().add(logLine);
            }
        }

        if (this.getModules().size() == 0) {
            Module module = new Module("unknownName", "FAILURE");
            module.getLines().addAll(this.getLines());
            this.getModules().add(module);
        }

        for (Module module : this.getModules()) {
            module.clean();
        }
    }

    /*
     * Parses the build section (if we encounter a build failure)
     * and extract the necessary information with in such as
     * failed goal and error reason
     */
    public void parseBuildSection() {
        List tempList = new ArrayList<>();
        boolean startFound = false;
        boolean errorSectionFound = false;

        for (String logLine : this.getLines()) {

            if (logLine.contains("BUILD FAILURE")) {
                startFound = true;
            }
            if (startFound && !errorSectionFound) {
                if (logLine.startsWith("[ERROR]")) {
                    errorSectionFound = true;
                }
            }
            if (startFound && errorSectionFound && logLine.startsWith("[ERROR]")) {
                tempList.add(logLine);
            }
        }
        if (tempList.size() > 0) {
            this.buildSection = new BuildSection(tempList);
        }
    }

    /*
     * This extract additional information from the log lines
     * It first find the call to the failed goal in the log and extract the
     * lines therein. If a hint is present, we pass this informtion to the hint
     * and finally extract the information within the hint using the Hint's method
     * extract().
     */
    public void extractAdditionalInformation() {
        boolean hasAdditionalHint = this.createAdditionalHint();
        String shortGoal = this.getBuildSection().getShortFailedGoal();
        Module failedModule = this.getFailedModule();
        List extractedLines = new ArrayList<>();

        if (failedModule != null) {
            boolean found = false;
            for (String logLine : failedModule.getLines()) {
                if (logLine.contains("[INFO] -----------------------------------") || logLine.equals("[ERROR] ")) {
                    found = false;
                }
                if (found) {
                    if (!logLine.contains("Downloaded") && !logLine.contains("Downloading")) {
                        extractedLines.add(logLine);
                    }
                }
                if (logLine.contains(shortGoal)) {
                    found = true;
                }
            }

            for (String logLine : extractedLines) {
                /*String[] multipleLines = logLine.split(";");
                if (multipleLines.length > 0) {
                    for (String line : multipleLines) {
                        String cleanedLine = this.getBuildSection().cleanupString(line);
                        if (hasAdditionalHint) {
                            this.getHint().getCleanedLogLines().add(cleanedLine);
                            this.getHint().getLogLines().add(line);
                        }
                        this.getBuildSection().insertAndCount(cleanedLine);
                    }
                } else {*/
                String cleanedLine = this.getBuildSection().cleanupString(logLine);
                if (hasAdditionalHint) {
                    this.getHint().getCleanedLogLines().add(cleanedLine);
                    this.getHint().getLogLines().add(logLine);
                }
                this.getBuildSection().insertAndCount(cleanedLine);
                /*}*/
            }
            if (hasAdditionalHint) {
                this.getHint().extract();
            }
        }
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setLines(List lines) {
        this.lines = lines;
    }

    public List getLines() {
        return this.lines;
    }

    public List getModules() {
        return modules;
    }

    public boolean hasReactor() {
        return getModules().size() > 1;
    }

    public boolean hasBuildSection() {
        return this.getBuildSection() != null;
    }

    public Module getFailedModule() {
        for (Module module : this.getModules()) {
            if (module.getStatus().equals("FAILURE")) {
                return module;
            }
        }
        return null;
    }

    public String getName() {
        return name;
    }

    /*
     * Helper Function to print the contents of the command
     */
    public List print() {
        List temp = new ArrayList();
        temp.add("Command: " + this.getName());
        temp.add("Has Reactor: " + this.hasReactor());
        for (Module module : this.getModules()) {
            temp.add("Module :" + module.getName());
            temp.add("Status :" + module.getStatus());
        }
        temp.add("Has Build Section :" + this.hasBuildSection());
        if (this.hasBuildSection()) {
            BuildSection buildSection = this.getBuildSection();
            temp.add("Build Status: " + buildSection.getStatus());
            if (buildSection.hasError()) {
                temp.add("Failed Goal: " + buildSection.getFailedGoal());
                temp.add("Error Cause: " + buildSection.getErrorCause());
            }
        }
        temp.add("----");
        return temp;
    }

    public BuildSection getBuildSection() {
        return buildSection;
    }

    public Hint getHint() {
        return hint;
    }

    /*
     * Returns if we encounter an additional Hint
     * This function checks all the implemented Hints through Reflection and checks
     * if a keyword matches any given Hint. If yes, the hint is instantiated and
     * assigned to the command
     *
     * @return bool hasHint
     */
    public boolean createAdditionalHint() {

        if (this.hasBuildSection()) {
            String failedGoal = this.getBuildSection().getFailedGoal();
            String errorReason = this.getBuildSection().getUncleanedError();

            Reflections reflections = new Reflections("com.github.tzemp.parser.hints");
            Set> classes = reflections.getSubTypesOf(Hint.class);

            for (Class hintClass : classes) {
                try {
                    Method mGetGoalKeyword = hintClass.getMethod("getGoalKeyword");
                    String goalKeyword = (String) mGetGoalKeyword.invoke(null);
                    if (failedGoal.contains(goalKeyword)) {
                        this.hint = (Hint) hintClass.newInstance();
                        this.hint.setFailedGoal(failedGoal);
                        this.hint.setErrorReason(errorReason);
                        this.hint.setBuildError(this.getBuildSection().getUncleanedError());
                        return true;
                    }

                    Method mGetReasonKeyword = hintClass.getMethod("getReasonKeyword");
                    String reasonKeyword = (String) mGetReasonKeyword.invoke(null);
                    if (errorReason.contains(reasonKeyword)) {
                        this.hint = (Hint) hintClass.newInstance();
                        this.hint.setFailedGoal(failedGoal);
                        this.hint.setErrorReason(errorReason);
                        this.hint.setBuildError(this.getBuildSection().getUncleanedError());
                        return true;
                    }

                } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException ignored) {
                }
            }
        }
        return false;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy