You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by ep...@apache.org on 2005/12/08 06:29:19 UTC

svn commit: r354995 [1/2] - in /maven/plugins/trunk/maven-checkstyle-plugin: ./ src/main/java/org/apache/maven/plugin/checkstyle/ src/main/resources/ src/main/resources/org/ src/main/resources/org/apache/ src/main/resources/org/apache/maven/ src/main/r...

Author: epunzalan
Date: Wed Dec  7 21:26:50 2005
New Revision: 354995

URL: http://svn.apache.org/viewcvs?rev=354995&view=rev
Log:
PR: MNG-1749
Submitted by: Joakim Erdfelt

Sync this plugin's features to m1's version.

Added:
    maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleResults.java   (with props)
    maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleViolationCheckMojo.java   (with props)
    maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/ReportResource.java   (with props)
    maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/VelocityTemplate.java   (with props)
    maven/plugins/trunk/maven-checkstyle-plugin/src/main/resources/org/
    maven/plugins/trunk/maven-checkstyle-plugin/src/main/resources/org/apache/
    maven/plugins/trunk/maven-checkstyle-plugin/src/main/resources/org/apache/maven/
    maven/plugins/trunk/maven-checkstyle-plugin/src/main/resources/org/apache/maven/plugin/
    maven/plugins/trunk/maven-checkstyle-plugin/src/main/resources/org/apache/maven/plugin/checkstyle/
    maven/plugins/trunk/maven-checkstyle-plugin/src/main/resources/org/apache/maven/plugin/checkstyle/checkstyle-rss.vm   (with props)
    maven/plugins/trunk/maven-checkstyle-plugin/src/site/resources/sample-checkstyle.rss   (with props)
Modified:
    maven/plugins/trunk/maven-checkstyle-plugin/pom.xml
    maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleReport.java
    maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleReportGenerator.java
    maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleReportListener.java
    maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/Locator.java
    maven/plugins/trunk/maven-checkstyle-plugin/src/main/resources/checkstyle-report.properties
    maven/plugins/trunk/maven-checkstyle-plugin/src/main/resources/checkstyle-report_fr.properties
    maven/plugins/trunk/maven-checkstyle-plugin/src/site/resources/sample-checkstyle.html

Modified: maven/plugins/trunk/maven-checkstyle-plugin/pom.xml
URL: http://svn.apache.org/viewcvs/maven/plugins/trunk/maven-checkstyle-plugin/pom.xml?rev=354995&r1=354994&r2=354995&view=diff
==============================================================================
--- maven/plugins/trunk/maven-checkstyle-plugin/pom.xml (original)
+++ maven/plugins/trunk/maven-checkstyle-plugin/pom.xml Wed Dec  7 21:26:50 2005
@@ -54,38 +54,30 @@
     </dependency -->
     <dependency>
       <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-velocity</artifactId>
+      <version>1.1.2</version>
+      <exclusions>
+        <exclusion>
+          <!-- Excluding old plexus-utils in favor of updated rev -->
+          <groupId>plexus</groupId>
+          <artifactId>plexus-utils</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.plexus</groupId>
       <artifactId>plexus-utils</artifactId>
+      <version>1.0.4</version>
     </dependency>
     <dependency>
       <groupId>checkstyle</groupId>
       <artifactId>checkstyle</artifactId>
-      <version>3.4</version>
+      <version>4.0</version>
     </dependency>
     <dependency>
       <groupId>checkstyle</groupId>
       <artifactId>checkstyle-optional</artifactId>
-      <version>3.4</version>
-    </dependency>
-    <!-- regexp, beanutils, logging, antlr should be transitive! -->
-    <dependency>
-      <groupId>commons-beanutils</groupId>
-      <artifactId>commons-beanutils</artifactId>
-      <version>1.6.1</version>
-    </dependency>
-    <dependency>
-      <groupId>commons-logging</groupId>
-      <artifactId>commons-logging</artifactId>
-      <version>1.0.3</version>
-    </dependency>
-    <dependency>
-      <groupId>antlr</groupId>
-      <artifactId>antlr</artifactId>
-      <version>2.7.2</version>
-    </dependency>
-    <dependency>
-      <groupId>regexp</groupId>
-      <artifactId>regexp</artifactId>
-      <version>1.3</version>
+      <version>4.0</version>
     </dependency>
   </dependencies>
 </project>

Modified: maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleReport.java
URL: http://svn.apache.org/viewcvs/maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleReport.java?rev=354995&r1=354994&r2=354995&view=diff
==============================================================================
--- maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleReport.java (original)
+++ maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleReport.java Wed Dec  7 21:26:50 2005
@@ -16,28 +16,6 @@
  * limitations under the License.
  */
 
-import com.puppycrawl.tools.checkstyle.Checker;
-import com.puppycrawl.tools.checkstyle.ConfigurationLoader;
-import com.puppycrawl.tools.checkstyle.DefaultLogger;
-import com.puppycrawl.tools.checkstyle.ModuleFactory;
-import com.puppycrawl.tools.checkstyle.PackageNamesLoader;
-import com.puppycrawl.tools.checkstyle.PropertiesExpander;
-import com.puppycrawl.tools.checkstyle.XMLLogger;
-import com.puppycrawl.tools.checkstyle.api.AuditListener;
-import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
-import com.puppycrawl.tools.checkstyle.api.Configuration;
-import com.puppycrawl.tools.checkstyle.api.FilterSet;
-import com.puppycrawl.tools.checkstyle.filters.SuppressionsLoader;
-
-import org.apache.maven.project.MavenProject;
-import org.apache.maven.reporting.AbstractMavenReport;
-import org.apache.maven.reporting.MavenReportException;
-import org.codehaus.doxia.site.renderer.SiteRenderer;
-import org.codehaus.plexus.util.FileUtils;
-import org.codehaus.plexus.util.StringInputStream;
-import org.codehaus.plexus.util.StringOutputStream;
-import org.codehaus.plexus.util.StringUtils;
-
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
@@ -45,6 +23,7 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.net.URL;
+import java.util.Calendar;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -53,8 +32,37 @@
 import java.util.Properties;
 import java.util.ResourceBundle;
 
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.reporting.AbstractMavenReport;
+import org.apache.maven.reporting.MavenReportException;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.context.Context;
+import org.apache.velocity.exception.ResourceNotFoundException;
+import org.apache.velocity.exception.VelocityException;
+import org.codehaus.doxia.site.renderer.SiteRenderer;
+import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.StringInputStream;
+import org.codehaus.plexus.util.StringOutputStream;
+import org.codehaus.plexus.util.StringUtils;
+import org.codehaus.plexus.velocity.VelocityComponent;
+
+import com.puppycrawl.tools.checkstyle.Checker;
+import com.puppycrawl.tools.checkstyle.ConfigurationLoader;
+import com.puppycrawl.tools.checkstyle.DefaultLogger;
+import com.puppycrawl.tools.checkstyle.ModuleFactory;
+import com.puppycrawl.tools.checkstyle.PackageNamesLoader;
+import com.puppycrawl.tools.checkstyle.PropertiesExpander;
+import com.puppycrawl.tools.checkstyle.XMLLogger;
+import com.puppycrawl.tools.checkstyle.api.AuditListener;
+import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
+import com.puppycrawl.tools.checkstyle.api.Configuration;
+import com.puppycrawl.tools.checkstyle.api.FilterSet;
+import com.puppycrawl.tools.checkstyle.api.SeverityLevel;
+import com.puppycrawl.tools.checkstyle.filters.SuppressionsLoader;
+
 /**
- * TODO: add report generation for ruleset/configuration. 
+ * Perform checkstyle analysis, and generate report on violations. 
  * 
  * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
  * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
@@ -64,6 +72,8 @@
 public class CheckstyleReport
     extends AbstractMavenReport
 {
+    private static final String PLUGIN_RESOURCES = "org/apache/maven/plugin/checkstyle";
+
     /**
      * @deprecated Remove with format parameter.
      */
@@ -88,11 +98,43 @@
      * @required
      */
     private File outputDirectory;
+    
+    /**
+     * Specifies if the Rules summary should be enabled or not.
+     * 
+     * @parameter expression="${checkstyle.enable.rules.summary}"
+     *            default-value="true"
+     */
+    private boolean enableRulesSummary;
 
     /**
+     * Specifies if the Severity summary should be enabled or not.
+     * 
+     * @parameter expression="${checkstyle.enable.severity.summary}"
+     *            default-value="true"
+     */
+    private boolean enableSeveritySummary;
+    
+    /**
+     * Specifies if the Files summary should be enabled or not.
+     * 
+     * @parameter expression="${checkstyle.enable.files.summary}"
+     *            default-value="true"
+     */
+    private boolean enableFilesSummary;
+    
+    /**
+     * Specifies if the Files summary should be enabled or not.
+     * 
+     * @parameter expression="${checkstyle.enable.rss}"
+     *            default-value="true"
+     */
+    private boolean enableRSS;
+    
+    /**
      * Specifies the names filter of the source files to be used for checkstyle
      *
-     * @parameter default-value="**\/*.java"
+     * @parameter expression="${checkstyle.includes}" default-value="**\/*.java"
      * @required
      */
     private String includes;
@@ -100,7 +142,7 @@
     /**
      * Specifies the names filter of the source files to be excluded for checkstyle
      *
-     * @parameter
+     * @parameter expression="${checkstyle.excludes}"
      */
     private String excludes;
 
@@ -119,8 +161,7 @@
      * 
      * <p>
      * This parameter is resolved as resource, URL, then file.  
-     * If resolved to a resource, or a URL, the contents of the configuration
-     * is copied into the 
+     * If successfully resolved, the contents of the configuration is copied into the 
      * <code>${project.build.directory}/checkstyle-configuration.xml</code>
      * file before being passed to checkstyle as a configuration.
      * </p>
@@ -136,7 +177,7 @@
      * <li><code>config/maven_checks.xml</code>: Maven Source Checks.</li>
      * </ul>
      * 
-     * @parameter default-value="config/sun_checks.xml"
+     * @parameter expression="${checkstyle.config.location}" default-value="config/sun_checks.xml"
      */
     private String configLocation;
     
@@ -157,8 +198,7 @@
      * 
      * <p>
      * This parameter is resolved as URL, File, then resource.  
-     * If successfully resolved, the contents of the properties location is 
-     * copied into the 
+     * If successfully resolved, the contents of the properties location is copied into the 
      * <code>${project.build.directory}/checkstyle-checker.properties</code>
      * file before being passed to checkstyle for loading.
      * </p>
@@ -170,7 +210,7 @@
      * parameter).
      * </p> 
      * 
-     * @parameter 
+     * @parameter expression="${checkstyle.properties.location}"
      * @since 2.0-beta-2
      */
     private String propertiesLocation;
@@ -203,7 +243,7 @@
      * that is used by Checkstyle to verify that source code has the 
      * correct copyright.
      *
-     * @parameter default-value="LICENSE.txt"
+     * @parameter expression="${checkstyle.header.file}" default-value="LICENSE.txt"
      * @since 2.0-beta-2
      */
     private String headerLocation;
@@ -239,13 +279,12 @@
      * 
      * <p>
      * This parameter is resolved as resource, URL, then file.  
-     * If resolved to a resource, or a URL, the contents of the suppressions
-     * XML is copied into the 
+     * If successfully resolved, the contents of the suppressions XML is copied into the 
      * <code>${project.build.directory}/checkstyle-supressions.xml</code>
      * file before being passed to checkstyle for loading.
      * </p>
      *
-     * @parameter
+     * @parameter expression="${checkstyle.suppressions.location}"
      * @since 2.0-beta-2
      */
     private String suppressionsLocation;
@@ -256,7 +295,7 @@
      * property. This allows using the Checkstyle property your own custom checkstyle
      * configuration file when specifying a suppressions file.
      *
-     * @parameter
+     * @parameter 
      * @deprecated Use suppressionsLocation instead.
      */
     private String suppressionsFile;
@@ -265,15 +304,16 @@
      * Specifies the path and filename to save the checkstyle output.  The format of the output file is
      * determined by the <code>outputFileFormat</code>
      *
-     * @parameter default-value="${project.build.directory}/checkstyle-result.txt"
+     * @parameter expression="${checkstyle.output.file}" 
+     *            default-value="${project.build.directory}/checkstyle-result.xml"
      */
-    private String outputFile;
+    private File outputFile;
 
     /**
      * Specifies the format of the output to be used when writing to the output file. Valid values are
      * "plain" and "xml"
      *
-     * @parameter default-value="plain"
+     * @parameter expression="${checkstyle.output.format}" default-value="xml"
      */
     private String outputFileFormat;
 
@@ -332,7 +372,15 @@
      * @readonly
      */
     private SiteRenderer siteRenderer;
-
+    
+    /**
+     * Velocity Component
+     * 
+     * @component role="org.codehaus.plexus.velocity.VelocityComponent"
+     * @required
+     */
+    private VelocityComponent velocityComponent;
+    
     private static final File[] EMPTY_FILE_ARRAY = new File[0];
 
     private StringOutputStream stringOutputStream;
@@ -395,13 +443,119 @@
 //        for when we start using maven-shared-io and maven-shared-monitor...
 //        locator = new Locator( new MojoLogMonitorAdaptor( getLog() ) );
         
-        locator = new Locator( getLog() );
+        locator = new Locator( getLog(), new File( project.getBuild().getDirectory() ) );
+        
+        String configFile = getConfigFile();
+        Properties overridingProperties = getOverridingProperties();
+        ModuleFactory moduleFactory;
+        Configuration config;
+        CheckstyleResults results;
+        try
+        {
+            moduleFactory = getModuleFactory();
+            config = ConfigurationLoader.loadConfiguration( configFile, new PropertiesExpander( overridingProperties ) );
+            results = executeCheckstyle( config, moduleFactory );
+        }
+        catch ( CheckstyleException e )
+        {
+            throw new MavenReportException( "Failed during checkstyle configuration", e );
+        }
 
-        Map files = executeCheckstyle();
+        ResourceBundle bundle = getBundle( locale );
+        
+        generateReportStatics();
+        generateMainReport( results, config, moduleFactory, bundle );
+        
+        if( enableRSS )
+        {
+            generateRSS( results );
+        }
+    }
+    
+    private void generateReportStatics()
+        throws MavenReportException
+    {
+        ReportResource rresource = new ReportResource( PLUGIN_RESOURCES, outputDirectory );
+        try
+        {
+            rresource.copy( "images/rss.png" );
+        }
+        catch ( IOException e )
+        {
+            throw new MavenReportException( "Unable to copy static resources." );
+        }
+    }
 
-        CheckstyleReportGenerator generator = new CheckstyleReportGenerator( getSink(), getBundle( locale ) );
+    private void generateRSS( CheckstyleResults results )
+        throws MavenReportException
+    {
+        VelocityTemplate vtemplate = new VelocityTemplate(velocityComponent, PLUGIN_RESOURCES);
+        vtemplate.setLog( getLog() );
+        
+        Context context = new VelocityContext();
+        context.put( "results", results );
+        context.put( "project", project );
+        context.put( "copyright", getCopyright() );
+        context.put( "levelInfo", SeverityLevel.INFO );
+        context.put( "levelWarning", SeverityLevel.WARNING );
+        context.put( "levelError", SeverityLevel.ERROR );
+        context.put( "stringutils", new StringUtils() );
+        
+        try
+        {
+            vtemplate.generate( outputDirectory.getPath() + "/checkstyle.rss", "checkstyle-rss.vm", context );
+        }
+        catch ( ResourceNotFoundException e )
+        {
+            throw new MavenReportException( "Unable to find checkstyle-rss.vm resource.", e );
+        }
+        catch ( MojoExecutionException e )
+        {
+            throw new MavenReportException( "Unable to generate checkstyle.rss.", e );
+        }
+        catch ( VelocityException e )
+        {
+            throw new MavenReportException( "Unable to generate checkstyle.rss.", e );
+        }
+        catch ( IOException e )
+        {
+            throw new MavenReportException( "Unable to generate checkstyle.rss.", e );
+        }
+    }
+
+    private String getCopyright()
+    {
+        String copyright;
+        int currentYear = Calendar.getInstance().get( Calendar.YEAR );
+        if ( StringUtils.isNotEmpty( project.getInceptionYear() )
+            && !String.valueOf( currentYear ).equals( project.getInceptionYear() ) )
+        {
+            copyright = project.getInceptionYear() + " - " + currentYear;
+        }
+        else
+        {
+            copyright = String.valueOf( currentYear );
+        }
 
-        generator.generateReport( files );
+        if ( ( project.getOrganization() != null ) && StringUtils.isNotEmpty( project.getOrganization().getName() ) )
+        {
+            copyright = copyright + " " + project.getOrganization().getName();
+        }
+        return copyright;
+    }
+
+    private void generateMainReport( CheckstyleResults results, Configuration config, ModuleFactory moduleFactory, ResourceBundle bundle )
+    {
+        CheckstyleReportGenerator generator = new CheckstyleReportGenerator( getSink(), bundle );
+
+        generator.setLog( getLog() );
+        generator.setEnableRulesSummary( enableRulesSummary );
+        generator.setEnableSeveritySummary( enableSeveritySummary );
+        generator.setEnableFilesSummary( enableFilesSummary );
+        generator.setEnableRSS( enableRSS );
+        generator.setCheckstyleConfig( config );
+        generator.setCheckstyleModuleFactory( moduleFactory );
+        generator.generateReport( results );
     }
 
     /**
@@ -448,8 +602,8 @@
         }
     }
 
-    private Map executeCheckstyle()
-        throws MavenReportException
+    private CheckstyleResults executeCheckstyle( Configuration config, ModuleFactory moduleFactory )
+        throws MavenReportException, CheckstyleException
     {
         File[] files = new File[0];
         try
@@ -461,40 +615,22 @@
             throw new MavenReportException( "Error getting files to process", e );
         }
 
-        String configFile = getConfigFile();
-        
-        Properties overridingProperties = getOverridingProperties();
+        FilterSet filterSet = getSuppressions();
 
-        Checker checker;
+        Checker checker = new Checker();
 
-        try
+        if ( moduleFactory != null )
         {
-            ModuleFactory moduleFactory = getModuleFactory();
-
-            FilterSet filterSet = getSuppressions();
-
-            Configuration config =
-                ConfigurationLoader.loadConfiguration( configFile, new PropertiesExpander( overridingProperties ) );
-
-            checker = new Checker();
-
-            if ( moduleFactory != null )
-            {
-                checker.setModuleFactory( moduleFactory );
-            }
-
-            if ( filterSet != null )
-            {
-                checker.addFilter( filterSet );
-            }
-
-            checker.configure( config );
+            checker.setModuleFactory( moduleFactory );
         }
-        catch ( CheckstyleException ce )
+
+        if ( filterSet != null )
         {
-            throw new MavenReportException( "Failed during checkstyle configuration", ce );
+            checker.addFilter( filterSet );
         }
 
+        checker.configure( config );
+
         AuditListener listener = getListener();
 
         if ( listener != null )
@@ -524,7 +660,7 @@
             throw new MavenReportException( "There are " + nbErrors + " formatting errors." );
         }
 
-        return sinkListener.getFiles();
+        return sinkListener.getResults();
     }
 
     /**
@@ -542,7 +678,7 @@
 
         if ( StringUtils.isNotEmpty( outputFileFormat ) )
         {
-            File resultFile = new File( outputFile );
+            File resultFile = outputFile;
 
             OutputStream out = getOutputStream( resultFile );
 
@@ -613,10 +749,6 @@
         return (File[]) files.toArray( EMPTY_FILE_ARRAY );
     }
     
-    private String getLocationTemp(String name) {
-        return project.getBuild().getDirectory() + File.separator + name;
-    }
-
     private Properties getOverridingProperties()
         throws MavenReportException
     {
@@ -624,8 +756,7 @@
 
         try
         {
-            File propertiesFile = locator.resolveLocation( propertiesLocation,
-                                                           getLocationTemp( "checkstyle-checker.properties" ) );
+            File propertiesFile = locator.resolveLocation( propertiesLocation, "checkstyle-checker.properties" );
             
             if ( propertiesFile != null )
             {
@@ -641,8 +772,7 @@
             {
                 try
                 {
-                    File headerFile = locator.resolveLocation( headerLocation,
-                                                               getLocationTemp( "checkstyle-header.txt" ) );
+                    File headerFile = locator.resolveLocation( headerLocation, "checkstyle-header.txt" );
                     if ( headerFile != null )
                     {
                         p.setProperty( "checkstyle.header.file", headerFile.getAbsolutePath() );
@@ -672,7 +802,7 @@
     {
         try
         {
-            File configFile = locator.resolveLocation( configLocation, getLocationTemp( "checkstyle-checker.xml" ) );
+            File configFile = locator.resolveLocation( configLocation, "checkstyle-checker.xml" );
             if ( configFile == null )
             {
                 throw new MavenReportException( "Unable to process null config location." );
@@ -689,23 +819,26 @@
     private ModuleFactory getModuleFactory()
         throws CheckstyleException
     {
+        // default to internal module factory.
+        ModuleFactory moduleFactory = PackageNamesLoader.loadModuleFactory( Thread.currentThread()
+            .getContextClassLoader() );
+
         try
         {
-            File packageNamesFile = locator.resolveLocation( packageNamesLocation,
-                                                             getLocationTemp( "checkstyle-packages.xml" ) );
+            // attempt to locate any specified package file.
+            File packageNamesFile = locator.resolveLocation( packageNamesLocation, "checkstyle-packages.xml" );
 
-            if ( packageNamesFile == null )
+            if ( packageNamesFile != null )
             {
-                return null;
+                // load resolved location.
+                moduleFactory = PackageNamesLoader.loadModuleFactory( packageNamesFile.getAbsolutePath() );
             }
-
-            return PackageNamesLoader.loadModuleFactory( packageNamesFile.getAbsolutePath() );
         }
         catch ( IOException e )
         {
             getLog().error( "Unable to process package names location: " + packageNamesLocation, e );
-            return null;
         }
+        return moduleFactory;
     }
 
     private FilterSet getSuppressions()
@@ -713,8 +846,7 @@
     {
         try
         {
-            File suppressionsFile = locator.resolveLocation( suppressionsLocation,
-                                                             getLocationTemp( "checkstyle-suppressions.xml" ) );
+            File suppressionsFile = locator.resolveLocation( suppressionsLocation, "checkstyle-suppressions.xml" );
 
             if ( suppressionsFile == null )
             {

Modified: maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleReportGenerator.java
URL: http://svn.apache.org/viewcvs/maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleReportGenerator.java?rev=354995&r1=354994&r2=354995&view=diff
==============================================================================
--- maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleReportGenerator.java (original)
+++ maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleReportGenerator.java Wed Dec  7 21:26:50 2005
@@ -16,29 +16,69 @@
  * limitations under the License.
  */
 
-import com.puppycrawl.tools.checkstyle.api.AuditEvent;
-import com.puppycrawl.tools.checkstyle.api.SeverityLevel;
-import java.util.Collections;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Iterator;
 import java.util.List;
 import java.util.ResourceBundle;
-import java.util.Map;
 
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.plugin.logging.SystemStreamLog;
 import org.codehaus.doxia.sink.Sink;
+import org.codehaus.plexus.util.StringUtils;
+
+import com.puppycrawl.tools.checkstyle.ModuleFactory;
+import com.puppycrawl.tools.checkstyle.api.AuditEvent;
+import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
+import com.puppycrawl.tools.checkstyle.api.Configuration;
+import com.puppycrawl.tools.checkstyle.api.SeverityLevel;
 
 public class CheckstyleReportGenerator
 {
+    private Log log;
+    
     private ResourceBundle bundle;
     
     private Sink sink;
     
     private SeverityLevel severityLevel;
     
+    private Configuration checkstyleConfig;
+    
+    private ModuleFactory checkstyleModuleFactory;
+    
+    private boolean enableRulesSummary;
+    
+    private boolean enableSeveritySummary;
+    
+    private boolean enableFilesSummary;
+    
+    private boolean enableRSS;
+    
     public CheckstyleReportGenerator( Sink sink, ResourceBundle bundle )
     {
         this.bundle = bundle;
         
         this.sink = sink;
+        
+        this.enableRulesSummary = true;
+        this.enableSeveritySummary = true;
+        this.enableFilesSummary = true;
+        this.enableRSS = true;
+    }
+    
+    public Log getLog()
+    {
+        if ( this.log == null )
+        {
+            this.log = new SystemStreamLog();
+        }
+        return this.log;
+    }
+    
+    public void setLog( Log log )
+    {
+        this.log = log;
     }
     
     private String getTitle()
@@ -53,18 +93,28 @@
         return title;
     }
 
-    public void generateReport( Map files )
+    public void generateReport( CheckstyleResults results )
     {
         doHeading();
         
         if ( getSeverityLevel() == null ) 
         {
-            doSeveritySummary( files );
-
-            doFilesSummary( files );
+            if(enableSeveritySummary) {
+                doSeveritySummary( results );
+            }
+            
+            if(enableRulesSummary) {
+                doRulesSummary( results );
+            }
+            
+            if(enableFilesSummary) {
+                doFilesSummary( results );
+            }
         }
         
-        doDetails( files );
+        doDetails( results );
+        sink.body_();
+        sink.flush();
     }
     
     private void doHeading()
@@ -81,79 +131,363 @@
         sink.sectionTitle1();
         sink.text( getTitle() );
         sink.sectionTitle1_();
-
+        
+        doxiaHack(); 
+        
         sink.paragraph();
         sink.text( bundle.getString( "report.checkstyle.checkstylelink" ) + " " );
         sink.link( "http://checkstyle.sourceforge.net/" );
         sink.text( "Checkstyle" );
         sink.link_();
+        sink.text( "." );
+        
+        if(enableRSS)
+        {
+            sink.nonBreakingSpace();
+            sink.link( "checkstyle.rss" );
+            sink.figure();
+            sink.figureCaption();
+            sink.text( "rss feed" );
+            sink.figureCaption_();
+            sink.figureGraphics( "images/rss.png" );
+            sink.figure_();
+            sink.link_();
+        }
+        
         sink.paragraph_();
+        doxiaHack(); 
+    }
+    
+    private void iconSeverity( String level )
+    {
+        if ( SeverityLevel.INFO.getName().equalsIgnoreCase( level ) )
+        {
+            iconInfo();
+        }
+        else if ( SeverityLevel.WARNING.getName().equalsIgnoreCase( level ) )
+        {
+            iconWarning();
+        }
+        else if ( SeverityLevel.ERROR.getName().equalsIgnoreCase( level ) )
+        {
+            iconError();
+        }
     }
     
-    private void doSeveritySummary( Map files )
+    private void iconInfo()
+    {
+        sink.figure();
+        sink.figureCaption();
+        sink.text( "info" );
+        sink.figureCaption_();
+        sink.figureGraphics( "images/icon_info_sml.gif" );
+        sink.figure_();
+    }
+
+    private void iconWarning()
     {
+        sink.figure();
+        sink.figureCaption();
+        sink.text( "warning" );
+        sink.figureCaption_();
+        sink.figureGraphics( "images/icon_warning_sml.gif" );
+        sink.figure_();
+    }
+
+    private void iconError()
+    {
+        sink.figure();
+        sink.figureCaption();
+        sink.text( "error" );
+        sink.figureCaption_();
+        sink.figureGraphics( "images/icon_error_sml.gif" );
+        sink.figure_();
+    }    
+    
+    private String getConfigAttribute(Configuration config, String attname, String defvalue) {
+        String ret = defvalue;
+        try
+        {
+            ret = config.getAttribute(attname);
+        }
+        catch ( CheckstyleException e )
+        {
+            ret = defvalue; 
+        } 
+        return ret;
+    }
+    
+    private void doRulesSummary( CheckstyleResults results )
+    {
+        if ( checkstyleConfig == null )
+        {
+            return;
+        }
+
         sink.section1();
         sink.sectionTitle1();
-        sink.text( bundle.getString( "report.checkstyle.summary" ) );
+        sink.text( bundle.getString( "report.checkstyle.rules" ) );
         sink.sectionTitle1_();
+        doxiaHack(); 
         
         sink.table();
         
         sink.tableRow();
         sink.tableHeaderCell();
-        sink.text( bundle.getString( "report.checkstyle.files" ) );
-        sink.tableHeaderCell_();
-        sink.tableHeaderCell();
-        sink.text( "Infos" );
+        sink.text( bundle.getString( "report.checkstyle.rules" ) );
         sink.tableHeaderCell_();
+        
         sink.tableHeaderCell();
-        sink.text( "Warnings" );
+        sink.text( "Violations" );
         sink.tableHeaderCell_();
+        
         sink.tableHeaderCell();
-        sink.text( "Errors" );
+        sink.text( "Severity" );
         sink.tableHeaderCell_();
         sink.tableRow_();
         
+        // Top level should be the checker.
+        if ( "checker".equalsIgnoreCase( checkstyleConfig.getName() ) )
+        {
+            doRuleChildren( checkstyleConfig.getChildren(), results );
+        }
+        else
+        {
+            sink.tableRow();
+            sink.tableCell();
+            sink.text( "No Rules Found." );
+            sink.tableCell_();
+            sink.tableRow_();
+        }
+
+        sink.table_();
+        
+        sink.section1_();
+        doxiaHack(); 
+    }
+    
+    private void doRuleChildren( Configuration configChildren[], CheckstyleResults results )
+    {
+        for ( int cci = 0; cci < configChildren.length; cci++ )
+        {
+            String ruleName = configChildren[cci].getName();
+
+            if ( "TreeWalker".equals( ruleName ) )
+            {
+                // special sub-case
+                doRuleChildren( configChildren[cci].getChildren(), results );
+            }
+            else
+            {
+                doRuleRow( configChildren[cci], ruleName, results );
+            }
+        }
+    }
+
+    private void doRuleRow( Configuration checkerConfig, String ruleName, CheckstyleResults results )
+    {
         sink.tableRow();
         sink.tableCell();
-        sink.text( String.valueOf( files.size() ) );
-        sink.tableCell_();
-        sink.tableCell();
-        sink.text( countSeverity( files.values().iterator(), SeverityLevel.INFO ) );
+        sink.text( ruleName );
+        
+        List attribnames = Arrays.asList( checkerConfig.getAttributeNames() );
+        attribnames.remove( "severity" ); // special value (deserves unique column)
+        if ( !attribnames.isEmpty() )
+        {
+            sink.list();
+            Iterator it = attribnames.iterator();
+            while ( it.hasNext() )
+            {
+                sink.listItem();
+                String name = (String) it.next();
+                sink.bold();
+                sink.text( name );
+                sink.bold_();
+
+                String value = getConfigAttribute( checkerConfig, name, "" );
+                // special case, Header.header and RegexpHeader.header
+                if ( "header".equals( name ) && ( "Header".equals( ruleName ) || "RegexpHeader".equals( ruleName ) ) )
+                {
+                    List lines = stringSplit(value, "\\n");
+                    int linenum = 1;
+                    Iterator itl = lines.iterator();
+                    while(itl.hasNext())
+                    {
+                        String line = (String) itl.next();
+                        sink.lineBreak();
+                        sink.rawText( "<span style=\"color: gray\">" );
+                        sink.text( linenum + ":" );
+                        sink.rawText( "</span>" );
+                        sink.nonBreakingSpace();
+                        sink.monospaced();
+                        sink.text(line);
+                        sink.monospaced_();
+                        linenum++;
+                    }
+                } else {
+                    sink.text( ": " );
+                    sink.monospaced();
+                    sink.text( "\"" );
+                    sink.text( value );
+                    sink.text( "\"" );
+                    sink.monospaced_();
+                }
+                sink.listItem_();
+                doxiaHack(); 
+            }
+            sink.list_();
+        }
+        
         sink.tableCell_();
+        
         sink.tableCell();
-        sink.text( countSeverity( files.values().iterator(), SeverityLevel.WARNING ) );
+        String fixedmessage = getConfigAttribute( checkerConfig, "message", null );
+        sink.text( countRuleViolation( results.getFiles().values().iterator(), ruleName, fixedmessage ) );
         sink.tableCell_();
+        
         sink.tableCell();
-        sink.text( countSeverity( files.values().iterator(), SeverityLevel.ERROR ) );
+        String configSeverity = getConfigAttribute( checkerConfig, "severity", "error" );
+        iconSeverity( configSeverity );
+        sink.nonBreakingSpace();
+        sink.text( StringUtils.capitalise( configSeverity ) );
         sink.tableCell_();
+        
         sink.tableRow_();
+        doxiaHack(); 
+    }
+    
+    /**
+     * Splits a string against a delim consisting of a string (not a single character).
+     * 
+     * @param input
+     * @param delim
+     * @return
+     */
+    private List stringSplit( String input, String delim )
+    {
+        List ret = new ArrayList();
+
+        int delimLen = delim.length();
+        int offset = 0;
+        int lastOffset = 0;
+        String line;
 
-        sink.table_();
-        
-        sink.section1_();
+        while ( ( offset = input.indexOf( delim, offset ) ) >= 0 )
+        {
+            line = input.substring( lastOffset, offset );
+            ret.add( line );
+            offset += delimLen;
+            lastOffset = offset;
+        }
+
+        line = input.substring( lastOffset );
+        ret.add( line );
+
+        return ret;
     }
     
-    private String countSeverity( Iterator files, SeverityLevel level )
+    private String countRuleViolation( Iterator files, String ruleName, String message )
     {
         long count = 0;
+        String sourceName;
+        
+        try
+        {
+            sourceName = checkstyleModuleFactory.createModule(ruleName).getClass().getName();
+        }
+        catch ( CheckstyleException e )
+        {
+            getLog().error("Unable to obtain Source Name for Rule '" + ruleName + "'.", e);
+            return "(report failure)";
+        } 
         
         while ( files.hasNext() )
         {
             List errors = (List) files.next();
-            
-            for( Iterator error = errors.iterator(); error.hasNext(); )
+
+            for ( Iterator error = errors.iterator(); error.hasNext(); )
             {
                 AuditEvent event = (AuditEvent) error.next();
-                
-                if ( event.getSeverityLevel().equals( level ) ) count++;
+
+                if ( event.getSourceName().equals( sourceName ) )
+                {
+                    // check message too, for those that have a specific one.
+                    // like GenericIllegalRegexp and Regexp
+                    if ( message != null )
+                    {
+                        if ( message.equals( event.getMessage() ) )
+                        {
+                            count++;
+                        }
+                    }
+                    else
+                    {
+                        count++;
+                    }
+                }
             }
         }
         
         return String.valueOf( count );
+    }    
+    
+    private void doSeveritySummary( CheckstyleResults results )
+    {
+        sink.section1();
+        sink.sectionTitle1();
+        sink.text( bundle.getString( "report.checkstyle.summary" ) );
+        sink.sectionTitle1_();
+        
+        doxiaHack();
+        
+        sink.table();
+        
+        sink.tableRow();
+        sink.tableHeaderCell();
+        sink.text( bundle.getString( "report.checkstyle.files" ) );
+        sink.tableHeaderCell_();
+        
+        sink.tableHeaderCell();
+        sink.text( "Infos" );
+        sink.nonBreakingSpace();
+        iconInfo();
+        sink.tableHeaderCell_();
+        
+        sink.tableHeaderCell();
+        sink.text( "Warnings" );
+        sink.nonBreakingSpace();
+        iconWarning();
+        sink.tableHeaderCell_();
+        
+        sink.tableHeaderCell();
+        sink.text( "Errors" );
+        sink.nonBreakingSpace();
+        iconError();
+        sink.tableHeaderCell_();
+        sink.tableRow_();
+        
+        sink.tableRow();
+        sink.tableCell();
+        sink.text( String.valueOf( results.getFileCount() ) );
+        sink.tableCell_();
+        sink.tableCell();
+        sink.text( String.valueOf( results.getSeverityCount( SeverityLevel.INFO ) ) );
+        sink.tableCell_();
+        sink.tableCell();
+        sink.text( String.valueOf( results.getSeverityCount( SeverityLevel.WARNING ) ) );
+        sink.tableCell_();
+        sink.tableCell();
+        sink.text( String.valueOf( results.getSeverityCount( SeverityLevel.ERROR ) ) );
+        sink.tableCell_();
+        sink.tableRow_();
+
+        sink.table_();
+        
+        sink.section1_();
+        doxiaHack(); 
     }
     
-    private void doFilesSummary( Map filesMap )
+    private void doFilesSummary( CheckstyleResults results )
     {
         sink.section1();
         sink.sectionTitle1();
@@ -168,19 +502,25 @@
         sink.tableHeaderCell_();
         sink.tableHeaderCell();
         sink.text( "I" );
+        sink.nonBreakingSpace();
+        iconInfo();
         sink.tableHeaderCell_();
         sink.tableHeaderCell();
         sink.text( "W" );
+        sink.nonBreakingSpace();
+        iconWarning();
         sink.tableHeaderCell_();
         sink.tableHeaderCell();
         sink.text( "E" );
+        sink.nonBreakingSpace();
+        iconError();
         sink.tableHeaderCell_();
         sink.tableRow_();
         
-        for( Iterator files = filesMap.keySet().iterator(); files.hasNext(); )
+        for( Iterator files = results.getFiles().keySet().iterator(); files.hasNext(); )
         {
             String filename = (String) files.next();
-            List errors = (List) filesMap.get( filename );
+            List violations = (List) results.getFileViolations( filename );
             
             sink.tableRow();
             
@@ -191,33 +531,35 @@
             sink.tableCell_();
             
             sink.tableCell();
-            sink.text( countSeverity( Collections.singletonList( errors ).iterator(), SeverityLevel.INFO ) );
+            sink.text( String.valueOf( results.getSeverityCount( violations, SeverityLevel.INFO ) ) );
             sink.tableCell_();
             
             sink.tableCell();
-            sink.text( countSeverity( Collections.singletonList( errors ).iterator(), SeverityLevel.WARNING ) );
+            sink.text( String.valueOf( results.getSeverityCount( violations, SeverityLevel.WARNING ) ) );
             sink.tableCell_();
             
             sink.tableCell();
-            sink.text( countSeverity( Collections.singletonList( errors ).iterator(), SeverityLevel.ERROR ) );
+            sink.text( String.valueOf( results.getSeverityCount( violations, SeverityLevel.ERROR ) ) );
             sink.tableCell_();
             
             sink.tableRow_();
+            doxiaHack(); 
         }
         
         sink.table_();
         sink.section1_();
     }
     
-    private void doDetails( Map filesMap )
+    private void doDetails( CheckstyleResults results )
     {
-        Iterator files = filesMap.keySet().iterator();
+        Iterator files = results.getFiles().keySet().iterator();
         
         while ( files.hasNext() )
         {
             String file = (String) files.next();
-            List eventList = (List) filesMap.get( file );
+            List violations = (List) results.getFileViolations( file );
             
+            doxiaHack(); 
             sink.section1();
             sink.sectionTitle1();
             sink.anchor( file.replace( '/', '.' ) );
@@ -238,7 +580,7 @@
             sink.tableHeaderCell_();
             sink.tableRow_();
 
-            doFileEvents( eventList);
+            doFileEvents( violations);
             
             sink.table_();
             sink.section1_();
@@ -259,19 +601,14 @@
             sink.tableRow();
             
             sink.tableCell();
-            sink.figure();
-            sink.figureCaption();
-            sink.text( level.getName() );
-            sink.figureCaption_();
             
             if ( SeverityLevel.INFO.equals( level ) )
-                sink.figureGraphics( "images/icon_info_sml.gif" );
+                iconInfo();
             else if ( SeverityLevel.WARNING.equals( level ) )
-                sink.figureGraphics( "images/icon_warning_sml.gif" );
+                iconWarning();
             else if ( SeverityLevel.ERROR.equals( level ) )
-                sink.figureGraphics( "images/icon_error_sml.gif" );
+                iconError();
 
-            sink.figure_();
             sink.tableCell_();
             
             sink.tableCell();
@@ -283,6 +620,7 @@
             sink.tableCell_();
 
             sink.tableRow_();
+            doxiaHack(); 
         }
     }
     
@@ -294,5 +632,81 @@
     public void setSeverityLevel(SeverityLevel severityLevel)
     {
         this.severityLevel = severityLevel;
+    }
+
+    public boolean isEnableRulesSummary()
+    {
+        return enableRulesSummary;
+    }
+
+    public void setEnableRulesSummary( boolean enableRulesSummary )
+    {
+        this.enableRulesSummary = enableRulesSummary;
+    }
+
+    public boolean isEnableSeveritySummary()
+    {
+        return enableSeveritySummary;
+    }
+
+    public void setEnableSeveritySummary( boolean enableSeveritySummary )
+    {
+        this.enableSeveritySummary = enableSeveritySummary;
+    }
+
+    public boolean isEnableFilesSummary()
+    {
+        return enableFilesSummary;
+    }
+
+    public void setEnableFilesSummary( boolean enableFilesSummary )
+    {
+        this.enableFilesSummary = enableFilesSummary;
+    }
+
+    public boolean isEnableRSS()
+    {
+        return enableRSS;
+    }
+
+    public void setEnableRSS( boolean enableRSS )
+    {
+        this.enableRSS = enableRSS;
+    }
+
+    public Configuration getCheckstyleConfig()
+    {
+        return checkstyleConfig;
+    }
+
+    public void setCheckstyleConfig( Configuration config )
+    {
+        this.checkstyleConfig = config;
+    }
+
+    public ModuleFactory getCheckstyleModuleFactory()
+    {
+        return checkstyleModuleFactory;
+    }
+
+    public void setCheckstyleModuleFactory( ModuleFactory checkstyleModuleFactory )
+    {
+        this.checkstyleModuleFactory = checkstyleModuleFactory;
+    }
+    
+    /**
+     * This is here purely as a hack against the large lines the XhtmlSink
+     * produces.
+     * 
+     * On a large report, this causes the report output to end prematurely.
+     * 
+     * Doxia needs to be fixed. See MNG-1744 for details.
+     * 
+     * @deprecated Remove when Doxia's XhtmlSink and MNG-1744 are fixed.
+     */
+    private void doxiaHack()
+    {
+        sink.rawText("\n");
+        sink.flush();
     }
 }

Modified: maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleReportListener.java
URL: http://svn.apache.org/viewcvs/maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleReportListener.java?rev=354995&r1=354994&r2=354995&view=diff
==============================================================================
--- maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleReportListener.java (original)
+++ maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleReportListener.java Wed Dec  7 21:26:50 2005
@@ -16,17 +16,15 @@
  * limitations under the License.
  */
 
+import java.io.File;
+import java.util.List;
+
+import org.codehaus.plexus.util.StringUtils;
+
 import com.puppycrawl.tools.checkstyle.api.AuditEvent;
 import com.puppycrawl.tools.checkstyle.api.AuditListener;
 import com.puppycrawl.tools.checkstyle.api.AutomaticBean;
 import com.puppycrawl.tools.checkstyle.api.SeverityLevel;
-import java.util.LinkedList;
-import java.util.TreeMap;
-import java.util.Map;
-import java.util.List;
-import java.io.File;
-
-import org.codehaus.plexus.util.StringUtils;
 
 /**
  * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
@@ -38,7 +36,7 @@
 {
     private File sourceDirectory;
 
-    private Map files;
+    private CheckstyleResults results;
 
     private String currentFile;
 
@@ -63,7 +61,7 @@
 
     public void auditStarted( AuditEvent event )
     {
-        setFiles( new TreeMap() );
+        setResults( new CheckstyleResults() );
     }
 
     public void auditFinished( AuditEvent event )
@@ -76,15 +74,12 @@
         currentFile = StringUtils.substring( event.getFileName(), sourceDirectory.getPath().length() + 1 );
         currentFile = StringUtils.replace( currentFile, "\\", "/" );
 
-        if ( !getFiles().containsKey( currentFile ) )
-            getFiles().put( currentFile, new LinkedList() );
-
-        events = (LinkedList) getFiles().get( currentFile );
+        events = getResults().getFileViolations( currentFile );
     }
 
     public void fileFinished( AuditEvent event )
     {
-        getFiles().put( currentFile, events );
+        getResults().setFileViolations( currentFile, events );
         currentFile = null;
     }
 
@@ -103,14 +98,14 @@
         //Do Nothing
     }
 
-    public Map getFiles()
+    public CheckstyleResults getResults()
     {
-        return files;
+        return results;
     }
 
-    public void setFiles( Map files )
+    public void setResults( CheckstyleResults results )
     {
-        this.files = files;
+        this.results = results;
     }
 }
 

Added: maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleResults.java
URL: http://svn.apache.org/viewcvs/maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleResults.java?rev=354995&view=auto
==============================================================================
--- maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleResults.java (added)
+++ maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleResults.java Wed Dec  7 21:26:50 2005
@@ -0,0 +1,127 @@
+package org.apache.maven.plugin.checkstyle;
+
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import com.puppycrawl.tools.checkstyle.api.AuditEvent;
+import com.puppycrawl.tools.checkstyle.api.SeverityLevel;
+
+/**
+ * Object holding the references to the CheckstyleResults.
+ * 
+ * @author <a href="mailto:joakim@erdfelt.net">Joakim Erdfelt</a>
+ * @todo provide fallback to disk based storage if too many results.
+ */
+public class CheckstyleResults
+{
+    private Map files;
+
+    public CheckstyleResults()
+    {
+        files = new HashMap();
+    }
+
+    public List getFileViolations( String file )
+    {
+        List violations;
+
+        if ( this.files.containsKey( file ) )
+        {
+            violations = (List) this.files.get( file );
+        }
+        else
+        {
+            violations = new LinkedList();
+            this.files.put( file, violations );
+        }
+
+        return violations;
+    }
+
+    public void setFileViolations( String file, List violations )
+    {
+        this.files.put( file, violations );
+    }
+
+    public Map getFiles()
+    {
+        return files;
+    }
+
+    public void setFiles( Map files )
+    {
+        this.files = files;
+    }
+
+    public int getFileCount()
+    {
+        return this.files.size();
+    }
+    
+    public long getSeverityCount( SeverityLevel level )
+    {
+        long count = 0;
+        
+        Iterator it = this.files.values().iterator();
+        
+        while ( it.hasNext() )
+        {
+            List errors = (List) it.next();
+            
+            count = count + getSeverityCount(errors, level);
+        }
+
+        return count;
+    }
+    
+    public long getSeverityCount( String file, SeverityLevel level )
+    {
+        long count = 0;
+        
+        if ( !this.files.containsKey( file ) )
+        {
+            return count;
+        }
+        
+        List violations = (List) this.files.get(file);
+        
+        count = getSeverityCount( violations, level );
+
+        return count;
+    }
+    
+    public long getSeverityCount( List violations, SeverityLevel level )
+    {
+        long count = 0;
+        
+        Iterator it = violations.iterator();
+        
+        while(it.hasNext())
+        {
+            AuditEvent event = (AuditEvent) it.next();
+            
+            if ( event.getSeverityLevel().equals( level ) ) count++;
+        }
+        
+        return count;
+    }
+}

Propchange: maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleResults.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleResults.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleViolationCheckMojo.java
URL: http://svn.apache.org/viewcvs/maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleViolationCheckMojo.java?rev=354995&view=auto
==============================================================================
--- maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleViolationCheckMojo.java (added)
+++ maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleViolationCheckMojo.java Wed Dec  7 21:26:50 2005
@@ -0,0 +1,118 @@
+package org.apache.maven.plugin.checkstyle;
+
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ */
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.codehaus.plexus.util.xml.pull.MXParser;
+import org.codehaus.plexus.util.xml.pull.XmlPullParser;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+/**
+ * Perform a violation check against the last checkstyle run to see if there are any violations.
+ * 
+ * @author <a href="mailto:joakim@erdfelt.net">Joakim Erdfelt</a>
+ * @goal check
+ * @phase verify
+ * @execute goal="checkstyle"
+ */
+public class CheckstyleViolationCheckMojo
+    extends AbstractMojo
+{
+    /**
+     * Specifies the path and filename to save the checkstyle output.  The format of the output file is
+     * determined by the <code>outputFileFormat</code>
+     *
+     * @parameter expression="${checkstyle.output.file}" 
+     *            default-value="${project.build.directory}/checkstyle-result.xml"
+     */
+    private File outputFile;
+
+    /**
+     * Specifies the format of the output to be used when writing to the output file. Valid values are
+     * "plain" and "xml"
+     *
+     * @parameter expression="${checkstyle.output.format}" default-value="xml"
+     */
+    private String outputFileFormat;
+
+    public void execute()
+        throws MojoExecutionException, MojoFailureException
+    {
+        if ( !"xml".equals( outputFileFormat ) )
+        {
+            throw new MojoExecutionException( "Output format is '" + outputFileFormat
+                + "', checkstyle:check requires format to be 'xml'." );
+        }
+
+        if ( !outputFile.exists() )
+        {
+            throw new MojoExecutionException( "Unable to perform checkstyle:check, "
+                + "unable to find checkstyle:checkstyle outputFile." );
+        }
+
+        try
+        {
+            XmlPullParser xpp = new MXParser();
+            FileReader freader = new FileReader( outputFile );
+            BufferedReader breader = new BufferedReader( freader );
+            xpp.setInput( breader );
+
+            int violations = countViolations( xpp );
+            if ( violations > 0 )
+            {
+                throw new MojoFailureException( "You have " + violations + " checkstyle violation"
+                    + ( ( violations > 1 ) ? "s" : "" ) + "." );
+            }
+        }
+        catch ( IOException e )
+        {
+            throw new MojoExecutionException( "Unable to read checkstyle results xml: " + outputFile.getAbsolutePath(),
+                                              e );
+        }
+        catch ( XmlPullParserException e )
+        {
+            throw new MojoExecutionException( "Unable to read checkstyle results xml: " + outputFile.getAbsolutePath(),
+                                              e );
+        }
+    }
+
+    private int countViolations( XmlPullParser xpp )
+        throws XmlPullParserException, IOException
+    {
+        int count = 0;
+
+        int eventType = xpp.getEventType();
+        while ( ( eventType != XmlPullParser.END_DOCUMENT ) )
+        {
+            if ( ( eventType == XmlPullParser.START_TAG ) && "error".equals( xpp.getName() ) )
+            {
+                count++;
+            }
+            eventType = xpp.next();
+        }
+
+        return count;
+    }
+}

Propchange: maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleViolationCheckMojo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleViolationCheckMojo.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Modified: maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/Locator.java
URL: http://svn.apache.org/viewcvs/maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/Locator.java?rev=354995&r1=354994&r2=354995&view=diff
==============================================================================
--- maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/Locator.java (original)
+++ maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/Locator.java Wed Dec  7 21:26:50 2005
@@ -16,16 +16,16 @@
  * limitations under the License.
  */
 
-import org.apache.maven.plugin.logging.Log;
-import org.apache.maven.plugin.logging.SystemStreamLog;
-import org.codehaus.plexus.util.FileUtils;
-import org.codehaus.plexus.util.StringUtils;
-
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.net.URL;
 
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.plugin.logging.SystemStreamLog;
+import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.StringUtils;
+
 /**
  * Performs Locator services for the <code>*Location</code> parameters in the 
  * Reports.
@@ -35,15 +35,18 @@
 public class Locator
 {
     private Log log;
+    private File localDir;
 
     /**
      * Create a Locator object.
      * 
      * @param logger the logger object to log with.
+     * @param resolveToDir the directory to resolve resources into.
      */
-    public Locator( Log log )
+    public Locator( Log log, File resolveToDir )
     {
         this.log = log;
+        this.localDir = resolveToDir;
     }
 
     /**
@@ -85,7 +88,7 @@
             return null;
         }
 
-        File retFile = new File( localfile );
+        File retFile = new File( localDir, localfile );
 
         // Attempt a URL
         if ( location.indexOf( "://" ) > 1 )

Added: maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/ReportResource.java
URL: http://svn.apache.org/viewcvs/maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/ReportResource.java?rev=354995&view=auto
==============================================================================
--- maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/ReportResource.java (added)
+++ maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/ReportResource.java Wed Dec  7 21:26:50 2005
@@ -0,0 +1,86 @@
+package org.apache.maven.plugin.checkstyle;
+
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.plugin.logging.SystemStreamLog;
+import org.codehaus.plexus.util.FileUtils;
+
+/**
+ * Generic Report Resource management.
+ * 
+ * @author <a href="mailto:joakim@erdfelt.net">Joakim Erdfelt</a>
+ */
+public class ReportResource
+{
+    private Log log;
+
+    private String resourcePathBase;
+
+    private File outputDirectory;
+
+    public ReportResource( String resourcePathBase, File outputDirectory )
+    {
+        this.resourcePathBase = resourcePathBase;
+        this.outputDirectory = outputDirectory;
+    }
+
+    public void copy( String resourceName )
+        throws IOException
+    {
+        URL url = Thread.currentThread().getContextClassLoader().getResource( resourcePathBase + "/" + resourceName );
+        FileUtils.copyURLToFile( url, new File( outputDirectory, resourceName ) );
+    }
+
+    public Log getLog()
+    {
+        if ( this.log == null )
+        {
+            this.log = new SystemStreamLog();
+        }
+        return log;
+    }
+
+    public void setLog( Log log )
+    {
+        this.log = log;
+    }
+
+    public File getOutputDirectory()
+    {
+        return outputDirectory;
+    }
+
+    public void setOutputDirectory( File outputDirectory )
+    {
+        this.outputDirectory = outputDirectory;
+    }
+
+    public String getResourcePathBase()
+    {
+        return resourcePathBase;
+    }
+
+    public void setResourcePathBase( String resourcePathBase )
+    {
+        this.resourcePathBase = resourcePathBase;
+    }
+}

Propchange: maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/ReportResource.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/ReportResource.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/VelocityTemplate.java
URL: http://svn.apache.org/viewcvs/maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/VelocityTemplate.java?rev=354995&view=auto
==============================================================================
--- maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/VelocityTemplate.java (added)
+++ maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/VelocityTemplate.java Wed Dec  7 21:26:50 2005
@@ -0,0 +1,153 @@
+package org.apache.maven.plugin.checkstyle;
+
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.plugin.logging.SystemStreamLog;
+import org.apache.velocity.context.Context;
+import org.apache.velocity.exception.ResourceNotFoundException;
+import org.apache.velocity.exception.VelocityException;
+import org.codehaus.plexus.velocity.VelocityComponent;
+
+/**
+ * <p>
+ * A component to work with VelocityTemplates from within plugins.
+ * </p>
+ * 
+ * <p>
+ * You will need to reference the velocity component as a parameter
+ * in your plugin.  Like this:
+ * </p>
+ * <pre>
+ * /&#042;&#042;
+ *  &#042; Velocity Component
+ *  &#042; &#064;parameter expression="${component.org.codehaus.plexus.velocity.VelocityComponent}"
+ *  &#042; &#064;readonly
+ *  &#042;/
+ *  private VelocityComponent velocity;
+ * </pre>
+ * 
+ * @author <a href="mailto:joakim@erdfelt.net">Joakim Erdfelt</a>
+ */
+public class VelocityTemplate
+{
+    private String templateDirectory;
+
+    private Log log;
+
+    private VelocityComponent velocity;
+
+    public VelocityTemplate( VelocityComponent velocityComponent, String templateBaseDirectory )
+    {
+        this.velocity = velocityComponent;
+        this.templateDirectory = templateBaseDirectory;
+    }
+
+    public String getTemplateDirectory()
+    {
+        return templateDirectory;
+    }
+
+    public VelocityComponent getVelocity()
+    {
+        return velocity;
+    }
+
+    /**
+     * Using a specified Velocity Template and provided context, create the outputFilename.
+     * @param outputFilename the file to be generated.
+     * @param template the velocity template to use.
+     * @param context the velocity context map.
+     *
+     * @throws ResourceNotFoundException if the template was not found.
+     * @throws VelocityException if the 
+     * @throws MojoExecutionException
+     * @throws IOException
+     */
+    public void generate( String outputFilename, String template, Context context )
+        throws ResourceNotFoundException, VelocityException, MojoExecutionException, IOException
+    {
+        File f;
+
+        try
+        {
+            f = new File( outputFilename );
+
+            if ( !f.getParentFile().exists() )
+            {
+                f.getParentFile().mkdirs();
+            }
+
+            Writer writer = new FileWriter( f );
+
+            getVelocity().getEngine().mergeTemplate( templateDirectory + "/" + template, context, writer );
+
+            writer.flush();
+            writer.close();
+
+            getLog().debug( "File " + outputFilename + " created..." );
+        }
+
+        catch ( ResourceNotFoundException e )
+        {
+            throw new ResourceNotFoundException( "Template not found: " + templateDirectory + "/" + template );
+        }
+        catch ( VelocityException e )
+        {
+            throw e; // to get past generic catch for Exception.
+        }
+        catch ( IOException e )
+        {
+            throw e; // to get past generic catch for Exception.
+        }
+        catch ( Exception e )
+        {
+            throw new MojoExecutionException( e.getMessage(), e );
+        }
+    }
+
+    public void setTemplateDirectory( String templateDirectory )
+    {
+        this.templateDirectory = templateDirectory;
+    }
+
+    public void setVelocity( VelocityComponent velocity )
+    {
+        this.velocity = velocity;
+    }
+
+    public Log getLog()
+    {
+        if ( this.log == null )
+        {
+            this.log = new SystemStreamLog();
+        }
+        return log;
+    }
+
+    public void setLog( Log log )
+    {
+        this.log = log;
+    }
+
+}

Propchange: maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/VelocityTemplate.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/VelocityTemplate.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Modified: maven/plugins/trunk/maven-checkstyle-plugin/src/main/resources/checkstyle-report.properties
URL: http://svn.apache.org/viewcvs/maven/plugins/trunk/maven-checkstyle-plugin/src/main/resources/checkstyle-report.properties?rev=354995&r1=354994&r2=354995&view=diff
==============================================================================
--- maven/plugins/trunk/maven-checkstyle-plugin/src/main/resources/checkstyle-report.properties (original)
+++ maven/plugins/trunk/maven-checkstyle-plugin/src/main/resources/checkstyle-report.properties Wed Dec  7 21:26:50 2005
@@ -22,4 +22,5 @@
 report.checkstyle.checkstylelink=The following document contains the results of
 report.checkstyle.files=Files
 report.checkstyle.summary=Summary
+report.checkstyle.rules=Rules
 report.checkstyle.severity_title=Checkstyle errors in severity

Modified: maven/plugins/trunk/maven-checkstyle-plugin/src/main/resources/checkstyle-report_fr.properties
URL: http://svn.apache.org/viewcvs/maven/plugins/trunk/maven-checkstyle-plugin/src/main/resources/checkstyle-report_fr.properties?rev=354995&r1=354994&r2=354995&view=diff
==============================================================================
--- maven/plugins/trunk/maven-checkstyle-plugin/src/main/resources/checkstyle-report_fr.properties (original)
+++ maven/plugins/trunk/maven-checkstyle-plugin/src/main/resources/checkstyle-report_fr.properties Wed Dec  7 21:26:50 2005
@@ -22,4 +22,5 @@
 report.checkstyle.checkstylelink=Le document suivant contient les résultats de
 report.checkstyle.files=Fichiers
 report.checkstyle.summary=Résumé
+report.checkstyle.rules=Réglée
 report.checkstyle.severity_title=Erreurs Checkstyle par sévérité

Added: maven/plugins/trunk/maven-checkstyle-plugin/src/main/resources/org/apache/maven/plugin/checkstyle/checkstyle-rss.vm
URL: http://svn.apache.org/viewcvs/maven/plugins/trunk/maven-checkstyle-plugin/src/main/resources/org/apache/maven/plugin/checkstyle/checkstyle-rss.vm?rev=354995&view=auto
==============================================================================
--- maven/plugins/trunk/maven-checkstyle-plugin/src/main/resources/org/apache/maven/plugin/checkstyle/checkstyle-rss.vm (added)
+++ maven/plugins/trunk/maven-checkstyle-plugin/src/main/resources/org/apache/maven/plugin/checkstyle/checkstyle-rss.vm Wed Dec  7 21:26:50 2005
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<rss version="0.91">
+  <channel>
+    <title>${project.name} - Checkstyle report</title>
+    <link>${project.url}</link>
+    <description>${project.name} - Checkstyle report</description>
+    <language>en-us</language>
+    <copyright>&#169;${copyright}</copyright>
+    <item>
+      <title>File: $results.getFileCount(),
+             Errors: $results.getSeverityCount($levelError),
+             Warnings: $results.getSeverityCount($levelWarning),
+             Infos: $results.getSeverityCount($levelInfo)
+      </title>
+      #set ( $reportlink = "${project.url}/checkstyle.html" )
+      <link>$reportlink</link>
+      <description>
+        <p>Click <a href="$reportlink">here</a> for the full Checkstyle report.</p>
+
+        <table summary="Files" boder="1">
+          <thead>
+            <tr>
+              <th>Files</th>
+              <th style="width:30px;"><abbr title="Info">I</abbr></th>
+              <th style="width:30px;"><abbr title="Warning">W</abbr></th>
+              <th style="width:30px;"><abbr title="Error">E</abbr></th>
+            </tr>
+          </thead>
+          <tbody>
+            #foreach( $key in $results.files.keySet() )
+              #set ( $filename = $key.toString() )
+              #set ( $anchor = $stringutils.replace( $filename, '\\', '/' ) )
+              #set ( $anchor = $stringutils.replace( $anchor, '/', '.' ) )
+              <tr>
+                <td>
+                  <a href="${reportlink}#$anchor">$filename</a>
+                </td>
+                <td>
+                  $results.getSeverityCount(${key}, $levelInfo)
+                </td>
+                <td>
+                  $results.getSeverityCount(${key}, $levelWarning)
+                </td>
+                <td>
+                  $results.getSeverityCount(${key}, $levelError)
+                </td>
+              </tr>
+            #end
+          </tbody>
+        </table>
+        
+      </description>
+    </item>
+  </channel>
+</rss>
+

Propchange: maven/plugins/trunk/maven-checkstyle-plugin/src/main/resources/org/apache/maven/plugin/checkstyle/checkstyle-rss.vm
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/plugins/trunk/maven-checkstyle-plugin/src/main/resources/org/apache/maven/plugin/checkstyle/checkstyle-rss.vm
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"