/* * Copyright (c) 2006 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 javax.annotation.*; import mockit.coverage.*; import mockit.coverage.data.*; import mockit.coverage.reporting.packages.*; import mockit.coverage.reporting.sourceFiles.*; class CoverageReport { @Nonnull private final String outputDir; private boolean outputDirCreated; @Nullable private final List<File> sourceDirs; @Nonnull private final Map<String, FileCoverageData> fileToFileData; @Nonnull private final Map<String, List<String>> packageToFiles; private final boolean withCallPoints; @Nullable private final Collection<String> sourceFilesNotFound; protected CoverageReport( @Nonnull String outputDir, boolean outputDirCreated, @Nullable String[] srcDirs, @Nonnull CoverageData coverageData, boolean withCallPoints) { this.outputDir = Configuration.getOrChooseOutputDirectory(outputDir, "coverage-report"); this.outputDirCreated = outputDirCreated; sourceDirs = srcDirs == null ? null : new SourceFiles().buildListOfSourceDirectories(srcDirs); fileToFileData = coverageData.getFileToFileDataMap(); packageToFiles = new HashMap<String, List<String>>(); this.withCallPoints = withCallPoints; sourceFilesNotFound = srcDirs == null ? null : new ArrayList<String>(); } public final void generate() throws IOException { createReportOutputDirIfNotExists(); 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(); new IndexPage(outputFile, sourceDirs, sourceFilesNotFound, packageToFiles, fileToFileData).generate(); new StaticFiles(outputDir).copyToOutputDir(withSourceFilePages); System.out.println("JMockit: Coverage report written to " + outputFile.getParentFile().getCanonicalPath()); } private void createReportOutputDirIfNotExists() { if (!outputDirCreated) { File outDir = new File(outputDir); outputDirCreated = outDir.mkdirs(); } } @Nullable 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(@Nonnull String sourceFile, @Nonnull FileCoverageData fileData) throws IOException { if (sourceDirs == null) { addFileToPackageFileList(sourceFile); } else { InputFile inputFile = InputFile.createIfFileExists(sourceDirs, sourceFile); if (inputFile != null) { new FileCoverageReport(outputDir, inputFile, fileData, withCallPoints).generate(); } else { deleteOutdatedHTMLFileIfExists(sourceFile); if (sourceFilesNotFound != null) { sourceFilesNotFound.add(sourceFile); } } addFileToPackageFileList(sourceFile); } } private void addFileToPackageFileList(@Nonnull 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 deleteOutdatedHTMLFileIfExists(@Nonnull String filePath) { if (!outputDirCreated) { File outputFile = OutputFile.getOutputFile(outputDir, filePath); //noinspection ResultOfMethodCallIgnored outputFile.delete(); } } }