package com.instantiations.assist.eclipse.analysis.audit.writer;
import com.instantiations.assist.eclipse.analysis.audit.core.*;
import com.instantiations.assist.eclipse.analysis.audit.resolution.*;
import com.instantiations.assist.eclipse.analysis.audit.util.AuditResultGroup;
import com.instantiations.jlib.license.*;
import com.instantiations.jlib.xml.*;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
/**
* Instances of the class HTMLAuditWriter
implement a audit writer
* that produces HTML formatted output.
*
* Copyright (c) 2003, Google, Inc.
* All Rights Reserved
*
* @author Dan Rubel
* @author Brian Wilkerson
* @version $Revision: 1.0 $
*/
public class HTMLAuditWriter extends AbstractAuditWriter
{
/**
* The string to be printed to represent a single level of indentation.
*/
protected static final String INDENTATION = " ";
/**
* The maximum number of columns in the TOC.
*/
protected static final int MAX_TOC_COLUMNS = 4;
/**
* The maximum number of rows in the TOC.
*/
protected static final int MAX_TOC_ROWS = 8;
/**
* The number of columns in the report.
*/
protected int numColumns = 3;
/**
* @see com.instantiations.assist.eclipse.analysis.audit.core.AuditResultWriter#writeHeader(AuditViolationSet)
*/
public void writeHeader(AuditViolationSet violationSet) {
if (includeRecommendations) numColumns++;
if (includeSeverities) numColumns++;
_writer.println("<html>");
_writer.println("");
_writer.println("<head>");
_writer.println("");
_writer.println("<style type=text/css>");
_writer.println("\tbody {font: 70% verdana,arial,helvetica; color: #000000}");
_writer.println("\tp {margin: 0.5em 2em 1em; line-height: 1.5em}");
_writer.println("\th1 {margin: 0px 0px 5px; font: 175% verdana,arial,helvetica}");
_writer.println("\th2 {margin: 0px 0px 5px; font: bold 175% verdana,arial,helvetica}");
_writer.println("\th3 {margin: 0px 0px 5px; font: 125% verdana,arial,helvetica}");
_writer.println("\th4 {margin-top: 1em; margin-bottom: 0.5em; font: bold 125% verdana,arial,helvetica}");
_writer.println("\ttable tr th {font-size: 75%}");
_writer.println("\ttable tr td {font-size: 75%} ");
_writer.println("\ttable.details tr th {background: #a6d0e0; font-weight: bold; text-align: left}");
_writer.println("\ttable.details tr td {background: #eeeeee; text-align: top; vertical-align: top}");
_writer.println("\ttable.detailgroup tr th {background: #91d5ac; font-weight: bold; text-align: center; font-size: 80%}");
_writer.println("</style>");
_writer.println("");
_writer.println("<meta name=\"GENERATOR\" content=\"" + Product.getMainProduct().getName() + "\">");
_writer.println("<title>CodePro Code Audit for " + violationSet.getName() + "</title>");
_writer.println("");
_writer.println("</head>");
_writer.println("");
_writer.println("<body>");
_writer.println("");
_writer.println("<h1><a name=top>CodePro Code Audit</a></h1>");
_writer.println("<h2 align=\"center\">" + violationSet.getName() + "</h2>");
AuditRuleSet auditRuleSet = violationSet.getAuditRuleSet();
if (auditRuleSet != null && !auditRuleSet.isDefault()) {
_writer.println("<h2 align=\"center\">Computed using " + auditRuleSet.getName() + "</h2>");
}
_writer.println("<h3 align=\"center\">Violation Summary - " + violationSet.getSeveritySummary() + "</h3>");
_writer.println("");
_writer.println("<p align=right>Powered by");
_writer.println( Product.getMainProduct().getName() + " and");
_writer.println("\t<a href=\"http://www.eclipse.org\">Eclipse</a>");
_writer.println("</p>");
_writer.println("");
}
/**
* @see com.instantiations.assist.eclipse.analysis.audit.core.AuditResultWriter#writeTableOfContents(AuditResultGroup[])
*/
public void writeTableOfContents(AuditResultGroup[] groups) {
String groupName;
int start, end;
int columns = Math.max(Math.min(((groups.length - 1) / MAX_TOC_ROWS) + 1, MAX_TOC_COLUMNS), 1);
int rows = ((groups.length - 1) / columns) + 1;
_writer.println("<hr size=2>");
_writer.println("<h4>Summary</h4>");
_writer.println("<table>");
_writer.println("\t<tr>");
for (int i = 0; i < columns; i++) {
start = Math.min(i * rows, groups.length - 1);
end = Math.min(start + rows , groups.length);
_writer.println("\t\t<td valign=\"top\">");
_writer.println("\t\t\t<b>");
for (int j = start; j < end; j++) {
groupName = getViolationContainerName(groups[j].getElement());
_writer.println("\t\t\t\t<a href=\"#" + groupName + "\">" + groupName + "</a><br>");
}
_writer.println("\t\t\t</b>");
_writer.println("\t\t</td>");
_writer.println("\t\t<td valign=\"top\" align=\"right\">");
_writer.println("\t\t\t<b>");
for (int j = start; j < end; j++) {
_writer.println("\t\t\t\t" + groups[j].getTotalViolationCount() + "<br>");
}
_writer.println("\t\t\t</b>");
_writer.println("\t\t</td>");
_writer.println("\t\t<td width=\"10\"/>");
}
_writer.println("\t</tr>");
_writer.println("</table>");
_writer.println("");
_writer.println("<hr size=2>");
_writer.println("<h4>Details</h4>");
_writer.println("<table class=details width=\"100%\">");
}
/**
* Write out information about the specified group of audit violations.
*
* @param violationContainer the violation container
* (e.g. an audit rule or a resource - not null)
* @param violationCount the number of violations in this group
* @param depth the depth of this group
*/
public void writeGroupHeader(Object violationContainer, int violationCount, int depth, int maxDepth)
{
String violationText = getViolationContainerText(violationContainer, violationCount);
violationText = XMLUtils.encodeData(violationText);
_writer.println("\t<tr>");
if (depth >= maxDepth) {
_writer.println("\t\t<th>");
_writer.print("\t\t\t<a name=\"");
_writer.print(getViolationContainerName(violationContainer));
_writer.print("\"/>");
_writer.print(violationText);
} else {
_writer.println("\t\t<th colspan=\"" + numColumns + "\">");
_writer.print("\t\t\t<table class=detailgroup width=\"100%\" cellspacing=\"2\" cellpadding=\"2\">");
_writer.println("\t\t\t\t<th>");
_writer.print("\t\t\t\t\t<a name=\"");
_writer.print(getViolationContainerName(violationContainer));
_writer.print("\"/>");
_writer.print(violationText);
_writer.println("\t\t\t\t</th>");
_writer.print("\t\t\t</table>");
}
//for (int i = 1; i < depth; i++) {
// _writer.print(INDENTATION);
//}
if (depth == maxDepth) {
_writer.println(" <a href=\"#top\">top</a>");
} else {
_writer.println("");
}
_writer.println("\t\t</th>");
if (depth >= maxDepth) {
if (includeRecommendations) {
_writer.println("\t\t<th>");
_writer.println("\t\t\tRecommendation");
_writer.println("\t\t</th>");
}
if (includeSeverities) {
_writer.println("\t\t<th>");
_writer.println("\t\t\tSeverity");
_writer.println("\t\t</th>");
}
_writer.println("\t\t<th>");
_writer.println("\t\t\tJava File");
_writer.println("\t\t</th>");
_writer.println("\t\t<th>");
_writer.println("\t\t\tLine");
_writer.println("\t\t</th>");
}
_writer.println("\t</tr>");
}
/**
* Write out information about the specified violation.
*
* @param violation the audit violation (not null)
* @param depth the depth of this violation
*/
public void writeViolation(AuditViolation violation, int depth)
{
AuditViolationResolution[] resolutions;
IMarker marker;
String colorText = "";
String colorEndText = "";
if (violation.getSeverity() >= AuditRule.HIGH_SEVERITY) {
colorText = "<font color=\"red\">";
colorEndText = "</font>";
}
_writer.println("\t<tr>");
// Write violation description
_writer.println("\t\t<td>");
_writer.print("\t\t\t");
//for (int i = 1; i < depth; i++) {
// _writer.print(INDENTATION);
//}
_writer.print(colorText + XMLUtils.encodeHtmlData(violation.getDescription()) + colorEndText);
_writer.println("");
_writer.println("\t\t</td>");
// Write recommendation
if (includeRecommendations) {
resolutions = violation.getResolutions();
_writer.println("\t\t<td>");
_writer.print("\t\t\t");
if (resolutions.length > 0) {
_writer.println(colorText + XMLUtils.encodeHtmlData(resolutions[0].getDescription()) + colorEndText);
} else {
_writer.println(" ");
}
_writer.println("\t\t</td>");
}
// Write severity
if (includeSeverities) {
_writer.println("\t\t<td>");
_writer.print("\t\t\t");
_writer.println(colorText + AuditRule.SEVERITY_LABELS[violation.getSeverity()] + colorEndText);
_writer.println("\t\t</td>");
}
// Write resource name
_writer.println("\t\t<td>");
_writer.print("\t\t\t");
_writer.println(colorText + violation.getResource().getName() + colorEndText);
_writer.println("\t\t</td>");
// Write line
_writer.println("\t\t<td>");
_writer.print("\t\t\t");
try {
marker = violation.getMarker();
if (marker == null) {
_writer.println("??");
} else {
_writer.println(colorText + marker.getAttribute(IMarker.LINE_NUMBER) + colorEndText);
}
} catch (CoreException exception) {
_writer.println("??");
}
_writer.println("\t\t</td>");
_writer.println("\t</tr>");
}
/**
* Write out information about the specified group of audit violations.
*
* @param violationContainer the violation container
* (e.g. an audit rule or a resource - not null)
* @param depth the depth of this group
*/
public void writeGroupFooter(Object violationContainer, int depth)
{
}
/**
* @see com.instantiations.assist.eclipse.analysis.audit.core.AuditResultWriter#writeFooter(AuditViolationSet)
*/
public void writeFooter(AuditViolationSet violationSet)
{
_writer.println("</table>");
_writer.println("");
_writer.println("</body>");
_writer.println("");
_writer.println("</html>");
}
}