/*
* Copyright (c) 2006-2011 Rogério Liesenfeld
* This file is subject to the terms of the MIT license (see LICENSE.txt).
*/
package mockit.coverage.reporting;
import java.io.*;
import java.util.*;
import java.util.Map.*;
import mockit.coverage.data.*;
import mockit.coverage.reporting.packages.*;
import mockit.coverage.reporting.sourceFiles.*;
class CoverageReport
{
private final String outputDir;
private final List<File> sourceDirs;
private final Map<String, FileCoverageData> fileToFileData;
private final Map<String, List<String>> packageToFiles;
private final boolean withCallPoints;
protected CoverageReport(
String outputDir, String[] srcDirs, CoverageData coverageData, boolean withCallPoints)
{
this.outputDir = outputDir.length() > 0 ? outputDir : "coverage-report";
sourceDirs = srcDirs == null ? null : new SourceFiles().buildListOfSourceDirectories(srcDirs);
fileToFileData = coverageData.getFileToFileDataMap();
packageToFiles = new HashMap<String, List<String>>();
this.withCallPoints = withCallPoints;
}
public final void generate() throws IOException
{
if (fileToFileData.isEmpty()) {
return;
}
createOutputDirIfNotExists();
File outputFile = createOutputFileForIndexPage();
if (outputFile == null) {
return;
}
boolean withSourceFilePages = sourceDirs != null;
if (withSourceFilePages && sourceDirs.size() > 1) {
System.out.println("JMockit: Coverage source dirs: " + sourceDirs);
}
generateFileCoverageReportsWhileBuildingPackageLists();
if (withSourceFilePages) {
addUncoveredSourceFilesToPackageLists();
}
new IndexPage(outputFile, sourceDirs, packageToFiles, fileToFileData).generate();
new StaticFiles().copyToOutputDir(outputDir, withSourceFilePages);
System.out.println(
"JMockit: Coverage report written to " + outputFile.getParentFile().getCanonicalPath());
}
private void createOutputDirIfNotExists()
{
File outDir = new File(outputDir);
if (!outDir.exists()) {
boolean dirCreated = outDir.mkdir();
assert dirCreated : "Failed to create output dir: " + outputDir;
}
}
private File createOutputFileForIndexPage() throws IOException
{
File outputFile = new File(outputDir, "index.html");
if (outputFile.exists() && !outputFile.canWrite()) {
System.out.println(
"JMockit: " + outputFile.getCanonicalPath() +
" is read-only; report generation canceled");
return null;
}
return outputFile;
}
private void generateFileCoverageReportsWhileBuildingPackageLists() throws IOException
{
Set<Entry<String, FileCoverageData>> files = fileToFileData.entrySet();
for (Entry<String, FileCoverageData> fileAndFileData : files) {
generateFileCoverageReport(fileAndFileData.getKey(), fileAndFileData.getValue());
}
}
private void generateFileCoverageReport(String sourceFile, FileCoverageData fileData)
throws IOException
{
if (sourceDirs == null) {
addFileToPackageFileList(sourceFile);
}
else {
InputFile inputFile = new InputFile(sourceDirs, sourceFile);
if (inputFile.wasFileFound()) {
new FileCoverageReport(outputDir, inputFile, fileData, withCallPoints).generate();
addFileToPackageFileList(sourceFile);
}
}
}
private void addFileToPackageFileList(String file)
{
int p = file.lastIndexOf('/');
String filePackage = p < 0 ? "" : file.substring(0, p);
List<String> filesInPackage = packageToFiles.get(filePackage);
if (filesInPackage == null) {
filesInPackage = new ArrayList<String>();
packageToFiles.put(filePackage, filesInPackage);
}
filesInPackage.add(file.substring(p + 1));
}
private void addUncoveredSourceFilesToPackageLists()
{
for (Entry<String, List<String>> packageAndFiles : packageToFiles.entrySet()) {
String packageRelDir = packageAndFiles.getKey();
List<String> packageFiles = packageAndFiles.getValue();
for (File srcDir : sourceDirs) {
addMissingSourceFiles(packageFiles, srcDir, packageRelDir);
}
}
}
private void addMissingSourceFiles(
List<String> packageFilesToReport, File srcDir, String packageRelDir)
{
File packageDir = new File(srcDir, packageRelDir);
String[] allPackageFiles = packageDir.list();
if (allPackageFiles != null) {
addMissingSourceFiles(packageFilesToReport, allPackageFiles);
}
}
private void addMissingSourceFiles(List<String> packageFilesToReport, String[] allPackageFiles)
{
for (String packageFile : allPackageFiles) {
if (
packageFile.endsWith(".java") && !"package-info.java".equals(packageFile) &&
!packageFilesToReport.contains(packageFile)
) {
packageFilesToReport.add(packageFile);
}
}
}
}