![JAR search and dependency download from the Maven repository](/logo.png)
org.codehaus.mojo.findbugs.FindBugsMojo Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of findbugs-maven-plugin Show documentation
Show all versions of findbugs-maven-plugin Show documentation
This Plug-In generates reports based on the FindBugs Library
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.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.StringTokenizer;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.artifact.repository.DefaultArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.artifact.resolver.ArtifactResolver;
import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.doxia.siterenderer.Renderer;
import org.apache.maven.model.ReportPlugin;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.MavenProject;
import org.apache.maven.reporting.AbstractMavenReport;
import org.apache.maven.reporting.MavenReportException;
import org.codehaus.plexus.util.FileUtils;
import edu.umd.cs.findbugs.BugReporter;
import edu.umd.cs.findbugs.ClassScreener;
import edu.umd.cs.findbugs.DetectorFactory;
import edu.umd.cs.findbugs.DetectorFactoryCollection;
import edu.umd.cs.findbugs.FindBugs2;
import edu.umd.cs.findbugs.Project;
import edu.umd.cs.findbugs.config.UserPreferences;
import edu.umd.cs.findbugs.filter.FilterException;
/**
* Generates a FindBugs report.
*
* @goal findbugs
* @description Generates a FindBugs Report.
* @execute phase="compile"
* @requiresDependencyResolution compile
* @requiresProject
*
* @author Cyrill Ruettimann
* @author Detlef Pleiss
* @author Garvin LeClaire
* @version $Id: FindBugsMojo.java 4041 2007-05-07 02:55:00Z gleclaire $
*/
public final class FindBugsMojo extends AbstractMavenReport
{
/**
* The name of the Plug-In.
*
*/
private static final String PLUGIN_NAME = "findbugs";
/**
* The name of the property resource bundle (Filesystem).
*
*/
private static final String BUNDLE_NAME = "findbugs";
/**
* 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 description of the Plug-In from the bundle.
*
*/
private static final String DESCRIPTION_KEY = "report.findbugs.description";
/**
* The key to get the source directory message of the Plug-In from the bundle.
*
*/
private static final String SOURCE_ROOT_KEY = "report.findbugs.sourceRoot";
/**
* The key to get the java source message of the Plug-In from the bundle.
*
*/
private static final String JAVA_SOURCES_KEY = "report.findbugs.javasources";
/**
* The regex pattern to search for java class files.
*
*/
private static final String JAVA_REGEX_PATTERN = "**/*.class";
/**
* The key to get the jxr-plugin artifactId from the bundle.
*
*/
private static final String JXR_ARTIFACT_ID_KEY = "report.findbugs.jxrplugin.artifactid";
/**
* The name of the coreplugin.
*
*/
private static final String FINDBUGS_COREPLUGIN = "report.findbugs.coreplugin";
/**
* Location where generated html will be created.
*
* @parameter default-value="${project.reporting.outputDirectory}"
* @required
*/
private String outputDirectory;
/**
* Turn on and off xml output of the Findbugs report.
*
* @parameter default-value="false"
*/
private boolean xmlOutput;
/**
* Specifies the directory where the xml output will be generated.
*
* @parameter default-value="${project.build.directory}"
* @required
*/
private File xmlOutputDirectory;
/**
* Doxia Site Renderer.
*
* @parameter expression="${component.org.apache.maven.doxia.siterenderer.Renderer}"
* @required
* @readonly
*/
private Renderer siteRenderer;
/**
* Directory containing the class files for FindBugs to analyze.
*
* @parameter default-value="${project.build.outputDirectory}"
* @required
*/
private File classFilesDirectory;
/**
* List of artifacts this plugin depends on. Used for resolving the Findbugs coreplugin.
*
* @parameter expression="${plugin.artifacts}"
* @required
* @readonly
*/
private ArrayList pluginArtifacts;
/**
* The local repository, needed to download the coreplugin jar.
*
* @parameter expression="${localRepository}"
* @required
* @readonly
*/
private DefaultArtifactRepository localRepository;
/**
* Remote repositories which will be searched for the coreplugin jar.
*
* @parameter expression="${project.remoteArtifactRepositories}"
* @required
* @readonly
*/
private List remoteArtifactRepositories;
/**
* Maven Project
*
* @parameter expression="${project}"
* @required
* @readonly
*/
private MavenProject project;
/**
* Threshold of minimum bug severity to report. Valid values are High, Medium, Low and Exp (for experimental).
*
* @parameter
*/
private String threshold;
/**
* Artifact resolver, needed to download the coreplugin jar.
*
* @component role="org.apache.maven.artifact.resolver.ArtifactResolver"
* @required
* @readonly
*/
private ArtifactResolver artifactResolver;
/**
* File name of the include filter. Only bugs in matching the filters are reported.
*
* @parameter
*/
private String includeFilterFile;
/**
* File name of the exclude filter. Bugs matching the filters are not reported.
*
* @parameter
*/
private String excludeFilterFile;
/**
* Effort of the bug finders. Valid values are Min, Default and Max.
*
* @parameter
*/
private String effort;
/**
* turn on Findbugs debugging
*
* @parameter default-value="false"
*/
private Boolean debug;
/**
* Relaxed reporting mode. For many detectors, this option suppresses the heuristics used to avoid reporting false
* positives.
*
* @parameter default-value="false"
*/
private Boolean relaxed;
/**
* The visitor list to run. This is a comma-delimited list.
*
* @parameter
*/
private String visitors;
/**
* The visitor list to omit. This is a comma-delimited list.
*
* @parameter
*/
private String omitVisitors;
/**
* The plugin list to include in the report. This is a comma-delimited list.
*
* @parameter
*/
private String pluginList;
/**
* The Base FindBugs reporter Class for reports.
*
* @parameter
* @readonly
*/
private BugReporter bugReporter;
/**
* Restrict analysis to find bugs to given comma-separated list of classes and packages.
*
* @parameter
*/
private String onlyAnalyze;
/**
* The Base FindBugs reporter Class for reports.
*
* @parameter
* @readonly
*/
private ClassScreener classScreener = new ClassScreener();
/**
* The Flag letting us know if classes have been loaded already.
*
* @parameter
* @readonly
*/
private static boolean pluginLoaded = false;
/**
* Skip entire check.
*
* @parameter expression="${findbugs.skip}" default-value="false"
*/
private boolean skip;
/**
* Checks whether prerequisites for generating this report are given.
*
* @return true if report can be generated, otherwise false
* @see org.apache.maven.reporting.MavenReport#canGenerateReport()
*/
public boolean canGenerateReport()
{
if ( !skip )
{
return this.classFilesDirectory.exists();
}
else
{
return false;
}
}
/**
* Returns the plugins description for the "generated reports" overview page.
*
* @param pLocale
* the locale the report should be generated for
*
* @return description of the report
* @see org.apache.maven.reporting.MavenReport#getDescription(java.util.Locale)
*/
public String getDescription( final Locale pLocale )
{
final ResourceBundle bundle = FindBugsMojo.getBundle( pLocale );
final String description = bundle.getString( FindBugsMojo.DESCRIPTION_KEY );
return description;
}
/**
* Returns the plugins name for the "generated reports" overview page and the menu.
*
* @param pLocale
* the locale the report should be generated for
*
* @return name of the report
* @see org.apache.maven.reporting.MavenReport#getName(java.util.Locale)
*/
public String getName( final Locale pLocale )
{
final ResourceBundle bundle = FindBugsMojo.getBundle( pLocale );
final String name = bundle.getString( FindBugsMojo.NAME_KEY );
return name;
}
/**
* Returns report output file name, without the extension.
*
* Called by AbstractMavenReport.execute() for creating the sink.
*
* @return name of the generated page
* @see org.apache.maven.reporting.MavenReport#getOutputName()
*/
public String getOutputName()
{
return FindBugsMojo.PLUGIN_NAME;
}
/**
* Adds the dependend libraries of the project to the findbugs aux classpath.
*
* @param findBugsProject
* The find bugs project to add the aux classpath entries.
* @throws DependencyResolutionRequiredException
* Exception that occurs when an artifact file is used, but has not been resolved.
*
*/
protected void addClasspathEntriesToFindBugsProject( final Project findBugsProject )
throws DependencyResolutionRequiredException
{
List auxClasspathElements = this.getProject().getCompileClasspathElements();
for ( int i = 0; i < auxClasspathElements.size(); ++i )
{
if ( this.getLog().isDebugEnabled() )
{
this.getLog().debug( " Trying to Add to AuxClasspath ->" + auxClasspathElements.get( i ).toString() );
}
findBugsProject.addAuxClasspathEntry( (String) auxClasspathElements.get( i ).toString() );
}
if ( this.getLog().isDebugEnabled() )
{
List findbugsAuxClasspath = findBugsProject.getAuxClasspathEntryList();
for ( int j = 0; j < findbugsAuxClasspath.size(); ++j )
{
this.getLog().debug( " Added to AuxClasspath ->" + findbugsAuxClasspath.get( j ).toString() );
}
}
}
/**
* Adds the specified filters of the project to the findbugs.
*
* @param findBugs
* The find bugs to add the filters.
* @throws IOException
* If filter file could not be read.
* @throws FilterException
* If filter file was invalid.
*
*/
protected void addFiltersToFindBugs( final FindBugs2 findBugs ) throws IOException, FilterException
{
if ( this.includeFilterFile != null )
{
if ( new File( this.includeFilterFile ).exists() )
{
findBugs.addFilter( this.includeFilterFile, true );
this.getLog().debug( " Using bug include filter " + this.includeFilterFile );
}
else
{
this.getLog().debug( " No bug include filter " + this.includeFilterFile + " found" );
}
}
else
{
this.getLog().info( " No bug include filter." );
}
if ( this.excludeFilterFile != null )
{
if ( new File( this.excludeFilterFile ).exists() )
{
findBugs.addFilter( this.excludeFilterFile, false );
this.getLog().debug( " Using bug exclude filter " + this.excludeFilterFile );
}
else
{
this.getLog().debug( " No bug exclude filter " + this.excludeFilterFile + " found" );
}
}
else
{
this.getLog().debug( " No bug exclude filter." );
}
}
/**
* Adds the source files to the find bugs project. The return value of the method call addFile
is
* omited, because we are not interested if the java source is already added.
*
* @param pSourceFiles
* The java sources (Type java.io.File
) to add to the project.
* @param findBugsProject
* The find bugs project to add the java source to.
*
*/
protected void addJavaSourcesToFindBugsProject( final List pSourceFiles, final Project findBugsProject )
{
final Iterator iterator = pSourceFiles.iterator();
while ( iterator.hasNext() )
{
final File currentSourceFile = (File) iterator.next();
final String filePath = currentSourceFile.getAbsolutePath();
findBugsProject.addFile( filePath );
}
}
/**
* Adds the specified plugins to findbugs. The coreplugin is always added first.
*
* @param pLocale
* The locale to print out the messages. Used here to get the nameof the coreplugin from the properties.
* @throws ArtifactNotFoundException
* If the coreplugin could not be found.
* @throws ArtifactResolutionException
* If the coreplugin could not be resolved.
* @throws MavenReportException
* If the findBugs plugins URL could not be resolved.
*
*/
protected void addClassScreenerToFindBugs( final FindBugs2 findBugs )
{
if ( this.onlyAnalyze != null )
{
this.getLog().debug( " Adding ClassScreener " );
// The argument is a comma-separated list of classes and packages
// to select to analyze. (If a list item ends with ".*",
// it specifies a package, otherwise it's a class.)
StringTokenizer stringToken = new StringTokenizer( this.onlyAnalyze, "," );
while ( stringToken.hasMoreTokens() )
{
String stringTokenItem = stringToken.nextToken();
if ( stringTokenItem.endsWith( ".-" ) )
{
classScreener.addAllowedPrefix( stringTokenItem.substring( 0, stringTokenItem.length() - 1 ) );
this.getLog().info(
" classScreener.addAllowedPrefix "
+ ( stringTokenItem.substring( 0, stringTokenItem.length() - 1 ) ) );
}
else if ( stringTokenItem.endsWith( ".*" ) )
{
classScreener.addAllowedPackage( stringTokenItem.substring( 0, stringTokenItem.length() - 1 ) );
this.getLog().info(
" classScreener.addAllowedPackage "
+ ( stringTokenItem.substring( 0, stringTokenItem.length() - 1 ) ) );
}
else
{
classScreener.addAllowedClass( stringTokenItem );
this.getLog().info( " classScreener.addAllowedClass " + stringTokenItem );
}
}
findBugs.setClassScreener( classScreener );
}
this.getLog().debug( " Done Adding Class Screeners" );
}
/**
* Adds the specified plugins to findbugs. The coreplugin is always added first.
*
* @param pLocale
* The locale to print out the messages. Used here to get the nameof the coreplugin from the properties.
* @throws ArtifactNotFoundException
* If the coreplugin could not be found.
* @throws ArtifactResolutionException
* If the coreplugin could not be resolved.
* @throws MavenReportException
* If the findBugs plugins URL could not be resolved.
*
*/
protected void addPluginsToFindBugs( final Locale pLocale )
throws ArtifactNotFoundException, ArtifactResolutionException, MavenReportException
{
URL corepluginpath = null;
try
{
corepluginpath = this.getCorePluginPath( pLocale ).toURL();
}
catch ( final MalformedURLException pException )
{
throw new MavenReportException( "The core plugin has an invalid URL", pException );
}
this.getLog().debug( " coreplugin Jar is located at " + corepluginpath.toString() );
URL[] plugins;
if ( this.pluginList != null )
{
this.getLog().debug( " Adding Plugins " );
final String[] pluginJars = this.pluginList.split( "," );
plugins = new URL[pluginJars.length + 1];
for ( int i = 0; i < pluginJars.length; i++ )
{
String pluginFile = pluginJars[i].trim();
if ( !pluginFile.endsWith( ".jar" ) )
{
throw new IllegalArgumentException( "Plugin File is not a Jar file: " + pluginFile );
}
try
{
plugins[i + 1] = new File( pluginFile ).toURL();
}
catch ( final MalformedURLException pException )
{
throw new MavenReportException( "The addin plugin has an invalid URL", pException );
}
this.getLog().debug( " Adding Plugin: " + plugins[i + 1].toString() );
}
}
else
{
plugins = new URL[1];
}
plugins[0] = corepluginpath;
DetectorFactoryCollection.rawInstance().setPluginList( plugins );
this.getLog().debug( " Done Adding Plugins" );
}
/**
* Adds the specified visitors to findbugs.
*
* @param preferences
* The find bugs UserPreferences.
*
*/
protected void addVisitorsToFindBugs( final UserPreferences preferences )
{
/*
* This is done in this order to make sure only one of vistors or omitVisitors options is run. This is
* consistent with the way the Findbugs commandline and Ant Tasks run.
*/
if ( this.visitors != null || this.omitVisitors != null )
{
boolean enableVisitor = true;
String[] visitorList;
if ( this.omitVisitors != null )
{
enableVisitor = false;
visitorList = this.omitVisitors.split( "," );
this.getLog().debug( " Omitting visitors : " + this.omitVisitors );
}
else
{
visitorList = this.visitors.split( "," );
this.getLog().debug( " Including visitors : " + this.visitors );
preferences.enableAllDetectors( false );
}
for ( int i = 0; i < visitorList.length; i++ )
{
String visitorName = visitorList[i].trim();
DetectorFactory factory = DetectorFactoryCollection.instance().getFactory( visitorName );
if ( factory == null )
{
throw new IllegalArgumentException( "Unknown detector: " + visitorName );
}
preferences.enableDetector( factory, enableVisitor );
}
}
}
/**
* Lists absolute paths of java source files for denugging purposes.
*
* @param pLocale
* The locale to print out the messages.
* @param pSourceFiles
* List of source files.
*/
protected void debugJavaSources( final Locale pLocale, final List pSourceFiles )
{
final ResourceBundle bundle = FindBugsMojo.getBundle( pLocale );
final String javaSourceMessage = bundle.getString( FindBugsMojo.JAVA_SOURCES_KEY );
this.getLog().debug( " " + javaSourceMessage );
final Iterator iterator = pSourceFiles.iterator();
while ( iterator.hasNext() )
{
final File currentFile = (File) iterator.next();
this.getLog().debug( " " + currentFile.getAbsolutePath() );
}
}
/**
* Prints out the source roots to the logger with severity debug.
*
* @param pLocale
* The locale to print out the messages.
* @param pSourceDirectory
* The source directory to print.
*
*/
protected void debugSourceDirectory( final Locale pLocale, final File pSourceDirectory )
{
final ResourceBundle bundle = FindBugsMojo.getBundle( pLocale );
final String sourceRootMessage = bundle.getString( FindBugsMojo.SOURCE_ROOT_KEY );
this.getLog().debug( " " + sourceRootMessage );
this.getLog().debug( " " + pSourceDirectory.getAbsolutePath() );
}
/**
* Executes the generation of the report.
*
* Callback from Maven Site Plugin or from AbstractMavenReport.execute() => generate().
*
* @param pLocale
* the locale the report should be generated for
* @throws MavenReportException
* if anything goes wrong
* @see org.apache.maven.reporting.AbstractMavenReport #executeReport(java.util.Locale)
*/
protected void executeReport( final Locale pLocale ) throws MavenReportException
{
if ( !skip )
{
FindBugs2 findBugs = null;
this.debugSourceDirectory( pLocale, this.classFilesDirectory );
if ( !canGenerateReport() )
{
getLog().info( "Output class directory doesn't exist. Skipping findbugs." );
return;
}
try
{
findBugs = this.initialiseFindBugs( pLocale, this.getJavaSources( pLocale, this.classFilesDirectory ) );
}
catch ( final IOException pException )
{
throw new MavenReportException( "A java source file could not be added", pException );
}
catch ( final DependencyResolutionRequiredException pException )
{
throw new MavenReportException( "Failed executing FindBugs", pException );
}
catch ( final FilterException pException )
{
throw new MavenReportException( "Failed adding filters to FindBugs", pException );
}
catch ( final ArtifactNotFoundException pException )
{
throw new MavenReportException( "Did not find coreplugin", pException );
}
catch ( final ArtifactResolutionException pException )
{
throw new MavenReportException( "Failed to resolve coreplugin", pException );
}
try
{
findBugs.execute();
}
catch ( final IOException pException )
{
throw new MavenReportException( "Failed executing FindBugs", pException );
}
catch ( final InterruptedException pException )
{
throw new MavenReportException( "Failed executing FindBugs", pException );
}
catch ( final Exception pException )
{
throw new MavenReportException( "Failed executing FindBugs", pException );
}
}
}
/**
* Retrieve the coreplugin module name
*
* @param pLocale
* The locale to print out the messages.
* @return corePluginName The coreplugin module name.
*
*/
protected String getCorePlugin( final Locale pLocale )
{
final ResourceBundle bundle = getBundle( pLocale );
final String corePluginName = bundle.getString( FINDBUGS_COREPLUGIN );
return corePluginName;
}
/**
* Get the File reference for the Findbugs core plugin.
*
* @param pLocale
* The locale of the messages.
* @return The File reference to the coreplugin JAR
* @throws ArtifactNotFoundException
* If the coreplugin could not be found.
* @throws ArtifactResolutionException
* If the coreplugin could not be resolved.
*
*/
protected File getCorePluginPath( final Locale pLocale )
throws ArtifactNotFoundException, ArtifactResolutionException
{
for ( Iterator it = this.pluginArtifacts.iterator(); it.hasNext(); )
{
final Artifact artifact = (Artifact) it.next();
if ( artifact.getArtifactId().equals( this.getCorePlugin( pLocale ) ) )
{
this.artifactResolver.resolve( artifact, this.remoteArtifactRepositories, this.localRepository );
return artifact.getFile();
}
}
return null;
}
/**
* Returns the effort parameter to use.
*
* @return A valid effort parameter.
*
*/
protected EffortParameter getEffortParameter()
{
EffortParameter effortParameter = EffortParameter.DEFAULT;
if ( this.effort == null )
{
this.getLog().info( " No effort provided, using default effort." );
}
else
{
if ( this.effort.equals( EffortParameter.MAX.getName() ) )
{
effortParameter = EffortParameter.MAX;
this.getLog().info( " Using maximum effort." );
}
else if ( this.effort.equals( EffortParameter.DEFAULT.getName() ) )
{
effortParameter = EffortParameter.DEFAULT;
this.getLog().info( " Using normal effort." );
}
else if ( this.effort.equals( EffortParameter.MIN.getName() ) )
{
effortParameter = EffortParameter.MIN;
this.getLog().info( " Using minimum effort." );
}
else
{
this.getLog().info( " Effort not recognised, using default effort" );
}
}
return effortParameter;
}
/**
* Collects the java sources from the source roots.
*
* @param pSourceDirectory
* The source directory to search for java sources.
* @param pLocale
* The locale to print out the messages.
* @return A list containing the java sources or an empty list if no java sources are found.
* @throws IOException
* If there are problems searching for java sources.
*
*/
protected List getJavaSources( final Locale pLocale, final File pSourceDirectory ) throws IOException
{
final List sourceFiles = new ArrayList();
if ( pSourceDirectory.exists() && pSourceDirectory.isDirectory() )
{
final List files = FileUtils.getFiles( pSourceDirectory, FindBugsMojo.JAVA_REGEX_PATTERN, null );
sourceFiles.addAll( files );
}
this.debugJavaSources( pLocale, sourceFiles );
return sourceFiles;
}
/**
* Returns the report output directory.
*
* Called by AbstractMavenReport.execute() for creating the sink.
*
* @return full path to the directory where the files in the site get copied to
* @see org.apache.maven.reporting.AbstractMavenReport#getOutputDirectory()
*/
protected String getOutputDirectory()
{
new File( this.outputDirectory ).mkdirs();
return this.outputDirectory;
}
/**
* Returns the maven project.
*
* @return the maven project
* @see org.apache.maven.reporting.AbstractMavenReport#getProject()
*/
protected MavenProject getProject()
{
return this.project;
}
/**
* Returns the doxia site renderer.
*
* @return the doxia Renderer
* @see org.apache.maven.reporting.AbstractMavenReport#getSiteRenderer()
*/
protected Renderer getSiteRenderer()
{
return this.siteRenderer;
}
/**
* Returns the threshold parameter to use.
*
* @return A valid threshold parameter.
*
*/
protected ThresholdParameter getThresholdParameter()
{
ThresholdParameter thresholdParameter = ThresholdParameter.DEFAULT;
if ( this.threshold == null )
{
this.getLog().info( " No threshold provided, using default threshold." );
}
else
{
if ( this.threshold.equals( ThresholdParameter.HIGH.getName() ) )
{
thresholdParameter = ThresholdParameter.HIGH;
this.getLog().info( " Using high threshold." );
}
else if ( this.threshold.equals( ThresholdParameter.NORMAL.getName() ) )
{
thresholdParameter = ThresholdParameter.NORMAL;
this.getLog().info( " Using normal threshold." );
}
else if ( this.threshold.equals( ThresholdParameter.LOW.getName() ) )
{
thresholdParameter = ThresholdParameter.LOW;
this.getLog().info( " Using low threshold." );
}
else if ( this.threshold.equals( ThresholdParameter.EXP.getName() ) )
{
thresholdParameter = ThresholdParameter.EXP;
this.getLog().info( " Using exp threshold." );
}
else if ( this.threshold.equals( ThresholdParameter.IGNORE.getName() ) )
{
thresholdParameter = ThresholdParameter.IGNORE;
this.getLog().info( " Using ignore threshold." );
}
else
{
this.getLog().info( " Threshold not recognised, using default threshold" );
}
}
return thresholdParameter;
}
/**
* Initialise FindBugs.
*
* @param pLocale
* The locale.
* @param pSourceFiles
* The source files FindBugs should analyse.
* @return An initialised FindBugs object.
* @throws DependencyResolutionRequiredException
* Exception that occurs when an artifact file is used, but has not been resolved.
* @throws IOException
* If filter file could not be read.
* @throws FilterException
* If filter file was invalid.
* @throws ArtifactNotFoundException
* If the coreplugin could not be found.
* @throws ArtifactResolutionException
* If the coreplugin could not be resolved.
* @throws MavenReportException
* If the findBugs plugins cannot be initialized
*
*/
protected FindBugs2 initialiseFindBugs( final Locale pLocale, final List pSourceFiles )
throws DependencyResolutionRequiredException, IOException, FilterException, ArtifactNotFoundException,
ArtifactResolutionException, MavenReportException
{
final Sink sink = this.getSink();
final ResourceBundle bundle = FindBugsMojo.getBundle( pLocale );
final Log log = this.getLog();
final EffortParameter effortParameter = this.getEffortParameter();
final Project findBugsProject = new Project();
this.getLog().info( " Using FindBugs Version: " + edu.umd.cs.findbugs.Version.RELEASE );
this.bugReporter = this.initialiseReporter( sink, bundle, log, effortParameter );
if ( this.xmlOutput )
{
this.getLog().info( " Using the xdoc format" );
if ( !this.xmlOutputDirectory.exists() )
{
if ( !this.xmlOutputDirectory.mkdirs() )
{
throw new MavenReportException( "Cannot create xml output directory" );
}
}
BugReporter htmlBugReporter = this.bugReporter;
this.bugReporter = new XDocsReporter( htmlBugReporter );
( (XDocsReporter) this.bugReporter ).setOutputWriter( new FileWriter( new File( this.xmlOutputDirectory
+ "/findbugs.xml" ) ) );
( (XDocsReporter) this.bugReporter ).setResourceBundle( bundle );
( (XDocsReporter) this.bugReporter ).setLog( log );
( (XDocsReporter) this.bugReporter ).setEffort( this.getEffortParameter() );
( (XDocsReporter) this.bugReporter ).setThreshold( this.getThresholdParameter() );
}
this.addJavaSourcesToFindBugsProject( pSourceFiles, findBugsProject );
this.addClasspathEntriesToFindBugsProject( findBugsProject );
final FindBugs2 findBugs = new FindBugs2();
findBugs.setBugReporter( this.bugReporter );
findBugs.setProject( findBugsProject );
if ( !pluginLoaded )
{
this.addPluginsToFindBugs( pLocale );
pluginLoaded = true;
}
final UserPreferences preferences = UserPreferences.createDefaultUserPreferences();
this.addVisitorsToFindBugs( preferences );
findBugs.setRelaxedReportingMode( this.relaxed.booleanValue() );
findBugs.setUserPreferences( preferences );
findBugs.setAnalysisFeatureSettings( effortParameter.getValue() );
findBugs.setDetectorFactoryCollection( DetectorFactoryCollection.rawInstance() );
this.setFindBugsDebug( findBugs );
this.addFiltersToFindBugs( findBugs );
this.addClassScreenerToFindBugs( findBugs );
return findBugs;
}
/**
* Initialises a reporter.
*
* @param pSink
* The sink to write the report to.
* @param pBundle
* The bundle to get messages from.
* @param pLog
* The logger to write logs to.
* @param pEffortParameter
* The effort to use.
* @return An initialised reporter.
*
*/
protected Reporter initialiseReporter( final Sink pSink, final ResourceBundle pBundle, final Log pLog,
final EffortParameter pEffortParameter )
{
ThresholdParameter thresholdParameter = this.getThresholdParameter();
final boolean isJXRPluginEnabled = this.isJXRPluginEnabled( pBundle );
final Reporter bugReporter =
new Reporter( pSink, pBundle, pLog, thresholdParameter, isJXRPluginEnabled, pEffortParameter );
bugReporter.setPriorityThreshold( thresholdParameter.getValue() );
return bugReporter;
}
/**
* Determines if the JXR-Plugin is included in the report section of the POM.
*
* @param pBundle
* The bundle to load the artifactIf of the jxr plugin.
* @return True if the JXR-Plugin is included in the POM, false otherwise.
*
*/
protected boolean isJXRPluginEnabled( final ResourceBundle pBundle )
{
boolean isEnabled = false;
final String artifactId = pBundle.getString( FindBugsMojo.JXR_ARTIFACT_ID_KEY );
final List reportPlugins = this.getProject().getReportPlugins();
final Iterator iterator = reportPlugins.iterator();
while ( iterator.hasNext() )
{
final ReportPlugin currentPlugin = (ReportPlugin) iterator.next();
final String currentArtifactId = currentPlugin.getArtifactId();
if ( artifactId.equals( currentArtifactId ) )
{
isEnabled = true;
}
}
return isEnabled;
}
/**
* Sets the Debug Level
*
* @param findBugs
* The find bugs to add debug level information.
*
*/
protected void setFindBugsDebug( final FindBugs2 findBugs )
{
System.setProperty( "findbugs.classpath.debug", this.debug.toString() );
System.setProperty( "findbugs.debug", this.debug.toString() );
if ( this.debug.booleanValue() )
{
this.getLog().info( " Debugging is On" );
}
else
{
this.getLog().info( " Debugging is Off" );
}
}
/**
* Returns the resource bundle for a specific locale.
*
* @param pLocale
* The locale to get the bundle for.
* @return A resource Bundle.
*
*/
protected static ResourceBundle getBundle( final Locale pLocale )
{
final ClassLoader loader = FindBugsMojo.class.getClassLoader();
final ResourceBundle bundle = ResourceBundle.getBundle( FindBugsMojo.BUNDLE_NAME, pLocale, loader );
return bundle;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy