Coverage Report - org.apache.maven.plugin.checkstyle.DefaultCheckstyleExecutor
 
Classes in this File Line Coverage Branch Coverage Complexity
DefaultCheckstyleExecutor
68%
136/200
53%
68/128
12,222
 
 1  
 package org.apache.maven.plugin.checkstyle;
 2  
 
 3  
 /*
 4  
  * Licensed to the Apache Software Foundation (ASF) under one
 5  
  * or more contributor license agreements.  See the NOTICE file
 6  
  * distributed with this work for additional information
 7  
  * regarding copyright ownership.  The ASF licenses this file
 8  
  * to you under the Apache License, Version 2.0 (the
 9  
  * "License"); you may not use this file except in compliance
 10  
  * with the License.  You may obtain a copy of the License at
 11  
  *
 12  
  *   http://www.apache.org/licenses/LICENSE-2.0
 13  
  *
 14  
  * Unless required by applicable law or agreed to in writing,
 15  
  * software distributed under the License is distributed on an
 16  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 17  
  * KIND, either express or implied.  See the License for the
 18  
  * specific language governing permissions and limitations
 19  
  * under the License.
 20  
  */
 21  
 
 22  
 import java.io.ByteArrayInputStream;
 23  
 import java.io.File;
 24  
 import java.io.FileInputStream;
 25  
 import java.io.IOException;
 26  
 import java.net.MalformedURLException;
 27  
 import java.net.URL;
 28  
 import java.net.URLClassLoader;
 29  
 import java.util.ArrayList;
 30  
 import java.util.Arrays;
 31  
 import java.util.List;
 32  
 import java.util.Properties;
 33  
 
 34  
 import org.apache.commons.io.IOUtils;
 35  
 import org.apache.maven.artifact.DependencyResolutionRequiredException;
 36  
 import org.apache.maven.project.MavenProject;
 37  
 import org.codehaus.plexus.logging.AbstractLogEnabled;
 38  
 import org.codehaus.plexus.resource.ResourceManager;
 39  
 import org.codehaus.plexus.resource.loader.FileResourceCreationException;
 40  
 import org.codehaus.plexus.resource.loader.FileResourceLoader;
 41  
 import org.codehaus.plexus.resource.loader.ResourceNotFoundException;
 42  
 import org.codehaus.plexus.util.FileUtils;
 43  
 import org.codehaus.plexus.util.StringUtils;
 44  
 
 45  
 import com.puppycrawl.tools.checkstyle.Checker;
 46  
 import com.puppycrawl.tools.checkstyle.ConfigurationLoader;
 47  
 import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
 48  
 import com.puppycrawl.tools.checkstyle.PackageNamesLoader;
 49  
 import com.puppycrawl.tools.checkstyle.PropertiesExpander;
 50  
 import com.puppycrawl.tools.checkstyle.api.AuditListener;
 51  
 import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
 52  
 import com.puppycrawl.tools.checkstyle.api.Configuration;
 53  
 import com.puppycrawl.tools.checkstyle.api.FilterSet;
 54  
 import com.puppycrawl.tools.checkstyle.filters.SuppressionsLoader;
 55  
 
 56  
 /**
 57  
  * @author <a href="mailto:olamy@apache.org">olamy</a>
 58  
  * @plexus.component role="org.apache.maven.plugin.checkstyle.CheckstyleExecutor" role-hint="default"
 59  
  *                   instantiation-strategy="per-lookup"
 60  
  * @since 2.5
 61  
  * @version $Id: org.apache.maven.plugin.checkstyle.DefaultCheckstyleExecutor.html 816673 2012-05-08 14:06:16Z hboutemy $
 62  
  */
 63  15
 public class DefaultCheckstyleExecutor
 64  
     extends AbstractLogEnabled
 65  
     implements CheckstyleExecutor
 66  
 {
 67  
 
 68  
     /**
 69  
      * @plexus.requirement role="org.codehaus.plexus.resource.ResourceManager" role-hint="default"
 70  
      */
 71  
     private ResourceManager locator;
 72  
 
 73  1
     private static final File[] EMPTY_FILE_ARRAY = new File[0];
 74  
 
 75  
     public CheckstyleResults executeCheckstyle( CheckstyleExecutorRequest request )
 76  
         throws CheckstyleExecutorException, CheckstyleException
 77  
     {
 78  
         // checkstyle will always use the context classloader in order
 79  
         // to load resources (dtds),
 80  
         // so we have to fix it
 81  
         // olamy this hack is not anymore needed in maven 3.x
 82  18
         ClassLoader checkstyleClassLoader = PackageNamesLoader.class.getClassLoader();
 83  18
         Thread.currentThread().setContextClassLoader( checkstyleClassLoader );
 84  
 
 85  18
         if ( getLogger().isDebugEnabled() )
 86  
         {
 87  0
             getLogger().debug( "executeCheckstyle start headerLocation : " + request.getHeaderLocation() );
 88  
         }
 89  18
         MavenProject project = request.getProject();
 90  18
         locator.setOutputDirectory( new File( project.getBuild().getDirectory() ) );
 91  
         File[] files;
 92  
         try
 93  
         {
 94  18
             files = getFilesToProcess( request );
 95  
         }
 96  0
         catch ( IOException e )
 97  
         {
 98  0
             throw new CheckstyleExecutorException( "Error getting files to process", e );
 99  18
         }
 100  
 
 101  18
         FilterSet filterSet = getSuppressions( request );
 102  
 
 103  18
         Checker checker = new Checker();
 104  
 
 105  
         // setup classloader, needed to avoid "Unable to get class information
 106  
         // for ..." errors
 107  18
         List<String> classPathStrings = new ArrayList<String>();
 108  18
         List<String> outputDirectories = new ArrayList<String>();
 109  18
         File sourceDirectory = request.getSourceDirectory();
 110  18
         File testSourceDirectory = request.getTestSourceDirectory();
 111  18
         prepareCheckstylePaths( request, project, classPathStrings, outputDirectories, sourceDirectory,
 112  
                                 testSourceDirectory );
 113  17
         if ( request.isAggregate() )
 114  
         {
 115  2
             for ( MavenProject childProject : request.getReactorProjects() )
 116  
             {
 117  2
                 prepareCheckstylePaths( request, childProject, classPathStrings, outputDirectories,
 118  
                                         new File( childProject.getBuild().getSourceDirectory() ),
 119  
                                         new File( childProject.getBuild().getTestSourceDirectory() ) );
 120  
             }
 121  
         }
 122  
 
 123  17
         List<URL> urls = new ArrayList<URL>( classPathStrings.size() );
 124  
 
 125  17
         for ( String path : classPathStrings )
 126  
         {
 127  
             try
 128  
             {
 129  17
                 urls.add( new File( path ).toURL() );
 130  
             }
 131  0
             catch ( MalformedURLException e )
 132  
             {
 133  0
                 throw new CheckstyleExecutorException( e.getMessage(), e );
 134  17
             }
 135  
         }
 136  
 
 137  17
         for ( String outputDirectoryString : outputDirectories )
 138  
         {
 139  
             try
 140  
             {
 141  19
                 if ( outputDirectoryString != null )
 142  
                 {
 143  0
                     File outputDirectoryFile = new File( outputDirectoryString );
 144  0
                     if ( outputDirectoryFile.exists() )
 145  
                     {
 146  0
                         URL outputDirectoryUrl = outputDirectoryFile.toURL();
 147  0
                         request.getLog().debug(
 148  
                                                 "Adding the outputDirectory " + outputDirectoryUrl.toString()
 149  
                                                     + " to the Checkstyle class path" );
 150  0
                         urls.add( outputDirectoryUrl );
 151  
                     }
 152  
                 }
 153  
             }
 154  0
             catch ( MalformedURLException e )
 155  
             {
 156  0
                 throw new CheckstyleExecutorException( e.getMessage(), e );
 157  19
             }
 158  
         }
 159  
 
 160  17
         URLClassLoader projectClassLoader = new URLClassLoader( (URL[]) urls.toArray( new URL[urls.size()] ), null );
 161  17
         checker.setClassloader( projectClassLoader );
 162  
 
 163  17
         checker.setModuleClassLoader( Thread.currentThread().getContextClassLoader() );
 164  
 
 165  17
         if ( filterSet != null )
 166  
         {
 167  0
             checker.addFilter( filterSet );
 168  
         }
 169  17
         Configuration configuration = getConfiguration( request );
 170  17
         checker.configure( configuration );
 171  
 
 172  17
         AuditListener listener = request.getListener();
 173  
 
 174  17
         if ( listener != null )
 175  
         {
 176  17
             checker.addListener( listener );
 177  
         }
 178  
 
 179  17
         if ( request.isConsoleOutput() )
 180  
         {
 181  4
             checker.addListener( request.getConsoleListener() );
 182  
         }
 183  
 
 184  17
         CheckstyleReportListener sinkListener = new CheckstyleReportListener( configuration );
 185  17
         addSourceDirectory( sinkListener, sourceDirectory, testSourceDirectory, request );
 186  17
         if ( request.isAggregate() )
 187  
         {
 188  2
             for ( MavenProject childProject : request.getReactorProjects() )
 189  
             {
 190  2
                 addSourceDirectory( sinkListener, new File( childProject.getBuild().getSourceDirectory() ),
 191  
                                     new File( childProject.getBuild().getSourceDirectory() ), request );
 192  
             }
 193  
         }
 194  
 
 195  17
         checker.addListener( sinkListener );
 196  
 
 197  17
         List<File> filesList = Arrays.asList( files );
 198  17
         int nbErrors = checker.process( filesList );
 199  
 
 200  17
         checker.destroy();
 201  
 
 202  17
         if ( request.getStringOutputStream() != null )
 203  
         {
 204  15
             request.getLog().info( request.getStringOutputStream().toString() );
 205  
         }
 206  
 
 207  17
         if ( request.isFailsOnError() && nbErrors > 0 )
 208  
         {
 209  
             // TODO: should be a failure, not an error. Report is not meant to
 210  
             // throw an exception here (so site would
 211  
             // work regardless of config), but should record this information
 212  1
             throw new CheckstyleExecutorException( "There are " + nbErrors + " checkstyle errors." );
 213  
         }
 214  16
         else if ( nbErrors > 0 )
 215  
         {
 216  16
             request.getLog().info( "There are " + nbErrors + " checkstyle errors." );
 217  
         }
 218  
 
 219  16
         return sinkListener.getResults();
 220  
     }
 221  
 
 222  
     protected void addSourceDirectory( CheckstyleReportListener sinkListener, File sourceDirectory,
 223  
                                        File testSourceDirectory, CheckstyleExecutorRequest request )
 224  
     {
 225  19
         if ( sourceDirectory != null )
 226  
         {
 227  17
             sinkListener.addSourceDirectory( sourceDirectory );
 228  
         }
 229  19
         if ( request.isIncludeTestSourceDirectory() && ( testSourceDirectory != null )
 230  
             && ( testSourceDirectory.exists() ) && ( testSourceDirectory.isDirectory() ) )
 231  
         {
 232  0
             sinkListener.addSourceDirectory( testSourceDirectory );
 233  
         }
 234  19
     }
 235  
 
 236  
     public Configuration getConfiguration( CheckstyleExecutorRequest request )
 237  
         throws CheckstyleExecutorException
 238  
     {
 239  
         try
 240  
         {
 241  
             // checkstyle will always use the context classloader in order
 242  
             // to load resources (dtds),
 243  
             // so we have to fix it
 244  17
             ClassLoader checkstyleClassLoader = PackageNamesLoader.class.getClassLoader();
 245  17
             Thread.currentThread().setContextClassLoader( checkstyleClassLoader );
 246  17
             String configFile = getConfigFile( request );
 247  17
             Properties overridingProperties = getOverridingProperties( request );
 248  17
             Configuration config = ConfigurationLoader
 249  
                 .loadConfiguration( configFile, new PropertiesExpander( overridingProperties ) );
 250  17
             String effectiveEncoding = StringUtils.isNotEmpty( request.getEncoding() ) ? request.getEncoding() : System
 251  
                 .getProperty( "file.encoding", "UTF-8" );
 252  17
             if ( StringUtils.isEmpty( request.getEncoding() ) )
 253  
             {
 254  0
                 request.getLog().warn(
 255  
                                        "File encoding has not been set, using platform encoding " + effectiveEncoding
 256  
                                            + ", i.e. build is platform dependent!" );
 257  
             }
 258  
 
 259  17
             if ( "Checker".equals( config.getName() )
 260  
                     || "com.puppycrawl.tools.checkstyle.Checker".equals( config.getName() ) )
 261  
             {
 262  17
                 if ( config instanceof DefaultConfiguration )
 263  
                 {
 264  
                     // MCHECKSTYLE-173 Only add the "charset" attribute if it has not been set
 265  
                     try
 266  
                     {
 267  17
                         if ( ( (DefaultConfiguration) config ).getAttribute( "charset" ) == null )
 268  
                         {
 269  0
                             ( (DefaultConfiguration) config ).addAttribute( "charset", effectiveEncoding );
 270  
                         }
 271  
                     }
 272  17
                     catch ( CheckstyleException ex )
 273  
                     {
 274  
                         // Checkstyle 5.4+ throws an exception when trying to access an attribute that doesn't exist
 275  17
                         ( (DefaultConfiguration) config ).addAttribute( "charset", effectiveEncoding );
 276  17
                     }
 277  
                 }
 278  
                 else
 279  
                 {
 280  0
                     request.getLog().warn( "Failed to configure file encoding on module " + config );
 281  
                 }
 282  
             }
 283  17
             Configuration[] modules = config.getChildren();
 284  130
             for ( int i = 0; i < modules.length; i++ )
 285  
             {
 286  113
                 Configuration module = modules[i];
 287  113
                 if ( "TreeWalker".equals( module.getName() )
 288  
                     || "com.puppycrawl.tools.checkstyle.TreeWalker".equals( module.getName() ) )
 289  
                 {
 290  17
                     if ( module instanceof DefaultConfiguration )
 291  
                     {
 292  
                         //MCHECKSTYLE-132 DefaultConfiguration addAttribute has changed in checkstyle 5.3
 293  
                         try
 294  
                         {
 295  17
                             if ( ( (DefaultConfiguration) module ).getAttribute( "cacheFile" ) == null )
 296  
                             {
 297  0
                                 ( (DefaultConfiguration) module ).addAttribute( "cacheFile", request.getCacheFile() );
 298  
                             }
 299  
                         }
 300  0
                         catch ( CheckstyleException ex )
 301  
                         {
 302  
                             //MCHECKSTYLE-159 - checkstyle 5.4 throws an exception instead of return null if "cacheFile"
 303  
                             // doesn't exist
 304  0
                             ( (DefaultConfiguration) module ).addAttribute( "cacheFile", request.getCacheFile() );
 305  17
                         }
 306  
                     }
 307  
                     else
 308  
                     {
 309  0
                         request.getLog().warn( "Failed to configure cache file on module " + module );
 310  
                     }
 311  
                 }
 312  
             }
 313  17
             return config;
 314  
         }
 315  0
         catch ( CheckstyleException e )
 316  
         {
 317  0
             throw new CheckstyleExecutorException( "Failed during checkstyle configuration", e );
 318  
         }
 319  
     }
 320  
 
 321  
     private void prepareCheckstylePaths( CheckstyleExecutorRequest request, MavenProject project,
 322  
                                          List<String> classPathStrings, List<String> outputDirectories,
 323  
                                          File sourceDirectory, File testSourceDirectory )
 324  
         throws CheckstyleExecutorException
 325  
     {
 326  
         try
 327  
         {
 328  20
             outputDirectories.add( project.getBuild().getOutputDirectory() );
 329  
 
 330  20
             if ( request.isIncludeTestSourceDirectory() && ( sourceDirectory != null )
 331  
                 && ( testSourceDirectory.exists() ) && ( testSourceDirectory.isDirectory() ) )
 332  
             {
 333  0
                 classPathStrings.addAll( project.getTestClasspathElements() );
 334  0
                 outputDirectories.add( project.getBuild().getTestOutputDirectory() );
 335  
             }
 336  
             else
 337  
             {
 338  20
                 classPathStrings.addAll( project.getCompileClasspathElements() );
 339  
             }
 340  
         }
 341  1
         catch ( DependencyResolutionRequiredException e )
 342  
         {
 343  1
             throw new CheckstyleExecutorException( e.getMessage(), e );
 344  19
         }
 345  19
     }
 346  
 
 347  
     private Properties getOverridingProperties( CheckstyleExecutorRequest request )
 348  
         throws CheckstyleExecutorException
 349  
     {
 350  17
         Properties p = new Properties();
 351  
 
 352  
         try
 353  
         {
 354  17
             if ( request.getPropertiesLocation() != null )
 355  
             {
 356  0
                 if ( getLogger().isDebugEnabled() )
 357  
                 {
 358  0
                     getLogger().debug( "request.getPropertiesLocation() " + request.getPropertiesLocation() );
 359  
                 }
 360  
 
 361  0
                 File propertiesFile = locator.getResourceAsFile( request.getPropertiesLocation(),
 362  
                                                                  "checkstyle-checker.properties" );
 363  
 
 364  0
                 FileInputStream properties = new FileInputStream( propertiesFile );
 365  
                 try
 366  
                 {
 367  0
                     if ( propertiesFile != null )
 368  
                     {
 369  0
                         p.load( properties );
 370  
                     }
 371  
                 }
 372  
                 finally
 373  
                 {
 374  0
                     IOUtils.closeQuietly( properties );
 375  0
                 }
 376  
             }
 377  
 
 378  17
             if ( StringUtils.isNotEmpty( request.getPropertyExpansion() ) )
 379  
             {
 380  0
                 String propertyExpansion = request.getPropertyExpansion();
 381  
                 // Convert \ to \\, so that p.load will convert it back properly
 382  0
                 propertyExpansion = StringUtils.replace( propertyExpansion, "\\", "\\\\" );
 383  0
                 p.load( new ByteArrayInputStream( propertyExpansion.getBytes() ) );
 384  
             }
 385  
 
 386  
             // Workaround for MCHECKSTYLE-48
 387  
             // Make sure that "config/maven-header.txt" is the default value
 388  
             // for headerLocation, if configLocation="config/maven_checks.xml"
 389  17
             String headerLocation = request.getHeaderLocation();
 390  17
             if ( "config/maven_checks.xml".equals( request.getConfigLocation() ) )
 391  
             {
 392  
 
 393  2
                 if ( "LICENSE.txt".equals( request.getHeaderLocation() ) )
 394  
                 {
 395  0
                     headerLocation = "config/maven-header.txt";
 396  
                 }
 397  
             }
 398  17
             if ( getLogger().isDebugEnabled() )
 399  
             {
 400  0
                 getLogger().debug( "headerLocation " + headerLocation );
 401  
             }
 402  
 
 403  17
             if ( StringUtils.isNotEmpty( headerLocation ) )
 404  
             {
 405  
                 try
 406  
                 {
 407  17
                     File headerFile = locator.getResourceAsFile( headerLocation, "checkstyle-header.txt" );
 408  
 
 409  17
                     if ( headerFile != null )
 410  
                     {
 411  17
                         p.setProperty( "checkstyle.header.file", headerFile.getAbsolutePath() );
 412  
                     }
 413  
                 }
 414  0
                 catch ( FileResourceCreationException e )
 415  
                 {
 416  0
                     throw new CheckstyleExecutorException( "Unable to process header location: " + headerLocation, e );
 417  
                 }
 418  0
                 catch ( ResourceNotFoundException e )
 419  
                 {
 420  0
                     throw new CheckstyleExecutorException( "Unable to process header location: " + headerLocation, e );
 421  17
                 }
 422  
             }
 423  
 
 424  17
             if ( request.getCacheFile() != null )
 425  
             {
 426  17
                 p.setProperty( "checkstyle.cache.file", request.getCacheFile() );
 427  
             }
 428  
         }
 429  0
         catch ( IOException e )
 430  
         {
 431  0
             throw new CheckstyleExecutorException( "Failed to get overriding properties", e );
 432  
         }
 433  0
         catch ( FileResourceCreationException e )
 434  
         {
 435  0
             throw new CheckstyleExecutorException( "Failed to get overriding properties", e );
 436  
         }
 437  0
         catch ( ResourceNotFoundException e )
 438  
         {
 439  0
             throw new CheckstyleExecutorException( "Failed to get overriding properties", e );
 440  17
         }
 441  17
         if ( request.getSuppressionsFileExpression() != null )
 442  
         {
 443  0
             String suppresionFile = request.getSuppressionsLocation();
 444  
 
 445  0
             if ( suppresionFile != null )
 446  
             {
 447  0
                 p.setProperty( request.getSuppressionsFileExpression(), suppresionFile );
 448  
             }
 449  
         }
 450  
 
 451  17
         return p;
 452  
     }
 453  
 
 454  
     private File[] getFilesToProcess( CheckstyleExecutorRequest request )
 455  
         throws IOException
 456  
     {
 457  18
         StringBuffer excludesStr = new StringBuffer();
 458  
 
 459  18
         if ( StringUtils.isNotEmpty( request.getExcludes() ) )
 460  
         {
 461  0
             excludesStr.append( request.getExcludes() );
 462  
         }
 463  
 
 464  18
         String[] defaultExcludes = FileUtils.getDefaultExcludes();
 465  684
         for ( int i = 0; i < defaultExcludes.length; i++ )
 466  
         {
 467  666
             if ( excludesStr.length() > 0 )
 468  
             {
 469  648
                 excludesStr.append( "," );
 470  
             }
 471  
 
 472  666
             excludesStr.append( defaultExcludes[i] );
 473  
         }
 474  
 
 475  18
         File sourceDirectory = request.getSourceDirectory();
 476  
 
 477  18
         List<File> files = new ArrayList<File>();
 478  18
         addFilesToProcess( request, excludesStr, sourceDirectory, files );
 479  18
         if ( request.isAggregate() )
 480  
         {
 481  2
             for ( MavenProject project : request.getReactorProjects() )
 482  
             {
 483  2
                 addFilesToProcess( request, excludesStr, new File( project.getBuild().getSourceDirectory() ), files );
 484  
             }
 485  
         }
 486  
 
 487  18
         return (File[]) files.toArray( EMPTY_FILE_ARRAY );
 488  
     }
 489  
 
 490  
     private void addFilesToProcess( CheckstyleExecutorRequest request, StringBuffer excludesStr, File sourceDirectory,
 491  
                                     List<File> files )
 492  
         throws IOException
 493  
     {
 494  20
         if ( sourceDirectory == null || !sourceDirectory.exists() )
 495  
         {
 496  2
             return;
 497  
         }
 498  18
         files.addAll(
 499  
             FileUtils.getFiles( sourceDirectory, request.getIncludes(), excludesStr.toString() ) );
 500  18
         File testSourceDirectory = request.getTestSourceDirectory();
 501  18
         if ( request.isIncludeTestSourceDirectory() && ( testSourceDirectory != null )
 502  
             && ( testSourceDirectory.exists() ) && ( testSourceDirectory.isDirectory() ) )
 503  
         {
 504  0
             files.addAll( FileUtils.getFiles( testSourceDirectory, request.getIncludes(),
 505  
                                               excludesStr.toString() ) );
 506  
         }
 507  18
     }
 508  
 
 509  
     private FilterSet getSuppressions( CheckstyleExecutorRequest request )
 510  
         throws CheckstyleExecutorException
 511  
     {
 512  
         try
 513  
         {
 514  18
             File suppressionsFile = locator.resolveLocation( request.getSuppressionsLocation(),
 515  
                                                              "checkstyle-suppressions.xml" );
 516  
 
 517  18
             if ( suppressionsFile == null )
 518  
             {
 519  18
                 return null;
 520  
             }
 521  
 
 522  0
             return SuppressionsLoader.loadSuppressions( suppressionsFile.getAbsolutePath() );
 523  
         }
 524  0
         catch ( CheckstyleException ce )
 525  
         {
 526  0
             throw new CheckstyleExecutorException( "failed to load suppressions location: "
 527  
                 + request.getSuppressionsLocation(), ce );
 528  
         }
 529  0
         catch ( IOException e )
 530  
         {
 531  0
             throw new CheckstyleExecutorException( "Failed to process supressions location: "
 532  
                 + request.getSuppressionsLocation(), e );
 533  
         }
 534  
     }
 535  
 
 536  
     private String getConfigFile( CheckstyleExecutorRequest request )
 537  
         throws CheckstyleExecutorException
 538  
     {
 539  
         try
 540  
         {
 541  17
             if ( getLogger().isDebugEnabled() )
 542  
             {
 543  0
                 getLogger().debug( "request.getConfigLocation() " + request.getConfigLocation() );
 544  
             }
 545  
 
 546  17
             MavenProject parent = request.getProject();
 547  34
             while ( parent != null && parent.getFile() != null )
 548  
             {
 549  
                 // MCHECKSTYLE-131 ( olamy ) I don't like this hack.
 550  
                 // (dkulp) Me either.   It really pollutes the location stuff
 551  
                 // by allowing searches of stuff outside the current module.
 552  17
                 File dir = parent.getFile().getParentFile();
 553  17
                 locator.addSearchPath( FileResourceLoader.ID, dir.getAbsolutePath() );
 554  17
                 parent = parent.getParent();
 555  17
             }
 556  17
             locator.addSearchPath( "url", "" );
 557  
 
 558  17
             File configFile = locator.getResourceAsFile( request.getConfigLocation(), "checkstyle-checker.xml" );
 559  17
             if ( configFile == null )
 560  
             {
 561  0
                 throw new CheckstyleExecutorException( "Unable to process config location: "
 562  
                     + request.getConfigLocation() );
 563  
             }
 564  17
             return configFile.getAbsolutePath();
 565  
         }
 566  0
         catch ( org.codehaus.plexus.resource.loader.ResourceNotFoundException e )
 567  
         {
 568  0
             throw new CheckstyleExecutorException( "Unable to find configuration file at location "
 569  
                 + request.getConfigLocation(), e );
 570  
         }
 571  0
         catch ( FileResourceCreationException e )
 572  
         {
 573  0
             throw new CheckstyleExecutorException( "Unable to process configuration file location "
 574  
                 + request.getConfigLocation(), e );
 575  
         }
 576  
 
 577  
     }
 578  
 }