blob: dd13594927435d9a7eb4822c38be2dc80bf0ec94 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.maven.plugins.pmd;
import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.plugins.pmd.model.CpdFile;
import org.apache.maven.plugins.pmd.model.Duplication;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.StringUtils;
/**
* Class that generated the CPD report.
*
* @author mperham
* @version $Id$
*/
public class CpdReportGenerator {
private Sink sink;
private Map<File, PmdFileInfo> fileMap;
private ResourceBundle bundle;
private boolean aggregate;
public CpdReportGenerator(Sink sink, Map<File, PmdFileInfo> fileMap, ResourceBundle bundle, boolean aggregate) {
this.sink = sink;
this.fileMap = fileMap;
this.bundle = bundle;
this.aggregate = aggregate;
}
/**
* Method that returns the title of the CPD Report
*
* @return a String that contains the title
*/
private String getTitle() {
return bundle.getString("report.cpd.title");
}
/**
* Method that generates the start of the CPD report.
*/
public void beginDocument() {
sink.head();
sink.title();
sink.text(getTitle());
sink.title_();
sink.head_();
sink.body();
sink.section1();
sink.sectionTitle1();
sink.text(getTitle());
sink.sectionTitle1_();
sink.paragraph();
sink.text(bundle.getString("report.cpd.cpdlink") + " ");
sink.link("https://pmd.github.io/latest/pmd_userdocs_cpd.html");
sink.text("CPD");
sink.link_();
sink.text(" " + AbstractPmdReport.getPmdVersion() + ".");
sink.paragraph_();
sink.section1_();
// TODO overall summary
sink.section1();
sink.sectionTitle1();
sink.text(bundle.getString("report.cpd.dupes"));
sink.sectionTitle1_();
// TODO files summary
}
/**
* Method that generates a line of CPD report according to a TokenEntry.
*/
private void generateFileLine(CpdFile duplicationMark) {
// Get information for report generation
String filename = duplicationMark.getPath();
File file = new File(filename);
PmdFileInfo fileInfo = fileMap.get(file);
File sourceDirectory = fileInfo.getSourceDirectory();
filename = StringUtils.substring(
filename, sourceDirectory.getAbsolutePath().length() + 1);
String xrefLocation = fileInfo.getXrefLocation();
MavenProject projectFile = fileInfo.getProject();
int line = duplicationMark.getLine();
sink.tableRow();
sink.tableCell();
sink.text(filename);
sink.tableCell_();
if (aggregate) {
sink.tableCell();
sink.text(projectFile.getName());
sink.tableCell_();
}
sink.tableCell();
if (xrefLocation != null) {
sink.link(xrefLocation + "/"
+ filename.replaceAll("\\.java$", ".html").replace('\\', '/') + "#L" + line);
}
sink.text(String.valueOf(line));
if (xrefLocation != null) {
sink.link_();
}
sink.tableCell_();
sink.tableRow_();
}
/**
* Method that generates the contents of the CPD report
*
* @param duplications the found duplications
*/
public void generate(List<Duplication> duplications) {
beginDocument();
if (duplications.isEmpty()) {
sink.paragraph();
sink.text(bundle.getString("report.cpd.noProblems"));
sink.paragraph_();
}
for (Duplication duplication : duplications) {
String code = duplication.getCodefragment();
sink.table();
sink.tableRows(null, false);
sink.tableRow();
sink.tableHeaderCell();
sink.text(bundle.getString("report.cpd.column.file"));
sink.tableHeaderCell_();
if (aggregate) {
sink.tableHeaderCell();
sink.text(bundle.getString("report.cpd.column.project"));
sink.tableHeaderCell_();
}
sink.tableHeaderCell();
sink.text(bundle.getString("report.cpd.column.line"));
sink.tableHeaderCell_();
sink.tableRow_();
// Iterating on every token entry
for (CpdFile mark : duplication.getFiles()) {
generateFileLine(mark);
}
// Source snippet
sink.tableRow();
int colspan = 2;
if (aggregate) {
++colspan;
}
// TODO Cleaner way to do this?
sink.rawText("<td colspan='" + colspan + "'>");
sink.verbatim(null);
sink.text(code);
sink.verbatim_();
sink.rawText("</td>");
sink.tableRow_();
sink.tableRows_();
sink.table_();
}
sink.section1_();
sink.body_();
sink.flush();
sink.close();
}
}