/* * Sonar W3C Markup Validation Plugin * Copyright (C) 2010 Matthijs Galesloot * dev@sonar.codehaus.org * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.sonar.plugins.web.markup.validation; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.sonar.api.utils.SonarException; import org.sonar.plugins.web.markup.rules.MarkupErrorCatalog; import org.sonar.plugins.web.markup.rules.MarkupErrorCatalog.MessageDefinition; /** * Builds HTML report from a list of W3C responses. * * @author Matthijs Galesloot * @since 1.0 */ public final class MarkupReportBuilder { private static final Logger LOG = Logger.getLogger(MarkupReportBuilder.class); private StringBuilder sb; private void addCells(Object... values) { for (Object value : values) { sb.append("<td>"); sb.append(value == null ? "" : value); sb.append("</td>\n"); } } private void addHeaderCell(Object value) { sb.append("<th>"); sb.append(value); sb.append("</th>\n"); } private void endRow() { sb.append("</tr>"); } private void startRow() { sb.append("<tr>"); } private static final class Violation { public int count; public String messageId; } public void buildReports(String key, Collection<File> reportFiles) { List<MarkupReport> reports = new ArrayList<MarkupReport>(); for (File reportFile : reportFiles) { MarkupReport report = MarkupReport.fromXml(reportFile); reports.add(report); } createHtmlReport(new File("target/" + key + "/markup-report.html"), reports, false); createHtmlReport(new File("target/" + key + "/markup-report-details.html"), reports, true); } private Violation findViolation(List<Violation> violations, String messageId) { for (Violation violation : violations) { if (violation.messageId.equals(messageId)) { return violation; } } Violation violation = new Violation(); violation.messageId = messageId; violations.add(violation); return violation; } private List<Violation> collectViolations(List<MarkupReport> reports) { List<Violation> violations = new ArrayList<Violation>(); for (MarkupReport report : reports) { for (MarkupMessage error : report.getErrors()) { Violation violation = findViolation(violations, error.getMessageId()); violation.count++; } } return violations; } private void createViolationsReport(List<MarkupReport> reports, boolean showDetails) { List<Violation> violations = collectViolations(reports); sb.append("<h2>Guidelines Summary</h2>"); sb.append("<table cellspacing='0' >"); startRow(); addHeaderCell("id"); addHeaderCell("remark"); addHeaderCell("count"); endRow(); MarkupErrorCatalog errorCatalog = new MarkupErrorCatalog(); for (Violation violation : violations) { MessageDefinition messageDefinition = errorCatalog.findErrorDefinition(violation.messageId); if (messageDefinition == null) { LOG.warn("Unknown error found:" + violation.messageId); } startRow(); addCells(violation.messageId, messageDefinition == null ? "?" : messageDefinition.getRemark(), violation.count); endRow(); if (showDetails) { startRow(); sb.append("<td colspan='4'>"); for (MarkupReport report : collectViolatedReports(reports, violation)) { sb.append(StringUtils.substringBeforeLast(report.getReportFile().getName(), ".")); sb.append("<br/>"); } sb.append("</td>"); endRow(); } } sb.append("</table>"); } private List<MarkupReport> collectViolatedReports(List<MarkupReport> reports, Violation violation) { List<MarkupReport> violatedReports = new ArrayList<MarkupReport>(); for (MarkupReport report : reports) { if (hasViolation(report, violation)) { violatedReports.add(report); } } return violatedReports; } private boolean hasViolation(MarkupReport report, Violation violation) { for (MarkupMessage error : report.getErrors()) { if (error.getMessageId().equals(violation.messageId)) { return true; } } return false; } private void createHtmlReport(File file, List<MarkupReport> reports, boolean showDetails) { sb = new StringBuilder(); sb.append("<style type='text/css'>"); sb.append("table{ border-color: gray; border-collapse: collapse; border: 1px solid}"); sb.append("th { text-align: left; border: 1px solid; padding: 2px; } td{ border: 1px solid; padding: 2px; }</style>"); sb.append("<h1>Markup Validation Report</h1>"); createViolationsReport(reports, showDetails); // createUrlsReport(reports, showDetails); try { FileUtils.writeStringToFile(file, sb.toString()); } catch (IOException e) { throw new SonarException(e); } } }