Package com.buschmais.jqassistant.mojo

Source Code of com.buschmais.jqassistant.mojo.AbstractAnalysisMojo$StoreOperation

package com.buschmais.jqassistant.mojo;

import com.buschmais.jqassistant.core.analysis.api.CatalogReader;
import com.buschmais.jqassistant.core.analysis.api.RuleSelector;
import com.buschmais.jqassistant.core.analysis.api.RuleSetReader;
import com.buschmais.jqassistant.core.analysis.api.RuleSetResolverException;
import com.buschmais.jqassistant.core.analysis.impl.CatalogReaderImpl;
import com.buschmais.jqassistant.core.analysis.impl.RuleSelectorImpl;
import com.buschmais.jqassistant.core.analysis.impl.RuleSetReaderImpl;
import com.buschmais.jqassistant.core.model.api.rule.Concept;
import com.buschmais.jqassistant.core.model.api.rule.Constraint;
import com.buschmais.jqassistant.core.model.api.rule.Group;
import com.buschmais.jqassistant.core.model.api.rule.RuleSet;
import com.buschmais.jqassistant.core.store.api.Store;
import org.apache.commons.io.DirectoryWalker;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojoExecutionException;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;

import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
* Abstract base implementation for analysis mojos.
*/
public abstract class AbstractAnalysisMojo extends org.apache.maven.plugin.AbstractMojo {

    /**
     * Defines the interface for an operation on the store.
     *
     * @param <T> The return type of the operation.
     */
    protected static interface StoreOperation<T> {
        public T run(Store store) throws MojoExecutionException, MojoFailureException;
    }

    public static final String RULES_DIRECTORY = "jqassistant";

    public static final String REPORT_XML = "/jqassistant/jqassistant-report.xml";

    public static final String LOG_LINE_PREFIX = "  \"";

    /**
     * The directory to scan for rules.
     *
     * @parameter expression="${jqassistant.rules.directory}"
     */
    protected File rulesDirectory;

    /**
     * The list of concept names to be applied.
     *
     * @parameter expression="${jqassistant.concepts}"
     */
    protected List<String> concepts;

    /**
     * The list of constraint names to be validated.
     *
     * @parameter expression="${jqassistant.constraints}"
     */
    protected List<String> constraints;

    /**
     * The list of group names to be executed.
     *
     * @parameter expression="${jqassistant.groups}"
     */
    protected List<String> groups;

    /**
     * The file to write the XML report to.
     *
     * @parameter expression="${jqassistant.report.xml}"
     */
    protected File xmlReportFile;


    /**
     * The artifactId.
     *
     * @parameter expression="${project.artifactId}"
     * @readonly
     */
    protected String artifactId;

    /**
     * The project rulesDirectory.
     *
     * @parameter expression="${basedir}"
     * @readonly
     */
    protected File basedir;


    /**
     * The build rulesDirectory.
     *
     * @parameter expression="${project.build.rulesDirectory}"
     * @readonly
     */
    protected File buildDirectory;

    /**
     * The classes rulesDirectory.
     *
     * @parameter expression="${project.build.outputDirectory}"
     * @readonly
     */
    protected File classesDirectory;

    /**
     * The classes rulesDirectory.
     *
     * @parameter expression="${project.build.testOutputDirectory}"
     * @readonly
     */
    protected File testClassesDirectory;

    /**
     * The store directory.
     *
     * @parameter expression="${jqassistant.store.directory}"
     * @readonly
     */
    protected File storeDirectory;

    /**
     * The Maven project.
     *
     * @parameter expression="${project}"
     */
    protected MavenProject project;

    /**
     * The Maven Session Object
     *
     * @parameter expression="${session}"
     * @readonly
     */
    protected MavenSession session;

    /**
     * Contains the full list of projects in the reactor.
     *
     * @parameter expression = "${reactorProjects}"
     */
    protected List<MavenProject> reactorProjects;

    /**
     * The catalog reader instance.
     */
    private CatalogReader catalogReader = new CatalogReaderImpl();

    /**
     * The rules reader instance.
     */
    private RuleSetReader ruleSetReader = new RuleSetReaderImpl();

    /**
     * The rule selector.
     */
    private RuleSelector ruleSelector = new RuleSelectorImpl();

    /**
     * @component
     */
    protected StoreProvider storeProvider;

    protected <T> T executeInTransaction(StoreOperation<T> operation) throws MojoExecutionException, MojoFailureException {
        final Store store = getStore();
        store.beginTransaction();
        try {
            return operation.run(store);
        } finally {
            store.commitTransaction();
        }
    }

    protected <T> T execute(StoreOperation<T> operation) throws MojoExecutionException, MojoFailureException {
        return operation.run(getStore());
    }

    private Store getStore() throws MojoExecutionException {
        File directory;
        if (storeDirectory != null) {
            directory = storeDirectory;
        } else {
            directory = new File(getBaseProject().getBuild().getDirectory() + "/jqassistant/store");
        }
        return storeProvider.getStore(directory);
    }

    /**
     * Reads the available rules from the rules directory and deployed catalogs.
     *
     * @return A {@link java.util.Map} containing {@link com.buschmais.jqassistant.core.model.api.rule.Group}s identified by their id.
     * @throws org.apache.maven.plugin.MojoExecutionException
     *          If the rules cannot be read.
     */
    protected RuleSet readRules() throws MojoExecutionException {
        File selectedDirectory = null;
        if (rulesDirectory != null) {
            selectedDirectory = rulesDirectory;
        } else {
            MavenProject baseProject = getBaseProject();
            if (baseProject != null) {
                selectedDirectory = new File(baseProject.getBasedir(), RULES_DIRECTORY);
            }
        }
        List<Source> sources = new ArrayList<>();
        // read rules from rules directory
        if (selectedDirectory != null) {
            List<File> ruleFiles = readRulesDirectory(selectedDirectory);
            for (File ruleFile : ruleFiles) {
                getLog().debug("Adding rules from file " + ruleFile.getAbsolutePath());
                sources.add(new StreamSource(ruleFile));
            }
        }
        sources.addAll(catalogReader.readCatalogs());
        return ruleSetReader.read(sources);
    }

    /**
     * Return the {@link MavenProject} which is the base project for scanning and analysis.
     * <p>The base project is by searching with the project tree starting from the current project over its parents until
     * a project is found containing a directory "jqassistant" or no parent can be determined.</p>
     *
     * @return The {@link MavenProject} containing a rules directory.
     * @throws MojoExecutionException If the directory cannot be resolved.
     */
    protected MavenProject getBaseProject() throws MojoExecutionException {
        MavenProject currentProject = project;
        if (project != null) {
            do {
                File directory = new File(currentProject.getBasedir(), RULES_DIRECTORY);
                if (directory.exists() && directory.isDirectory()) {
                    return currentProject;
                }
                MavenProject parent = currentProject.getParent();
                if (parent == null || parent.getBasedir() == null) {
                    return currentProject;
                }
                currentProject = parent;
            } while (currentProject != null);
        }
        throw new MojoExecutionException("Cannot resolve base directory.");
    }

    /**
     * Retrieves the list of available rules from the rules directory.
     *
     * @param rulesDirectory The rules directory.
     * @return The {@link java.util.List} of available rule {@link java.io.File}s.
     * @throws org.apache.maven.plugin.MojoExecutionException
     *          If the rules directory cannot be read.
     */
    private List<File> readRulesDirectory(File rulesDirectory) throws MojoExecutionException {
        if (rulesDirectory.exists() && !rulesDirectory.isDirectory()) {
            throw new MojoExecutionException(rulesDirectory.getAbsolutePath() + " does not exist or is not a rulesDirectory.");
        }
        getLog().info("Reading rules from rulesDirectory " + rulesDirectory.getAbsolutePath());
        final List<File> ruleFiles = new ArrayList<File>();
        try {
            new DirectoryWalker<File>() {

                @Override
                protected void handleFile(File file, int depth, Collection<File> results) throws IOException {
                    if (!file.isDirectory() && file.getName().endsWith(".xml")) {
                        results.add(file);
                    }
                }

                public void scan(File directory) throws IOException {
                    super.walk(directory, ruleFiles);
                }
            }.scan(rulesDirectory);
            return ruleFiles;
        } catch (IOException e) {
            throw new MojoExecutionException("Cannot read rulesDirectory: " + rulesDirectory.getAbsolutePath(), e);
        }
    }

    /**
     * Resolves the effective rules.
     *
     * @return The resolved rule set.
     * @throws MojoExecutionException If resolving fails.
     */
    protected RuleSet resolveEffectiveRules() throws MojoExecutionException {
        RuleSet ruleSet = readRules();
        validateRuleSet(ruleSet);
        try {
            return ruleSelector.getEffectiveRuleSet(ruleSet, concepts, constraints, groups);
        } catch (RuleSetResolverException e) {
            throw new MojoExecutionException("Cannot resolve rules.", e);
        }
    }

    /**
     * Validates the given rule set for unresolved concepts, constraints or groups.
     *
     * @param ruleSet The rule set.
     * @throws MojoExecutionException If there are unresolved concepts, constraints or groups.
     */
    private void validateRuleSet(RuleSet ruleSet) throws MojoExecutionException {
        StringBuffer message = new StringBuffer();
        if (!ruleSet.getMissingConcepts().isEmpty()) {
            message.append("\n  Concepts: ");
            message.append(ruleSet.getMissingConcepts());
        }
        if (!ruleSet.getMissingConstraints().isEmpty()) {
            message.append("\n  Constraints: ");
            message.append(ruleSet.getMissingConstraints());
        }
        if (!ruleSet.getMissingGroups().isEmpty()) {
            message.append("\n  Groups: ");
            message.append(ruleSet.getMissingGroups());
        }
        if (message.length() > 0) {
            throw new MojoExecutionException("The following rules are referenced but are not available;" + message);
        }
    }

    /**
     * Logs the given {@link RuleSet} on level info.
     *
     * @param ruleSet The {@link RuleSet}.
     */
    protected void logRuleSet(RuleSet ruleSet) {
        getLog().info("Groups [" + ruleSet.getGroups().size() + "]");
        for (Group group : ruleSet.getGroups().values()) {
            getLog().info(LOG_LINE_PREFIX + group.getId() + "\"");
        }
        getLog().info("Constraints [" + ruleSet.getConstraints().size() + "]");
        for (Constraint constraint : ruleSet.getConstraints().values()) {
            getLog().info(LOG_LINE_PREFIX + constraint.getId() + "\" - " + constraint.getDescription());
        }
        getLog().info("Concepts [" + ruleSet.getConcepts().size() + "]");
        for (Concept concept : ruleSet.getConcepts().values()) {
            getLog().info(LOG_LINE_PREFIX + concept.getId() + "\" - " + concept.getDescription());
        }
        if (!ruleSet.getMissingConcepts().isEmpty()) {
            getLog().warn("Missing concepts [" + ruleSet.getMissingConcepts().size() + "]");
            for (String missingConcept : ruleSet.getMissingConcepts()) {
                getLog().warn(LOG_LINE_PREFIX + missingConcept);
            }
        }
        if (!ruleSet.getMissingConstraints().isEmpty()) {
            getLog().warn("Missing constraints [" + ruleSet.getMissingConstraints().size() + "]");
            for (String missingConstraint : ruleSet.getMissingConstraints()) {
                getLog().warn(LOG_LINE_PREFIX + missingConstraint);
            }
        }
        if (!ruleSet.getMissingGroups().isEmpty()) {
            getLog().warn("Missing groups [" + ruleSet.getMissingGroups().size() + "]");
            for (String missingGroup : ruleSet.getMissingGroups()) {
                getLog().warn(LOG_LINE_PREFIX + missingGroup);
            }
        }
    }

    /**
     * Determines a report file name.
     *
     * @param reportFile The report file as specified in the pom.xml file or on the command line.
     * @return The resolved {@link File}.
     * @throws MojoExecutionException If the file cannot be determined.
     */
    protected File getReportFile(File reportFile, String defaultFile) throws MojoExecutionException {
        MavenProject baseProject = getBaseProject();
        File selectedXmlReportFile;
        if (reportFile != null) {
            selectedXmlReportFile = reportFile;
        } else if (baseProject != null) {
            String rulesProjectOutputDirectory = baseProject.getBuild().getDirectory();
            selectedXmlReportFile = new File(rulesProjectOutputDirectory + defaultFile);
        } else if (project != null) {
            String outputDirectory = project.getBuild().getDirectory();
            selectedXmlReportFile = new File(outputDirectory + defaultFile);
        } else {
            throw new MojoExecutionException("Cannot determine report file.");
        }
        return selectedXmlReportFile;
    }
}
TOP

Related Classes of com.buschmais.jqassistant.mojo.AbstractAnalysisMojo$StoreOperation

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.