com.google.test.metric.eclipse.internal.core.TestabilityLauncher.java Source code

Java tutorial

Introduction

Here is the source code for com.google.test.metric.eclipse.internal.core.TestabilityLauncher.java

Source

/*
 * Copyright 2009 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.test.metric.eclipse.internal.core;

import com.google.classpath.ClassPath;
import com.google.classpath.ClassPathFactory;
import com.google.test.metric.AnalysisModel;
import com.google.test.metric.CostModel;
import com.google.test.metric.JavaClassRepository;
import com.google.test.metric.JavaTestabilityModule;
import com.google.test.metric.JavaTestabilityRunner;
import com.google.test.metric.MetricComputer;
import com.google.test.metric.RegExpWhiteList;
import com.google.test.metric.ReportGeneratorProvider;
import com.google.test.metric.ReportGeneratorProvider.ReportFormat;
import com.google.test.metric.eclipse.core.TestabilityLaunchListener;
import com.google.test.metric.eclipse.core.plugin.Activator;
import com.google.test.metric.eclipse.internal.util.JavaProjectHelper;
import com.google.test.metric.eclipse.internal.util.Logger;
import com.google.test.metric.eclipse.internal.util.TestabilityConstants;
import com.google.test.metric.report.ReportGenerator;
import com.google.test.metric.report.ReportModel;
import com.google.test.metric.report.ReportOptions;
import com.google.test.metric.report.SourceLoader;
import com.google.test.metric.report.html.HtmlReportModel;
import com.google.test.metric.report.issues.ClassIssues;
import com.google.test.metric.report.issues.HypotheticalCostModel;
import com.google.test.metric.report.issues.IssuesReporter;
import com.google.test.metric.report.issues.TriageIssuesQueue;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.Launch;
import org.eclipse.debug.core.model.ILaunchConfigurationDelegate2;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaModelException;

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.List;

/**
 * Launcher for testability configurations.
 * 
 * @author klundberg@google.com (Karin Lundberg)
 *
 */
public class TestabilityLauncher implements ILaunchConfigurationDelegate2 {

    private JavaProjectHelper javaProjectHelper = new JavaProjectHelper();
    private final Logger logger = new Logger();

    public boolean buildForLaunch(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) {
        // make sure everything is built before the launch
        return TestabilityConstants.TESTABILITY.equals(mode);
    }

    public boolean finalLaunchCheck(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) {
        return TestabilityConstants.TESTABILITY.equals(mode);
    }

    public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) {
        if (TestabilityConstants.TESTABILITY.equals(mode)) {
            return new Launch(configuration, mode, null);
        } else {
            throw new IllegalStateException(
                    "Cannot launch testability configuration when not in testability mode.");
        }
    }

    public boolean preLaunchCheck(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) {
        return TestabilityConstants.TESTABILITY.equals(mode);
    }

    @SuppressWarnings("unchecked")
    public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor)
            throws CoreException {
        if (!TestabilityConstants.TESTABILITY.equals(mode)) {
            throw new IllegalStateException(
                    "Cannot launch testability configuration when not in testability mode.");
        }

        String projectName = configuration.getAttribute(TestabilityConstants.CONFIGURATION_ATTR_PROJECT_NAME, "");

        IJavaProject javaProject = javaProjectHelper.getJavaProject(projectName);
        String projectLocation = javaProjectHelper.getProjectLocation(javaProject);

        String[] classPaths = getClassPaths(javaProject, projectLocation);

        List<String> allJavaPackages = javaProjectHelper.getAllJavaPackages(javaProject);

        ClassPathFactory classPathFactory = new ClassPathFactory();
        ClassPath classPath = classPathFactory.createFromPaths(classPaths);

        IPath pluginStateLocation = Activator.getDefault().getStateLocation();
        String baseReportDirectoryString = configuration
                .getAttribute(TestabilityConstants.CONFIGURATION_ATTR_REPORT_FOLDER_NAME, "");
        if ("".equals(baseReportDirectoryString)) {
            baseReportDirectoryString = pluginStateLocation.toOSString();
        }
        File reportDirectory = new File(baseReportDirectoryString,
                javaProject.getProject().getName() + "-TestabilityReport");
        if (!reportDirectory.exists()) {
            reportDirectory.mkdirs();
        }

        int maxExcellentCost = configuration.getAttribute(
                TestabilityConstants.CONFIGURATION_ATTR_MAX_EXCELLENT_COST,
                TestabilityConstants.MAX_EXCELLENT_COST);
        int maxAcceptableCost = configuration.getAttribute(
                TestabilityConstants.CONFIGURATION_ATTR_MAX_ACCEPTABLE_COST,
                TestabilityConstants.MAX_ACCEPTABLE_COST);
        int maxClassesInReport = configuration.getAttribute(
                TestabilityConstants.CONFIGURATION_ATTR_MAX_CLASSES_IN_REPORT,
                TestabilityConstants.MAX_CLASSES_TO_SHOW_IN_ISSUES_REPORTER);
        double globalCost = configuration.getAttribute(TestabilityConstants.CONFIGURATION_ATTR_GLOBAL_STATE_COST,
                TestabilityConstants.GLOBAL_STATE_COST);
        double cyclomaticCost = configuration.getAttribute(TestabilityConstants.CONFIGURATION_ATTR_CYCLOMATIC_COST,
                TestabilityConstants.CYCLOMATIC_COST);
        double constructorMultiplier = configuration.getAttribute(
                TestabilityConstants.CONFIGURATION_ATTR_CONSTRUCTOR_MULT, TestabilityConstants.CONSTRUCTOR_MULT);
        int printDepth = TestabilityConstants.RECORDING_DEPTH;
        List<String> whitelistPackages = configuration
                .getAttribute(TestabilityConstants.CONFIGURATION_ATTR_WHITELIST, TestabilityConstants.WHITELIST);

        try {
            PrintStream reportStream = new PrintStream(
                    new FileOutputStream(new File(reportDirectory, TestabilityConstants.HTML_REPORT_FILENAME)));
            PrintStream errorStream = new PrintStream(
                    new FileOutputStream(new File(reportDirectory, TestabilityConstants.ERROR_LOG_FILENAME)));

            RegExpWhiteList whitelist = new RegExpWhiteList("java.");
            for (String packageName : whitelistPackages) {
                whitelist.addPackage(packageName);
            }

            CostModel costModel = new CostModel(cyclomaticCost, globalCost, constructorMultiplier);
            JavaClassRepository classRepository = new JavaClassRepository(classPath);
            MetricComputer computer = new MetricComputer(classRepository, errorStream, whitelist, printDepth);
            HypotheticalCostModel hypotheticalCostModel = new HypotheticalCostModel(costModel);
            IssuesReporter issuesReporter = new IssuesReporter(new TriageIssuesQueue<ClassIssues>(maxAcceptableCost,
                    maxClassesInReport, new ClassIssues.TotalCostComparator()), hypotheticalCostModel);
            ReportOptions options = new ReportOptions(cyclomaticCost, globalCost, constructorMultiplier,
                    maxExcellentCost, maxAcceptableCost, maxClassesInReport, -1, -1, printDepth, -1, "", "");
            SourceLoader sourceLoader = new SourceLoader(classPath);

            AnalysisModel analysisModel = new AnalysisModel(issuesReporter);
            ReportModel reportModel = new HtmlReportModel(costModel, analysisModel, options);
            ReportGenerator report = new ReportGeneratorProvider(classPath, options, reportStream,
                    hypotheticalCostModel, ReportFormat.html).build(costModel, reportModel, sourceLoader);

            new JavaTestabilityRunner(report, classPath, classRepository, computer, allJavaPackages, whitelist,
                    errorStream).run();

            boolean runningInCompilationMode = configuration
                    .getAttribute(TestabilityConstants.CONFIGURATION_ATTR_RUNNING_IN_COMPILATION_MODE, false);
            notifyAllListeners(options, analysisModel.getWorstOffenders(), javaProject, reportDirectory,
                    runningInCompilationMode);

            reportStream.flush();
            reportStream.close();
        } catch (Exception e) {
            logger.logException(e);
        }
    }

    private void notifyAllListeners(ReportOptions reportOptions, List<ClassIssues> classIssues,
            IJavaProject javaProject, File reportDirectory, boolean runningInCompilationMode) {
        IConfigurationElement[] elements = Platform.getExtensionRegistry()
                .getConfigurationElementsFor("com.google.test.metric.eclipse.core.testabilityLaunchListener");

        for (IConfigurationElement element : elements) {
            try {
                TestabilityLaunchListener launchListener = (TestabilityLaunchListener) element
                        .createExecutableExtension("class");
                launchListener.onLaunchCompleted(reportOptions, javaProject, classIssues, reportDirectory,
                        runningInCompilationMode);
            } catch (CoreException e) {
                logger.logException("Error creating Testability Launch Listener", e);
            }
        }
    }

    public String[] getClassPaths(IJavaProject javaProject, String projectLocation) throws JavaModelException {
        IClasspathEntry[] classPathEntries = javaProject.getRawClasspath();
        String[] classPaths = new String[classPathEntries.length + 1];
        for (int i = 0; i < classPathEntries.length; i++) {
            IClasspathEntry classPathEntry = classPathEntries[i];
            String classPathString = null;
            IPath outputPath = classPathEntry.getOutputLocation();
            if (outputPath != null) {
                classPathString = projectLocation + outputPath.toOSString();
            } else {
                IPath classPath = classPathEntry.getPath();
                classPathString = classPath.toOSString();
                if (!classPathString.startsWith(System.getProperty("file.separator"))) {
                    classPathString = System.getProperty("file.separator") + classPathString;
                }
                classPathString = projectLocation + classPathString;
            }
            classPathString = classPathString.replace("\\", "/");
            classPaths[i] = classPathString;
        }
        String defaultOutputPath = javaProject.getOutputLocation().toOSString();
        defaultOutputPath = defaultOutputPath.replace("\\", "/");
        classPaths[classPathEntries.length] = projectLocation + defaultOutputPath;
        return classPaths;
    }
}