You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by rf...@apache.org on 2014/08/19 19:23:18 UTC

svn commit: r1618905 - in /maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle: ./ exec/

Author: rfscholte
Date: Tue Aug 19 17:23:18 2014
New Revision: 1618905

URL: http://svn.apache.org/r1618905
Log:
[MCHECKSTYLE-70] Support for multiple source folders
Support for multiple test source folders added as well.
SourceFolders are used twice, so using a List(stand-alone) or Map(aggregator) to hold entries for reuse in DCExecutor.
Using Collection, so signatures won't change if we must switch between List and Set
File.isDirectory() already implies that it exists, so those checks have been removed

Modified:
    maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/AbstractCheckstyleReport.java
    maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleAggregateReport.java
    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/CheckstyleViolationCheckMojo.java
    maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/exec/CheckstyleExecutorRequest.java
    maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/exec/DefaultCheckstyleExecutor.java

Modified: maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/AbstractCheckstyleReport.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/AbstractCheckstyleReport.java?rev=1618905&r1=1618904&r2=1618905&view=diff
==============================================================================
--- maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/AbstractCheckstyleReport.java (original)
+++ maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/AbstractCheckstyleReport.java Tue Aug 19 17:23:18 2014
@@ -27,6 +27,7 @@ import java.io.IOException;
 import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.Calendar;
+import java.util.Collections;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
@@ -55,6 +56,7 @@ import org.apache.maven.reporting.Abstra
 import org.apache.maven.reporting.MavenReportException;
 import org.codehaus.plexus.resource.ResourceManager;
 import org.codehaus.plexus.resource.loader.FileResourceLoader;
+import org.codehaus.plexus.util.FileUtils;
 import org.codehaus.plexus.util.PathTool;
 import org.codehaus.plexus.util.StringUtils;
 
@@ -279,21 +281,40 @@ public abstract class AbstractCheckstyle
 
     /**
      * Specifies the location of the source directory to be used for Checkstyle.
+     * 
+     * @deprecated instead use {@link #sourceDirectories}
      */
-    @Parameter( defaultValue = "${project.build.sourceDirectory}", required = true )
-    protected File sourceDirectory;
+    @Deprecated
+    @Parameter
+    private File sourceDirectory;
 
     /**
+     * Specifies the location of the source directories to be used for Checkstyle.
+     * @since 2.13
+     */
+    @Parameter( defaultValue = "${project.compileSourceRoots}" )
+    private List<String> sourceDirectories;
+    
+    /**
      * Specifies the location of the test source directory to be used for
      * Checkstyle.
      *
      * @since 2.2
+     * @deprecated instead use {@link #testSourceDirectories}
      */
-    @Parameter( defaultValue = "${project.build.testSourceDirectory}" )
-    protected File testSourceDirectory;
+    @Parameter
+    @Deprecated
+    private File testSourceDirectory;
+    
+    /**
+     * Specifies the location of the test source directories to be used for Checkstyle.
+     * @since 2.13
+     */
+    @Parameter( defaultValue = "${project.testCompileSourceRoots}" )
+    private List<String> testSourceDirectories;
 
     /**
-     * Include or not the test source directory to be used for Checkstyle.
+     * Include or not the test source directory/directories to be used for Checkstyle.
      *
      * @since 2.2
      */
@@ -754,5 +775,44 @@ public abstract class AbstractCheckstyle
         this.outputDirectory = reportOutputDirectory;
     }
     
-    
+    protected List<File> getSourceDirectories()
+    {
+        List<File> sourceDirs = null;
+        // if sourceDirectory is explicitly set, use it
+        if( sourceDirectory != null )
+        {
+            sourceDirs = Collections.singletonList( sourceDirectory );
+        }
+        else
+        {
+            sourceDirs = new ArrayList<File>( sourceDirectories.size() );
+            for ( String sourceDir : sourceDirectories )
+            {
+                sourceDirs.add( FileUtils.resolveFile( project.getBasedir(), sourceDir ) );
+            }
+        }
+        
+        return sourceDirs;
+    }
+
+    protected List<File> getTestSourceDirectories()
+    {
+        List<File> testSourceDirs = null;
+        // if testSourceDirectory is explicitly set, use it
+        if( testSourceDirectory != null )
+        {
+            testSourceDirs = Collections.singletonList( testSourceDirectory );
+        }
+        // probably null-check only required due to MavenProjectStubs
+        else if ( testSourceDirectories != null )
+        {
+            testSourceDirs = new ArrayList<File>( testSourceDirectories.size() );
+            for ( String testSourceDir : testSourceDirectories )
+            {
+                testSourceDirs.add( FileUtils.resolveFile( project.getBasedir(), testSourceDir ) );
+            }
+        }
+        
+        return testSourceDirs;
+    }
 }

Modified: maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleAggregateReport.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleAggregateReport.java?rev=1618905&r1=1618904&r2=1618905&view=diff
==============================================================================
--- maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleAggregateReport.java (original)
+++ maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleAggregateReport.java Tue Aug 19 17:23:18 2014
@@ -71,10 +71,10 @@ public class CheckstyleAggregateReport
             .setResourceIncludes( resourceIncludes )
             .setResourceExcludes( resourceExcludes )
             .setIncludeTestSourceDirectory( includeTestSourceDirectory ).setListener( getListener() )
-            .setLog( getLog() ).setProject( project ).setSourceDirectory( sourceDirectory ).setResources( resources )
+            .setLog( getLog() ).setProject( project ).setSourceDirectories( getSourceDirectories() ).setResources( resources )
             .setTestResources( testResources )
             .setStringOutputStream( stringOutputStream ).setSuppressionsLocation( suppressionsLocation )
-            .setTestSourceDirectory( testSourceDirectory ).setConfigLocation( configLocation )
+            .setTestSourceDirectories( getTestSourceDirectories() ).setConfigLocation( configLocation )
             .setPropertyExpansion( propertyExpansion ).setHeaderLocation( headerLocation )
             .setCacheFile( cacheFile ).setSuppressionsFileExpression( suppressionsFileExpression )
             .setEncoding( encoding ).setPropertiesLocation( propertiesLocation );

Modified: maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleReport.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleReport.java?rev=1618905&r1=1618904&r2=1618905&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 Tue Aug 19 17:23:18 2014
@@ -19,6 +19,14 @@ package org.apache.maven.plugin.checksty
  * under the License.
  */
 
+import java.io.File;
+import java.net.URL;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
 import org.apache.maven.model.Resource;
 import org.apache.maven.plugin.checkstyle.exec.CheckstyleExecutorRequest;
 import org.apache.maven.plugins.annotations.Mojo;
@@ -28,14 +36,6 @@ import org.apache.maven.project.MavenPro
 import org.apache.maven.reporting.MavenReportException;
 import org.codehaus.plexus.util.StringUtils;
 
-import java.io.File;
-import java.net.URL;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
 /**
  * A reporting task that performs Checkstyle analysis and generates an HTML
  * report on any violations that Checkstyle finds.
@@ -171,9 +171,9 @@ public class CheckstyleReport
             .setIncludeResources( includeResources )
             .setIncludeTestResources( includeTestResources )
             .setIncludeTestSourceDirectory( includeTestSourceDirectory ).setListener( getListener() )
-            .setLog( getLog() ).setProject( project ).setSourceDirectory( sourceDirectory ).setResources( resources )
+            .setLog( getLog() ).setProject( project ).setSourceDirectories( getSourceDirectories() ).setResources( resources )
             .setStringOutputStream( stringOutputStream ).setSuppressionsLocation( suppressionsLocation )
-            .setTestSourceDirectory( testSourceDirectory ).setConfigLocation( configLocation )
+            .setTestSourceDirectories( getTestSourceDirectories() ).setConfigLocation( configLocation )
             .setPropertyExpansion( propertyExpansion ).setHeaderLocation( headerLocation )
             .setCacheFile( cacheFile ).setSuppressionsFileExpression( suppressionsFileExpression )
             .setEncoding( encoding ).setPropertiesLocation( propertiesLocation );
@@ -189,10 +189,32 @@ public class CheckstyleReport
     /** {@inheritDoc} */
     public boolean canGenerateReport()
     {
+        if ( skip )
+        {
+            return false;
+        }
+        
         // TODO: would be good to scan the files here
-        return !skip && ( sourceDirectory.exists()
-            || ( includeTestSourceDirectory && testSourceDirectory.exists() )
-            || ( includeResources && hasResources( resources ) )
+        for ( File sourceDirectory : getSourceDirectories() )
+        {
+            if ( sourceDirectory.exists() )
+            {
+                return true;
+            }
+        }
+        
+        if ( includeTestSourceDirectory )
+        {
+            for ( File testSourceDirectory : getTestSourceDirectories() )
+            {
+                if ( testSourceDirectory.exists() )
+                {
+                    return true;
+                }
+            }
+        }
+        
+        return ( ( includeResources && hasResources( resources ) )
             || ( includeTestResources && hasResources( testResources ) )
         );
     }

Modified: maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleViolationCheckMojo.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleViolationCheckMojo.java?rev=1618905&r1=1618904&r2=1618905&view=diff
==============================================================================
--- maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleViolationCheckMojo.java (original)
+++ maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/CheckstyleViolationCheckMojo.java Tue Aug 19 17:23:18 2014
@@ -28,6 +28,7 @@ import java.io.IOException;
 import java.io.OutputStream;
 import java.io.Reader;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
@@ -382,11 +383,21 @@ public class CheckstyleViolationCheckMoj
      * Checkstyle.
      *
      * @since 2.2
+     * @deprecated instead use {@link #testSourceDirectories} 
      */
-    @Parameter( defaultValue = "${project.build.testSourceDirectory}" )
+    @Deprecated
+    @Parameter
     private File testSourceDirectory;
 
     /**
+     * Specifies the location of the test source directories to be used for
+     * Checkstyle.
+     * @since 2.13
+     */
+    @Parameter( defaultValue = "${project.testCompileSourceRoots}" )
+    private List<String> testSourceDirectories;
+
+    /**
      * Include or not the test source directory to be used for Checkstyle.
      *
      * @since 2.2
@@ -396,11 +407,21 @@ public class CheckstyleViolationCheckMoj
 
     /**
      * Specifies the location of the source directory to be used for Checkstyle.
+     * 
+     * @deprecated instead use {@link #sourceDirectories}
      */
-    @Parameter( defaultValue = "${project.build.sourceDirectory}", required = true )
+    @Deprecated
+    @Parameter
     private File sourceDirectory;
 
     /**
+     * Specifies the location of the source directories to be used for Checkstyle.
+     * @since 2.13
+     */
+    @Parameter( defaultValue = "${project.compileSourceRoots}" )
+    private List<String> sourceDirectories;
+
+    /**
      * Whether to apply Checkstyle to resource directories.
      * @since 2.11
      */
@@ -499,10 +520,10 @@ public class CheckstyleViolationCheckMoj
                     .setIncludeResources( includeResources )
                     .setIncludeTestResources( includeTestResources )
                     .setIncludeTestSourceDirectory( includeTestSourceDirectory ).setListener( getListener() )
-                    .setLog( getLog() ).setProject( project ).setSourceDirectory( sourceDirectory )
+                    .setLog( getLog() ).setProject( project ).setSourceDirectories( getSourceDirectories() )
                     .setResources( resources )
                     .setStringOutputStream( stringOutputStream ).setSuppressionsLocation( suppressionsLocation )
-                    .setTestSourceDirectory( testSourceDirectory ).setConfigLocation( configLocation )
+                    .setTestSourceDirectories( getTestSourceDirectories() ).setConfigLocation( configLocation )
                     .setConfigurationArtifacts( collectArtifacts( "config" ) )
                     .setPropertyExpansion( propertyExpansion )
                     .setHeaderLocation( headerLocation ).setLicenseArtifacts( collectArtifacts( "license" ) )
@@ -793,4 +814,45 @@ public class CheckstyleViolationCheckMoj
         return artifacts;
     }
     
+    private List<File> getSourceDirectories()
+    {
+        List<File> sourceDirs = null;
+        // if sourceDirectory is explicitly set, use it
+        if( sourceDirectory != null )
+        {
+            sourceDirs = Collections.singletonList( sourceDirectory );
+        }
+        else
+        {
+            sourceDirs = new ArrayList<File>( sourceDirectories.size() );
+            for ( String sourceDir : sourceDirectories )
+            {
+                sourceDirs.add( FileUtils.resolveFile( project.getBasedir(), sourceDir ) );
+            }
+        }
+        
+        return sourceDirs;
+    }
+    
+    private List<File> getTestSourceDirectories()
+    {
+        List<File> testSourceDirs = null;
+        // if testSourceDirectory is explicitly set, use it
+        if( testSourceDirectory != null )
+        {
+            testSourceDirs = Collections.singletonList( testSourceDirectory );
+        }
+        // probably null-check only required due to MavenProjectStubs
+        else if ( testSourceDirectories != null )
+        {
+            testSourceDirs = new ArrayList<File>( testSourceDirectories.size() );
+            for ( String testSourceDir : testSourceDirectories )
+            {
+                testSourceDirs.add( FileUtils.resolveFile( project.getBasedir(), testSourceDir ) );
+            }
+        }
+        
+        return testSourceDirs;
+    }
+    
 }

Modified: maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/exec/CheckstyleExecutorRequest.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/exec/CheckstyleExecutorRequest.java?rev=1618905&r1=1618904&r2=1618905&view=diff
==============================================================================
--- maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/exec/CheckstyleExecutorRequest.java (original)
+++ maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/exec/CheckstyleExecutorRequest.java Tue Aug 19 17:23:18 2014
@@ -21,6 +21,8 @@ package org.apache.maven.plugin.checksty
 
 import java.io.ByteArrayOutputStream;
 import java.io.File;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 
 import org.apache.maven.artifact.Artifact;
@@ -67,9 +69,9 @@ public class CheckstyleExecutorRequest
 
     private boolean includeTestSourceDirectory;
 
-    private File testSourceDirectory;
+    private Collection<File> testSourceDirectories;
 
-    private File sourceDirectory;
+    private Collection<File> sourceDirectories;
 
     private boolean includeResources;
 
@@ -226,25 +228,86 @@ public class CheckstyleExecutorRequest
         return this;
     }
 
+    /**
+     * 
+     * @return first entry of testSourceDirectories, otherwise {@code null}
+     * @deprecated instead use {@link #getTestSourceDirectories()}
+     */
+    @Deprecated
     public File getTestSourceDirectory()
     {
-        return testSourceDirectory;
+        if( testSourceDirectories == null || testSourceDirectories.size() == 0 )
+        {
+            return null;
+        }
+        else
+        {
+            return testSourceDirectories.iterator().next();
+        }
     }
 
+    /**
+     * 
+     * @param testSourceDirectory a single testSourceDirectory
+     * @return this request
+     * @deprecated instead use {@link #setTestSourceDirectories(Collection)}
+     */
+    @Deprecated
     public CheckstyleExecutorRequest setTestSourceDirectory( File testSourceDirectory )
     {
-        this.testSourceDirectory = testSourceDirectory;
+        this.testSourceDirectories = Collections.singletonList( testSourceDirectory );
         return this;
     }
-
+    
+    public Collection<File> getTestSourceDirectories()
+    {
+        return testSourceDirectories;
+    }
+    
+    public CheckstyleExecutorRequest setTestSourceDirectories( Collection<File> testSourceDirectories )
+    {
+        this.testSourceDirectories = testSourceDirectories;
+        return this;
+    }
+    
+    /**
+     * @return first entry of sourceDirectories, otherwise {@code null}
+     * @deprecated instead use {@link #getSourceDirectories()}
+     */
+    @Deprecated
     public File getSourceDirectory()
     {
-        return sourceDirectory;
+        if( sourceDirectories == null || sourceDirectories.size() == 0 )
+        {
+            return null;
+        }
+        else
+        {
+            return sourceDirectories.iterator().next();
+        }
     }
 
+    /**
+     * 
+     * @param sourceDirectory a single sourceDirectory
+     * @return this request
+     * @deprecated instead use {@link #setSourceDirectories(Collection)}
+     */
+    @Deprecated
     public CheckstyleExecutorRequest setSourceDirectory( File sourceDirectory )
     {
-        this.sourceDirectory = sourceDirectory;
+        this.sourceDirectories = Collections.singletonList( sourceDirectory );
+        return this;
+    }
+    
+    public Collection<File> getSourceDirectories()
+    {
+        return sourceDirectories;
+    }
+    
+    public CheckstyleExecutorRequest setSourceDirectories( Collection<File> sourceDirectories )
+    {
+        this.sourceDirectories = sourceDirectories;
         return this;
     }
 

Modified: maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/exec/DefaultCheckstyleExecutor.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/exec/DefaultCheckstyleExecutor.java?rev=1618905&r1=1618904&r2=1618905&view=diff
==============================================================================
--- maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/exec/DefaultCheckstyleExecutor.java (original)
+++ maven/plugins/trunk/maven-checkstyle-plugin/src/main/java/org/apache/maven/plugin/checkstyle/exec/DefaultCheckstyleExecutor.java Tue Aug 19 17:23:18 2014
@@ -29,8 +29,13 @@ import java.net.URL;
 import java.net.URLClassLoader;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Properties;
+import java.util.Set;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.maven.artifact.Artifact;
@@ -118,21 +123,44 @@ public class DefaultCheckstyleExecutor
         // setup classloader, needed to avoid "Unable to get class information for ..." errors
         List<String> classPathStrings = new ArrayList<String>();
         List<String> outputDirectories = new ArrayList<String>();
-        File sourceDirectory = request.getSourceDirectory();
-        File testSourceDirectory = request.getTestSourceDirectory();
+        
+        // stand-alone
+        Collection<File> sourceDirectories = null;
+        Collection<File> testSourceDirectories = request.getTestSourceDirectories();
+        
+        // aggregator
+        Map<MavenProject, Collection<File>> sourceDirectoriesByProject = new HashMap<MavenProject, Collection<File>>();
+        Map<MavenProject, Collection<File>> testSourceDirectoriesByProject = new HashMap<MavenProject, Collection<File>>();
+        
         if ( request.isAggregate() )
         {
             for ( MavenProject childProject : request.getReactorProjects() )
             {
+                sourceDirectories = new ArrayList<File>( childProject.getCompileSourceRoots().size() );
+                List<String> compileSourceRoots = childProject.getCompileSourceRoots();
+                for ( String compileSourceRoot : compileSourceRoots )
+                {
+                    sourceDirectories.add( new File( compileSourceRoot ) );
+                }
+                sourceDirectoriesByProject.put( childProject, sourceDirectories );
+                
+                testSourceDirectories = new ArrayList<File>( childProject.getTestCompileSourceRoots().size() );
+                List<String> testCompileSourceRoots = childProject.getTestCompileSourceRoots();
+                for ( String testCompileSourceRoot : testCompileSourceRoots )
+                {
+                    sourceDirectories.add( new File( testCompileSourceRoot ) );
+                }
+                sourceDirectoriesByProject.put( childProject, sourceDirectories );
+                
                 prepareCheckstylePaths( request, childProject, classPathStrings, outputDirectories,
-                                        new File( childProject.getBuild().getSourceDirectory() ),
-                                        new File( childProject.getBuild().getTestSourceDirectory() ) );
+                                        sourceDirectories, testSourceDirectories );
             }
         }
         else
         {
-            prepareCheckstylePaths( request, project, classPathStrings, outputDirectories, sourceDirectory,
-                                    testSourceDirectory );
+            sourceDirectories = request.getSourceDirectories();
+            prepareCheckstylePaths( request, project, classPathStrings, outputDirectories, sourceDirectories,
+                                    testSourceDirectories );
         }
 
         List<URL> urls = new ArrayList<URL>( classPathStrings.size() );
@@ -201,14 +229,16 @@ public class DefaultCheckstyleExecutor
         {
             for ( MavenProject childProject : request.getReactorProjects() )
             {
-                addSourceDirectory( checkerListener, new File( childProject.getBuild().getSourceDirectory() ),
-                                    new File( childProject.getBuild().getTestSourceDirectory() ),
+                sourceDirectories = sourceDirectoriesByProject.get( childProject );
+                testSourceDirectories = sourceDirectoriesByProject.get( childProject );
+                addSourceDirectory( checkerListener, sourceDirectories,
+                                    testSourceDirectories,
                                     childProject.getResources(), request );
             }
         }
         else
         {
-            addSourceDirectory( checkerListener, sourceDirectory, testSourceDirectory, request.getResources(),
+            addSourceDirectory( checkerListener, sourceDirectories, testSourceDirectories, request.getResources(),
                                 request );
         }
 
@@ -252,19 +282,30 @@ public class DefaultCheckstyleExecutor
         return checkerListener.getResults();
     }
 
-    protected void addSourceDirectory( CheckstyleCheckerListener sinkListener, File sourceDirectory,
-                                       File testSourceDirectory, List<Resource> resources,
+    protected void addSourceDirectory( CheckstyleCheckerListener sinkListener, Collection<File> sourceDirectories,
+                                       Collection<File> testSourceDirectories, List<Resource> resources,
                                        CheckstyleExecutorRequest request )
     {
-        if ( sourceDirectory != null )
+        if ( sourceDirectories != null )
         {
-            sinkListener.addSourceDirectory( sourceDirectory );
+            for ( File sourceDirectory : sourceDirectories )
+            {
+                if ( sourceDirectory.exists() )
+                {
+                    sinkListener.addSourceDirectory( sourceDirectory );
+                }
+            }
         }
 
-        if ( request.isIncludeTestSourceDirectory() && ( testSourceDirectory != null )
-            && ( testSourceDirectory.exists() ) && ( testSourceDirectory.isDirectory() ) )
+        if ( request.isIncludeTestSourceDirectory() && ( testSourceDirectories != null ) )
         {
-            sinkListener.addSourceDirectory( testSourceDirectory );
+            for ( File testSourceDirectory : testSourceDirectories )
+            {
+                if( testSourceDirectory.isDirectory() )
+                {
+                    sinkListener.addSourceDirectory( testSourceDirectory );
+                }
+            }
         }
 
         if ( resources != null )
@@ -373,15 +414,15 @@ public class DefaultCheckstyleExecutor
 
     private void prepareCheckstylePaths( CheckstyleExecutorRequest request, MavenProject project,
                                          List<String> classPathStrings, List<String> outputDirectories,
-                                         File sourceDirectory, File testSourceDirectory )
+                                         Collection<File> sourceDirectories, Collection<File> testSourceDirectories )
         throws CheckstyleExecutorException
     {
         try
         {
             outputDirectories.add( project.getBuild().getOutputDirectory() );
 
-            if ( request.isIncludeTestSourceDirectory() && ( testSourceDirectory != null )
-                && ( testSourceDirectory.exists() ) && ( testSourceDirectory.isDirectory() ) )
+            if ( request.isIncludeTestSourceDirectory() && ( testSourceDirectories != null )
+                && anyDirectoryExists( testSourceDirectories ) )
             {
                 classPathStrings.addAll( project.getTestClasspathElements() );
                 outputDirectories.add( project.getBuild().getTestOutputDirectory() );
@@ -396,6 +437,18 @@ public class DefaultCheckstyleExecutor
             throw new CheckstyleExecutorException( e.getMessage(), e );
         }
     }
+    
+    private boolean anyDirectoryExists( Collection<File> files )
+    {
+        for ( File file : files )
+        {
+            if ( file.isDirectory() )
+            {
+                return true;
+            }
+        }
+        return false;
+    }
 
     private Properties getOverridingProperties( CheckstyleExecutorRequest request )
         throws CheckstyleExecutorException
@@ -527,23 +580,37 @@ public class DefaultCheckstyleExecutor
             excludesStr.append( defaultExclude );
         }
 
-        File sourceDirectory = request.getSourceDirectory();
-
         List<File> files = new ArrayList<File>();
         if ( request.isAggregate() )
         {
             for ( MavenProject project : request.getReactorProjects() )
             {
-                addFilesToProcess( request, new File( project.getBuild().getSourceDirectory() ),
-                                   project.getResources(), project.getTestResources(),
-                                   files, new File( project.getBuild().getTestSourceDirectory() )
-                );
+                Set<File> sourceDirectories = new LinkedHashSet<File>();
+                
+                // CompileSourceRoots are absolute paths
+                List<String> compileSourceRoots = project.getCompileSourceRoots(); 
+                for ( String compileSourceRoot : compileSourceRoots )
+                {
+                    sourceDirectories.add( new File( compileSourceRoot ) );
+                }
+
+                Set<File> testSourceDirectories = new LinkedHashSet<File>();
+                // CompileSourceRoots are absolute paths
+                List<String> testCompileSourceRoots = project.getTestCompileSourceRoots(); 
+                for ( String testCompileSourceRoot : testCompileSourceRoots )
+                {
+                    testSourceDirectories.add( new File( testCompileSourceRoot ) );
+                }
+
+                addFilesToProcess( request, sourceDirectories, project.getResources(), project.getTestResources(),
+                                   files, testSourceDirectories );
             }
         }
         else
         {
-            addFilesToProcess( request, sourceDirectory, request.getResources(),
-                request.getTestResources(), files, request.getTestSourceDirectory() );
+            Collection<File> sourceDirectories = request.getSourceDirectories();
+            addFilesToProcess( request, sourceDirectories, request.getResources(),
+                request.getTestResources(), files, request.getTestSourceDirectories() );
         }
 
         getLogger().debug( "Added " + files.size() + " files to process." );
@@ -551,27 +618,39 @@ public class DefaultCheckstyleExecutor
         return files.toArray( new File[files.size()] );
     }
 
-    private void addFilesToProcess( CheckstyleExecutorRequest request, File sourceDirectory, List<Resource> resources,
-                                    List<Resource> testResources, List<File> files, File testSourceDirectory )
+    private void addFilesToProcess( CheckstyleExecutorRequest request, Collection<File> sourceDirectories, List<Resource> resources,
+                                    List<Resource> testResources, List<File> files, Collection<File> testSourceDirectories )
         throws IOException
     {
-        if ( sourceDirectory != null && sourceDirectory.exists() )
+        if ( sourceDirectories != null )
         {
-            final List<File> sourceFiles =
-                FileUtils.getFiles( sourceDirectory, request.getIncludes(), request.getExcludes() );
-            files.addAll( sourceFiles );
-            getLogger().debug( "Added " + sourceFiles.size() + " source files found in '"
-                    + sourceDirectory.getAbsolutePath() + "'." );
-        }
-
-        if ( request.isIncludeTestSourceDirectory() && ( testSourceDirectory != null )
-            && ( testSourceDirectory.exists() ) && ( testSourceDirectory.isDirectory() ) )
-        {
-            final List<File> testSourceFiles =
-                FileUtils.getFiles( testSourceDirectory, request.getIncludes(), request.getExcludes() );
-            files.addAll( testSourceFiles );
-            getLogger().debug( "Added " + testSourceFiles.size() + " test source files found in '"
-                    + testSourceDirectory.getAbsolutePath() + "'." );
+            for ( File sourceDirectory : sourceDirectories )
+            {
+                if ( sourceDirectory.isDirectory() )
+                {
+                    final List<File> sourceFiles =
+                        FileUtils.getFiles( sourceDirectory, request.getIncludes(), request.getExcludes() );
+                    files.addAll( sourceFiles );
+                    getLogger().debug( "Added " + sourceFiles.size() + " source files found in '"
+                                           + sourceDirectory.getAbsolutePath() + "'." );
+                }
+            }
+        }
+
+        if ( request.isIncludeTestSourceDirectory() && testSourceDirectories != null )
+        {
+            for ( File testSourceDirectory : testSourceDirectories )
+            {
+                if ( testSourceDirectory.isDirectory() )
+                {
+                    final List<File> testSourceFiles =
+                                    FileUtils.getFiles( testSourceDirectory, request.getIncludes(), request.getExcludes() );
+                    
+                    files.addAll( testSourceFiles );
+                    getLogger().debug( "Added " + testSourceFiles.size() + " test source files found in '"
+                            + testSourceDirectory.getAbsolutePath() + "'." );
+                }
+            }
         }
 
         if ( resources != null && request.isIncludeResources() )