package org.apache.maven.plugins.checkstyle.exec;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
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;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.model.Resource;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.resource.ResourceManager;
import org.codehaus.plexus.resource.loader.FileResourceCreationException;
import org.codehaus.plexus.resource.loader.FileResourceLoader;
import org.codehaus.plexus.resource.loader.ResourceNotFoundException;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.StringUtils;

import com.puppycrawl.tools.checkstyle.Checker;
import com.puppycrawl.tools.checkstyle.ConfigurationLoader;
import com.puppycrawl.tools.checkstyle.ConfigurationLoader.IgnoredModulesOptions;
import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
import com.puppycrawl.tools.checkstyle.PackageNamesLoader;
import com.puppycrawl.tools.checkstyle.PropertiesExpander;
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;

/**
 * @author Olivier Lamy
 * @since 2.5
 *
 */
@Component( role = CheckstyleExecutor.class, hint = "default", instantiationStrategy = "per-lookup" )
public class DefaultCheckstyleExecutor
    extends AbstractLogEnabled
    implements CheckstyleExecutor
{
    @Requirement( hint = "default" )
    private ResourceManager locator;
    
    @Requirement( hint = "license" )
    private ResourceManager licenseLocator;

    public CheckstyleResults executeCheckstyle( CheckstyleExecutorRequest request )
        throws CheckstyleExecutorException, CheckstyleException
    {
        if ( getLogger().isDebugEnabled() )
        {
            getLogger().debug( "executeCheckstyle start headerLocation : " + request.getHeaderLocation() );
        }

        MavenProject project = request.getProject();

        configureResourceLocator( locator, request, null );
        
        configureResourceLocator( licenseLocator, request, request.getLicenseArtifacts() );

        // Config is less critical than License, locator can still be used.
        // configureResourceLocator( configurationLocator, request, request.getConfigurationArtifacts() );

        List<File> files;
        try
        {
            files = getFilesToProcess( request );
        }
        catch ( IOException e )
        {
            throw new CheckstyleExecutorException( "Error getting files to process", e );
        }

        final String suppressionsFilePath = getSuppressionsFilePath( request );
        FilterSet filterSet = getSuppressionsFilterSet( suppressionsFilePath );

        Checker checker = new Checker();

        // setup classloader, needed to avoid "Unable to get class information for ..." errors
        List<String> classPathStrings = new ArrayList<>();
        List<String> outputDirectories = new ArrayList<>();
        
        // stand-alone
        Collection<File> sourceDirectories = null;
        Collection<File> testSourceDirectories = request.getTestSourceDirectories();
        
        // aggregator
        Map<MavenProject, Collection<File>> sourceDirectoriesByProject = new HashMap<>();
        Map<MavenProject, Collection<File>> testSourceDirectoriesByProject = new HashMap<>();
        
        if ( request.isAggregate() )
        {
            for ( MavenProject childProject : request.getReactorProjects() )
            {
                sourceDirectories = new ArrayList<>( childProject.getCompileSourceRoots().size() );
                List<String> compileSourceRoots = childProject.getCompileSourceRoots();
                for ( String compileSourceRoot : compileSourceRoots )
                {
                    sourceDirectories.add( new File( compileSourceRoot ) );
                }
                sourceDirectoriesByProject.put( childProject, sourceDirectories );
                
                testSourceDirectories = new ArrayList<>( childProject.getTestCompileSourceRoots().size() );
                List<String> testCompileSourceRoots = childProject.getTestCompileSourceRoots();
                for ( String testCompileSourceRoot : testCompileSourceRoots )
                {
                    testSourceDirectories.add( new File( testCompileSourceRoot ) );
                }
                testSourceDirectoriesByProject.put( childProject, testSourceDirectories );
                
                prepareCheckstylePaths( request, childProject, classPathStrings, outputDirectories,
                                        sourceDirectories, testSourceDirectories );
            }
        }
        else
        {
            sourceDirectories = request.getSourceDirectories();
            prepareCheckstylePaths( request, project, classPathStrings, outputDirectories, sourceDirectories,
                                    testSourceDirectories );
        }

        setUpCheckstyleClassloader( checker, classPathStrings, outputDirectories );

        checker.setModuleClassLoader( Thread.currentThread().getContextClassLoader() );

        if ( filterSet != null )
        {
            checker.addFilter( filterSet );
        }
        Configuration configuration = getConfiguration( request );
        checker.configure( configuration );

        AuditListener listener = request.getListener();

        if ( listener != null )
        {
            checker.addListener( listener );
        }

        if ( request.isConsoleOutput() )
        {
            checker.addListener( request.getConsoleListener() );
        }

        CheckstyleCheckerListener checkerListener = new CheckstyleCheckerListener( configuration );
        if ( request.isAggregate() )
        {
            for ( MavenProject childProject : request.getReactorProjects() )
            {
                sourceDirectories = sourceDirectoriesByProject.get( childProject );
                testSourceDirectories = testSourceDirectoriesByProject.get( childProject );
                addSourceDirectory( checkerListener, sourceDirectories,
                                    testSourceDirectories,
                                    childProject.getResources(), request );
            }
        }
        else
        {
            addSourceDirectory( checkerListener, sourceDirectories, testSourceDirectories, request.getResources(),
                                request );
        }

        checker.addListener( checkerListener );

        int nbErrors = checker.process( files );

        checker.destroy();

        if ( request.getStringOutputStream() != null )
        {
            String message = request.getStringOutputStream().toString().trim();

            if ( message.length() > 0 )
            {
                getLogger().info( message );
            }
        }

        if ( nbErrors > 0 )
        {
            StringBuilder message = new StringBuilder( "There " );
            if ( nbErrors == 1 )
            {
                message.append( "is" );
            }
            else
            {
                message.append( "are" );
            }
            message.append( " " );
            message.append( nbErrors );
            message.append( " error" );
            if ( nbErrors != 1 )
            {
                message.append( "s" );
            }
            message.append( " reported by Checkstyle" );
            String version = getCheckstyleVersion();
            if ( version != null )
            {
                message.append( " " );
                message.append( version );
            }
            message.append( " with " );
            message.append( request.getConfigLocation() );
            message.append( " ruleset." );

            if ( request.isFailsOnError() )
            {
                // TODO: should be a failure, not an error. Report is not meant to
                // throw an exception here (so site would
                // work regardless of config), but should record this information
                throw new CheckstyleExecutorException( message.toString() );
            }
            else
            {
                getLogger().info( message.toString() );
            }
        }

        return checkerListener.getResults();
    }

    private void setUpCheckstyleClassloader( Checker checker,
                                             List<String> classPathStrings,
                                             List<String> outputDirectories )
        throws CheckstyleExecutorException
    {
        final List<URL> urls = new ArrayList<>( classPathStrings.size() );

        for ( String path : classPathStrings )
        {
            try
            {
                urls.add( new File( path ).toURI().toURL() );
            }
            catch ( MalformedURLException e )
            {
                throw new CheckstyleExecutorException( e.getMessage(), e );
            }
        }

        for ( String outputDirectoryString : outputDirectories )
        {
            try
            {
                if ( outputDirectoryString != null )
                {
                    File outputDirectoryFile = new File( outputDirectoryString );
                    if ( outputDirectoryFile.exists() )
                    {
                        URL outputDirectoryUrl = outputDirectoryFile.toURI().toURL();
                        getLogger().debug( "Adding the outputDirectory " + outputDirectoryUrl.toString()
                                               + " to the Checkstyle class path" );
                        urls.add( outputDirectoryUrl );
                    }
                }
            }
            catch ( MalformedURLException e )
            {
                throw new CheckstyleExecutorException( e.getMessage(), e );
            }
        }

        URLClassLoader projectClassLoader = AccessController.doPrivileged( new PrivilegedAction<URLClassLoader>()
        {
            public URLClassLoader run()
            {
                return new URLClassLoader( urls.toArray( new URL[0] ), null );
            }
        } );

        /*
         * MCHECKSTYLE-381: More recent Checkstyle versions will drop the setClassLoader() method.
         * However, it was used before Checkstyle 8.25.
         */
        try
        {
            checker.setClassLoader( projectClassLoader );
        }
        catch ( NoSuchMethodError ignored )
        {
            /*
             * The current checkstyle version does not support the method setClassLoader anymore.
             * This is expected. The method call is being retained for less recent versions of checkstyle.
             */
        }

    }

    protected void addSourceDirectory( CheckstyleCheckerListener sinkListener, Collection<File> sourceDirectories,
                                       Collection<File> testSourceDirectories, List<Resource> resources,
                                       CheckstyleExecutorRequest request )
    {
        if ( sourceDirectories != null )
        {
            for ( File sourceDirectory : sourceDirectories )
            {
                if ( sourceDirectory.exists() )
                {
                    sinkListener.addSourceDirectory( sourceDirectory );
                }
            }
        }

        if ( request.isIncludeTestSourceDirectory() && ( testSourceDirectories != null ) )
        {
            for ( File testSourceDirectory : testSourceDirectories )
            {
                if ( testSourceDirectory.isDirectory() )
                {
                    sinkListener.addSourceDirectory( testSourceDirectory );
                }
            }
        }

        if ( resources != null )
        {
            for ( Resource resource : resources )
            {
                if ( resource.getDirectory() != null )
                {
                    File resourcesDirectory = new File( resource.getDirectory() );
                    if ( resourcesDirectory.exists() && resourcesDirectory.isDirectory() )
                    {
                        sinkListener.addSourceDirectory( resourcesDirectory );
                        getLogger().debug( "Added '" + resourcesDirectory.getAbsolutePath()
                                + "' as a source directory." );
                    }
                }
            }
        }
    }

    public Configuration getConfiguration( CheckstyleExecutorRequest request )
        throws CheckstyleExecutorException
    {
        try
        {
            // Checkstyle will always use the context classloader in order
            // to load resources (dtds),
            // so we have to fix it
            ClassLoader checkstyleClassLoader = PackageNamesLoader.class.getClassLoader();
            Thread.currentThread().setContextClassLoader( checkstyleClassLoader );
            String configFile = getConfigFile( request );
            Properties overridingProperties = getOverridingProperties( request );
            IgnoredModulesOptions omitIgnoredModules;
            if ( request.isOmitIgnoredModules() )
            {
                omitIgnoredModules = IgnoredModulesOptions.OMIT;
            }
            else
            {
                omitIgnoredModules = IgnoredModulesOptions.EXECUTE;
            }
            Configuration config =
                ConfigurationLoader.loadConfiguration( configFile, new PropertiesExpander( overridingProperties ),
                                                       omitIgnoredModules );
            String effectiveEncoding = StringUtils.isNotEmpty( request.getEncoding() ) ? request.getEncoding() : System
                .getProperty( "file.encoding", "UTF-8" );
            
            if ( StringUtils.isEmpty( request.getEncoding() ) )
            {
                getLogger().warn( "File encoding has not been set, using platform encoding " + effectiveEncoding
                                      + ", i.e. build is platform dependent!" );
            }

            if ( "Checker".equals( config.getName() )
                    || "com.puppycrawl.tools.checkstyle.Checker".equals( config.getName() ) )
            {
                if ( config instanceof DefaultConfiguration )
                {
                    // MCHECKSTYLE-173 Only add the "charset" attribute if it has not been set
                    addAttributeIfNotExists( (DefaultConfiguration) config, "charset", effectiveEncoding );
                    addAttributeIfNotExists( (DefaultConfiguration) config, "cacheFile", request.getCacheFile() );
                }
                else
                {
                    getLogger().warn( "Failed to configure file encoding on module " + config );
                }
            }
            return config;
        }
        catch ( CheckstyleException e )
        {
            throw new CheckstyleExecutorException( "Failed during checkstyle configuration", e );
        }
    }

    private void addAttributeIfNotExists( DefaultConfiguration config, String name, String value )
    {
        try
        {
            // MCHECKSTYLE-132 DefaultConfiguration addAttribute has changed in checkstyle 5.3
            if ( config.getAttribute( name ) == null )
            {
                config.addAttribute( name, value );
            }
        }
        catch ( CheckstyleException ex )
        {
            // MCHECKSTYLE-159 Checkstyle 5.4+ throws an exception when trying to access an attribute that doesn't exist
            config.addAttribute( name, value );
        }
    }

    private void prepareCheckstylePaths( CheckstyleExecutorRequest request, MavenProject project,
                                         List<String> classPathStrings, List<String> outputDirectories,
                                         Collection<File> sourceDirectories, Collection<File> testSourceDirectories )
        throws CheckstyleExecutorException
    {
        try
        {
            outputDirectories.add( project.getBuild().getOutputDirectory() );

            if ( request.isIncludeTestSourceDirectory() && ( testSourceDirectories != null )
                && anyDirectoryExists( testSourceDirectories ) )
            {
                classPathStrings.addAll( project.getTestClasspathElements() );
                outputDirectories.add( project.getBuild().getTestOutputDirectory() );
            }
            else
            {
                classPathStrings.addAll( project.getCompileClasspathElements() );
            }
        }
        catch ( DependencyResolutionRequiredException e )
        {
            throw new CheckstyleExecutorException( e.getMessage(), e );
        }
    }
    
    private boolean anyDirectoryExists( Collection<File> files )
    {
        for ( File file : files )
        {
            if ( file.isDirectory() )
            {
                return true;
            }
        }
        return false;
    }

    /**
     * Get the effective Checkstyle version at runtime.
     * @return the MANIFEST implementation version of Checkstyle API package (can be <code>null</code>)
     *
     *@todo Copied from CheckstyleReportGenerator - move to a utility class
     */
    private String getCheckstyleVersion()
    {
        Package checkstyleApiPackage = Configuration.class.getPackage();

        return ( checkstyleApiPackage == null ) ? null : checkstyleApiPackage.getImplementationVersion();
    }

    private Properties getOverridingProperties( CheckstyleExecutorRequest request )
        throws CheckstyleExecutorException
    {
        Properties p = new Properties();
        InputStream in = null;
        try
        {
            if ( request.getPropertiesLocation() != null )
            {
                if ( getLogger().isDebugEnabled() )
                {
                    getLogger().debug( "request.getPropertiesLocation() " + request.getPropertiesLocation() );
                }

                File propertiesFile = locator.getResourceAsFile( request.getPropertiesLocation(),
                                                                 "checkstyle-checker.properties" );

                if ( propertiesFile != null )
                {
                    in = new FileInputStream( propertiesFile );
                    p.load( in );
                    in.close();
                    in = null;
                }
            }

            if ( StringUtils.isNotEmpty( request.getPropertyExpansion() ) )
            {
                String propertyExpansion = request.getPropertyExpansion();
                // Convert \ to \\, so that p.load will convert it back properly
                propertyExpansion = StringUtils.replace( propertyExpansion, "\\", "\\\\" );
                p.load( new ByteArrayInputStream( propertyExpansion.getBytes() ) );
            }

            // Workaround for MCHECKSTYLE-48
            // Make sure that "config/maven-header.txt" is the default value
            // for headerLocation, if configLocation="config/maven_checks.xml"
            String headerLocation = request.getHeaderLocation();
            if ( "config/maven_checks.xml".equals( request.getConfigLocation() ) )
            {

                if ( "LICENSE.txt".equals( request.getHeaderLocation() ) )
                {
                    headerLocation = "config/maven-header.txt";
                }
            }
            if ( getLogger().isDebugEnabled() )
            {
                getLogger().debug( "headerLocation " + headerLocation );
            }

            if ( StringUtils.isNotEmpty( headerLocation ) )
            {
                try
                {
                    File headerFile = licenseLocator.getResourceAsFile( headerLocation, "checkstyle-header.txt" );

                    if ( headerFile != null )
                    {
                        p.setProperty( "checkstyle.header.file", headerFile.getAbsolutePath() );
                    }
                }
                catch ( FileResourceCreationException | ResourceNotFoundException e )
                {
                    getLogger().debug( "Unable to process header location: " + headerLocation );
                    getLogger().debug( "Checkstyle will throw exception if ${checkstyle.header.file} is used" );
                }
            }

            if ( request.getCacheFile() != null )
            {
                p.setProperty( "checkstyle.cache.file", request.getCacheFile() );
            }
        }
        catch ( IOException | ResourceNotFoundException | FileResourceCreationException e )
        {
            throw new CheckstyleExecutorException( "Failed to get overriding properties", e );
        }
        finally
        {
            IOUtils.closeQuietly( in );
        }
        if ( request.getSuppressionsFileExpression() != null )
        {
            String suppressionsFilePath = getSuppressionsFilePath( request );

            if ( suppressionsFilePath != null )
            {
                p.setProperty( request.getSuppressionsFileExpression(), suppressionsFilePath );
            }
        }

        return p;
    }

    private List<File> getFilesToProcess( CheckstyleExecutorRequest request )
        throws IOException
    {
        StringBuilder excludesStr = new StringBuilder();

        if ( StringUtils.isNotEmpty( request.getExcludes() ) )
        {
            excludesStr.append( request.getExcludes() );
        }

        String[] defaultExcludes = FileUtils.getDefaultExcludes();
        for ( String defaultExclude : defaultExcludes )
        {
            if ( excludesStr.length() > 0 )
            {
                excludesStr.append( "," );
            }

            excludesStr.append( defaultExclude );
        }

        Set<File> files = new LinkedHashSet<>();
        if ( request.isAggregate() )
        {
            for ( MavenProject project : request.getReactorProjects() )
            {
                Set<File> sourceDirectories = new LinkedHashSet<>();
                
                // CompileSourceRoots are absolute paths
                List<String> compileSourceRoots = project.getCompileSourceRoots(); 
                for ( String compileSourceRoot : compileSourceRoots )
                {
                    sourceDirectories.add( new File( compileSourceRoot ) );
                }

                Set<File> testSourceDirectories = new LinkedHashSet<>();
                // 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
        {
            Collection<File> sourceDirectories = request.getSourceDirectories();
            addFilesToProcess( request, sourceDirectories, request.getResources(),
                request.getTestResources(), files, request.getTestSourceDirectories() );
        }

        getLogger().debug( "Added " + files.size() + " files to process." );

        return new ArrayList<>( files );
    }

    private void addFilesToProcess( CheckstyleExecutorRequest request, Collection<File> sourceDirectories,
                                    List<Resource> resources, List<Resource> testResources, Collection<File> files,
                                    Collection<File> testSourceDirectories )
        throws IOException
    {
        if ( sourceDirectories != null )
        {
            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() )
        {
            addResourceFilesToProcess( request, resources, files );
        }
        else
        {
            getLogger().debug( "No resources found in this project." );
        }

        if ( testResources != null && request.isIncludeTestResources() )
        {
            addResourceFilesToProcess( request, testResources, files );
        }
        else
        {
            getLogger().debug( "No test resources found in this project." );
        }
    }

    private void addResourceFilesToProcess( CheckstyleExecutorRequest request, List<Resource> resources,
                                            Collection<File> files )
        throws IOException
    {
        for ( Resource resource : resources )
        {
            if ( resource.getDirectory() != null )
            {
                File resourcesDirectory = new File( resource.getDirectory() );
                if ( resourcesDirectory.isDirectory() )
                {
                    String includes = request.getResourceIncludes();
                    String excludes = request.getResourceExcludes();

                    // MCHECKSTYLE-214: Only with project-root respect in/excludes, otherwise you'll get every file
                    if ( resourcesDirectory.equals( request.getProject().getBasedir() ) )
                    {
                        String resourceIncludes = StringUtils.join( resource.getIncludes().iterator(), "," );
                        if ( StringUtils.isEmpty( includes ) )
                        {
                            includes = resourceIncludes;
                        }
                        else
                        {
                            includes += "," + resourceIncludes;
                        }
                        
                        String resourceExcludes = StringUtils.join( resource.getExcludes().iterator(), "," );
                        if ( StringUtils.isEmpty( excludes ) )
                        {
                            excludes = resourceExcludes;
                        }
                        else
                        {
                            excludes += "," + resourceExcludes;
                        }
                    }
                    
                    List<File> resourceFiles =
                        FileUtils.getFiles( resourcesDirectory, includes, excludes );
                    files.addAll( resourceFiles );
                    getLogger().debug( "Added " + resourceFiles.size() + " resource files found in '"
                            + resourcesDirectory.getAbsolutePath() + "'." );
                }
                else
                {
                    getLogger().debug( "The resources directory '" + resourcesDirectory.getAbsolutePath()
                            + "' does not exist or is not a directory." );
                }
            }
        }
    }

    private FilterSet getSuppressionsFilterSet( final String suppressionsFilePath )
        throws CheckstyleExecutorException
    {
        if ( suppressionsFilePath == null )
        {
            return null;
        }

        try
        {
            return SuppressionsLoader.loadSuppressions( suppressionsFilePath );
        }
        catch ( CheckstyleException ce )
        {
            throw new CheckstyleExecutorException( "Failed to load suppressions file from: "
                + suppressionsFilePath, ce );
        }
    }

    private String getSuppressionsFilePath( final CheckstyleExecutorRequest request )
        throws CheckstyleExecutorException
    {
        final String suppressionsLocation = request.getSuppressionsLocation();
        if ( StringUtils.isEmpty( suppressionsLocation ) )
        {
            return null;
        }
        
        try
        {
            File suppressionsFile = locator.getResourceAsFile( suppressionsLocation, "checkstyle-suppressions.xml" );
            return suppressionsFile == null ? null : suppressionsFile.getAbsolutePath();
        }
        catch ( ResourceNotFoundException e )
        {
            throw new CheckstyleExecutorException( "Unable to find suppressions file at location: "
                + suppressionsLocation, e );
        }
        catch ( FileResourceCreationException e )
        {
            throw new CheckstyleExecutorException( "Unable to process suppressions file location: "
                + suppressionsLocation, e );
        }
    }

    private String getConfigFile( CheckstyleExecutorRequest request )
        throws CheckstyleExecutorException
    {
        try
        {
            if ( getLogger().isDebugEnabled() )
            {
                getLogger().debug( "request.getConfigLocation() " + request.getConfigLocation() );
            }

            File configFile = locator.getResourceAsFile( request.getConfigLocation(), "checkstyle-checker.xml" );
            if ( configFile == null )
            {
                throw new CheckstyleExecutorException( "Unable to process config location: "
                    + request.getConfigLocation() );
            }
            return configFile.getAbsolutePath();
        }
        catch ( ResourceNotFoundException e )
        {
            throw new CheckstyleExecutorException( "Unable to find configuration file at location: "
                + request.getConfigLocation(), e );
        }
        catch ( FileResourceCreationException e )
        {
            throw new CheckstyleExecutorException( "Unable to process configuration file at location: "
                + request.getConfigLocation(), e );
        }

    }

    /**
     * Configures search paths in the resource locator.
     * This method should only be called once per execution.
     *
     * @param request executor request data.
     */
    private void configureResourceLocator( final ResourceManager resourceManager,
                                           final CheckstyleExecutorRequest request,
                                           final List<Artifact> additionalArtifacts )
    {
        final MavenProject project = request.getProject();
        resourceManager.setOutputDirectory( new File( project.getBuild().getDirectory() ) );

        // Recurse up the parent hierarchy and add project directories to the search roots
        MavenProject parent = project;
        while ( parent != null && parent.getFile() != null )
        {
            // MCHECKSTYLE-131 ( olamy ) I don't like this hack.
            // (dkulp) Me either.   It really pollutes the location stuff
            // by allowing searches of stuff outside the current module.
            File dir = parent.getFile().getParentFile();
            resourceManager.addSearchPath( FileResourceLoader.ID, dir.getAbsolutePath() );
            parent = parent.getParent();
        }
        resourceManager.addSearchPath( "url", "" );
        
        // MCHECKSTYLE-225: load licenses from additional artifacts, not from classpath
        if ( additionalArtifacts != null )
        {
            for ( Artifact licenseArtifact : additionalArtifacts )
            {
                try
                {
                    resourceManager.addSearchPath( "jar", "jar:" + licenseArtifact.getFile().toURI().toURL() );
                }
                catch ( MalformedURLException e )
                {
                    // noop
                }
            }
        }
    }
}
