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

org.codehaus.mojo.findbugs.FindBugsMojo.groovy Maven / Gradle / Ivy

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

/*
 * 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.
 */

import org.apache.maven.artifact.Artifact
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.repository.ArtifactRepository
import org.apache.maven.artifact.resolver.ArtifactResolver
import org.apache.maven.doxia.siterenderer.Renderer
import org.apache.maven.doxia.tools.SiteTool

import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.LifecyclePhase
import org.apache.maven.plugins.annotations.Mojo
import org.apache.maven.plugins.annotations.Parameter
import org.apache.maven.plugins.annotations.ResolutionScope

import org.apache.maven.plugin.MojoExecutionException

import org.apache.maven.project.MavenProject
import org.apache.maven.reporting.AbstractMavenReport
import org.codehaus.plexus.resource.ResourceManager
import org.codehaus.plexus.resource.loader.FileResourceCreationException
import org.codehaus.plexus.resource.loader.FileResourceLoader

import groovy.xml.StreamingMarkupBuilder
import org.codehaus.plexus.util.FileUtils

import org.sonatype.plexus.build.incremental.BuildContext


/**
 * Generates a FindBugs Report when the site plugin is run.
 * The HTML report is generated for site commands only.
 *
 *
 * @author Garvin LeClaire
 * @version $Id: FindBugsMojo.groovy 16932 2012-06-21 01:13:14Z gleclaire $
 */

@Mojo(name = "findbugs", defaultPhase = LifecyclePhase.COMPILE, requiresDependencyResolution = ResolutionScope.COMPILE, requiresProject = true, threadSafe = true)
class FindBugsMojo extends AbstractMavenReport {

    /**
     * Location where generated html will be created.
     *
     */

    @Parameter(defaultValue = '${project.reporting.outputDirectory}', required = true)
    File outputDirectory

    /**
     * Turn on and off xml output of the Findbugs report.
     *
     * @since 1.0.0
     */
    @Parameter(defaultValue = "false", property = "findbugs.xmlOutput", required = true)
    boolean xmlOutput

    /**
     * Specifies the directory where the xml output will be generated.
     *
     * @since 1.0.0
     */
    @Parameter(defaultValue = '${project.build.directory}', required = true)
    File xmlOutputDirectory

    /**
     * This has been deprecated and is on by default.
     *
     * @since 1.2.0
     *
     */
    @Deprecated
    @Parameter(defaultValue = "true")
    boolean findbugsXmlOutput

    /**
     * Specifies the directory where the findbugs native xml output will be generated.
     *
     * @since 1.2.0
     */
    @Parameter(defaultValue = '${project.build.directory}', required = true)
    File findbugsXmlOutputDirectory

    /**
     * Doxia Site Renderer.
     *
     * @component
     *
     */
    @Component(role = Renderer.class)
    Renderer siteRenderer

    /**
     * Directory containing the class files for FindBugs to analyze.
     *
     * @required
     */
    @Parameter(defaultValue = '${project.build.outputDirectory}', required = true)
    File classFilesDirectory

    /**
     * Directory containing the test class files for FindBugs to analyze.
     *
     */
    @Parameter(defaultValue = '${project.build.testOutputDirectory}', required = true)
    File testClassFilesDirectory

    /**
     * Location of the Xrefs to link to.
     *
     */
    @Parameter(defaultValue = '${project.reporting.outputDirectory}/xref')
    File xrefLocation

    /**
     * Location of the Test Xrefs to link to.
     *
     */
    @Parameter(defaultValue = '${project.reporting.outputDirectory}/xref-test')
    File xrefTestLocation

    /**
     * The directories containing the sources to be compiled.
     *
     */
    @Parameter(defaultValue = '${project.compileSourceRoots}', required = true, readonly = true)
    List compileSourceRoots

    /**
     * The directories containing the test-sources to be compiled.
     *
     * @since 2.0
     */
    @Parameter(defaultValue = '${project.testCompileSourceRoots}', required = true, readonly = true)
    List testSourceRoots

    /**
     * Run Findbugs on the tests.
     *
     * @since 2.0
     */
    @Parameter(defaultValue = "false", property = "findbugs.includeTests")
    boolean includeTests

    /**
     * List of artifacts this plugin depends on. Used for resolving the Findbugs coreplugin.
     *
     */
    @Parameter(property = "plugin.artifacts", required = true, readonly = true)
    ArrayList pluginArtifacts

    /**
     * List of Remote Repositories used by the resolver
     *
     */
    @Parameter(property = "project.remoteArtifactRepositories", required = true, readonly = true)
    List remoteRepositories

    /**
     * The local repository, needed to download the coreplugin jar.
     *
     */
    @Parameter(property = "localRepository", required = true, readonly = true)
    ArtifactRepository localRepository

    /**
     * Remote repositories which will be searched for the coreplugin jar.
     *
     */
    @Parameter(property = "project.remoteArtifactRepositories", required = true, readonly = true)
    List remoteArtifactRepositories

    /**
     * Maven Project
     *
     */
    @Parameter(property = "project", required = true, readonly = true)
    MavenProject project

    /**
     * Encoding used for xml files. Default value is UTF-8.
     *
     */
    @Parameter(defaultValue = "UTF-8", readonly = true)
    String xmlEncoding

    /**
     * The file encoding to use when reading the source files. If the property project.build.sourceEncoding
     * is not set, the platform default encoding is used.
     *
     * @since 2.2
     */
    @Parameter(defaultValue = '${project.build.sourceEncoding}', property = "encoding")
    String sourceEncoding

    /**
     * The file encoding to use when creating the HTML reports. If the property project.reporting.outputEncoding
     * is not set, the platform default encoding is used.
     *
     * @since 2.2
     */
    @Parameter(defaultValue = '${project.reporting.outputEncoding}', property = "outputEncoding")
    String outputEncoding

    /**
     * Threshold of minimum bug severity to report. Valid values are High, Default, Low, Ignore, and Exp (for experimental).
     *
     */
    @Parameter(defaultValue = "Default", property = "findbugs.threshold")
    String threshold

    /**
     * Artifact resolver, needed to download the coreplugin jar.
     *
     * @required
     * @readonly
     */
    @Component(role = org.apache.maven.artifact.resolver.ArtifactResolver.class)
    ArtifactResolver artifactResolver

    /**
     * Used to look up Artifacts in the remote repository.
     *
     */
    @Parameter(property = "component.org.apache.maven.artifact.factory.ArtifactFactory", required = true, readonly = true)
    ArtifactFactory factory

    /**
     * 

* File name of the include filter. Only bugs in matching the filters are reported. *

* *

* Potential values are a filesystem path, a URL, or a classpath resource. *

* *

* This parameter is resolved as resource, URL, then file. If successfully * resolved, the contents of the configuration is copied into the * ${project.build.directory} * directory before being passed to Findbugs as a filter file. *

* * @since 1.0-beta-1 */ @Parameter(property = "findbugs.includeFilterFile") String includeFilterFile /** *

* File name of the exclude filter. Bugs matching the filters are not reported. *

* *

* Potential values are a filesystem path, a URL, or a classpath resource. *

* *

* This parameter is resolved as resource, URL, then file. If successfully * resolved, the contents of the configuration is copied into the * ${project.build.directory} * directory before being passed to Findbugs as a filter file. *

* * @since 1.0-beta-1 */ @Parameter(property = "findbugs.excludeFilterFile") String excludeFilterFile /** *

* File names of the baseline files. Bugs found in the baseline files won't be reported. *

* *

* Potential values are a filesystem path, a URL, or a classpath resource. *

* *

* This parameter is resolved as resource, URL, then file. If successfully * resolved, the contents of the configuration is copied into the * ${project.build.directory} * directory before being passed to Findbugs as a filter file. *

* * This is a comma-delimited list. * * @since 2.4.1 */ @Parameter(property = "findbugs.excludeBugsFile") String excludeBugsFile /** * Effort of the bug finders. Valid values are Min, Default and Max. * * @since 1.0-beta-1 */ @Parameter(defaultValue = "Default", property = "findbugs.effort") String effort /** * turn on Findbugs debugging * */ @Parameter(defaultValue = "false", property = "findbugs.debug") Boolean debug /** * Relaxed reporting mode. For many detectors, this option suppresses the heuristics used to avoid reporting false * positives. * * @since 1.1 */ @Parameter(defaultValue = "false", property = "findbugs.relaxed") Boolean relaxed /** * The visitor list to run. This is a comma-delimited list. * * @since 1.0-beta-1 */ @Parameter(property = "findbugs.visitors") String visitors /** * The visitor list to omit. This is a comma-delimited list. * * @since 1.0-beta-1 */ @Parameter(property = "findbugs.omitVisitors") String omitVisitors /** *

* The plugin list to include in the report. This is a comma-delimited list. *

* *

* Potential values are a filesystem path, a URL, or a classpath resource. *

* *

* This parameter is resolved as resource, URL, then file. If successfully * resolved, the contents of the configuration is copied into the * ${project.build.directory} * directory before being passed to Findbugs as a plugin file. *

* * @since 1.0-beta-1 */ @Parameter(property = "findbugs.pluginList") String pluginList /** *

* Collection of PluginArtifact to work on. (PluginArtifact contains groupId, artifactId, version, type.) * See Usage for details. *

* * * @since 2.4.1 */ @Parameter PluginArtifact[] plugins; /** * Restrict analysis to the given comma-separated list of classes and packages. * * @since 1.1 */ @Parameter(property = "findbugs.onlyAnalyze") String onlyAnalyze /** * This option enables or disables scanning of nested jar and zip files found * in the list of files and directories to be analyzed. * * @since 2.3.2 */ @Parameter(property = "findbugs.nested", defaultValue = "false") Boolean nested /** * Prints a trace of detectors run and classes analyzed to standard output. * Useful for troubleshooting unexpected analysis failures. * * @since 2.3.2 */ @Parameter(property = "findbugs.trace", defaultValue = "false") Boolean trace /** * Maximum bug ranking to record. * * @since 2.4.1 */ @Parameter(property = "findbugs.maxRank") int maxRank /** * Skip entire check. * * @since 1.1 */ @Parameter(property = "findbugs.skip", defaultValue = "false") boolean skip /** * @required * @readonly * @since 2.0 */ @Component(role = ResourceManager.class) ResourceManager resourceManager /** * SiteTool. * * @since 2.1-SNAPSHOT * @required * @readonly */ @Component(role = org.apache.maven.doxia.tools.SiteTool.class) SiteTool siteTool /** * Fail the build on an error. * * @since 2.0 */ @Parameter(property = "findbugs.failOnError", defaultValue = "true") boolean failOnError /** * Fork a VM for FindBugs analysis. This will allow you to set timeouts and heap size * * @since 2.3.2 */ @Parameter(property = "findbugs.fork", defaultValue = "true") boolean fork /** * Maximum Java heap size in megabytes (default=512). * This only works if the fork parameter is set true. * * @since 2.2 */ @Parameter(property = "findbugs.maxHeap", defaultValue = "512") int maxHeap /** * Specifies the amount of time, in milliseconds, that FindBugs may run before * it is assumed to be hung and is terminated. * The default is 600,000 milliseconds, which is ten minutes. * This only works if the fork parameter is set true. * * @since 2.2 */ @Parameter(property = "findbugs.timeout", defaultValue = "600000") int timeout /** *

* the arguments to pass to the forked VM (ignored if fork is disabled). *

* * @since 2.4.1 */ @Parameter(property = "findbugs.jvmArgs") String jvmArgs /** * Skip the FindBugs HTML report generation if there are no violations found. Defaults to * false. * * @since 3.0.1 */ @Parameter(property = "findbugs.skipEmptyReport", defaultValue = "false") boolean skipEmptyReport int bugCount int errorCount ResourceBundle bundle File outputFindbugsFile /** * 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() */ boolean canGenerateReport() { def canGenerate = false log.debug("****** FindBugsMojo canGenerateReport *******") if (!skip && classFilesDirectory.exists()) { classFilesDirectory.eachFileRecurse { if (it.name.contains(FindBugsInfo.CLASS_SUFFIX)) { canGenerate = true } } log.debug("canGenerate Src is ${canGenerate}") } if (!skip && testClassFilesDirectory.exists() && includeTests) { testClassFilesDirectory.eachFileRecurse { if (it.name.contains(FindBugsInfo.CLASS_SUFFIX)) { canGenerate = true } } log.debug("canGenerate Test Src is ${canGenerate}") } if (canGenerate && outputFindbugsFile == null) { outputFindbugsFile = new File("${findbugsXmlOutputDirectory}/findbugsXml.xml") ClassLoader tccl = Thread.currentThread().getContextClassLoader(); try { // The SAX parser factory will fail with CCE if the TCCL is out of sync with our class loader // This for Maven 2.2.1 only MFINDBUGS-178 Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); executeFindbugs(outputFindbugsFile) } finally { Thread.currentThread().setContextClassLoader(tccl); } if (skipEmptyReport && bugCount == 0) { canGenerate = false } } log.debug("canGenerate is ${canGenerate}") return canGenerate } /** * Returns the plugins description for the "generated reports" overview page. * * @param locale * the locale the report should be generated for * * @return description of the report * @see org.apache.maven.reporting.MavenReport#getDescription(java.util.Locale) */ String getDescription(Locale locale) { return getBundle(locale).getString(FindBugsInfo.DESCRIPTION_KEY) } /** * Returns the plugins name for the "generated reports" overview page and the menu. * * @param locale * the locale the report should be generated for * * @return name of the report * @see org.apache.maven.reporting.MavenReport#getName(java.util.Locale) */ String getName(Locale locale) { return getBundle(locale).getString(FindBugsInfo.NAME_KEY) } /** * 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() */ String getOutputName() { return FindBugsInfo.PLUGIN_NAME } /** * Executes the generation of the report. * * Callback from Maven Site Plugin. * * @param locale he wanted locale to generate the report, could be null. * * @see org.apache.maven.reporting.MavenReport #executeReport(java.util.Locale) */ void executeReport(Locale locale) { log.debug("****** FindBugsMojo executeReport *******") executeCheck(locale) if (!skip && canGenerateReport()) { log.debug("Locale is ${locale.getLanguage()}") log.debug("****** FindBugsMojo executeReport *******") log.debug("report Output Directory is " + getReportOutputDirectory()) log.debug("Output Directory is " + outputDirectory) log.debug("Classes Directory is " + classFilesDirectory) log.debug(" Plugin Artifacts to be added ->" + pluginArtifacts.toString()) generateXDoc(locale) if (!outputDirectory.exists()) { if (!outputDirectory.mkdirs()) { throw new MojoExecutionException("Cannot create html output directory") } } if (outputFindbugsFile != null && outputFindbugsFile.exists()) { if (skipEmptyReport && bugCount == 0) { log.info("Skipping Generation Findbugs HTML since there are not any bugs") } else { log.debug("Generating Findbugs HTML") FindbugsReportGenerator generator = new FindbugsReportGenerator(getSink(), getBundle(locale), this.project.getBasedir(), siteTool) boolean isJxrPluginEnabled = isJxrPluginEnabled() generator.setIsJXRReportEnabled(isJxrPluginEnabled) if (isJxrPluginEnabled) { generator.setCompileSourceRoots(this.compileSourceRoots) generator.setTestSourceRoots(this.testSourceRoots) generator.setXrefLocation(this.xrefLocation) generator.setXrefTestLocation(this.xrefTestLocation) generator.setIncludeTests(this.includeTests) } generator.setLog(log) generator.threshold = threshold generator.effort = effort generator.setFindbugsResults(new XmlSlurper().parse(outputFindbugsFile)) generator.setOutputDirectory(new File(outputDirectory.getAbsolutePath())) generator.generateReport() log.debug("xmlOutput is ${xmlOutput}") } } } else { log.info("cannot generate report"); } } public void execute() { log.debug("****** FindBugsMojo execute *******") Locale locale = new Locale("pt", "BR") if (!skip) { executeCheck(locale) if (canGenerateReport()) { generateXDoc(locale) } } } private void executeCheck(Locale locale) { log.debug("****** FindBugsMojo executeCheck *******") log.debug("Generating Findbugs XML") if (!findbugsXmlOutputDirectory.exists()) { if (!findbugsXmlOutputDirectory.mkdirs()) { throw new MojoExecutionException("Cannot create xml output directory") } } } private void generateXDoc(Locale locale) { log.debug("****** FindBugsMojo generateXDoc *******") if (outputFindbugsFile != null && outputFindbugsFile.exists()) { log.debug("xmlOutput is ${xmlOutput}") if (xmlOutput) { log.debug(" Using the xdoc format") if (!xmlOutputDirectory.exists()) { if (!xmlOutputDirectory.mkdirs()) { throw new MojoExecutionException("Cannot create xdoc output directory") } } XDocsReporter xDocsReporter = new XDocsReporter(getBundle(locale), log, threshold, effort, outputEncoding) xDocsReporter.setOutputWriter(new OutputStreamWriter(new FileOutputStream(new File("${xmlOutputDirectory}/findbugs.xml")), outputEncoding)) xDocsReporter.setFindbugsResults(new XmlSlurper().parse(outputFindbugsFile)) xDocsReporter.setCompileSourceRoots(this.compileSourceRoots) xDocsReporter.setTestSourceRoots(this.testSourceRoots) xDocsReporter.generateReport() } } } /** * 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() { return outputDirectory.getAbsolutePath() } /** * Return the project. * * @return the project. * @see org.apache.maven.reporting.AbstractMavenReport#getProject() */ protected MavenProject getProject() { return this.project } /** * Return the Site Renderer. * */ protected Renderer getSiteRenderer() { return this.siteRenderer } /** * Determines if the JXR-Plugin is included in the report section of the POM. * * @param bundle * 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() { boolean isEnabled = false if (xrefLocation.exists()) { isEnabled = true return isEnabled } List reportPlugins = getProject().getReportPlugins() reportPlugins.each() { reportPlugin -> log.debug("report plugin -> ${reportPlugin.getArtifactId()}") if ("maven-jxr-plugin".equals(reportPlugin.getArtifactId()) || "jxr-maven-plugin".equals(reportPlugin.getArtifactId())) { isEnabled = true } } log.debug("jxr report links are ${isEnabled ? "enabled" : "disabled"}") return isEnabled } ResourceBundle getBundle(locale) { this.bundle = ResourceBundle.getBundle(FindBugsInfo.BUNDLE_NAME, locale, FindBugsMojo.class.getClassLoader()) log.debug("Mojo Locale is " + this.bundle.getLocale().getLanguage()) return bundle } /** * Get the Findbugs command line arguments. * * @param Findbugs temp output file * * @return Findbugs command line arguments. * */ private ArrayList getFindbugsArgs(File tempFile) { def args = new ArrayList() args << "-xml:withMessages" args << "-auxclasspathFromInput" args << "-projectName" args << "${project.name}" args << getEffortParameter() args << getThresholdParameter() if (debug) { log.debug("progress on") args << "-progress" } if (pluginList || plugins) { args << "-pluginList" args << getFindbugsPlugins() } if (visitors) { args << "-visitors" args << visitors } if (omitVisitors) { args << "-omitVisitors" args << omitVisitors } if (relaxed) { args << "-relaxed" } if (nested) { args << "-nested:true" } else { args << "-nested:false" } if (onlyAnalyze) { args << "-onlyAnalyze" args << onlyAnalyze } if (includeFilterFile) { log.debug(" Adding Include Filter File ") args << "-include" args << getResourceFile(includeFilterFile.trim()) } if (excludeFilterFile) { log.debug(" Adding Exclude Filter File ") args << "-exclude" args << getResourceFile(excludeFilterFile.trim()) } if (excludeBugsFile) { log.debug(" Adding Exclude Bug Files (Baselines)") String[] excludeFiles = excludeBugsFile.split(FindBugsInfo.COMMA) excludeFiles.each() { excludeFile -> args << "-excludeBugs" args << getResourceFile(excludeFile.trim()) } } if (maxRank) { args << "-maxRank" args << maxRank } args << "-output" args << tempFile.getAbsolutePath() if (classFilesDirectory.exists() && classFilesDirectory.isDirectory()) { log.debug(" Adding to Source Directory ->" + classFilesDirectory.absolutePath) args << classFilesDirectory.absolutePath } if (testClassFilesDirectory.exists() && testClassFilesDirectory.isDirectory() && includeTests) { log.debug(" Adding to Source Directory ->" + testClassFilesDirectory.absolutePath) args << testClassFilesDirectory.absolutePath } return args } /** * Get the Findbugs AuxClasspath. * */ private String getFindbugsAuxClasspath() { def auxClasspathElements if (classFilesDirectory.exists() && classFilesDirectory.isDirectory()) { auxClasspathElements = project.compileClasspathElements } if (testClassFilesDirectory.exists() && testClassFilesDirectory.isDirectory() && includeTests) { auxClasspathElements = project.testClasspathElements } def auxClasspath = "" pluginArtifacts.each() { pluginArtifact -> log.debug(" Adding to AuxClasspath ->" + pluginArtifact.file.toString()) auxClasspath += pluginArtifact.file.toString() + ((pluginArtifact == pluginArtifacts[pluginArtifacts.size() - 1]) ? "" : File.pathSeparator) } log.debug(" auxClasspathElements -> ${auxClasspathElements}") if (auxClasspathElements) { log.debug(" AuxClasspath Elements ->" + auxClasspathElements) def auxClasspathList = auxClasspathElements.findAll { project.build.outputDirectory != it.toString() } if (auxClasspathList.size() > 0) { auxClasspath += File.pathSeparator log.debug(" Last AuxClasspath is ->" + auxClasspathList[auxClasspathList.size() - 1]) auxClasspathList.each() { auxClasspathElement -> log.debug(" Adding to AuxClasspath ->" + auxClasspathElement.toString()) auxClasspath += auxClasspathElement.toString() + ((auxClasspathElement == auxClasspathList[auxClasspathList.size() - 1]) ? "" : File.pathSeparator) } } } log.debug(" AuxClasspath is ->" + auxClasspath) return auxClasspath } /** * Set up and run the Findbugs engine. * * @param locale * the locale the report should be generated for * */ private void executeFindbugs(File outputFile) { log.debug("****** FindBugsMojo executeFindbugs *******") long startTime, duration File tempFile = new File("${project.build.directory}/findbugsTemp.xml") if (tempFile.exists()) { tempFile.delete() } tempFile.getParentFile().mkdirs() tempFile.createNewFile() outputEncoding = outputEncoding ?: 'UTF-8' log.debug("****** Executing FindBugsMojo *******") resourceManager.addSearchPath(FileResourceLoader.ID, project.getFile().getParentFile().getAbsolutePath()) resourceManager.addSearchPath(FindBugsInfo.URL, "") resourceManager.setOutputDirectory(new File(project.getBuild().getDirectory())) log.debug("resourceManager outputDirectory is ${resourceManager.outputDirectory}") log.debug(" Plugin Artifacts to be added -> ${pluginArtifacts.toString()}") log.debug("outputFile is " + outputFile.getCanonicalPath()) log.debug("output Directory is " + findbugsXmlOutputDirectory.getAbsolutePath()) log.debug("Temp File is " + tempFile.getCanonicalPath()) def ant = new AntBuilder() log.info("Fork Value is ${fork}") if (log.isDebugEnabled()) { startTime = System.nanoTime() } def findbugsArgs = getFindbugsArgs(tempFile) ant.java(classname: "edu.umd.cs.findbugs.FindBugs2", inputstring: getFindbugsAuxClasspath(), fork: "${fork}", failonerror: "true", clonevm: "false", timeout: "${timeout}", maxmemory: "${maxHeap}m") { def effectiveEncoding = System.getProperty("file.encoding", "UTF-8") if (sourceEncoding) { effectiveEncoding = sourceEncoding } log.debug("File Encoding is " + effectiveEncoding) sysproperty(key: "file.encoding", value: effectiveEncoding) if (jvmArgs && fork) { log.debug("Adding JVM Args => ${jvmArgs}") String[] args = jvmArgs.split(FindBugsInfo.BLANK) args.each() { jvmArg -> log.debug("Adding JVM Arg => ${jvmArg}") jvmarg(value: jvmArg) } } if (debug || trace) { sysproperty(key: "findbugs.debug", value: true) } classpath() { pluginArtifacts.each() { pluginArtifact -> log.debug(" Adding to pluginArtifact ->" + pluginArtifact.file.toString()) pathelement(location: pluginArtifact.file) } } findbugsArgs.each { findbugsArg -> log.debug("Findbugs arg is ${findbugsArg}") arg(value: findbugsArg) } } if (log.isDebugEnabled()) { duration = (System.nanoTime() - startTime) / 1000000000.00 log.debug("FindBugs duration is ${duration}") } log.info("Done FindBugs Analysis....") if (tempFile.exists()) { if (tempFile.size() > 0) { def path = new XmlSlurper().parse(tempFile) def allNodes = path.depthFirst().collect { it } bugCount = allNodes.findAll { it.name() == 'BugInstance' }.size() log.debug("BugInstance size is ${bugCount}") errorCount = allNodes.findAll { it.name() == 'Error' }.size() log.debug("Error size is ${errorCount}") def xmlProject = path.Project compileSourceRoots.each() { compileSourceRoot -> xmlProject.appendNode { SrcDir(compileSourceRoot) } } if (testClassFilesDirectory.exists() && testClassFilesDirectory.isDirectory() && includeTests) { testSourceRoots.each() { testSourceRoot -> xmlProject.appendNode { SrcDir(testSourceRoot) } } } path.FindbugsResults.FindBugsSummary.'total_bugs' = bugCount // Fixes visitor problem xmlProject.appendNode { WrkDir(project.build.directory) } def xmlBuilder = new StreamingMarkupBuilder() if (outputFile.exists()) { outputFile.delete() } outputFile.getParentFile().mkdirs() outputFile.createNewFile() outputFile.write "\n" outputFile << xmlBuilder.bind { mkp.yield path } } else { log.info("No bugs found") } if (!log.isDebugEnabled()) { tempFile.delete() } } } /** * Returns the threshold parameter to use. * * @return A valid threshold parameter. * */ protected String getThresholdParameter() { log.debug("threshold is ${threshold}") String thresholdParameter switch (threshold) { case "High": thresholdParameter = "-high"; break case "Exp": thresholdParameter = "-experimental"; break case "Low": thresholdParameter = "-low"; break case "high": thresholdParameter = "-high"; break default: thresholdParameter = "-medium"; break } log.debug("thresholdParameter is ${thresholdParameter}") return thresholdParameter } /** * Returns the effort parameter to use. * * @return A valid effort parameter. * */ protected String getEffortParameter() { log.debug("effort is ${effort}") String effortParameter switch (effort) { case "Max": effortParameter = "max"; break case "Min": effortParameter = "min"; break default: effortParameter = "default"; break } log.debug("effortParameter is ${effortParameter}") return "-effort:" + effortParameter } /** * Get the File reference for a File passed in as a string reference. * * @param resource * The file for the resource manager to locate * @return The File of the resource * */ protected File getResourceFile(String resource) { assert resource String location = null String artifact = resource if (resource.indexOf(FindBugsInfo.FORWARD_SLASH) != -1) { artifact = resource.substring(resource.lastIndexOf(FindBugsInfo.FORWARD_SLASH) + 1) } if (resource.indexOf(FindBugsInfo.FORWARD_SLASH) != -1) { location = resource.substring(0, resource.lastIndexOf(FindBugsInfo.FORWARD_SLASH)) } // replace all occurrences of the following characters: ? : & = location = location?.replaceAll("[\\?\\:\\&\\=\\%]", "_") artifact = artifact?.replaceAll("[\\?\\:\\&\\=\\%]", "_") log.debug("resource is " + resource) log.debug("location is " + location) log.debug("artifact is " + artifact) File resourceFile = getResourceAsFile(resource, artifact, findbugsXmlOutputDirectory) log.debug("location of resourceFile file is " + resourceFile.absolutePath) return resourceFile } /** * Adds the specified plugins to findbugs. The coreplugin is always added first. * */ protected String getFindbugsPlugins() { URL[] pluginURL def urlPlugins = "" if (pluginList) { log.debug(" Adding Plugins ") String[] pluginJars = pluginList.split(FindBugsInfo.COMMA) pluginJars.each() { pluginJar -> def pluginFileName = pluginJar.trim() if (!pluginFileName.endsWith(".jar")) { throw new IllegalArgumentException("Plugin File is not a Jar file: " + pluginFileName) } try { log.debug(" Processing Plugin: " + pluginFileName.toString()) urlPlugins += getResourceFile(pluginFileName.toString()).absolutePath + ((pluginJar == pluginJars[pluginJars.size() - 1]) ? "" : File.pathSeparator) } catch (MalformedURLException exception) { throw new MojoExecutionException("The addin plugin has an invalid URL") } } } if (plugins) { log.debug(" Adding Plugins from a repository") if (urlPlugins.size() > 0) { urlPlugins += File.pathSeparator } Artifact pomArtifact plugins.each() { plugin -> log.debug(" Processing Plugin: " + plugin.toString()) log.debug("groupId is ${plugin['groupId']} ****** artifactId is ${plugin['artifactId']} ****** version is ${plugin['version']} ****** type is ${plugin['type']}") pomArtifact = this.factory.createArtifact(plugin['groupId'], plugin['artifactId'], plugin['version'], "", plugin['type']) log.debug("pomArtifact is ${pomArtifact} ****** groupId is ${plugin['groupId']} ****** artifactId is ${plugin['artifactId']} ****** version is ${plugin['version']} ****** type is ${plugin['type']}") artifactResolver.resolve(pomArtifact, this.remoteRepositories, this.localRepository) urlPlugins += getResourceFile(pomArtifact.file.absolutePath).absolutePath + ((plugin == plugins[plugins.size() - 1]) ? "" : File.pathSeparator) } } log.debug(" Plugin list is: ${urlPlugins}") return urlPlugins } /** * @see org.apache.maven.reporting.AbstractMavenReport#setReportOutputDirectory(java.io.File) */ public void setReportOutputDirectory(File reportOutputDirectory) { super.setReportOutputDirectory(reportOutputDirectory) this.outputDirectory = reportOutputDirectory } /** * Collects the java sources from the source roots. * * @return A list containing the java sources or an empty list if no java sources are found. * */ protected List getJavaSources(Locale locale) { List sourceFiles = new ArrayList() if (classFilesDirectory.exists() && classFilesDirectory.isDirectory()) { List files = FileUtils.getFiles(classFilesDirectory, FindBugsInfo.JAVA_REGEX_PATTERN, null) sourceFiles.addAll(files) } if (testClassFilesDirectory.exists() && testClassFilesDirectory.isDirectory() && includeTests) { List files = FileUtils.getFiles(testClassFilesDirectory, FindBugsInfo.JAVA_REGEX_PATTERN, null) sourceFiles.addAll(files) } return sourceFiles } File getResourceAsFile(String name, String outputPath, File outputDirectory) { // Optimization for File to File fetches File f = FileResourceLoader.getResourceAsFile(name, outputPath, outputDirectory) if (f != null) { return f } // End optimization InputStream is = new BufferedInputStream(resourceManager.getResourceAsInputStream(name)) File outputResourceFile if (outputPath == null) { outputResourceFile = FileUtils.createTempFile("plexus-resources", "tmp", null) } else { if (outputDirectory != null) { outputResourceFile = new File(outputDirectory, outputPath) } else { outputResourceFile = new File(outputPath) } } try { if (!outputResourceFile.getParentFile().exists()) { outputResourceFile.getParentFile().mkdirs() } def os = new FileOutputStream(outputResourceFile) os << is } catch (IOException e) { throw new FileResourceCreationException("Cannot create file-based resource.", e) } finally { is.close() } return outputResourceFile } } class PluginArtifact { String groupId, artifactId, version String type = "jar" }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy