htmlreport.java

来自「java覆盖率测试工具」· Java 代码 · 共 843 行 · 第 1/2 页

JAVA
843
字号
/*
 * Cobertura - http://cobertura.sourceforge.net/
 *
 * Copyright (C) 2005 Mark Doliner
 * Copyright (C) 2005 Grzegorz Lukasik
 * Copyright (C) 2005 Jeremy Thomerson
 * Copyright (C) 2006 Naoki Iwami
 *
 * Cobertura is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation; either version 2 of the License,
 * or (at your option) any later version.
 *
 * Cobertura is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Cobertura; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 */

package net.sourceforge.cobertura.reporting.html;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.Vector;

import net.sourceforge.cobertura.coveragedata.ClassData;
import net.sourceforge.cobertura.coveragedata.CoverageData;
import net.sourceforge.cobertura.coveragedata.LineData;
import net.sourceforge.cobertura.coveragedata.PackageData;
import net.sourceforge.cobertura.coveragedata.ProjectData;
import net.sourceforge.cobertura.coveragedata.SourceFileData;
import net.sourceforge.cobertura.reporting.ComplexityCalculator;
import net.sourceforge.cobertura.reporting.html.files.CopyFiles;
import net.sourceforge.cobertura.util.FileFinder;
import net.sourceforge.cobertura.util.Header;
import net.sourceforge.cobertura.util.IOUtil;
import net.sourceforge.cobertura.util.StringUtil;

import org.apache.log4j.Logger;

public class HTMLReport
{

	private static final Logger LOGGER = Logger.getLogger(HTMLReport.class);

	private File destinationDir;

	private FileFinder finder;

	private ComplexityCalculator complexity;

	private ProjectData projectData;

	/**
	 * Create a coverage report
	 */
	public HTMLReport(ProjectData projectData, File outputDir,
			FileFinder finder, ComplexityCalculator complexity)
			throws Exception
	{
		this.destinationDir = outputDir;
		this.finder = finder;
		this.complexity = complexity;
		this.projectData = projectData;

		CopyFiles.copy(outputDir);
		generatePackageList();
		generateSourceFileLists();
		generateOverviews();
		generateSourceFiles();
	}

	private String generatePackageName(PackageData packageData)
	{
		if (packageData.getName().equals(""))
			return "(default)";
		return packageData.getName();
	}

	private void generatePackageList() throws IOException
	{
		File file = new File(destinationDir, "frame-packages.html");
		PrintWriter out = null;

		try
		{
			out = IOUtil.getPrintWriter(file);

			out
					.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"");
			out
					.println("           \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");

			out
					.println("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">");
			out.println("<head>");
			out
					.println("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />");
			out.println("<title>Coverage Report</title>");
			out
					.println("<link title=\"Style\" type=\"text/css\" rel=\"stylesheet\" href=\"css/main.css\" />");
			out.println("</head>");
			out.println("<body>");
			out.println("<h5>Packages</h5>");
			out.println("<table width=\"100%\">");
			out.println("<tr>");
			out
					.println("<td nowrap=\"nowrap\"><a href=\"frame-summary.html\" onclick='parent.sourceFileList.location.href=\"frame-sourcefiles.html\"' target=\"summary\">All</a></td>");
			out.println("</tr>");

			Iterator iter = projectData.getPackages().iterator();
			while (iter.hasNext())
			{
				PackageData packageData = (PackageData)iter.next();
				String url1 = "frame-summary-" + packageData.getName()
						+ ".html";
				String url2 = "frame-sourcefiles-" + packageData.getName()
						+ ".html";
				out.println("<tr>");
				out.println("<td nowrap=\"nowrap\"><a href=\"" + url1
						+ "\" onclick='parent.sourceFileList.location.href=\""
						+ url2 + "\"' target=\"summary\">"
						+ generatePackageName(packageData) + "</a></td>");
				out.println("</tr>");
			}
			out.println("</table>");
			out.println("</body>");
			out.println("</html>");
		}
		finally
		{
			if (out != null)
			{
				out.close();
			}
		}
	}

	private void generateSourceFileLists() throws IOException
	{
		generateSourceFileList(null);
		Iterator iter = projectData.getPackages().iterator();
		while (iter.hasNext())
		{
			PackageData packageData = (PackageData)iter.next();
			generateSourceFileList(packageData);
		}
	}

	private void generateSourceFileList(PackageData packageData)
			throws IOException
	{
		String filename;
		Collection sourceFiles;
		if (packageData == null)
		{
			filename = "frame-sourcefiles.html";
			sourceFiles = projectData.getSourceFiles();
		}
		else
		{
			filename = "frame-sourcefiles-" + packageData.getName() + ".html";
			sourceFiles = packageData.getSourceFiles();
		}

		// sourceFiles may be sorted, but if so it's sorted by
		// the full path to the file, and we only want to sort
		// based on the file's basename.
		Vector sortedSourceFiles = new Vector();
		sortedSourceFiles.addAll(sourceFiles);
		Collections.sort(sortedSourceFiles,
				new SourceFileDataBaseNameComparator());

		File file = new File(destinationDir, filename);
		PrintWriter out = null;
		try
		{
			out = IOUtil.getPrintWriter(file);

			out
					.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"");
			out
					.println("           \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");

			out.println("<html>");
			out.println("<head>");
			out
					.println("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/>");
			out.println("<title>Coverage Report Classes</title>");
			out
					.println("<link title=\"Style\" type=\"text/css\" rel=\"stylesheet\" href=\"css/main.css\"/>");
			out.println("</head>");
			out.println("<body>");
			out.println("<h5>");
			out.println(packageData == null ? "All Packages"
					: generatePackageName(packageData));
			out.println("</h5>");
			out.println("<div class=\"separator\">&nbsp;</div>");
			out.println("<h5>Classes</h5>");
			if (!sortedSourceFiles.isEmpty())
			{
				out.println("<table width=\"100%\">");
				out.println("<tbody>");

				for (Iterator iter = sortedSourceFiles.iterator(); iter
						.hasNext();)
				{
					SourceFileData sourceFileData = (SourceFileData)iter.next();
					out.println("<tr>");
					String percentCovered;
					if (sourceFileData.getNumberOfValidLines() > 0)
						percentCovered = getPercentValue(sourceFileData
								.getLineCoverageRate());
					else
						percentCovered = "N/A";
					out
							.println("<td nowrap=\"nowrap\"><a target=\"summary\" href=\""
									+ sourceFileData.getNormalizedName()
									+ ".html\">"
									+ sourceFileData.getBaseName()
									+ "</a> <i>("
									+ percentCovered
									+ ")</i></td>");
					out.println("</tr>");
				}
				out.println("</tbody>");
				out.println("</table>");
			}

			out.println("</body>");
			out.println("</html>");
		}
		finally
		{
			if (out != null)
			{
				out.close();
			}
		}
	}

	private void generateOverviews() throws IOException
	{
		generateOverview(null);
		Iterator iter = projectData.getPackages().iterator();
		while (iter.hasNext())
		{
			PackageData packageData = (PackageData)iter.next();
			generateOverview(packageData);
		}
	}

	private void generateOverview(PackageData packageData) throws IOException
	{
		Iterator iter;

		String filename;
		if (packageData == null)
		{
			filename = "frame-summary.html";
		}
		else
		{
			filename = "frame-summary-" + packageData.getName() + ".html";
		}
		File file = new File(destinationDir, filename);
		PrintWriter out = null;

		try
		{
			out = IOUtil.getPrintWriter(file);;

			out
					.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"");
			out
					.println("           \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");

			out.println("<html>");
			out.println("<head>");
			out
					.println("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/>");
			out.println("<title>Coverage Report</title>");
			out
					.println("<link title=\"Style\" type=\"text/css\" rel=\"stylesheet\" href=\"css/main.css\"/>");
			out
					.println("<link title=\"Style\" type=\"text/css\" rel=\"stylesheet\" href=\"css/sortabletable.css\"/>");
			out
					.println("<script type=\"text/javascript\" src=\"js/popup.js\"></script>");
			out
					.println("<script type=\"text/javascript\" src=\"js/sortabletable.js\"></script>");
			out
					.println("<script type=\"text/javascript\" src=\"js/customsorttypes.js\"></script>");
			out.println("</head>");
			out.println("<body>");

			out.print("<h5>Coverage Report - ");
			out.print(packageData == null ? "All Packages"
					: generatePackageName(packageData));
			out.println("</h5>");
			out.println("<div class=\"separator\">&nbsp;</div>");
			out.println("<table class=\"report\" id=\"packageResults\">");
			out.println(generateTableHeader("Package", true));
			out.println("<tbody>");

			SortedSet packages;
			if (packageData == null)
			{
				// Output a summary line for all packages
				out.println(generateTableRowForTotal());

				// Get packages
				packages = projectData.getPackages();
			}
			else
			{
				// Get subpackages
				packages = projectData.getSubPackages(packageData.getName());
			}

			// Output a line for each package or subpackage
			iter = packages.iterator();
			while (iter.hasNext())
			{
				PackageData subPackageData = (PackageData)iter.next();
				out.println(generateTableRowForPackage(subPackageData));
			}

			out.println("</tbody>");
			out.println("</table>");
			out.println("<script type=\"text/javascript\">");
			out
					.println("var packageTable = new SortableTable(document.getElementById(\"packageResults\"),");
			out
					.println("    [\"String\", \"Number\", \"Percentage\", \"Percentage\", \"FormattedNumber\"]);");
			out.println("packageTable.sort(0);");
			out.println("</script>");

			// Get the list of source files in this package
			Collection sourceFiles;
			if (packageData == null)
			{
				PackageData defaultPackage = (PackageData)projectData
						.getChild("");
				if (defaultPackage != null)
				{
					sourceFiles = defaultPackage.getSourceFiles();
				}
				else
				{
					sourceFiles = new TreeSet();
				}
			}
			else
			{
				sourceFiles = packageData.getSourceFiles();
			}

			// Output a line for each source file
			if (sourceFiles.size() > 0)
			{
				out.println("<div class=\"separator\">&nbsp;</div>");
				out.println("<table class=\"report\" id=\"classResults\">");
				out.println(generateTableHeader("Classes in this Package",
						false));
				out.println("<tbody>");

				iter = sourceFiles.iterator();
				while (iter.hasNext())
				{
					SourceFileData sourceFileData = (SourceFileData)iter.next();
					out.println(generateTableRowsForSourceFile(sourceFileData));
				}

				out.println("</tbody>");
				out.println("</table>");
				out.println("<script type=\"text/javascript\">");
				out
						.println("var classTable = new SortableTable(document.getElementById(\"classResults\"),");
				out
						.println("    [\"String\", \"Percentage\", \"Percentage\", \"FormattedNumber\"]);");
				out.println("classTable.sort(0);");
				out.println("</script>");
			}

			out.println(generateFooter());

			out.println("</body>");
			out.println("</html>");
		}
		finally
		{
			if (out != null)
			{
				out.close();
			}
		}
	}

	private void generateSourceFiles()
	{
		Iterator iter = projectData.getSourceFiles().iterator();
		while (iter.hasNext())

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?