/eclipse-plugin/plugins/com.google.test.metric.eclipse.core/src/main/java/com/google/test/metric/eclipse/internal/core/TestabilityLauncher.java
Java | 240 lines | 191 code | 27 blank | 22 comment | 12 complexity | 27ede7eded7299ee6766e6a5c3582ca8 MD5 | raw file
1/* 2 * Copyright 2009 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16package com.google.test.metric.eclipse.internal.core; 17 18import com.google.classpath.ClassPath; 19import com.google.classpath.ClassPathFactory; 20import com.google.test.metric.AnalysisModel; 21import com.google.test.metric.CostModel; 22import com.google.test.metric.JavaClassRepository; 23import com.google.test.metric.JavaTestabilityModule; 24import com.google.test.metric.JavaTestabilityRunner; 25import com.google.test.metric.MetricComputer; 26import com.google.test.metric.RegExpWhiteList; 27import com.google.test.metric.ReportGeneratorProvider; 28import com.google.test.metric.ReportGeneratorProvider.ReportFormat; 29import com.google.test.metric.eclipse.core.TestabilityLaunchListener; 30import com.google.test.metric.eclipse.core.plugin.Activator; 31import com.google.test.metric.eclipse.internal.util.JavaProjectHelper; 32import com.google.test.metric.eclipse.internal.util.Logger; 33import com.google.test.metric.eclipse.internal.util.TestabilityConstants; 34import com.google.test.metric.report.ReportGenerator; 35import com.google.test.metric.report.ReportModel; 36import com.google.test.metric.report.ReportOptions; 37import com.google.test.metric.report.SourceLoader; 38import com.google.test.metric.report.html.HtmlReportModel; 39import com.google.test.metric.report.issues.ClassIssues; 40import com.google.test.metric.report.issues.HypotheticalCostModel; 41import com.google.test.metric.report.issues.IssuesReporter; 42import com.google.test.metric.report.issues.TriageIssuesQueue; 43 44import org.eclipse.core.runtime.CoreException; 45import org.eclipse.core.runtime.IConfigurationElement; 46import org.eclipse.core.runtime.IPath; 47import org.eclipse.core.runtime.IProgressMonitor; 48import org.eclipse.core.runtime.Platform; 49import org.eclipse.debug.core.ILaunch; 50import org.eclipse.debug.core.ILaunchConfiguration; 51import org.eclipse.debug.core.Launch; 52import org.eclipse.debug.core.model.ILaunchConfigurationDelegate2; 53import org.eclipse.jdt.core.IClasspathEntry; 54import org.eclipse.jdt.core.IJavaProject; 55import org.eclipse.jdt.core.JavaModelException; 56 57import java.io.File; 58import java.io.FileOutputStream; 59import java.io.PrintStream; 60import java.util.List; 61 62/** 63 * Launcher for testability configurations. 64 * 65 * @author klundberg@google.com (Karin Lundberg) 66 * 67 */ 68public class TestabilityLauncher implements ILaunchConfigurationDelegate2 { 69 70 private JavaProjectHelper javaProjectHelper = new JavaProjectHelper(); 71 private final Logger logger = new Logger(); 72 73 public boolean buildForLaunch(ILaunchConfiguration configuration, String mode, 74 IProgressMonitor monitor) { 75 // make sure everything is built before the launch 76 return TestabilityConstants.TESTABILITY.equals(mode); 77 } 78 79 public boolean finalLaunchCheck(ILaunchConfiguration configuration, String mode, 80 IProgressMonitor monitor) { 81 return TestabilityConstants.TESTABILITY.equals(mode); 82 } 83 84 public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) { 85 if (TestabilityConstants.TESTABILITY.equals(mode)) { 86 return new Launch(configuration, mode, null); 87 } else { 88 throw new IllegalStateException( 89 "Cannot launch testability configuration when not in testability mode."); 90 } 91 } 92 93 public boolean preLaunchCheck(ILaunchConfiguration configuration, String mode, 94 IProgressMonitor monitor) { 95 return TestabilityConstants.TESTABILITY.equals(mode); 96 } 97 98 @SuppressWarnings("unchecked") 99 public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, 100 IProgressMonitor monitor) throws CoreException { 101 if (!TestabilityConstants.TESTABILITY.equals(mode)) { 102 throw new IllegalStateException( 103 "Cannot launch testability configuration when not in testability mode."); 104 } 105 106 String projectName = 107 configuration.getAttribute(TestabilityConstants.CONFIGURATION_ATTR_PROJECT_NAME, ""); 108 109 IJavaProject javaProject = javaProjectHelper.getJavaProject(projectName); 110 String projectLocation = javaProjectHelper.getProjectLocation(javaProject); 111 112 String[] classPaths = getClassPaths(javaProject, projectLocation); 113 114 List<String> allJavaPackages = javaProjectHelper.getAllJavaPackages(javaProject); 115 116 ClassPathFactory classPathFactory = new ClassPathFactory(); 117 ClassPath classPath = classPathFactory.createFromPaths(classPaths); 118 119 IPath pluginStateLocation = Activator.getDefault().getStateLocation(); 120 String baseReportDirectoryString = 121 configuration.getAttribute(TestabilityConstants.CONFIGURATION_ATTR_REPORT_FOLDER_NAME, ""); 122 if ("".equals(baseReportDirectoryString)) { 123 baseReportDirectoryString = pluginStateLocation.toOSString(); 124 } 125 File reportDirectory = 126 new File(baseReportDirectoryString, javaProject.getProject().getName() 127 + "-TestabilityReport"); 128 if (!reportDirectory.exists()) { 129 reportDirectory.mkdirs(); 130 } 131 132 int maxExcellentCost = 133 configuration.getAttribute(TestabilityConstants.CONFIGURATION_ATTR_MAX_EXCELLENT_COST, 134 TestabilityConstants.MAX_EXCELLENT_COST); 135 int maxAcceptableCost = 136 configuration.getAttribute(TestabilityConstants.CONFIGURATION_ATTR_MAX_ACCEPTABLE_COST, 137 TestabilityConstants.MAX_ACCEPTABLE_COST); 138 int maxClassesInReport = 139 configuration.getAttribute(TestabilityConstants.CONFIGURATION_ATTR_MAX_CLASSES_IN_REPORT, 140 TestabilityConstants.MAX_CLASSES_TO_SHOW_IN_ISSUES_REPORTER); 141 double globalCost = 142 configuration.getAttribute(TestabilityConstants.CONFIGURATION_ATTR_GLOBAL_STATE_COST, 143 TestabilityConstants.GLOBAL_STATE_COST); 144 double cyclomaticCost = 145 configuration.getAttribute(TestabilityConstants.CONFIGURATION_ATTR_CYCLOMATIC_COST, 146 TestabilityConstants.CYCLOMATIC_COST); 147 double constructorMultiplier = 148 configuration.getAttribute(TestabilityConstants.CONFIGURATION_ATTR_CONSTRUCTOR_MULT, 149 TestabilityConstants.CONSTRUCTOR_MULT); 150 int printDepth = TestabilityConstants.RECORDING_DEPTH; 151 List<String> whitelistPackages = 152 configuration.getAttribute(TestabilityConstants.CONFIGURATION_ATTR_WHITELIST, 153 TestabilityConstants.WHITELIST); 154 155 try { 156 PrintStream reportStream = new PrintStream(new FileOutputStream( 157 new File(reportDirectory, TestabilityConstants.HTML_REPORT_FILENAME))); 158 PrintStream errorStream = new PrintStream(new FileOutputStream( 159 new File(reportDirectory, TestabilityConstants.ERROR_LOG_FILENAME))); 160 161 RegExpWhiteList whitelist = new RegExpWhiteList("java."); 162 for (String packageName : whitelistPackages) { 163 whitelist.addPackage(packageName); 164 } 165 166 CostModel costModel = new CostModel(cyclomaticCost, globalCost, constructorMultiplier); 167 JavaClassRepository classRepository = new JavaClassRepository(classPath); 168 MetricComputer computer = new MetricComputer(classRepository, errorStream, whitelist, printDepth); 169 HypotheticalCostModel hypotheticalCostModel = new HypotheticalCostModel(costModel); 170 IssuesReporter issuesReporter = new IssuesReporter( 171 new TriageIssuesQueue<ClassIssues>(maxAcceptableCost, 172 maxClassesInReport, new ClassIssues.TotalCostComparator()), hypotheticalCostModel); 173 ReportOptions options = new ReportOptions(cyclomaticCost, globalCost, constructorMultiplier, 174 maxExcellentCost, maxAcceptableCost, maxClassesInReport, -1, -1, printDepth, -1, "", ""); 175 SourceLoader sourceLoader = new SourceLoader(classPath); 176 177 AnalysisModel analysisModel = new AnalysisModel(issuesReporter); 178 ReportModel reportModel = new HtmlReportModel(costModel, analysisModel, options); 179 ReportGenerator report = new ReportGeneratorProvider(classPath, options, 180 reportStream, hypotheticalCostModel, ReportFormat.html).build(costModel, reportModel, sourceLoader); 181 182 new JavaTestabilityRunner(report, classPath, classRepository, computer, allJavaPackages, whitelist, errorStream).run(); 183 184 boolean runningInCompilationMode = configuration.getAttribute( 185 TestabilityConstants.CONFIGURATION_ATTR_RUNNING_IN_COMPILATION_MODE, false); 186 notifyAllListeners(options, analysisModel.getWorstOffenders(), javaProject, reportDirectory, 187 runningInCompilationMode); 188 189 reportStream.flush(); 190 reportStream.close(); 191 } catch (Exception e) { 192 logger.logException(e); 193 } 194 } 195 196 private void notifyAllListeners(ReportOptions reportOptions, 197 List<ClassIssues> classIssues, IJavaProject javaProject, File reportDirectory, 198 boolean runningInCompilationMode) { 199 IConfigurationElement[] elements = Platform.getExtensionRegistry().getConfigurationElementsFor( 200 "com.google.test.metric.eclipse.core.testabilityLaunchListener"); 201 202 for (IConfigurationElement element : elements) { 203 try { 204 TestabilityLaunchListener launchListener = 205 (TestabilityLaunchListener) element.createExecutableExtension("class"); 206 launchListener.onLaunchCompleted(reportOptions, javaProject, classIssues, reportDirectory, 207 runningInCompilationMode); 208 } catch (CoreException e) { 209 logger.logException("Error creating Testability Launch Listener", e); 210 } 211 } 212 } 213 214 public String[] getClassPaths(IJavaProject javaProject, String projectLocation) 215 throws JavaModelException { 216 IClasspathEntry[] classPathEntries = javaProject.getRawClasspath(); 217 String[] classPaths = new String[classPathEntries.length + 1]; 218 for (int i = 0; i < classPathEntries.length; i++) { 219 IClasspathEntry classPathEntry = classPathEntries[i]; 220 String classPathString = null; 221 IPath outputPath = classPathEntry.getOutputLocation(); 222 if (outputPath != null) { 223 classPathString = projectLocation + outputPath.toOSString(); 224 } else { 225 IPath classPath = classPathEntry.getPath(); 226 classPathString = classPath.toOSString(); 227 if (!classPathString.startsWith(System.getProperty("file.separator"))) { 228 classPathString = System.getProperty("file.separator") + classPathString; 229 } 230 classPathString = projectLocation + classPathString; 231 } 232 classPathString = classPathString.replace("\\", "/"); 233 classPaths[i] = classPathString; 234 } 235 String defaultOutputPath = javaProject.getOutputLocation().toOSString(); 236 defaultOutputPath = defaultOutputPath.replace("\\", "/"); 237 classPaths[classPathEntries.length] = projectLocation + defaultOutputPath; 238 return classPaths; 239 } 240}