blob: 0674449eae7149e2904c158460d554da4c68bb8f [file] [log] [blame]
package org.apache.maven.plugin.pmd;
/*
* Copyright 2005 The Apache Software Foundation.
*
* 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.
*/
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.ResourceBundle;
import net.sourceforge.pmd.ReportListener;
import net.sourceforge.pmd.RuleViolation;
import net.sourceforge.pmd.stat.Metric;
import org.codehaus.doxia.sink.Sink;
import org.codehaus.plexus.util.StringUtils;
/**
* Handle events from PMD, converting them into Doxia events.
*
* @author Brett Porter
* @version $Id: PmdReportListener.java,v 1.1.1.1 2005/02/17 07:16:22 brett Exp $
*/
public class PmdReportListener
implements ReportListener
{
private Sink sink;
private String sourceDirectory;
private String currentFilename;
private boolean fileInitialized;
private ResourceBundle bundle;
private String xrefLocation;
private List violations = new ArrayList();
private List metrics = new ArrayList();
public PmdReportListener( Sink sink, String sourceDirectory, ResourceBundle bundle )
{
this.sink = sink;
this.sourceDirectory = sourceDirectory;
this.bundle = bundle;
}
private String getTitle()
{
return bundle.getString( "report.pmd.title" );
}
public void ruleViolationAdded( RuleViolation ruleViolation )
{
if ( !fileInitialized )
{
sink.section2();
sink.sectionTitle2();
sink.text( currentFilename );
sink.sectionTitle2_();
sink.table();
sink.tableRow();
sink.tableHeaderCell();
sink.text( bundle.getString( "report.pmd.column.violation" ) );
sink.tableHeaderCell_();
sink.tableHeaderCell();
sink.text( bundle.getString( "report.pmd.column.line" ) );
sink.tableHeaderCell_();
sink.tableRow_();
fileInitialized = true;
}
violations.add( ruleViolation );
}
// When dealing with multiple rulesets, the violations will get out of order
// wrt their source line number. We re-sort them before writing them to the report.
private void processViolations()
{
Collections.sort( violations, new Comparator()
{
public int compare( Object o1, Object o2 )
{
return ( (RuleViolation) o1 ).getLine() - ( (RuleViolation) o2 ).getLine();
}
} );
for ( Iterator it = violations.iterator(); it.hasNext(); )
{
RuleViolation ruleViolation = (RuleViolation) it.next();
sink.tableRow();
sink.tableCell();
sink.text( ruleViolation.getDescription() );
sink.tableCell_();
sink.tableCell();
if ( getXrefLocation() != null )
{
sink.link( getXrefLocation() + "/" + currentFilename.replaceAll( "\\.java$", ".html" ) + "#"
+ ruleViolation.getLine() );
}
sink.text( String.valueOf( ruleViolation.getLine() ) );
if ( getXrefLocation() != null )
{
sink.link_();
}
sink.tableCell_();
sink.tableRow_();
}
violations.clear();
}
public void metricAdded( Metric metric )
{
if ( metric.getCount() != 0 )
{
// Skip metrics which have no data
metrics.add( metric );
}
}
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.pmd.pmdlink" ) + " " );
sink.link( "http://pmd.sourceforge.net/" );
sink.text( "PMD" );
sink.link_();
sink.paragraph_();
// TODO overall summary
sink.section1_();
sink.section1();
sink.sectionTitle1();
sink.text( bundle.getString( "report.pmd.files" ) );
sink.sectionTitle1_();
// TODO files summary
}
public void beginFile( File file )
{
currentFilename = StringUtils.substring( file.getAbsolutePath(), sourceDirectory.length() + 1 );
currentFilename = StringUtils.replace( currentFilename, "\\", "/" );
fileInitialized = false;
}
public void endFile( File file )
{
if ( fileInitialized )
{
processViolations();
sink.table_();
sink.section2_();
}
}
private void processMetrics()
{
if ( metrics.size() == 0 )
{
return;
}
sink.section1();
sink.sectionTitle1();
sink.text( "Metrics" );
sink.sectionTitle1_();
sink.table();
sink.tableRow();
sink.tableHeaderCell();
sink.text( "Name" );
sink.tableHeaderCell_();
sink.tableHeaderCell();
sink.text( "Count" );
sink.tableHeaderCell_();
sink.tableHeaderCell();
sink.text( "High" );
sink.tableHeaderCell_();
sink.tableHeaderCell();
sink.text( "Low" );
sink.tableHeaderCell_();
sink.tableHeaderCell();
sink.text( "Average" );
sink.tableHeaderCell_();
sink.tableRow_();
for ( Iterator iter = metrics.iterator(); iter.hasNext(); )
{
Metric met = (Metric) iter.next();
sink.tableRow();
sink.tableCell();
sink.text( met.getMetricName() );
sink.tableCell_();
sink.tableCell();
sink.text( "" + met.getCount() );
sink.tableCell_();
sink.tableCell();
sink.text( "" + met.getHighValue() );
sink.tableCell_();
sink.tableCell();
sink.text( "" + met.getLowValue() );
sink.tableCell_();
sink.tableCell();
sink.text( "" + met.getAverage() );
sink.tableCell_();
sink.tableRow_();
}
sink.table_();
sink.section1_();
}
public void endDocument()
{
sink.section1_();
processMetrics();
sink.body_();
sink.flush();
sink.close();
}
public String getXrefLocation()
{
return xrefLocation;
}
public void setXrefLocation( String xrefLocation )
{
this.xrefLocation = xrefLocation;
}
}