All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.codehaus.mojo.findbugs.Reporter Maven / Gradle / Ivy

There is a newer version: 3.0.5
Show newest version
package org.codehaus.mojo.findbugs;

/* Copyright (c) 2004, The Codehaus
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is furnished to do
 * so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

import java.util.HashSet;
import java.util.Iterator;
import java.util.ResourceBundle;
import java.util.Set;

import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.plugin.logging.Log;

import edu.umd.cs.findbugs.AnalysisError;
import edu.umd.cs.findbugs.BugInstance;
import edu.umd.cs.findbugs.BugPattern;
import edu.umd.cs.findbugs.BugReporter;
import edu.umd.cs.findbugs.SortedBugCollection;
import edu.umd.cs.findbugs.SourceLineAnnotation;
import edu.umd.cs.findbugs.TextUIBugReporter;
import edu.umd.cs.findbugs.classfile.ClassDescriptor;

/**
 * The reporter controls the generation of the FindBugs report. It contains call back methods which gets called by
 * FindBugs if a bug is found.
 * 
 * @author $Author: cyrill $
 * @author Cyrill Ruettimann
 * @author Garvin LeClaire
 * @version $Id: Reporter.java 4042 2007-05-07 04:52:38Z gleclaire $
 */
public final class Reporter extends TextUIBugReporter
{

    /**
     * The key to get the value if the line number is not available.
     * 
     */
    private static final String NOLINE_KEY = "report.findbugs.noline";

    /**
     * The key to get the column title for the line.
     * 
     */
    private static final String COLUMN_LINE_KEY = "report.findbugs.column.line";

    /**
     * The key to get the column title for the bug.
     * 
     */
    private static final String COLUMN_BUG_KEY = "report.findbugs.column.bug";

    /**
     * The key to get the column title for the bugs.
     * 
     */
    private static final String COLUMN_BUGS_KEY = "report.findbugs.column.bugs";

    /**
     * The key to get the column title for the category.
     * 
     */
    private static final String COLUMN_CATEGORY_KEY = "report.findbugs.column.category";

    /**
     * The key to get the column title for the details.
     * 
     */
    private static final String COLUMN_DETAILS_KEY = "report.findbugs.column.details";

    /**
     * The key to get the report title of the Plug-In from the bundle.
     * 
     */
    private static final String REPORT_TITLE_KEY = "report.findbugs.reporttitle";

    /**
     * The key to get the report link title of the Plug-In from the bundle.
     * 
     */
    private static final String LINKTITLE_KEY = "report.findbugs.linktitle";

    /**
     * The key to get the report link of the Plug-In from the bundle.
     * 
     */
    private static final String LINK_KEY = "report.findbugs.link";

    /**
     * The key to get the name of the Plug-In from the bundle.
     * 
     */
    private static final String NAME_KEY = "report.findbugs.name";

    /**
     * The key to get the files title of the Plug-In from the bundle.
     * 
     */
    private static final String FILES_KEY = "report.findbugs.files";

    /**
     * The key to get the threshold of the report from the bundle.
     * 
     */
    private static final String THRESHOLD_KEY = "report.findbugs.threshold";

    /**
     * The character to separate URL tokens.
     * 
     */
    private static final String URL_SEPARATOR = "/";

    /**
     * The key to get the jxr-plugin path prefix.
     * 
     */
    private static final String JXR_PATHPREFIX_KEY = "report.findbugs.jxrplugin.pathprefix";

    /**
     * The key to get the effort of the report from the bundle.
     * 
     */
    private static final String EFFORT_KEY = "report.findbugs.effort";

    /**
     * The key to get the link to FindBugs description page from the bundle.
     * 
     */
    private static final String DETAILSLINK_KEY = "report.findbugs.detailslink";

    /**
     * The key to get the version title for FindBugs from the bundle.
     * 
     */
    private static final String VERSIONTITLE_KEY = "report.findbugs.versiontitle";

    /**
     * The key to get the files title of the Plug-In from the bundle.
     * 
     */
    private static final String SUMMARY_KEY = "report.findbugs.summary";

    /**
     * The key to column title for the Class.
     * 
     */
    private static final String COLUMN_CLASS_KEY = "report.findbugs.column.class";

    /**
     * The key to column title for the Classes.
     * 
     */
    private static final String COLUMN_CLASSES_KEY = "report.findbugs.column.classes";

    /**
     * The key to column title for the errors.
     * 
     */
    private static final String COLUMN_ERRORS_KEY = "report.findbugs.column.errors";

    /**
     * The key to column title for the files.
     * 
     */
    private static final String COLUMN_FILES_KEY = "report.findbugs.column.files";

    /**
     * The key to column title for the files.
     * 
     */
    private static final String COLUMN_MISSINGCLASSES_KEY = "report.findbugs.column.missingclasses";

    /**
     * The sink to write the report to.
     * 
     */
    private final Sink sink;

    /**
     * The bundle to get the messages from.
     * 
     */
    private final ResourceBundle bundle;

    /**
     * The logger to write logs to.
     * 
     */
    private final Log mavenLog;

    /**
     * The threshold of bugs severity.
     * 
     */
    private final ThresholdParameter threshold;

    /**
     * The used effort for searching bugs.
     * 
     */
    private final EffortParameter effort;

    /**
     * The name of the current class which is analysed by FindBugs.
     * 
     */
    private String currentClassName;

    /**
     * Signals if the report for the current class is opened.
     * 
     */
    private boolean mIsCurrentClassReportOpened = false;

    /**
     * Signals if the jxr report plugin is enabled.
     * 
     */
    private boolean isJXRReportEnabled = false;

    /**
     * The Collection of Bugs and Error collected during analysis.
     * 
     */
    private SortedBugCollection bugCollection = new SortedBugCollection();

    /**
     * The running total of bugs reported.
     * 
     */
    private int bugCount;

    /**
     * The running total of missing classes reported.
     * 
     */
    private int missingClassCount;

    /**
     * The running total of files analyzed.
     * 
     */
    private int fileCount;

    /**
     * The Set of missing classes names reported.
     * 
     */
    private Set missingClassSet = new HashSet();

    /**
     * The running total of errors reported.
     * 
     */
    private int errorCount;

    /**
     * Default constructor.
     * 
     * @param pSink
     *            The sink to generate the report.
     * @param pBundle
     *            The resource bundle to get the messages from.
     * @param pLog
     *            The logger.
     * @param pThreshold
     *            The threshold for the report.
     * @param isJXRReportEnabled
     *            Is the jxr report plugin enabled.
     * @param pEffort
     *            The used effort.
     */
    public Reporter( final Sink pSink, final ResourceBundle pBundle, final Log pLog,
                     final ThresholdParameter pThreshold, final boolean isJXRReportEnabled,
                     final EffortParameter pEffort )
    {
        super();

        if ( pSink == null )
        {
            throw new IllegalArgumentException( "pSink not allowed to be null" );
        }

        if ( pBundle == null )
        {
            throw new IllegalArgumentException( "pBundle not allowed to be null" );
        }

        if ( pLog == null )
        {
            throw new IllegalArgumentException( "pLog not allowed to be null" );
        }

        if ( pThreshold == null )
        {
            throw new IllegalArgumentException( "pThreshold not allowed to be null" );
        }

        if ( pEffort == null )
        {
            throw new IllegalArgumentException( "pEffort not allowed to be null" );
        }

        this.sink = pSink;
        this.bundle = pBundle;
        this.mavenLog = pLog;
        this.threshold = pThreshold;
        this.isJXRReportEnabled = isJXRReportEnabled;
        this.effort = pEffort;
        this.currentClassName = "";

        this.bugCount = 0;
        this.missingClassCount = 0;
        this.errorCount = 0;
        this.fileCount = 0;

        this.initialiseReport();
    }

    /**
     * Hide default constructor.
     * 
     */
    private Reporter()
    {
        super();

        this.sink = null;
        this.bundle = null;
        this.mavenLog = null;
        this.threshold = null;
        this.effort = null;
    }

    /**
     * @see edu.umd.cs.findbugs.BugReporter#finish()
     */
    public void finish()
    {
        this.mavenLog.debug( "Finished searching for bugs!" );

        this.printSummary();

        this.printFilesSummary();

        this.mIsCurrentClassReportOpened = false;

        for ( Iterator i = this.bugCollection.iterator(); i.hasNext(); )
        {
            BugInstance bugInstance = ( BugInstance ) i.next();

            this.mavenLog.debug( "Annotation Class is " + bugInstance.getPrimarySourceLineAnnotation().getClassName() );
            this.mavenLog.debug( "Class is " + this.currentClassName );
            this.mavenLog.debug( " " );

            if ( !bugInstance.getPrimarySourceLineAnnotation().getClassName().equals( this.currentClassName ) )
            {

                this.currentClassName = bugInstance.getPrimarySourceLineAnnotation().getClassName();

                if ( this.mIsCurrentClassReportOpened )
                {
                    this.closeClassReportSection();
                    this.mIsCurrentClassReportOpened = false;
                }
            }

            this.printBug( bugInstance );
        }

        // close the last class report section
        if ( this.mIsCurrentClassReportOpened )
        {
            this.closeClassReportSection();
        }

        // close the report, write it
        this.sink.section1_();
        this.sink.body_();
        this.sink.flush();
        this.sink.close();

        this.mavenLog.debug( "bugCount = " + this.bugCount );
        this.mavenLog.debug( "errorCount = " + this.errorCount );
        this.mavenLog.debug( "missingClassCount = " + this.missingClassCount );
    }

    /**
     * Get the real bug reporter at the end of a chain of delegating bug reporters. All non-delegating bug reporters
     * should simply "return this".
     * 
     * @return the real bug reporter at the end of the chain, or this object if there is no delegation
     * @see edu.umd.cs.findbugs.BugReporter#getRealBugReporter()
     */
    public BugReporter getRealBugReporter()
    {
        return this;
    }

    /**
     * Observe a class.
     * 
     * @param clazz
     *            the class
     * @see edu.umd.cs.findbugs.classfile.IClassObserver #observeClass(edu.umd.cs.findbugs.classfile.ClassDescriptor)
     */
    public void observeClass( final ClassDescriptor clazz )
    {
        this.mavenLog.debug( "Observe class: " + clazz.getClassName() );

        ++this.fileCount;
    }

    /**
     * Report a queued error.
     * 
     * @param analysisError
     *            the queued error
     * @see edu.umd.cs.findbugs.AbstractBugReporter #reportAnalysisError(edu.umd.cs.findbugs.AnalysisError)
     */
    public void reportAnalysisError( final AnalysisError analysisError )
    {
        this.mavenLog.debug( "  Found an analysisError: " + analysisError.getMessage() );
        this.bugCollection.addError( analysisError.getMessage() );
        ++this.errorCount;
        super.reportAnalysisError( analysisError );
    }

    public void logError( String message )
    {
        this.mavenLog.debug( "  Found an analysisError: " + message );
        this.bugCollection.addError( message );
        ++this.errorCount;
        super.logError( message );
    }

    public void logError( String message, Throwable e )
    {
        this.mavenLog.debug( "  Found an analysisError: " + message );
        this.bugCollection.addError( message );
        ++this.errorCount;
        super.logError( message, e );
    }

    /**
     * Report a missing class.
     * 
     * @param missingClass
     *            the name of the class
     * @see edu.umd.cs.findbugs.AbstractBugReporter #reportMissingClass(java.lang.String)
     */
    public void reportMissingClass( final String missingClass )
    {
        this.mavenLog.debug( "Found a missing class: " + missingClass );
        if ( this.missingClassSet.add( missingClass ) )
        {
            ++this.missingClassCount;
        }
        super.reportMissingClass( missingClass );
    }

    public void reportMissingClass( ClassNotFoundException ex )
    {
        this.mavenLog.debug( "Found a missing class: " + ex.getMessage() );
        if ( this.missingClassSet.add( ex.getMessage() ) )
        {
            ++this.missingClassCount;
        }
        super.reportMissingClass( ex );
    }

    /* (non-Javadoc)
     * @see edu.umd.cs.findbugs.classfile.IErrorLogger#reportMissingClass(edu.umd.cs.findbugs.classfile.ClassDescriptor)
     */
    public void reportMissingClass( ClassDescriptor classDescriptor )
    {
        this.reportMissingClass( classDescriptor.toDottedClassName() );
    }

    /**
     * Initialises the report.
     */
    private void initialiseReport()
    {
        this.sink.head();
        this.sink.title();
        this.sink.text( this.getReportTitle() );
        this.sink.title_();
        this.sink.head_();

        this.sink.body();

        // the title of the report
        this.sink.section1();
        this.sink.sectionTitle1();
        this.sink.text( this.getReportTitle() );
        this.sink.sectionTitle1_();

        // information about FindBugs
        this.sink.paragraph();
        this.sink.text( this.getReportLinkTitle() + " " );
        this.sink.link( this.getFindBugsLink() );
        this.sink.text( this.getFindBugsName() );
        this.sink.link_();
        this.sink.paragraph_();

        this.sink.paragraph();
        this.sink.text( this.getVersionTitle() + " " );
        this.sink.italic();
        this.sink.text( this.getFindBugsVersion() );
        this.sink.italic_();
        this.sink.paragraph_();

        this.sink.paragraph();
        this.sink.text( this.getThresholdTitle() + " " );
        this.sink.italic();
        this.sink.text( this.threshold.getName() );
        this.sink.italic_();
        this.sink.paragraph_();

        this.sink.paragraph();
        this.sink.text( this.getEffortTitle() + " " );
        this.sink.italic();
        this.sink.text( this.effort.getName() );
        this.sink.italic_();
        this.sink.paragraph_();
        this.sink.section1_();

    }

    /**
     * Print the bug collection to a line in the table
     *  
     * @param bugInstance the bug to print
     */
    protected void printBug( final BugInstance bugInstance )
    {
        final SourceLineAnnotation line = bugInstance.getPrimarySourceLineAnnotation();
        final BugPattern pattern = bugInstance.getBugPattern();
        final String lineNumber = this.valueForLine( line );
        final String category = pattern.getCategory();
        final String type = pattern.getType();

        this.mavenLog.debug( "Bug line = " + line.getClassName() );
        this.mavenLog.debug( "Bug pattern = " + pattern.getShortDescription() );
        this.mavenLog.debug( "Bug line Number = " + lineNumber );
        this.mavenLog.debug( "Bug Category = " + category );
        this.mavenLog.debug( "Bug Type = " + type );
        this.mavenLog.debug( " " );

        if ( !this.mIsCurrentClassReportOpened )
        {
            this.openClassReportSection();
            this.mIsCurrentClassReportOpened = true;
        }

        this.sink.tableRow();

        // bug
        this.sink.tableCell();
        this.sink.text( bugInstance.getMessageWithoutPrefix() );
        this.sink.tableCell_();

        // category
        this.sink.tableCell();
        this.sink.text( category );
        this.sink.tableCell_();

        // description link
        this.sink.tableCell();
        this.sink.link( this.getDetailsLink( type ) );
        this.sink.text( type );
        this.sink.link_();
        this.sink.tableCell_();

        // line
        this.sink.tableCell();
        if ( this.isJXRReportEnabled )
        {
            this.sink.rawText( this.assembleJXRHyperlink( line, lineNumber ) );
        }
        else
        {
            this.sink.text( lineNumber );
        }

        this.sink.tableCell_();
        this.sink.tableRow_();
    }

    /**
     * Assembles the hyperlink to point to the source code.
     * 
     * @param pLine
     *            The line number object with the bug.
     * @param pLineNumber
     *            The line number to show in the hyperlink.
     * @return The hyperlink which points to the code.
     * 
     */
    protected String assembleJXRHyperlink( final SourceLineAnnotation pLine, final String pLineNumber )
    {
        String hyperlink = null;
        final String prefix = this.bundle.getString( Reporter.JXR_PATHPREFIX_KEY );
        final String path = prefix + Reporter.URL_SEPARATOR + this.currentClassName.replaceAll( "[.]", "/" ).replaceAll("[$].*","");

        if ( pLine == null )
        {
            hyperlink = "" + pLineNumber + "";
        }
        else
        {
            hyperlink = "" + pLineNumber + "";
        }

        return hyperlink;
    }

    /**
     * Closes the class report section.
     */
    protected void closeClassReportSection()
    {
        this.mavenLog.debug( "Closing report Section" );
        this.sink.table_();
        this.sink.section2_();
    }

    /**
     * @param bugInstance The bug to report
     * @see edu.umd.cs.findbugs.AbstractBugReporter #doReportBug(edu.umd.cs.findbugs.BugInstance)
     */
    protected void doReportBug( final BugInstance bugInstance )
    {
        this.mavenLog.debug( "  Found a bug: " + bugInstance.getMessage() );
        if ( this.bugCollection.add( bugInstance ) )
        {
            ++this.bugCount;
            this.notifyObservers( bugInstance );
            this.notifyObservers( bugInstance );
        }

    }

    /**
     * Gets the link to details description on findbugs site.
     * 
     * @param pType
     *            the bug type
     * @return The report link.
     * 
     */
    protected String getDetailsLink( final String pType )
    {
        final String link = this.bundle.getString( Reporter.DETAILSLINK_KEY ) + "#" + pType;

        return link;
    }

    /**
     * Gets the effort title of the report.
     * 
     * @return The effort title of the report.
     * 
     */
    protected String getEffortTitle()
    {
        final String effortTitle = this.bundle.getString( Reporter.EFFORT_KEY );

        return effortTitle;
    }

    /**
     * Gets the title for the files title.
     * 
     * @return The name for the File Section.
     * 
     */
    protected String getFilesTitle()
    {
        final String fileTitle = this.bundle.getString( Reporter.FILES_KEY );

        return fileTitle;
    }

    /**
     * Gets the title for the summary section.
     * 
     * @return The name for the Summary Section.
     * 
     */
    protected String getSummaryTitle()
    {
        final String summaryTitle = this.bundle.getString( Reporter.SUMMARY_KEY );

        return summaryTitle;
    }

    /**
     * Gets the link to FindBugs.
     * 
     * @return The report link.
     * 
     */
    protected String getFindBugsLink()
    {
        final String link = this.bundle.getString( Reporter.LINK_KEY );

        return link;
    }

    /**
     * Gets the name of FindBugs.
     * 
     * @return The name of FindBugs.
     * 
     */
    protected String getFindBugsName()
    {
        final String name = this.bundle.getString( Reporter.NAME_KEY );

        return name;
    }

    /**
     * Gets the Findbugs Version of the report.
     * 
     * @return The Findbugs Version used on the report.
     * 
     */
    protected String getFindBugsVersion()
    {
        return edu.umd.cs.findbugs.Version.RELEASE;
    }

    /**
     * Gets the name of the link to FindBugs.
     * 
     * @return The report link title.
     * 
     */
    protected String getReportLinkTitle()
    {
        final String reportLink = this.bundle.getString( Reporter.LINKTITLE_KEY );

        return reportLink;
    }

    /**
     * Gets the report title.
     * 
     * @return The report title.
     * 
     */
    protected String getReportTitle()
    {
        final String reportTitle = this.bundle.getString( Reporter.REPORT_TITLE_KEY );

        return reportTitle;
    }

    /**
     * Gets the threshold title of the report.
     * 
     * @return The threshold title of the report.
     * 
     */
    protected String getThresholdTitle()
    {
        final String threshholdTitle = this.bundle.getString( Reporter.THRESHOLD_KEY );

        return threshholdTitle;
    }

    /**
     * Gets the Findbugs Version title of the report.
     * 
     * @return The Findbugs Version used on the report.
     * 
     */
    protected String getVersionTitle()
    {
        final String versionTitle = this.bundle.getString( VERSIONTITLE_KEY );

        return versionTitle;
    }

    /**
     * Initialised a bug report section in the report for a particular class.
     */
    protected void openClassReportSection()
    {
        final String columnBugText = this.bundle.getString( Reporter.COLUMN_BUG_KEY );
        final String columnBugCategory = this.bundle.getString( Reporter.COLUMN_CATEGORY_KEY );
        final String columnDescriptionLink = this.bundle.getString( Reporter.COLUMN_DETAILS_KEY );
        final String columnLineText = this.bundle.getString( Reporter.COLUMN_LINE_KEY );

        this.mavenLog.debug( "Opening Class Report Section" );

        this.sink.anchor( this.currentClassName );
        this.sink.anchor_();

        this.sink.section2();
        this.sink.sectionTitle2();
        this.sink.text( this.currentClassName );
        this.sink.sectionTitle2_();
        this.sink.table();
        this.sink.tableRow();

        // bug
        this.sink.tableHeaderCell();
        this.sink.text( columnBugText );
        this.sink.tableHeaderCell_();

        // category
        this.sink.tableHeaderCell();
        this.sink.text( columnBugCategory );
        this.sink.tableHeaderCell_();

        // description link
        this.sink.tableHeaderCell();
        this.sink.text( columnDescriptionLink );
        this.sink.tableHeaderCell_();

        // line
        this.sink.tableHeaderCell();
        this.sink.text( columnLineText );
        this.sink.tableHeaderCell_();

        this.sink.tableRow_();
    }

    /**
     * Return the value to display. If FindBugs does not provide a line number, a default message is returned. The line
     * number otherwise.
     * 
     * @param pLine
     *            The line to get the value from.
     * @return The line number the bug appears or a statement that there is no source line available.
     * 
     */
    protected String valueForLine( final SourceLineAnnotation pLine )
    {
        String value = null;

        if ( pLine == null )
        {
            value = this.bundle.getString( Reporter.NOLINE_KEY );
        }
        else
        {
            final int startLine = pLine.getStartLine();
            final int endLine = pLine.getEndLine();

            if ( startLine == endLine )
            {
                if ( startLine == -1 )
                {
                    value = this.bundle.getString( Reporter.NOLINE_KEY );
                }
                else
                {
                    value = String.valueOf( startLine );
                }
            }
            else
            {
                value = String.valueOf( startLine ) + "-" + String.valueOf( endLine );
            }
        }

        return value;
    }

    /**
     * Print the Summary Section.
     */
    protected void printSummary()
    {
        // the summary section
        this.sink.sectionTitle1();
        this.sink.text( this.getSummaryTitle() );
        this.sink.sectionTitle1_();

        this.sink.table();
        this.sink.tableRow();

        // classes
        this.sink.tableHeaderCell();
        this.sink.text( this.bundle.getString( Reporter.COLUMN_CLASSES_KEY ) );
        this.sink.tableHeaderCell_();

        // bugs
        this.sink.tableHeaderCell();
        this.sink.text( this.bundle.getString( Reporter.COLUMN_BUGS_KEY ) );
        this.sink.tableHeaderCell_();

        // Errors
        this.sink.tableHeaderCell();
        this.sink.text( this.bundle.getString( Reporter.COLUMN_ERRORS_KEY ) );
        this.sink.tableHeaderCell_();

        // Missing Classes
        this.sink.tableHeaderCell();
        this.sink.text( this.bundle.getString( Reporter.COLUMN_MISSINGCLASSES_KEY ) );
        this.sink.tableHeaderCell_();

        this.sink.tableRow_();

        this.sink.tableRow();

        // files
        this.sink.tableCell();
        this.sink.text( Integer.toString( this.fileCount ) );
        this.sink.tableCell_();

        // bug
        this.sink.tableCell();
        this.sink.text( Integer.toString( this.bugCount ) );
        this.sink.tableCell_();

        // Errors
        this.sink.tableCell();
        this.sink.text( Integer.toString( this.errorCount  ));
        this.sink.tableCell_();

        // Missing Classes
        this.sink.tableCell();
        this.sink.text( Integer.toString( this.missingClassCount ));
        this.sink.tableCell_();

        this.sink.tableRow_();
        this.sink.table_();

        this.sink.paragraph_();
        this.sink.section1_();
    }

    /**
     * Print the File Summary Section.
     */
    protected void printFilesSummary()
    {
        // the Files section
        this.sink.sectionTitle1();
        this.sink.text( this.getFilesTitle() );
        this.sink.sectionTitle1_();

        /**
         * Class Summary
         */

        int classBugs = 0;

        this.sink.table();
        this.sink.tableRow();

        // files
        this.sink.tableHeaderCell();
        this.sink.text( this.bundle.getString( Reporter.COLUMN_CLASS_KEY ) );
        this.sink.tableHeaderCell_();

        // bugs
        this.sink.tableHeaderCell();
        this.sink.text( this.bundle.getString( Reporter.COLUMN_BUGS_KEY ) );
        this.sink.tableHeaderCell_();

        this.sink.tableRow_();

        for ( Iterator i = this.bugCollection.iterator(); i.hasNext(); )
        {
            BugInstance bugInstance = ( BugInstance ) i.next();

            this.mavenLog.debug( "Annotation Class is " + bugInstance.getPrimarySourceLineAnnotation().getClassName() );
            this.mavenLog.debug( "Class is " + this.currentClassName );
            this.mavenLog.debug( " " );

            if ( bugInstance.getPrimarySourceLineAnnotation().getClassName().equals( this.currentClassName ) )
            {
                ++classBugs;
            }
            else
            {
                if ( this.currentClassName.length() > 0 )
                {
                    this.printFilesSummaryLine( classBugs );
                }

                classBugs = 1;
                this.currentClassName = bugInstance.getPrimarySourceLineAnnotation().getClassName();

            }
        }

        this.printFilesSummaryLine( classBugs );

        this.sink.table_();

    }

    protected void printFilesSummaryLine( int classBugs )
    {
        this.sink.tableRow();

        // class name
        this.sink.tableCell();
        this.sink.link( "#" + this.currentClassName );
        this.sink.text( this.currentClassName );
        this.sink.link_();
        this.sink.tableCell_();

        // class bug total count
        this.sink.tableCell();
        this.sink.text( Integer.toString( classBugs ));
        this.sink.tableCell_();

        this.sink.tableRow_();

    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy