Package qubexplorer.runner

Source Code of qubexplorer.runner.SonarRunnerProccess

package qubexplorer.runner;

import java.io.File;
import java.net.URL;
import java.util.Objects;
import java.util.Properties;
import java.util.Set;
import org.apache.maven.model.Model;
import org.netbeans.api.java.project.JavaProjectConstants;
import org.netbeans.api.java.queries.BinaryForSourceQuery;
import org.netbeans.api.java.queries.SourceLevelQuery;
import org.netbeans.api.project.Project;
import org.netbeans.api.project.ProjectUtils;
import org.netbeans.api.project.SourceGroup;
import org.netbeans.api.project.Sources;
import org.netbeans.api.queries.FileEncodingQuery;
import org.netbeans.spi.project.SubprojectProvider;
import org.openide.util.Utilities;
import org.sonar.runner.api.ForkedRunner;
import org.sonar.runner.api.PrintStreamConsumer;
import org.sonar.runner.api.ProcessMonitor;
import org.sonar.runner.api.Runner;
import qubexplorer.UserCredentials;
import qubexplorer.AuthorizationException;
import qubexplorer.MvnModelFactory;
import qubexplorer.MvnModelInputException;
import qubexplorer.PassEncoder;
import qubexplorer.server.SonarQube;

/**
*
* @author Victor
*/
public class SonarRunnerProccess {

    private final Project project;
    private final String sonarUrl;
    private AnalysisMode analysisMode = AnalysisMode.INCREMENTAL;
    private PrintStreamConsumer outConsumer;
    private PrintStreamConsumer errConsumer;
    private WrapperConsumer wrapper;

    public enum AnalysisMode {

        INCREMENTAL,
        PREVIEW;
    }

    /**
     * This state is modified while running.
     */
    private final MvnModelFactory mvnModelFactory = new MvnModelFactory();
    private String projectHome;
    private final StringBuilder modules = new StringBuilder();
    private final Properties properties = new Properties();

    public SonarRunnerProccess(String sonarUrl, Project project) {
        this.sonarUrl = sonarUrl;
        this.project = project;
    }

    public PrintStreamConsumer getOutConsumer() {
        return outConsumer;
    }

    public void setOutConsumer(PrintStreamConsumer outConsumer) {
        this.outConsumer = outConsumer;
    }

    public PrintStreamConsumer getErrConsumer() {
        return errConsumer;
    }

    public void setErrConsumer(PrintStreamConsumer errConsumer) {
        this.errConsumer = errConsumer;
    }

    public AnalysisMode getAnalysisMode() {
        return analysisMode;
    }

    public void setAnalysisMode(AnalysisMode analysisMode) {
        Objects.requireNonNull(analysisMode, "analysisMode is null");
        this.analysisMode = analysisMode;
    }

    protected Runner createForProject(UserCredentials userCredentials, ProcessMonitor processMonitor) throws MvnModelInputException {
        int sourcesCounter = 0;
        ForkedRunner runner = ForkedRunner.create(processMonitor);
        projectHome = project.getProjectDirectory().getPath();
        Model model = mvnModelFactory.createModel(project);
        properties.setProperty("sonar.projectName", model.getName() != null ? model.getName() : model.getArtifactId());
        properties.setProperty("sonar.projectBaseDir", projectHome);
        properties.setProperty("sonar.projectVersion", model.getVersion());
        properties.setProperty("sonar.sourceEncoding", FileEncodingQuery.getEncoding(project.getProjectDirectory()).displayName());
        properties.setProperty("sonar.host.url", sonarUrl);
        properties.setProperty("sonar.java.source", SourceLevelQuery.getSourceLevel(project.getProjectDirectory()));
        int version = getMajorVersion(new SonarQube(sonarUrl).getVersion(userCredentials));
        if (version >= 4) {
            properties.setProperty("sonar.analysis.mode", analysisMode.toString().toLowerCase());
        } else {
            properties.setProperty("sonar.dryRun", "true");
        }
        properties.setProperty("sonar.projectDir", projectHome);
        properties.setProperty("project.home", projectHome);
        properties.setProperty("sonar.working.directory", projectHome + "/./.sonar");
        if (userCredentials != null) {
            properties.setProperty("sonar.login", userCredentials.getUsername());
            properties.setProperty("sonar.password", PassEncoder.decodeAsString(userCredentials.getPassword()));
        }
        boolean containsSources = configureSourcesAndBinariesProperties(null, project);
        if(containsSources) {
            sourcesCounter++;
        }

        SubprojectProvider subprojectProvider = project.getLookup().lookup(SubprojectProvider.class);
        boolean hasSubprojects = false;
        if (subprojectProvider != null) {
            Set<? extends Project> subprojects = subprojectProvider.getSubprojects();
            hasSubprojects = !subprojects.isEmpty();
            for (Project subproject : subprojects) {
                String module = subproject.getProjectDirectory().getNameExt();
                boolean moduleContainsSources = addModuleProperties(module, subproject);
                if (moduleContainsSources) {
                    if (modules.length() > 0) {
                        modules.append(',');
                    }
                    modules.append(module);
                    sourcesCounter++;
                }
            }
        }
        if (sourcesCounter == 0) {
            throw new SourcesNotFoundException();
        }
        String projectKey = model.getGroupId();
        if (!hasSubprojects) {
            projectKey += ":" + model.getArtifactId();
        }
        properties.setProperty("sonar.projectKey", projectKey);
        if (modules.length() > 0) {
            properties.setProperty("sonar.modules", modules.toString());
        }
        if (outConsumer != null) {
            runner.setStdOut(outConsumer);
        }
        wrapper = new WrapperConsumer(errConsumer);
        runner.setStdErr(wrapper);
        runner.addProperties(properties);
        return runner;
    }

    /**
     * @param project
     * @return True if the project contains sources.
     */
    private boolean configureSourcesAndBinariesProperties(String module, Project project) {
        Sources sources = ProjectUtils.getSources(project);
        SourceGroup[] sourceGroups = sources.getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA);
        if (sourceGroups != null && sourceGroups.length != 0) {
            String sourceProperty = "sonar.sources";
            if (module != null) {
                sourceProperty = module + "." + sourceProperty;
            }
            properties.setProperty(sourceProperty, sourceGroups[0].getRootFolder().getPath());
            URL[] roots = BinaryForSourceQuery.findBinaryRoots(sourceGroups[0].getRootFolder().toURL()).getRoots();
            if (roots.length > 0) {
                File f = Utilities.toFile(roots[0]);
                String binariesProperty = "sonar.binaries";
                if (module != null) {
                    binariesProperty = module + "." + binariesProperty;
                }
                properties.setProperty(binariesProperty, f.getPath());
            }
            return true;
        } else {
            return false;
        }
    }

    private boolean addModuleProperties(String module, Project moduleProject) throws MvnModelInputException {
        Model submodel = mvnModelFactory.createModel(moduleProject);
        boolean containsSources = configureSourcesAndBinariesProperties(module, moduleProject);
        if(containsSources){
            properties.setProperty(module + ".sonar.projectKey", submodel.getArtifactId());
            properties.setProperty(module + ".sonar.projectName", submodel.getName() != null ? submodel.getName() : submodel.getArtifactId());
            properties.setProperty(module + ".sonar.projectBaseDir", moduleProject.getProjectDirectory().getPath());
        }
        return containsSources;
    }

    public SonarRunnerResult executeRunner(UserCredentials token, ProcessMonitor processMonitor) throws MvnModelInputException {
        Runner runner = createForProject(token, processMonitor);
        try {
            runner.execute();
        } catch (Exception ex) {
            if (wrapper.isUnauthorized()) {
                throw new AuthorizationException();
            } else {
                throw new SonarRunnerException(ex);
            }
        }
        if(processMonitor.stop()) {
            throw new SonarRunnerCancelledException();
        }else{
            File jsonFile = new File(properties.getProperty("sonar.working.directory"), "sonar-report.json");
            if (!jsonFile.exists()) {
                throw new SonarRunnerException();
            } else {
                return new SonarRunnerResult(jsonFile);
            }
        }
    }

    protected static int getMajorVersion(String version) {
        int index = version.indexOf('.');
        if (index != -1) {
            return Integer.parseInt(version.substring(0, index));
        } else {
            throw new IllegalArgumentException("Problem getting major version in " + version);
        }
    }

    private static class WrapperConsumer extends PrintStreamConsumer {

        private boolean unauthorized;
        private final PrintStreamConsumer wrapee;

        public WrapperConsumer(PrintStreamConsumer consumer) {
            super(null);
            this.wrapee = consumer;
        }

        public boolean isUnauthorized() {
            return unauthorized;
        }

        @Override
        public void consumeLine(String line) {
            if (line.toLowerCase().contains("not authorized")) {
                unauthorized = true;
            }
            if (wrapee != null) {
                wrapee.consumeLine(line);
            }
        }

    }

}
TOP

Related Classes of qubexplorer.runner.SonarRunnerProccess

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.