Author: olamy
Date: Mon Jul  1 11:00:22 2013
New Revision: 1498365

URL: http://svn.apache.org/r1498365
Log:
[MPMD-168] Skip report generation if results are empty
Submitted by Andreas Dangel.

Removed:
    
maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-2/rulesets/basic.xml
Modified:
    maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-1/pom.xml
    
maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-1/src/main/config/pmd/latin-1.xml
    
maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-1/src/main/config/pmd/utf-8.xml
    maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-2/pom.xml
    maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-3/pom.xml
    
maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-3/src/main/config/pmd/abs.xml
    
maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-3/src/main/config/pmd/rel.xml
    maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-4/pom.xml
    
maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/AbstractPmdReport.java
    
maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/CpdReport.java
    
maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/PmdReport.java
    
maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/PmdReportListener.java
    
maven/plugins/trunk/maven-pmd-plugin/src/test/java/org/apache/maven/plugin/pmd/CpdReportTest.java
    
maven/plugins/trunk/maven-pmd-plugin/src/test/java/org/apache/maven/plugin/pmd/PmdReportTest.java

Modified: maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-1/pom.xml
URL: 
http://svn.apache.org/viewvc/maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-1/pom.xml?rev=1498365&r1=1498364&r2=1498365&view=diff
==============================================================================
--- maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-1/pom.xml 
(original)
+++ maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-1/pom.xml Mon 
Jul  1 11:00:22 2013
@@ -49,6 +49,7 @@ under the License.
             <ruleset>src/main/config/pmd/utf-8.xml</ruleset>
             <ruleset>src/main/config/pmd/latin-1.xml</ruleset>
           </rulesets>
+          <skipEmptyReport>false</skipEmptyReport>
         </configuration>
       </plugin>
     </plugins>

Modified: 
maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-1/src/main/config/pmd/latin-1.xml
URL: 
http://svn.apache.org/viewvc/maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-1/src/main/config/pmd/latin-1.xml?rev=1498365&r1=1498364&r2=1498365&view=diff
==============================================================================
--- 
maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-1/src/main/config/pmd/latin-1.xml
 (original)
+++ 
maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-1/src/main/config/pmd/latin-1.xml
 Mon Jul  1 11:00:22 2013
@@ -7,6 +7,6 @@
   <description>
     This ruleset is encoded with ISO-8859-1 to check proper encoding handling.
   </description>
-  <rule ref="rulesets/basic.xml/UnnecessaryReturn" message="LATIN-1-CHARS: 
ÄÖÜäöüß¼½¾¤"/>
+  <rule ref="rulesets/java/basic.xml/UnnecessaryReturn" 
message="LATIN-1-CHARS: ÄÖÜäöüß¼½¾¤"/>
   <!-- note: ¼½¾¤ = 0xBC 0xBD 0xBE 0xA4 don't exist any more in Latin 15, 
replaced by OE oe Y" and euro -->
 </ruleset>

Modified: 
maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-1/src/main/config/pmd/utf-8.xml
URL: 
http://svn.apache.org/viewvc/maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-1/src/main/config/pmd/utf-8.xml?rev=1498365&r1=1498364&r2=1498365&view=diff
==============================================================================
--- 
maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-1/src/main/config/pmd/utf-8.xml
 (original)
+++ 
maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-1/src/main/config/pmd/utf-8.xml
 Mon Jul  1 11:00:22 2013
@@ -7,5 +7,5 @@
   <description>
     This ruleset is encoded with UTF-8 to check proper encoding handling.
   </description>
-  <rule ref="rulesets/basic.xml/EmptyStatementNotInLoop" message="UTF-8-CHARS: 
ÄÖÜäöüß¼½¾¤"/>
+  <rule ref="rulesets/java/basic.xml/EmptyStatementNotInLoop" 
message="UTF-8-CHARS: ÄÖÜäöüß¼½¾¤"/>
 </ruleset>

Modified: maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-2/pom.xml
URL: 
http://svn.apache.org/viewvc/maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-2/pom.xml?rev=1498365&r1=1498364&r2=1498365&view=diff
==============================================================================
--- maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-2/pom.xml 
(original)
+++ maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-2/pom.xml Mon 
Jul  1 11:00:22 2013
@@ -43,8 +43,9 @@ under the License.
         <configuration>
           <rulesets>
             <!-- NOTE: Clashes with classpath resource, check resolution -->
-            <ruleset>rulesets/basic.xml</ruleset>
+            <ruleset>rulesets/java/basic.xml</ruleset>
           </rulesets>
+          <skipEmptyReport>false</skipEmptyReport>
         </configuration>
       </plugin>
     </plugins>

Modified: maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-3/pom.xml
URL: 
http://svn.apache.org/viewvc/maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-3/pom.xml?rev=1498365&r1=1498364&r2=1498365&view=diff
==============================================================================
--- maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-3/pom.xml 
(original)
+++ maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-3/pom.xml Mon 
Jul  1 11:00:22 2013
@@ -46,6 +46,7 @@ under the License.
             <ruleset>src/main/config/pmd/rel.xml</ruleset>
             <ruleset>${basedir}/src/main/config/pmd/abs.xml</ruleset>
           </rulesets>
+          <skipEmptyReport>false</skipEmptyReport>
         </configuration>
       </plugin>
     </plugins>

Modified: 
maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-3/src/main/config/pmd/abs.xml
URL: 
http://svn.apache.org/viewvc/maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-3/src/main/config/pmd/abs.xml?rev=1498365&r1=1498364&r2=1498365&view=diff
==============================================================================
--- 
maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-3/src/main/config/pmd/abs.xml
 (original)
+++ 
maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-3/src/main/config/pmd/abs.xml
 Mon Jul  1 11:00:22 2013
@@ -7,5 +7,5 @@
   <description>
     This ruleset is specified via an absolute filesystem path.
   </description>
-  <rule ref="rulesets/basic.xml/UnnecessaryReturn" message="TEST: 
ABSOLUTE-PATH"/>
+  <rule ref="rulesets/java/basic.xml/UnnecessaryReturn" message="TEST: 
ABSOLUTE-PATH"/>
 </ruleset>

Modified: 
maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-3/src/main/config/pmd/rel.xml
URL: 
http://svn.apache.org/viewvc/maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-3/src/main/config/pmd/rel.xml?rev=1498365&r1=1498364&r2=1498365&view=diff
==============================================================================
--- 
maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-3/src/main/config/pmd/rel.xml
 (original)
+++ 
maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-3/src/main/config/pmd/rel.xml
 Mon Jul  1 11:00:22 2013
@@ -7,5 +7,5 @@
   <description>
     This ruleset is specified via a relative filesystem path.
   </description>
-  <rule ref="rulesets/basic.xml/EmptyStatementNotInLoop" message="TEST: 
RELATIVE-PATH"/>
+  <rule ref="rulesets/java/basic.xml/EmptyStatementNotInLoop" message="TEST: 
RELATIVE-PATH"/>
 </ruleset>

Modified: maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-4/pom.xml
URL: 
http://svn.apache.org/viewvc/maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-4/pom.xml?rev=1498365&r1=1498364&r2=1498365&view=diff
==============================================================================
--- maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-4/pom.xml 
(original)
+++ maven/plugins/trunk/maven-pmd-plugin/src/it/multi-module/mod-4/pom.xml Mon 
Jul  1 11:00:22 2013
@@ -42,6 +42,7 @@ under the License.
         <version>@project.version@</version>
         <configuration>
           <format>none</format>
+          <skipEmptyReport>false</skipEmptyReport>
         </configuration>
       </plugin>
     </plugins>

Modified: 
maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/AbstractPmdReport.java
URL: 
http://svn.apache.org/viewvc/maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/AbstractPmdReport.java?rev=1498365&r1=1498364&r2=1498365&view=diff
==============================================================================
--- 
maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/AbstractPmdReport.java
 (original)
+++ 
maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/AbstractPmdReport.java
 Mon Jul  1 11:00:22 2013
@@ -195,6 +195,18 @@ public abstract class AbstractPmdReport
     protected boolean includeXmlInSite;
 
     /**
+     * Skip the PMD/CPD report generation if there are no violations or 
duplications found.
+     * Defaults to <code>true</code>.
+     *
+     * @since 3.1
+     */
+    @Parameter( defaultValue = "true" )
+    protected boolean skipEmptyReport;
+
+    /** The files that are being analyzed. */
+    protected Map<File, PmdFileInfo> filesToProcess;
+
+    /**
      * {@inheritDoc}
      */
     protected MavenProject getProject()
@@ -396,6 +408,10 @@ public abstract class AbstractPmdReport
     {
         return "html".equals( format );
     }
+    protected boolean isXml()
+    {
+        return "xml".equals( format );
+    }
 
     /**
      * {@inheritDoc}
@@ -414,13 +430,13 @@ public abstract class AbstractPmdReport
 
         // if format is XML, we need to output it even if the file list is 
empty
         // so the "check" goals can check for failures
-        if ( "xml".equals( format ) )
+        if ( isXml() )
         {
             return true;
         }
         try
         {
-            Map<File, PmdFileInfo> filesToProcess = getFilesToProcess();
+            filesToProcess = getFilesToProcess();
             if ( filesToProcess.isEmpty() )
             {
                 return false;

Modified: 
maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/CpdReport.java
URL: 
http://svn.apache.org/viewvc/maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/CpdReport.java?rev=1498365&r1=1498364&r2=1498365&view=diff
==============================================================================
--- 
maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/CpdReport.java
 (original)
+++ 
maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/CpdReport.java
 Mon Jul  1 11:00:22 2013
@@ -42,7 +42,6 @@ import java.io.OutputStreamWriter;
 import java.io.UnsupportedEncodingException;
 import java.io.Writer;
 import java.util.Locale;
-import java.util.Map;
 import java.util.Properties;
 import java.util.ResourceBundle;
 
@@ -92,6 +91,9 @@ public class CpdReport
     @Parameter( property = "cpd.ignoreIdentifiers", defaultValue = "false" )
     private boolean ignoreIdentifiers;
 
+    /** The CPD instance used to analyze the files. Will itself collect the 
duplicated code matches. */
+    private CPD cpd;
+
     /**
      * {@inheritDoc}
      */
@@ -137,9 +139,9 @@ public class CpdReport
             {
                 Thread.currentThread().setContextClassLoader( 
this.getClass().getClassLoader() );
 
-                CPD cpd = generateReport( locale );
+                generateReport( locale );
 
-                if ( !isHtml() )
+                if ( !isHtml() && !isXml() )
                 {
                     writeNonHtml( cpd );
                 }
@@ -152,9 +154,56 @@ public class CpdReport
         }
     }
 
-    private CPD generateReport( Locale locale )
+    public boolean canGenerateReport()
+    {
+        boolean result = super.canGenerateReport();
+        if ( result )
+        {
+            try
+            {
+                executeCpdWithClassloader();
+                if ( skipEmptyReport )
+                {
+                    result = cpd.getMatches().hasNext();
+                    if ( result )
+                    {
+                        getLog().debug("Skipping Report as skipEmptyReport is 
true and there are no CPD issues.");
+                    }
+                }
+            }
+            catch ( MavenReportException e )
+            {
+                throw new RuntimeException( e );
+            }
+        }
+        return result;
+    }
+
+    private void executeCpdWithClassloader()
         throws MavenReportException
     {
+        ClassLoader origLoader = 
Thread.currentThread().getContextClassLoader();
+        try
+        {
+            Thread.currentThread().setContextClassLoader( 
this.getClass().getClassLoader() );
+            executeCpd();
+        }
+        finally
+        {
+            Thread.currentThread().setContextClassLoader( origLoader );
+        }
+    }
+
+    private void executeCpd()
+        throws MavenReportException
+    {
+        if ( cpd != null )
+        {
+            // CPD has already been run
+            getLog().debug( "CPD has already been run - skipping redundant 
execution." );
+            return;
+        }
+
         Properties p = new Properties();
         if ( ignoreLiterals )
         {
@@ -165,18 +214,19 @@ public class CpdReport
             p.setProperty( JavaTokenizer.IGNORE_IDENTIFIERS, "true" );
         }
 
-        CPD cpd;
-        Map<File, PmdFileInfo> files = null;
-
         try
         {
-            files = getFilesToProcess();
-            String encoding = determineEncoding( !files.isEmpty() );
+            if ( filesToProcess == null )
+            {
+                filesToProcess = getFilesToProcess();
+            }
+
+            String encoding = determineEncoding( !filesToProcess.isEmpty() );
 
             CPDConfiguration cpdConfiguration = new CPDConfiguration( 
minimumTokens, new JavaLanguage( p ), encoding );
             cpd = new CPD( cpdConfiguration );
 
-            for ( File file : files.keySet() )
+            for ( File file : filesToProcess.keySet() )
             {
                 cpd.add( file );
             }
@@ -189,12 +239,22 @@ public class CpdReport
         {
             throw new MavenReportException( e.getMessage(), e );
         }
+        getLog().debug( "Executing CPD..." );
         cpd.go();
+        getLog().debug( "CPD finished." );
 
-        CpdReportGenerator gen = new CpdReportGenerator( getSink(), files, 
getBundle( locale ), aggregate );
-        gen.generate( cpd.getMatches() );
+        // if format is XML, we need to output it even if the file list is 
empty or we have no duplications
+        // so the "check" goals can check for violations
+        if ( isXml() )
+        {
+            writeNonHtml( cpd );
+        }
+    }
 
-        return cpd;
+    private void generateReport( Locale locale )
+    {
+        CpdReportGenerator gen = new CpdReportGenerator( getSink(), 
filesToProcess, getBundle( locale ), aggregate );
+        gen.generate( cpd.getMatches() );
     }
 
     private String determineEncoding( boolean showWarn )
@@ -283,9 +343,7 @@ public class CpdReport
         Renderer renderer = null;
         if ( "xml".equals( format ) )
         {
-            //TODO: pmd should provide a better way to specify the output 
encoding (getOutputEncoding());
-            System.setProperty( "file.encoding", getOutputEncoding() );
-            renderer = new XMLRenderer();
+            renderer = new XMLRenderer( getOutputEncoding() );
         }
         else if ( "csv".equals( format ) )
         {

Modified: 
maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/PmdReport.java
URL: 
http://svn.apache.org/viewvc/maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/PmdReport.java?rev=1498365&r1=1498364&r2=1498365&view=diff
==============================================================================
--- 
maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/PmdReport.java
 (original)
+++ 
maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/PmdReport.java
 Mon Jul  1 11:00:22 2013
@@ -58,7 +58,6 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Locale;
-import java.util.Map;
 import java.util.Properties;
 import java.util.ResourceBundle;
 
@@ -135,6 +134,9 @@ public class PmdReport
     @Component
     private ResourceManager locator;
 
+    /** The PMD report listener for collecting violations. */
+    private PmdReportListener reportListener;
+
     /**
      * {@inheritDoc}
      */
@@ -178,11 +180,6 @@ public class PmdReport
     private void execute( Locale locale )
         throws MavenReportException
     {
-        //configure ResourceManager
-        locator.addSearchPath( FileResourceLoader.ID, 
project.getFile().getParentFile().getAbsolutePath() );
-        locator.addSearchPath( "url", "" );
-        locator.setOutputDirectory( targetDirectory );
-
         if ( !skip && canGenerateReport() )
         {
             ClassLoader origLoader = 
Thread.currentThread().getContextClassLoader();
@@ -192,7 +189,7 @@ public class PmdReport
 
                 Report report = generateReport( locale );
 
-                if ( !isHtml() )
+                if ( !isHtml() && !isXml() )
                 {
                     writeNonHtml( report );
                 }
@@ -204,16 +201,65 @@ public class PmdReport
         }
     }
 
-    private Report generateReport( Locale locale )
+    public boolean canGenerateReport()
+    {
+        boolean result = super.canGenerateReport();
+        if ( result )
+        {
+            try
+            {
+                executePmdWithClassloader();
+                if ( skipEmptyReport )
+                {
+                    result = reportListener.hasViolations();
+                    if ( result )
+                    {
+                        getLog().debug("Skipping Report as skipEmptyReport is 
true and there are no PMD violations.");
+                    }
+                }
+            }
+            catch ( MavenReportException e )
+            {
+                throw new RuntimeException( e );
+            }
+        }
+        return result;
+    }
+
+    private void executePmdWithClassloader()
         throws MavenReportException
     {
-        Sink sink = getSink();
+        ClassLoader origLoader = 
Thread.currentThread().getContextClassLoader();
+        try
+        {
+            Thread.currentThread().setContextClassLoader( 
this.getClass().getClassLoader() );
+            executePmd();
+        }
+        finally
+        {
+            Thread.currentThread().setContextClassLoader( origLoader );
+        }
+    }
 
+    private void executePmd()
+        throws MavenReportException
+    {
+        if ( reportListener != null )
+        {
+            // PMD has already been run
+            getLog().debug( "PMD has already been run - skipping redundant 
execution." );
+            return;
+        }
+
+        //configure ResourceManager
+        locator.addSearchPath( FileResourceLoader.ID, 
project.getFile().getParentFile().getAbsolutePath() );
+        locator.addSearchPath( "url", "" );
+        locator.setOutputDirectory( targetDirectory );
+
+        reportListener = new PmdReportListener();
         PMDConfiguration pmdConfiguration = getPMDConfiguration();
-        final PmdReportListener reportSink = new PmdReportListener( getLog(), 
sink, getBundle( locale ), aggregate );
         RuleContext ruleContext = new RuleContext();
-        ruleContext.getReport().addListener( reportSink );
-        reportSink.beginDocument();
+        ruleContext.getReport().addListener( reportListener );
 
         RuleSetFactory ruleSetFactory = new RuleSetFactory();
         ruleSetFactory.setMinimumPriority( RulePriority.valueOf( 
this.minimumPriority ) );
@@ -243,14 +289,17 @@ public class PmdReport
         }
         pmdConfiguration.setRuleSets( StringUtils.join( sets, "," ) );
 
-        Map<File, PmdFileInfo> files;
         try
         {
-            files = getFilesToProcess();
-            if ( files.isEmpty() && !"java".equals( language ) )
+            if ( filesToProcess == null )
+            {
+                filesToProcess = getFilesToProcess();
+            }
+
+            if ( filesToProcess.isEmpty() && !"java".equals( language ) )
             {
                 getLog().warn(
-                    "No files found to process. Did you add your additional 
source folders like javascript? (see also build-helper-maven-plugin)" );
+                        "No files found to process. Did you add your 
additional source folders like javascript? (see also 
build-helper-maven-plugin)" );
             }
         }
         catch ( IOException e )
@@ -259,7 +308,7 @@ public class PmdReport
         }
 
         String encoding = getSourceEncoding();
-        if ( StringUtils.isEmpty( encoding ) && !files.isEmpty() )
+        if ( StringUtils.isEmpty( encoding ) && !filesToProcess.isEmpty() )
         {
             getLog().warn( "File encoding has not been set, using platform 
encoding " + ReaderFactory.FILE_ENCODING
                                + ", i.e. build is platform dependent!" );
@@ -267,32 +316,56 @@ public class PmdReport
         }
         pmdConfiguration.setSourceEncoding( encoding );
 
-        reportSink.setFiles( files );
-        List<DataSource> dataSources = new ArrayList<DataSource>( files.size() 
);
-        for ( File f : files.keySet() )
+        List<DataSource> dataSources = new ArrayList<DataSource>( 
filesToProcess.size() );
+        for ( File f : filesToProcess.keySet() )
         {
             dataSources.add( new FileDataSource( f ) );
         }
 
         try
         {
+            getLog().debug( "Executing PMD..." );
+
             PMD.processFiles( pmdConfiguration, ruleSetFactory, dataSources, 
ruleContext, Collections.<Renderer> emptyList() );
+
+            if ( getLog().isDebugEnabled() )
+            {
+                getLog().debug( "PMD finished. Found " + 
reportListener.getViolations().size() + " violations." );
+            }
         }
         catch ( Exception e )
         {
             getLog().warn( "Failure executing PMD: " + 
e.getLocalizedMessage(), e );
         }
 
+        // if format is XML, we need to output it even if the file list is 
empty or we have no violations
+        // so the "check" goals can check for violations
+        if ( isXml() && reportListener != null )
+        {
+            writeNonHtml( reportListener.asReport() );
+        }
+    }
+
+    private Report generateReport( Locale locale )
+        throws MavenReportException
+    {
+        Sink sink = getSink();
+        PmdReportGenerator renderer = new PmdReportGenerator( getLog(), sink, 
getBundle( locale ), aggregate );
+        renderer.setFiles( filesToProcess );
+        renderer.setViolations( reportListener.getViolations() );
+
         try
         {
-            reportSink.endDocument();
+            renderer.beginDocument();
+            renderer.render();
+            renderer.endDocument();
         }
         catch ( IOException e )
         {
             getLog().warn( "Failure creating the report: " + 
e.getLocalizedMessage(), e );
         }
 
-        return reportSink.asReport();
+        return reportListener.asReport();
     }
 
     /**

Modified: 
maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/PmdReportListener.java
URL: 
http://svn.apache.org/viewvc/maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/PmdReportListener.java?rev=1498365&r1=1498364&r2=1498365&view=diff
==============================================================================
--- 
maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/PmdReportListener.java
 (original)
+++ 
maven/plugins/trunk/maven-pmd-plugin/src/main/java/org/apache/maven/plugin/pmd/PmdReportListener.java
 Mon Jul  1 11:00:22 2013
@@ -19,66 +19,25 @@ package org.apache.maven.plugin.pmd;
  * under the License.
  */
 
-import java.io.File;
-import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
-import java.util.ResourceBundle;
 
 import net.sourceforge.pmd.Report;
 import net.sourceforge.pmd.ReportListener;
 import net.sourceforge.pmd.RuleViolation;
 import net.sourceforge.pmd.stat.Metric;
 
-import org.apache.maven.doxia.sink.Sink;
-import org.apache.maven.plugin.logging.Log;
-import org.codehaus.plexus.util.StringUtils;
-
 /**
- * Handle events from PMD, converting them into Doxia events.
- *
- * @author Brett Porter
- * @version $Id$
+ * Handle events from PMD and collect violations.
  */
 public class PmdReportListener
     implements ReportListener
 {
-    private Log log;
-
-    private Sink sink;
-
-    private String currentFilename;
-
-    private ResourceBundle bundle;
-
     private HashSet<RuleViolation> violations = new HashSet<RuleViolation>();
 
-    private boolean aggregate;
-
-    // The number of erroneous files
-    private int fileCount = 0;
-
-    private Map<File, PmdFileInfo> files;
-
 //    private List<Metric> metrics = new ArrayList<Metric>();
 
-    public PmdReportListener( Log log, Sink sink, ResourceBundle bundle, 
boolean aggregate )
-    {
-        this.log = log;
-        this.sink = sink;
-        this.bundle = bundle;
-        this.aggregate = aggregate;
-    }
-
-    private String getTitle()
-    {
-        return bundle.getString( "report.pmd.title" );
-    }
-
     /**
      * {@inheritDoc}
      */
@@ -92,6 +51,11 @@ public class PmdReportListener
         return new ArrayList<RuleViolation>( violations );
     }
 
+    public boolean hasViolations()
+    {
+        return !violations.isEmpty();
+    }
+
     /**
      * Create a new single report with all violations for further rendering 
into other formats than HTML.
      */
@@ -104,145 +68,6 @@ public class PmdReportListener
         return report;
     }
 
-    private void startFileSection( String currentFilename, PmdFileInfo 
fileInfo )
-    {
-        sink.section2();
-        sink.sectionTitle2();
-
-        // prepare the filename
-        this.currentFilename = currentFilename;
-        if ( fileInfo != null && fileInfo.getSourceDirectory() != null )
-        {
-            this.currentFilename =
-                StringUtils.substring( currentFilename, 
fileInfo.getSourceDirectory().getAbsolutePath().length() + 1 );
-        }
-        this.currentFilename = StringUtils.replace( this.currentFilename, 
"\\", "/" );
-
-        String title = this.currentFilename;
-        if ( aggregate && fileInfo != null && fileInfo.getProject() != null )
-        {
-            title = fileInfo.getProject().getName() + " - " + 
this.currentFilename;
-        }
-        sink.text( title );
-        sink.sectionTitle2_();
-
-        sink.table();
-        sink.tableRow();
-        sink.tableHeaderCell();
-        sink.text( bundle.getString( "report.pmd.column.violation" ) );
-        sink.tableHeaderCell_();
-        sink.tableHeaderCell();
-        sink.text( bundle.getString( "report.pmd.column.line" ) );
-        sink.tableHeaderCell_();
-        sink.tableRow_();
-    }
-
-    private void endFileSection()
-    {
-        sink.table_();
-        sink.section2_();
-    }
-
-    private void processSingleRuleViolation( RuleViolation ruleViolation, 
PmdFileInfo fileInfo )
-    {
-        sink.tableRow();
-        sink.tableCell();
-        sink.text( ruleViolation.getDescription() );
-        sink.tableCell_();
-        sink.tableCell();
-
-        int beginLine = ruleViolation.getBeginLine();
-        outputLineLink( beginLine, fileInfo );
-        int endLine = ruleViolation.getEndLine();
-        if ( endLine != beginLine )
-        {
-            sink.text( " - " );
-            outputLineLink( endLine, fileInfo );
-        }
-
-        sink.tableCell_();
-        sink.tableRow_();
-    }
-
-    // PMD might run the analysis multi-threaded, so the violations might be 
reported
-    // out of order. We sort them here by filename and line number before 
writing them to
-    // the report.
-    private void processViolations()
-        throws IOException
-    {
-        fileCount = files.size();
-        ArrayList<RuleViolation> violations2 = new ArrayList<RuleViolation>( 
violations );
-        Collections.sort( violations2, new Comparator<RuleViolation>()
-        {
-            /** {@inheritDoc} */
-            public int compare( RuleViolation o1, RuleViolation o2 )
-            {
-                int filenames = o1.getFilename().compareTo( o2.getFilename() );
-                if ( filenames == 0 )
-                {
-                    return o1.getBeginLine() - o2.getBeginLine();
-                }
-                else
-                {
-                    return filenames;
-                }
-            }
-        } );
-
-        boolean fileSectionStarted = false;
-        String previousFilename = null;
-        for ( RuleViolation ruleViolation : violations2 )
-        {
-            String currentFn = ruleViolation.getFilename();
-            File canonicalFilename = new File( currentFn ).getCanonicalFile();
-            PmdFileInfo fileInfo = files.get( canonicalFilename );
-            if ( fileInfo == null )
-            {
-                log.warn( "Couldn't determine PmdFileInfo for file " + 
currentFn + " (canonical: " + canonicalFilename
-                              + "). XRef links won't be available." );
-            }
-
-            if ( !currentFn.equalsIgnoreCase( previousFilename ) && 
fileSectionStarted )
-            {
-                endFileSection();
-                fileSectionStarted = false;
-            }
-            if ( !fileSectionStarted )
-            {
-                startFileSection( currentFn, fileInfo );
-                fileSectionStarted = true;
-            }
-
-            processSingleRuleViolation( ruleViolation, fileInfo );
-
-            previousFilename = currentFn;
-        }
-
-        if ( fileSectionStarted )
-        {
-            endFileSection();
-        }
-    }
-
-    private void outputLineLink( int line, PmdFileInfo fileInfo )
-    {
-        String xrefLocation = null;
-        if ( fileInfo != null )
-        {
-            xrefLocation = fileInfo.getXrefLocation();
-        }
-
-        if ( xrefLocation != null )
-        {
-            sink.link( xrefLocation + "/" + currentFilename.replaceAll( 
"\\.java$", ".html" ) + "#" + line );
-        }
-        sink.text( String.valueOf( line ) );
-        if ( xrefLocation != null )
-        {
-            sink.link_();
-        }
-    }
-
     /**
      * {@inheritDoc}
      */
@@ -254,129 +79,4 @@ public class PmdReportListener
 //            metrics.add( metric );
 //        }
     }
-
-    public void beginDocument()
-    {
-        sink.head();
-        sink.title();
-        sink.text( getTitle() );
-        sink.title_();
-        sink.head_();
-
-        sink.body();
-
-        sink.section1();
-        sink.sectionTitle1();
-        sink.text( getTitle() );
-        sink.sectionTitle1_();
-
-        sink.paragraph();
-        sink.text( bundle.getString( "report.pmd.pmdlink" ) + " " );
-        sink.link( "http://pmd.sourceforge.net/"; );
-        sink.text( "PMD" );
-        sink.link_();
-        sink.text( " " + AbstractPmdReport.getPmdVersion() + "." );
-        sink.paragraph_();
-
-        sink.section1_();
-
-        // TODO overall summary
-
-        sink.section1();
-        sink.sectionTitle1();
-        sink.text( bundle.getString( "report.pmd.files" ) );
-        sink.sectionTitle1_();
-
-        // TODO files summary
-    }
-
-/*
-    private void processMetrics()
-    {
-        if ( metrics.size() == 0 )
-        {
-            return;
-        }
-
-        sink.section1();
-        sink.sectionTitle1();
-        sink.text( "Metrics" );
-        sink.sectionTitle1_();
-
-        sink.table();
-        sink.tableRow();
-        sink.tableHeaderCell();
-        sink.text( "Name" );
-        sink.tableHeaderCell_();
-        sink.tableHeaderCell();
-        sink.text( "Count" );
-        sink.tableHeaderCell_();
-        sink.tableHeaderCell();
-        sink.text( "High" );
-        sink.tableHeaderCell_();
-        sink.tableHeaderCell();
-        sink.text( "Low" );
-        sink.tableHeaderCell_();
-        sink.tableHeaderCell();
-        sink.text( "Average" );
-        sink.tableHeaderCell_();
-        sink.tableRow_();
-
-        for ( Metric met : metrics )
-        {
-            sink.tableRow();
-            sink.tableCell();
-            sink.text( met.getMetricName() );
-            sink.tableCell_();
-            sink.tableCell();
-            sink.text( String.valueOf( met.getCount() ) );
-            sink.tableCell_();
-            sink.tableCell();
-            sink.text( String.valueOf( met.getHighValue() ) );
-            sink.tableCell_();
-            sink.tableCell();
-            sink.text( String.valueOf( met.getLowValue() ) );
-            sink.tableCell_();
-            sink.tableCell();
-            sink.text( String.valueOf( met.getAverage() ) );
-            sink.tableCell_();
-            sink.tableRow_();
-        }
-        sink.table_();
-        sink.section1_();
-    }
-*/
-
-    public void endDocument()
-        throws IOException
-    {
-        processViolations();
-
-        if ( fileCount == 0 )
-        {
-            sink.paragraph();
-            sink.text( bundle.getString( "report.pmd.noProblems" ) );
-            sink.paragraph_();
-        }
-
-        sink.section1_();
-
-        // The Metrics report useless with the current PMD metrics impl.
-        // For instance, run the coupling ruleset and you will get a boatload
-        // of excessive imports metrics, none of which is really any use.
-        // TODO Determine if we are going to just ignore metrics.
-
-//        processMetrics();
-
-        sink.body_();
-
-        sink.flush();
-
-        sink.close();
-    }
-
-    public void setFiles( Map<File, PmdFileInfo> files )
-    {
-        this.files = files;
-    }
 }
\ No newline at end of file

Modified: 
maven/plugins/trunk/maven-pmd-plugin/src/test/java/org/apache/maven/plugin/pmd/CpdReportTest.java
URL: 
http://svn.apache.org/viewvc/maven/plugins/trunk/maven-pmd-plugin/src/test/java/org/apache/maven/plugin/pmd/CpdReportTest.java?rev=1498365&r1=1498364&r2=1498365&view=diff
==============================================================================
--- 
maven/plugins/trunk/maven-pmd-plugin/src/test/java/org/apache/maven/plugin/pmd/CpdReportTest.java
 (original)
+++ 
maven/plugins/trunk/maven-pmd-plugin/src/test/java/org/apache/maven/plugin/pmd/CpdReportTest.java
 Mon Jul  1 11:00:22 2013
@@ -209,6 +209,33 @@ public class CpdReportTest
         assertNotNull( pmdCpdDocument );
     }
 
+    public void testSkipEmptyReportConfiguration()
+            throws Exception
+    {
+        File testPom = new File( getBasedir(), 
"src/test/resources/unit/empty-report/cpd-skip-empty-report-plugin-config.xml" 
);
+        CpdReport mojo = (CpdReport) lookupMojo( "cpd", testPom );
+        mojo.execute();
+
+        // verify the generated files do not exist because PMD was skipped
+        File generatedFile = new File( getBasedir(), 
"target/test/unit/empty-report/target/site/cpd.html" );
+        assertFalse( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
+    }
+
+    public void testEmptyReportConfiguration()
+            throws Exception
+    {
+        File testPom = new File( getBasedir(), 
"src/test/resources/unit/empty-report/cpd-empty-report-plugin-config.xml" );
+        CpdReport mojo = (CpdReport) lookupMojo( "cpd", testPom );
+        mojo.execute();
+
+        // verify the generated files do exist, even if there are no violations
+        File generatedFile = new File( getBasedir(), 
"target/test/unit/empty-report/target/site/cpd.html" );
+        assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
+        String str = readFile( new File( getBasedir(), 
"target/test/unit/empty-report/target/site/cpd.html" ) );
+        assertTrue( str.toLowerCase().indexOf( "Hello.java".toLowerCase() ) == 
-1 );
+    }
+
+
     public static class MockCpd
         extends CPD
     {

Modified: 
maven/plugins/trunk/maven-pmd-plugin/src/test/java/org/apache/maven/plugin/pmd/PmdReportTest.java
URL: 
http://svn.apache.org/viewvc/maven/plugins/trunk/maven-pmd-plugin/src/test/java/org/apache/maven/plugin/pmd/PmdReportTest.java?rev=1498365&r1=1498364&r2=1498365&view=diff
==============================================================================
--- 
maven/plugins/trunk/maven-pmd-plugin/src/test/java/org/apache/maven/plugin/pmd/PmdReportTest.java
 (original)
+++ 
maven/plugins/trunk/maven-pmd-plugin/src/test/java/org/apache/maven/plugin/pmd/PmdReportTest.java
 Mon Jul  1 11:00:22 2013
@@ -224,6 +224,32 @@ public class PmdReportTest
         assertFalse( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
     }
 
+    public void testSkipEmptyReportConfiguration()
+        throws Exception
+    {
+        File testPom = new File( getBasedir(), 
"src/test/resources/unit/empty-report/skip-empty-report-plugin-config.xml" );
+        PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
+        mojo.execute();
+
+        // verify the generated files do not exist because PMD was skipped
+        File generatedFile = new File( getBasedir(), 
"target/test/unit/empty-report/target/site/pmd.html" );
+        assertFalse( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
+    }
+
+    public void testEmptyReportConfiguration()
+            throws Exception
+    {
+        File testPom = new File( getBasedir(), 
"src/test/resources/unit/empty-report/empty-report-plugin-config.xml" );
+        PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
+        mojo.execute();
+
+        // verify the generated files do exist, even if there are no violations
+        File generatedFile = new File( getBasedir(), 
"target/test/unit/empty-report/target/site/pmd.html" );
+        assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
+        String str = readFile( new File( getBasedir(), 
"target/test/unit/empty-report/target/site/pmd.html" ) );
+        assertTrue( str.toLowerCase().indexOf( "Hello.java".toLowerCase() ) == 
-1 );
+    }
+
     public void testInvalidFormat()
         throws Exception
     {


Reply via email to