package org.apache.tomcat.maven.plugin.tomcat8.run;
/*
 * 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 org.apache.catalina.Context;
import org.apache.catalina.Host;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.WebResource;
import org.apache.catalina.WebResourceSet;
import org.apache.catalina.Wrapper;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.loader.WebappLoader;
import org.apache.catalina.realm.MemoryRealm;
import org.apache.catalina.servlets.DefaultServlet;
import org.apache.catalina.startup.Catalina;
import org.apache.catalina.startup.CatalinaProperties;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.valves.AccessLogValve;
import org.apache.catalina.webresources.FileResource;
import org.apache.catalina.webresources.StandardRoot;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.artifact.resolver.ArtifactResolver;
import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
import org.apache.maven.artifact.versioning.VersionRange;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.shared.filtering.MavenFileFilter;
import org.apache.maven.shared.filtering.MavenFileFilterRequest;
import org.apache.maven.shared.filtering.MavenFilteringException;
import org.apache.tomcat.JarScanner;
import org.apache.tomcat.maven.common.config.AbstractWebapp;
import org.apache.tomcat.maven.common.run.EmbeddedRegistry;
import org.apache.tomcat.maven.common.run.ExternalRepositoriesReloadableWebappLoader;
import org.apache.tomcat.maven.plugin.tomcat8.AbstractTomcat8Mojo;
import org.apache.tomcat.util.scan.StandardJarScanner;
import org.codehaus.plexus.archiver.ArchiverException;
import org.codehaus.plexus.archiver.UnArchiver;
import org.codehaus.plexus.archiver.manager.ArchiverManager;
import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
import org.codehaus.plexus.classworlds.ClassWorld;
import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.codehaus.plexus.classworlds.realm.DuplicateRealmException;
import org.codehaus.plexus.util.DirectoryScanner;
import org.codehaus.plexus.util.FileUtils;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

import javax.servlet.ServletException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

/**
 * @author Olivier Lamy
 * @since 2.0
 */
public abstract class AbstractRunMojo
    extends AbstractTomcat8Mojo
{
    // ---------------------------------------------------------------------
    // Mojo Components
    // ---------------------------------------------------------------------

    /**
     * Used to look up Artifacts in the remote repository.
     */
    @Component
    protected ArtifactFactory factory;

    /**
     * Location of the local repository.
     */
    @Parameter( defaultValue = "${localRepository}", required = true, readonly = true )
    private ArtifactRepository local;

    /**
     * Used to look up Artifacts in the remote repository.
     */
    @Component
    protected ArtifactResolver resolver;

    // ----------------------------------------------------------------------
    // Mojo Parameters
    // ----------------------------------------------------------------------

    /**
     * The packaging of the Maven project that this goal operates upon.
     */
    @Parameter( defaultValue = "${project.packaging}", required = true, readonly = true )
    private String packaging;

    /**
     * The directory to create the Tomcat server configuration under.
     */
    @Parameter( defaultValue = "${project.build.directory}/tomcat" )
    private File configurationDir;

    /**
     * The port to run the Tomcat server on.
     * Will be exposed as System props and session.executionProperties with key tomcat.maven.http.port
     */
    @Parameter( property = "maven.tomcat.port", defaultValue = "8080" )
    private int port;

    /**
     * this IP address will be used on all ports
     *
     * @since 2.2
     */
    @Parameter( property = "maven.tomcat.address" )
    private String address;

    /**
     * The AJP port to run the Tomcat server on.
     * By default it's 0 this means won't be started.
     * The ajp connector will be started only for value > 0.
     * Will be exposed as System props and session.executionProperties with key tomcat.maven.ajp.port
     *
     * @since 2.0
     */
    @Parameter( property = "maven.tomcat.ajp.port", defaultValue = "0" )
    private int ajpPort;

    /**
     * The AJP protocol to run the Tomcat server on.
     * By default it's ajp.
     * NOTE The ajp connector will be started only if {@link #ajpPort} > 0.
     * possible values are:
     * <ul>
     * <li>org.apache.coyote.ajp.AjpProtocol - new blocking Java connector that supports an executor</li>
     * <li>org.apache.coyote.ajp.AjpAprProtocol - the APR/native connector.</li>
     * </ul>
     *
     * @since 2.0
     */
    @Parameter( property = "maven.tomcat.ajp.protocol", defaultValue = "org.apache.coyote.ajp.AjpProtocol" )
    private String ajpProtocol;

    /**
     * The https port to run the Tomcat server on.
     * By default it's 0 this means won't be started.
     * The https connector will be started only for value > 0.
     * Will be exposed as System props and session.executionProperties with key tomcat.maven.https.port
     *
     * @since 1.0
     */
    @Parameter( property = "maven.tomcat.httpsPort", defaultValue = "0" )
    private int httpsPort;

    /**
     * The max post size to run the Tomcat server on.
     * By default it's 2097152 bytes. That's the default Tomcat configuration.
     * Set this value to 0 or less to disable the post size limit.
     *
     * @since 2.3
     */
    @Parameter( property = "maven.tomcat.maxPostSize", defaultValue = "2097152" )
    private int maxPostSize;

    /**
     * The character encoding to use for decoding URIs.
     *
     * @since 1.0
     */
    @Parameter( property = "maven.tomcat.uriEncoding", defaultValue = "ISO-8859-1" )
    private String uriEncoding;

    /**
     * List of System properties to pass to the Tomcat Server.
     *
     * @since 1.0-alpha-2
     */
    @Parameter
    private Map<String, String> systemProperties;

    /**
     * The directory contains additional configuration Files that copied in the Tomcat conf Directory.
     *
     * @since 1.0-alpha-2
     */
    @Parameter( property = "maven.tomcat.additionalConfigFilesDir", defaultValue = "${basedir}/src/main/tomcatconf" )
    private File additionalConfigFilesDir;

    /**
     * server.xml to use <b>Note if you use this you must configure in this file your webapp paths</b>.
     *
     * @since 1.0-alpha-2
     */
    @Parameter( property = "maven.tomcat.serverXml" )
    private File serverXml;

    /**
     * overriding the providing web.xml to run tomcat
     * <b>This override the global Tomcat web.xml located in $CATALINA_HOME/conf/</b>
     *
     * @since 1.0-alpha-2
     */
    @Parameter( property = "maven.tomcat.webXml" )
    private File tomcatWebXml;

    /**
     * Set this to true to allow Maven to continue to execute after invoking
     * the run goal.
     *
     * @since 1.0
     */
    @Parameter( property = "maven.tomcat.fork", defaultValue = "false" )
    private boolean fork;

    /**
     * Will create a tomcat context for each dependencies of war type with 'scope' set to 'tomcat'.
     * In other words, dependencies with:
     * <pre>
     *    &lt;type&gt;war&lt;/type&gt;
     *    &lt;scope&gt;tomcat&lt;/scope&gt;
     * </pre>
     * To preserve backward compatibility it's false by default.
     *
     * @since 1.0
     * @deprecated use webapps instead
     */
    @Parameter( property = "maven.tomcat.addContextWarDependencies", defaultValue = "false" )
    private boolean addContextWarDependencies;

    /**
     * The maven project.
     *
     * @since 1.0
     */
    @Parameter( defaultValue = "${project}", readonly = true )
    protected MavenProject project;

    /**
     * The archive manager.
     *
     * @since 1.0
     */
    @Component
    private ArchiverManager archiverManager;

    /**
     * if <code>true</code> a new classLoader separated from maven core will be created to start tomcat.
     *
     * @since 1.0
     */
    @Parameter( property = "tomcat.useSeparateTomcatClassLoader", defaultValue = "false" )
    protected boolean useSeparateTomcatClassLoader;

    /**
     * @since 1.0
     */
    @Parameter( defaultValue = "${plugin.artifacts}", required = true )
    private List<Artifact> pluginArtifacts;

    /**
     * If set to true ignore if packaging of project is not 'war'.
     *
     * @since 1.0
     */
    @Parameter( property = "tomcat.ignorePackaging", defaultValue = "false" )
    private boolean ignorePackaging;

    /**
     * Override the default keystoreFile for the HTTPS connector (if enabled)
     *
     * @since 1.1
     */
    @Parameter
    private String keystoreFile;

    /**
     * Override the default keystorePass for the HTTPS connector (if enabled)
     *
     * @since 1.1
     */
    @Parameter
    private String keystorePass;

    /**
     * Override the type of keystore file to be used for the server certificate. If not specified, the default value is "JKS".
     *
     * @since 2.0
     */
    @Parameter( defaultValue = "JKS" )
    private String keystoreType;

    /**
     * <p>
     * Enables or disables naming support for the embedded Tomcat server.
     * </p>
     * <p>
     * <strong>Note:</strong> This setting is ignored if you provide a <code>server.xml</code> for your
     * Tomcat. Instead please configure naming in the <code>server.xml</code>.
     * </p>
     *
     * @see <a href="http://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/catalina/startup/Embedded.html">org.apache.catalina.startup.Embedded</a>
     * @see <a href="http://tomcat.apache.org/tomcat-8.0-doc/api/org/apache/catalina/startup/Tomcat.html">org.apache.catalina.startup.Tomcat</a>
     * @since 2.0
     */
    @Parameter( property = "maven.tomcat.useNaming", defaultValue = "true" )
    private boolean useNaming;

    /**
     * Force context scanning if you don't use a context file with reloadable = "true".
     * The other way to use contextReloadable is to add attribute reloadable = "true"
     * in your context file.
     *
     * @since 2.0
     */
    @Parameter( property = "maven.tomcat.contextReloadable", defaultValue = "false" )
    protected boolean contextReloadable;

    /**
     * represents the delay in seconds between each classPathScanning change invocation
     *
     * @see <a href="http://tomcat.apache.org/tomcat-7.0-doc/config/context.html">http://tomcat.apache.org/tomcat-7.0-doc/config/context.html</a>
     */
    @Parameter( property = "maven.tomcat.backgroundProcessorDelay", defaultValue = "-1" )
    protected int backgroundProcessorDelay = -1;


    /**
     * <p>The path of the Tomcat context XML file.</p>
     * <p>Since release 2.0, the file is filtered as a maven resource so you can use
     * interpolation tokens ${ }</p>
     */
    @Parameter( property = "maven.tomcat.contextFile" )
    protected File contextFile;

    /**
     * The default context file to check for if contextFile not configured.
     * If no contextFile configured and the below default not present, no
     * contextFile will be sent to Tomcat, resulting in the latter's default
     * context configuration being used instead.
     */
    @Parameter( defaultValue = "${project.build.directory}/${project.build.finalName}/META-INF/context.xml",
                readonly = true )
    private File defaultContextFile;

    /**
     * The protocol to run the Tomcat server on.
     * By default it's HTTP/1.1.
     * See possible values <a href="http://tomcat.apache.org/tomcat-7.0-doc/config/http.html">HTTP Connector</a>
     * protocol attribute
     *
     * @since 2.0
     */
    @Parameter( property = "maven.tomcat.protocol", defaultValue = "HTTP/1.1" )
    private String protocol;

    /**
     * The path of the Tomcat users XML file.
     *
     * @since 2.0
     */
    @Parameter( property = "maven.tomcat.tomcatUsers.file" )
    private File tomcatUsers;

    /**
     * The path of the Tomcat logging configuration.
     *
     * @since 2.0
     */
    @Parameter( property = "maven.tomcat.tomcatLogging.file" )
    private File tomcatLoggingFile;

    /**
     * Skip execution
     *
     * @since 2.0
     */
    @Parameter( property = "maven.tomcat.skip", defaultValue = "false" )
    protected boolean skip;

    /**
     * Collection of webapp artifacts to be deployed. Elements are &lt;webapp&gt; and contain
     * usual GAVC plus contextPath and/or contextFile elements.<p>
     *
     * @see {@link Webapp}
     * @since 2.0
     */
    @Parameter
    private List<Webapp> webapps;

    /**
     * The static context
     *
     * @since 2.0
     */
    @Parameter( property = "maven.tomcat.staticContextPath", defaultValue = "/" )
    private String staticContextPath;

    /**
     * The static context docroot base fully qualified path
     * if <code>null</code> static context won't be added
     *
     * @since 2.0
     */
    @Parameter( property = "maven.tomcat.staticContextDocbase" )
    private String staticContextDocbase;

    /**
     * Class loader class to set.
     *
     * @since 2.0
     */
    @Parameter
    protected String classLoaderClass;

    @Parameter( defaultValue = "${session}", readonly = true, required = true )
    protected MavenSession session;

    /**
     * Will dump port in a properties file (see ports for property names).
     * If empty no file generated
     */
    @Parameter( property = "maven.tomcat.propertiesPortFilePath" )
    protected String propertiesPortFilePath;

    /**
     * configure host name
     *
     * @since 2.0
     */
    @Parameter( property = "maven.tomcat.hostName", defaultValue = "localhost" )
    protected String hostName;

    /**
     * configure aliases
     * see <a href="http://tomcat.apache.org/tomcat-7.0-doc/config/host.html#Host_Name_Aliases">Host Name aliases</a>
     *
     * @since 2.0
     */
    @Parameter
    protected String[] aliases;

    /**
     * enable client authentication for https (if configured)
     * see <a href="http://tomcat.apache.org/tomcat-7.0-doc/config/http.html#SSL_Support_-_BIO_and_NIO">http://tomcat.apache.org/tomcat-7.0-doc/config/http.html#SSL_Support_-_BIO_and_NIO</a>
     *
     * @since 2.1
     */
    @Parameter( property = "maven.tomcat.https.clientAuth", defaultValue = "false" )
    protected String clientAuth = "false";

    @Component( role = MavenFileFilter.class, hint = "default" )
    protected MavenFileFilter mavenFileFilter;


    /**
     * In case a module in your reactors has some web-fragments they will be read.
     * If you don't need that for performance reasons, you can deactivate it.
     *
     * @since 2.2
     */
    @Parameter( property = "maven.tomcat.jarScan.allDirectories", defaultValue = "true" )
    protected boolean jarScanAllDirectories = true;

    /**
     * @since 2.2
     */
    @Parameter( property = "maven.tomcat.useBodyEncodingForURI", defaultValue = "false" )
    protected boolean useBodyEncodingForURI;

    /**
     * @since 2.2
     */
    @Parameter
    protected String trustManagerClassName;

    /**
     * @since 2.2
     */
    @Parameter
    protected String trustMaxCertLength;

    /**
     * @since 2.2
     */
    @Parameter
    protected String truststoreAlgorithm;

    /**
     * @since 2.2
     */
    @Parameter
    protected String truststoreFile;

    /**
     * @since 2.2
     */
    @Parameter
    protected String truststorePass;

    /**
     * @since 2.2
     */
    @Parameter
    protected String truststoreProvider;

    /**
     * @since 2.2
     */
    @Parameter
    protected String truststoreType;

    // ----------------------------------------------------------------------
    // Fields
    // ----------------------------------------------------------------------

    /**
     * @since 1.0
     */
    private ClassRealm tomcatRealm;

    // ----------------------------------------------------------------------
    // Mojo Implementation
    // ----------------------------------------------------------------------

    /**
     * {@inheritDoc}
     */
    public void execute()
        throws MojoExecutionException, MojoFailureException
    {
        if ( skip )
        {
            getLog().info( "skip execution" );
            return;
        }
        // ensure project is a web application
        if ( !isWar() && !addContextWarDependencies && getAdditionalWebapps().isEmpty() )
        {
            getLog().info( messagesProvider.getMessage( "AbstractRunMojo.nonWar" ) );
            return;
        }
        ClassLoader originalClassLoader = null;
        if ( useSeparateTomcatClassLoader )
        {
            originalClassLoader = Thread.currentThread().getContextClassLoader();
        }
        try
        {
            getLog().info( messagesProvider.getMessage( "AbstractRunMojo.runningWar", getWebappUrl() ) );

            initConfiguration();
            startContainer();
            if ( !fork )
            {
                waitIndefinitely();
            }
        }
        catch ( LifecycleException exception )
        {
            throw new MojoExecutionException( messagesProvider.getMessage( "AbstractRunMojo.cannotStart" ), exception );
        }
        catch ( IOException exception )
        {
            throw new MojoExecutionException(
                messagesProvider.getMessage( "AbstractRunMojo.cannotCreateConfiguration" ), exception );
        }
        catch ( ServletException e )
        {
            throw new MojoExecutionException( e.getMessage(), e );
        }
        catch ( MavenFilteringException e )
        {
            throw new MojoExecutionException( "filtering issue: " + e.getMessage(), e );
        }
        finally
        {
            if ( useSeparateTomcatClassLoader )
            {
                Thread.currentThread().setContextClassLoader( originalClassLoader );
            }
        }
    }

    // ----------------------------------------------------------------------
    // Protected Methods
    // ----------------------------------------------------------------------

    /**
     * Gets the webapp context path to use for the web application being run.
     *
     * @return the webapp context path
     */
    protected String getPath()
    {
        return path;
    }

    protected void enhanceContext( final Context context )
        throws MojoExecutionException
    {
        // no op
    }


    /**
     * Gets the context to run this web application under for the specified embedded Tomcat.
     *
     * @param container the embedded Tomcat container being used
     * @return the context to run this web application under
     * @throws IOException            if the context could not be created
     * @throws MojoExecutionException in case of an error creating the context
     */
    protected Context createContext( Tomcat container )
        throws IOException, MojoExecutionException, ServletException
    {
        String contextPath = getPath();

        String baseDir = getDocBase().getAbsolutePath();

        File overriddenContextFile = getContextFile();

        StandardContext standardContext = null;

        if ( overriddenContextFile != null && overriddenContextFile.exists() )
        {
            standardContext = parseContextFile( overriddenContextFile );
        }
        else if ( defaultContextFile.exists() )
        {
            standardContext = parseContextFile( defaultContextFile );
        }

        if ( standardContext != null )
        {
            if ( standardContext.getPath() != null )
            {
                contextPath = standardContext.getPath();
            }
            if ( standardContext.getDocBase() != null )
            {
                baseDir = standardContext.getDocBase();
            }
        }

        contextPath = "/".equals( contextPath ) ? "" : contextPath;

        getLog().info( "create webapp with contextPath: " + contextPath );

        Context context = container.addWebapp( contextPath, baseDir );

        context.setResources(
            new MyDirContext( new File( project.getBuild().getOutputDirectory() ).getAbsolutePath(), //
                              getPath(), //
                              getLog() ) );

        if ( useSeparateTomcatClassLoader )
        {
            context.setParentClassLoader( getTomcatClassLoader() );
        }

        enhanceContext( context );

        final WebappLoader loader = createWebappLoader();

        context.setLoader( loader );

        if ( overriddenContextFile != null )
        {
            // here, send file to Tomcat for it to complain if missing
            context.setConfigFile( overriddenContextFile.toURI().toURL() );
        }
        else if ( defaultContextFile.exists() )
        {
            // here, only sending default file if it indeed exists
            // otherwise Tomcat will create a default context
            context.setConfigFile( defaultContextFile.toURI().toURL() );
        }

        if ( classLoaderClass != null )
        {
            loader.setLoaderClass( classLoaderClass );
        }

        // https://issues.apache.org/jira/browse/MTOMCAT-239
        // get the jar scanner to configure scanning directories as we can run a jar or a reactor project with a jar so
        // the entries is a directory (target/classes)
        JarScanner jarScanner = context.getJarScanner();

        // normally this one only but just in case ...
        if ( jarScanner instanceof StandardJarScanner )
        {
            ( (StandardJarScanner) jarScanner ).setScanAllDirectories( jarScanAllDirectories );
        }

        return context;

    }

    protected StandardContext parseContextFile( File file )
        throws MojoExecutionException
    {
        try
        {
            StandardContext standardContext = new StandardContext();
            XMLStreamReader reader = XMLInputFactory.newFactory().createXMLStreamReader( new FileInputStream( file ) );

            int tag = reader.next();

            while ( true )
            {
                if ( tag == XMLStreamConstants.START_ELEMENT && StringUtils.equals( "Context", reader.getLocalName() ) )
                {
                    String path = reader.getAttributeValue( null, "path" );
                    if ( StringUtils.isNotBlank( path ) )
                    {
                        standardContext.setPath( path );
                    }

                    String docBase = reader.getAttributeValue( null, "docBase" );
                    if ( StringUtils.isNotBlank( docBase ) )
                    {
                        standardContext.setDocBase( docBase );
                    }
                }
                if ( !reader.hasNext() )
                {
                    break;
                }
                tag = reader.next();
            }

            return standardContext;
        }
        catch ( XMLStreamException e )
        {
            throw new MojoExecutionException( e.getMessage(), e );
        }
        catch ( FileNotFoundException e )
        {
            throw new MojoExecutionException( e.getMessage(), e );
        }
    }


    protected static class MyDirContext
        extends StandardRoot
    {
        String buildOutputDirectory;

        String webAppPath;

        WebResourceSet webResourceSet;

        Log log;

        MyDirContext( String buildOutputDirectory, String webAppPath, Log log )
        {

            this.buildOutputDirectory = buildOutputDirectory;
            this.webAppPath = webAppPath;
            this.log = log;
        }

        @Override
        public WebResource getResource( String path )
        {

            log.debug( "MyDirContext#getResource: " + path );
            if ( "/WEB-INF/classes".equals( path ) )
            {
                return new FileResource( this, this.webAppPath, new File( this.buildOutputDirectory ), true );
            }

            File file = new File( path );
            if ( file.exists() )
            {
                return new FileResource( this, this.webAppPath, file, true );
            }
            WebResource webResource = super.getResource( path );
            return webResource;
        }


        @Override
        public WebResource getClassLoaderResource( String path )
        {
            log.debug( "MyDirContext#getClassLoaderResource: " + path );
            // here get resources from various paths
            return super.getClassLoaderResource( path );
        }


        @Override
        public WebResource[] listResources( String path )
        {
            log.debug( "MyDirContext#listResources: " + path );
            return super.listResources( path );
        }

        @Override
        public WebResource[] getClassLoaderResources( String path )
        {
            log.debug( "MyDirContext#getClassLoaderResources: " + path );
            return super.getClassLoaderResources( path );
        }

        @Override
        public WebResource[] getResources( String path )
        {
            log.debug( "MyDirContext#getResources: " + path );
            return super.getResources( path );
        }

        @Override
        protected WebResource[] getResourcesInternal( String path, boolean useClassLoaderResources )
        {
            log.debug( "MyDirContext#getResourcesInternal: " + path );
            return super.getResourcesInternal( path, useClassLoaderResources );
        }


    }

    /**
     * Gets the webapp loader to run this web application under.
     *
     * @return the webapp loader to use
     * @throws IOException            if the webapp loader could not be created
     * @throws MojoExecutionException in case of an error creating the webapp loader
     */
    protected WebappLoader createWebappLoader()
        throws IOException, MojoExecutionException
    {
        WebappLoader webappLoader = null;
        if ( useSeparateTomcatClassLoader )
        {
            if ( isContextReloadable() )
            {
                webappLoader = new ExternalRepositoriesReloadableWebappLoader( getTomcatClassLoader(), getLog() );
            }
            else
            {
                webappLoader = new WebappLoader( getTomcatClassLoader() );
            }
        }
        else
        {
            if ( isContextReloadable() )
            {
                webappLoader =
                    new ExternalRepositoriesReloadableWebappLoader( Thread.currentThread().getContextClassLoader(),
                                                                    getLog() );
            }
            else
            {
                webappLoader = new WebappLoader( Thread.currentThread().getContextClassLoader() );
            }
        }
        return webappLoader;
    }

    /**
     * Determine whether the passed context.xml file declares the context as reloadable or not.
     *
     * @return false by default, true if  reloadable="true" in context.xml.
     */
    protected boolean isContextReloadable()
        throws MojoExecutionException
    {
        if ( contextReloadable || backgroundProcessorDelay > 0 )
        {
            return true;
        }
        // determine whether to use a reloadable Loader or not (default is false).
        boolean reloadable = false;
        try
        {
            if ( contextFile != null && contextFile.exists() )
            {
                DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
                DocumentBuilder builder = builderFactory.newDocumentBuilder();
                Document contextDoc = builder.parse( contextFile );
                contextDoc.getDocumentElement().normalize();

                NamedNodeMap nodeMap = contextDoc.getDocumentElement().getAttributes();
                Node reloadableAttribute = nodeMap.getNamedItem( "reloadable" );

                reloadable =
                    ( reloadableAttribute != null ) ? Boolean.valueOf( reloadableAttribute.getNodeValue() ) : false;
            }
            getLog().debug( "context reloadable: " + reloadable );
        }
        catch ( IOException ioe )
        {
            getLog().error( "Could not parse file: [" + contextFile.getAbsolutePath() + "]", ioe );
        }
        catch ( ParserConfigurationException pce )
        {
            getLog().error( "Could not configure XML parser", pce );
        }
        catch ( SAXException se )
        {
            getLog().error( "Could not parse file: [" + contextFile.getAbsolutePath() + "]", se );
        }

        return reloadable;
    }


    /**
     * Gets the webapp directory to run.
     *
     * @return the webapp directory
     */
    protected abstract File getDocBase()
        throws IOException;

    /**
     * Gets the Tomcat context XML file to use.
     *
     * @return the context XML file
     */
    protected abstract File getContextFile()
        throws MojoExecutionException;

    // ----------------------------------------------------------------------
    // Private Methods
    // ----------------------------------------------------------------------

    /**
     * Gets whether this project uses WAR packaging.
     *
     * @return whether this project uses WAR packaging
     */
    protected boolean isWar()
    {
        return "war".equals( packaging ) || ignorePackaging;
    }

    /**
     * Gets the URL of the running webapp.
     *
     * @return the URL of the running webapp
     * @throws java.net.MalformedURLException if the running webapp URL is invalid
     */
    private URL getWebappUrl()
        throws MalformedURLException
    {
        return new URL( "http", "localhost", port, getPath() );
    }

    /**
     * FIXME not sure we need all of those files with tomcat8
     * Creates the Tomcat configuration directory with the necessary resources.
     *
     * @throws IOException            if the Tomcat configuration could not be created
     * @throws MojoExecutionException if the Tomcat configuration could not be created
     */
    private void initConfiguration()
        throws IOException, MojoExecutionException, MavenFilteringException
    {
        if ( configurationDir.exists() )
        {
            getLog().info( messagesProvider.getMessage( "AbstractRunMojo.usingConfiguration", configurationDir ) );
        }
        else
        {
            getLog().info( messagesProvider.getMessage( "AbstractRunMojo.creatingConfiguration", configurationDir ) );

            configurationDir.mkdirs();

            File confDir = new File( configurationDir, "conf" );
            confDir.mkdir();

            if ( tomcatLoggingFile != null )
            {
                FileUtils.copyFile( tomcatLoggingFile, new File( confDir, "logging.properties" ) );
            }
            else
            {
                copyFile( "/conf/logging.properties", new File( confDir, "logging.properties" ) );
            }

            copyFile( "/conf/tomcat-users.xml", new File( confDir, "tomcat-users.xml" ) );
            if ( tomcatWebXml != null )
            {
                if ( !tomcatWebXml.exists() )
                {
                    throw new MojoExecutionException( " tomcatWebXml " + tomcatWebXml.getPath() + " not exists" );
                }
                //MTOMCAT-42  here it's a real file resources not a one coming with the mojo
                //MTOMCAT-128 apply filtering
                MavenFileFilterRequest mavenFileFilterRequest = new MavenFileFilterRequest();
                mavenFileFilterRequest.setFrom( tomcatWebXml );
                mavenFileFilterRequest.setTo( new File( confDir, "web.xml" ) );
                mavenFileFilterRequest.setMavenProject( project );
                mavenFileFilterRequest.setMavenSession( session );
                mavenFileFilterRequest.setFiltering( true );

                mavenFileFilter.copyFile( mavenFileFilterRequest );

            }
            else
            {
                copyFile( "/conf/web.xml", new File( confDir, "web.xml" ) );
            }

            File logDir = new File( configurationDir, "logs" );
            logDir.mkdir();

            File webappsDir = new File( configurationDir, "webapps" );
            webappsDir.mkdir();

            if ( additionalConfigFilesDir != null && additionalConfigFilesDir.exists() )
            {
                DirectoryScanner scanner = new DirectoryScanner();
                scanner.addDefaultExcludes();
                scanner.setBasedir( additionalConfigFilesDir.getPath() );
                scanner.scan();

                String[] files = scanner.getIncludedFiles();

                if ( files != null && files.length > 0 )
                {
                    getLog().info( "Coping additional tomcat config files" );

                    for ( int i = 0; i < files.length; i++ )
                    {
                        File file = new File( additionalConfigFilesDir, files[i] );

                        getLog().info( " copy " + file.getName() );

                        FileUtils.copyFileToDirectory( file, confDir );
                    }
                }
            }
        }
    }

    /**
     * Copies the specified class resource to the specified file.
     *
     * @param fromPath the path of the class resource to copy
     * @param toFile   the file to copy to
     * @throws IOException if the file could not be copied
     */
    private void copyFile( String fromPath, File toFile )
        throws IOException
    {
        URL fromURL = getClass().getResource( fromPath );

        if ( fromURL == null )
        {
            throw new FileNotFoundException( fromPath );
        }

        FileUtils.copyURLToFile( fromURL, toFile );
    }

    /**
     * Starts the embedded Tomcat server.
     *
     * @throws IOException            if the server could not be configured
     * @throws LifecycleException     if the server could not be started
     * @throws MojoExecutionException if the server could not be configured
     */
    private void startContainer()
        throws IOException, LifecycleException, MojoExecutionException, ServletException
    {
        String previousCatalinaBase = System.getProperty( "catalina.base" );

        try
        {

            // Set the system properties
            setupSystemProperties();

            System.setProperty( "catalina.base", configurationDir.getAbsolutePath() );

            if ( serverXml != null )
            {
                if ( !serverXml.exists() )
                {
                    throw new MojoExecutionException( serverXml.getPath() + " not exists" );
                }

                Catalina container = new Catalina();

                if ( useSeparateTomcatClassLoader )
                {
                    Thread.currentThread().setContextClassLoader( getTomcatClassLoader() );
                    container.setParentClassLoader( getTomcatClassLoader() );
                }

                container.setUseNaming( this.useNaming );
                container.setConfigFile( serverXml.getAbsolutePath() );
                container.start();
                EmbeddedRegistry.getInstance().register( container );
            }
            else
            {

                System.setProperty( "java.util.logging.manager", "org.apache.juli.ClassLoaderLogManager" );
                System.setProperty( "java.util.logging.config.file",
                                    new File( configurationDir, "conf/logging.properties" ).toString() );

                // Trigger loading of catalina.properties
                CatalinaProperties.getProperty( "foo" );

                Tomcat embeddedTomcat = new ExtendedTomcat( configurationDir );

                embeddedTomcat.setBaseDir( configurationDir.getAbsolutePath() );
                MemoryRealm memoryRealm = new MemoryRealm();

                if ( tomcatUsers != null )
                {
                    if ( !tomcatUsers.exists() )
                    {
                        throw new MojoExecutionException( " tomcatUsers " + tomcatUsers.getPath() + " not exists" );
                    }
                    getLog().info( "use tomcat-users.xml from " + tomcatUsers.getAbsolutePath() );
                    memoryRealm.setPathname( tomcatUsers.getAbsolutePath() );
                }

                embeddedTomcat.getEngine().setRealm( memoryRealm );

                Context ctx = createContext( embeddedTomcat );

                if ( useNaming )
                {
                    embeddedTomcat.enableNaming();
                }

                embeddedTomcat.getHost().setAppBase( new File( configurationDir, "webapps" ).getAbsolutePath() );

                if ( hostName != null )
                {
                    embeddedTomcat.getHost().setName( hostName );
                }
                if ( aliases != null )
                {
                    for ( String alias : aliases )
                    {
                        embeddedTomcat.getHost().addAlias( alias );
                    }

                }
                createStaticContext( embeddedTomcat, ctx, embeddedTomcat.getHost() );

                Connector connector = new Connector( protocol );
                connector.setPort( port );
                connector.setMaxPostSize( maxPostSize );

                if ( httpsPort > 0 )
                {
                    connector.setRedirectPort( httpsPort );
                }

                if ( address != null )
                {
                    connector.setAttribute( "address", address );
                }

                connector.setURIEncoding( uriEncoding );

                connector.setUseBodyEncodingForURI( this.useBodyEncodingForURI );

                embeddedTomcat.getService().addConnector( connector );

                embeddedTomcat.setConnector( connector );

                AccessLogValve alv = new AccessLogValve();
                alv.setDirectory( new File( configurationDir, "logs" ).getAbsolutePath() );
                alv.setPattern( "%h %l %u %t \"%r\" %s %b %I %D" );
                embeddedTomcat.getHost().getPipeline().addValve( alv );

                // create https connector
                Connector httpsConnector = null;
                if ( httpsPort > 0 )
                {
                    httpsConnector = new Connector( protocol );
                    httpsConnector.setPort( httpsPort );
                    httpsConnector.setMaxPostSize( maxPostSize );
                    httpsConnector.setSecure( true );
                    httpsConnector.setProperty( "SSLEnabled", "true" );
                    // should be default but configure it anyway
                    httpsConnector.setProperty( "sslProtocol", "TLS" );
                    if ( keystoreFile != null )
                    {
                        httpsConnector.setAttribute( "keystoreFile", keystoreFile );
                    }
                    if ( keystorePass != null )
                    {
                        httpsConnector.setAttribute( "keystorePass", keystorePass );
                    }
                    if ( keystoreType != null )
                    {
                        httpsConnector.setAttribute( "keystoreType", keystoreType );
                    }

                    if ( trustManagerClassName != null )
                    {
                        httpsConnector.setAttribute( "trustManagerClassName", trustManagerClassName );
                    }

                    if ( trustMaxCertLength != null )
                    {
                        httpsConnector.setAttribute( "trustMaxCertLength", trustMaxCertLength );
                    }

                    if ( truststoreAlgorithm != null )
                    {
                        httpsConnector.setAttribute( "truststoreAlgorithm", truststoreAlgorithm );
                    }

                    if ( truststoreFile != null )
                    {
                        httpsConnector.setAttribute( "truststoreFile", truststoreFile );
                    }

                    if ( truststorePass != null )
                    {
                        httpsConnector.setAttribute( "truststorePass", truststorePass );
                    }

                    if ( truststoreProvider != null )
                    {
                        httpsConnector.setAttribute( "truststoreProvider", truststoreProvider );
                    }

                    if ( truststoreType != null )
                    {
                        httpsConnector.setAttribute( "truststoreType", truststoreType );
                    }

                    httpsConnector.setAttribute( "clientAuth", clientAuth );

                    httpsConnector.setUseBodyEncodingForURI( this.useBodyEncodingForURI );

                    if ( address != null )
                    {
                        httpsConnector.setAttribute( "address", address );
                    }

                    embeddedTomcat.getEngine().getService().addConnector( httpsConnector );

                }

                // create ajp connector
                Connector ajpConnector = null;
                if ( ajpPort > 0 )
                {
                    ajpConnector = new Connector( ajpProtocol );
                    ajpConnector.setPort( ajpPort );
                    ajpConnector.setURIEncoding( uriEncoding );
                    ajpConnector.setUseBodyEncodingForURI( this.useBodyEncodingForURI );
                    if ( address != null )
                    {
                        ajpConnector.setAttribute( "address", address );
                    }
                    embeddedTomcat.getEngine().getService().addConnector( ajpConnector );
                }

                if ( addContextWarDependencies || !getAdditionalWebapps().isEmpty() )
                {
                    createDependencyContexts( embeddedTomcat );
                }

                if ( useSeparateTomcatClassLoader )
                {
                    Thread.currentThread().setContextClassLoader( getTomcatClassLoader() );
                    embeddedTomcat.getEngine().setParentClassLoader( getTomcatClassLoader() );
                }

                embeddedTomcat.start();

                Properties portProperties = new Properties();

                portProperties.put( "tomcat.maven.http.port", Integer.toString( connector.getLocalPort() ) );

                session.getExecutionProperties().put( "tomcat.maven.http.port",
                                                      Integer.toString( connector.getLocalPort() ) );
                System.setProperty( "tomcat.maven.http.port", Integer.toString( connector.getLocalPort() ) );

                if ( httpsConnector != null )
                {
                    session.getExecutionProperties().put( "tomcat.maven.https.port",
                                                          Integer.toString( httpsConnector.getLocalPort() ) );
                    portProperties.put( "tomcat.maven.https.port", Integer.toString( httpsConnector.getLocalPort() ) );
                    System.setProperty( "tomcat.maven.https.port", Integer.toString( httpsConnector.getLocalPort() ) );
                }

                if ( ajpConnector != null )
                {
                    session.getExecutionProperties().put( "tomcat.maven.ajp.port",
                                                          Integer.toString( ajpConnector.getLocalPort() ) );
                    portProperties.put( "tomcat.maven.ajp.port", Integer.toString( ajpConnector.getLocalPort() ) );
                    System.setProperty( "tomcat.maven.ajp.port", Integer.toString( ajpConnector.getLocalPort() ) );
                }
                if ( propertiesPortFilePath != null )
                {
                    File propertiesPortsFile = new File( propertiesPortFilePath );
                    if ( propertiesPortsFile.exists() )
                    {
                        propertiesPortsFile.delete();
                    }
                    FileOutputStream fileOutputStream = new FileOutputStream( propertiesPortsFile );
                    try
                    {
                        portProperties.store( fileOutputStream, "Apache Tomcat Maven plugin port used" );
                    }
                    finally
                    {
                        IOUtils.closeQuietly( fileOutputStream );
                    }
                }

                EmbeddedRegistry.getInstance().register( embeddedTomcat );

            }


        }
        finally
        {
            if ( previousCatalinaBase != null )
            {
                System.setProperty( "catalina.base", previousCatalinaBase );
            }
        }
    }

    private List<Webapp> getAdditionalWebapps()
    {
        if ( webapps == null )
        {
            return Collections.emptyList();
        }
        return webapps;
    }

    protected ClassRealm getTomcatClassLoader()
        throws MojoExecutionException
    {
        if ( this.tomcatRealm != null )
        {
            return tomcatRealm;
        }
        try
        {
            ClassWorld world = new ClassWorld();
            ClassRealm root = world.newRealm( "tomcat", Thread.currentThread().getContextClassLoader() );

            for ( Iterator<Artifact> i = pluginArtifacts.iterator(); i.hasNext(); )
            {
                Artifact pluginArtifact = i.next();
                // add all plugin artifacts see https://issues.apache.org/jira/browse/MTOMCAT-122
                if ( pluginArtifact.getFile() != null )
                {
                    root.addURL( pluginArtifact.getFile().toURI().toURL() );
                }

            }
            tomcatRealm = root;
            return root;
        }
        catch ( DuplicateRealmException e )
        {
            throw new MojoExecutionException( e.getMessage(), e );
        }
        catch ( MalformedURLException e )
        {
            throw new MojoExecutionException( e.getMessage(), e );
        }
    }

    @SuppressWarnings( "unchecked" )
    public Set<Artifact> getProjectArtifacts()
    {
        return project.getArtifacts();
    }

    /**
     * Causes the current thread to wait indefinitely. This method does not return.
     */
    private void waitIndefinitely()
    {
        Object lock = new Object();

        synchronized ( lock )
        {
            try
            {
                lock.wait();
            }
            catch ( InterruptedException exception )
            {
                getLog().warn( messagesProvider.getMessage( "AbstractRunMojo.interrupted" ), exception );
            }
        }
    }


    /**
     * Set the SystemProperties from the configuration.
     */
    private void setupSystemProperties()
    {
        if ( systemProperties != null && !systemProperties.isEmpty() )
        {
            getLog().info( "setting SystemProperties:" );

            for ( String key : systemProperties.keySet() )
            {
                String value = systemProperties.get( key );

                if ( value != null )
                {
                    getLog().info( " " + key + "=" + value );
                    System.setProperty( key, value );
                }
                else
                {
                    getLog().info( "skip sysProps " + key + " with empty value" );
                }
            }
        }
    }


    /**
     * Allows the startup of additional webapps in the tomcat container by declaration with scope
     * "tomcat".
     *
     * @param container tomcat
     * @return dependency tomcat contexts of warfiles in scope "tomcat"
     */
    private Collection<Context> createDependencyContexts( Tomcat container )
        throws MojoExecutionException, MalformedURLException, ServletException, IOException
    {
        getLog().info( "Deploying dependency wars" );
        // Let's add other modules
        List<Context> contexts = new ArrayList<Context>();

        ScopeArtifactFilter filter = new ScopeArtifactFilter( "tomcat" );
        @SuppressWarnings( "unchecked" ) Set<Artifact> artifacts = project.getArtifacts();
        for ( Artifact artifact : artifacts )
        {

            // Artifact is not yet registered and it has neither test, nor a
            // provided scope, not is it optional
            if ( "war".equals( artifact.getType() ) && !artifact.isOptional() && filter.include( artifact ) )
            {
                addContextFromArtifact( container, contexts, artifact, "/" + artifact.getArtifactId(), null, false );
            }
        }

        for ( AbstractWebapp additionalWebapp : getAdditionalWebapps() )
        {
            String contextPath = additionalWebapp.getContextPath();
            if ( !contextPath.startsWith( "/" ) )
            {
                contextPath = "/" + contextPath;
            }
            addContextFromArtifact( container, contexts, getArtifact( additionalWebapp ), contextPath,
                                    additionalWebapp.getContextFile(), additionalWebapp.isAsWebapp() );
        }
        return contexts;
    }


    private void addContextFromArtifact( Tomcat container, List<Context> contexts, Artifact artifact,
                                         String contextPath, File contextXml, boolean asWebApp )
        throws MojoExecutionException, ServletException, IOException
    {
        getLog().info( "Deploy warfile: " + String.valueOf( artifact.getFile() ) + " to contextPath: " + contextPath );
        File webapps = new File( configurationDir, "webapps" );
        File artifactWarDir = new File( webapps, artifact.getArtifactId() );
        if ( !artifactWarDir.exists() )
        {
            //dont extract if exists
            artifactWarDir.mkdir();
            try
            {
                UnArchiver unArchiver = archiverManager.getUnArchiver( "zip" );
                unArchiver.setSourceFile( artifact.getFile() );
                unArchiver.setDestDirectory( artifactWarDir );

                // Extract the module
                unArchiver.extract();
            }
            catch ( NoSuchArchiverException e )
            {
                getLog().error( e );
                return;
            }
            catch ( ArchiverException e )
            {
                getLog().error( e );
                return;
            }
        }
        // TODO make that configurable ?
        //WebappLoader webappLoader = new WebappLoader( Thread.currentThread().getContextClassLoader() );
        WebappLoader webappLoader = createWebappLoader();
        Context context = null;
        if ( asWebApp )
        {
            context = container.addWebapp( contextPath, artifactWarDir.getAbsolutePath() );
        }
        else
        {
            context = container.addContext( contextPath, artifactWarDir.getAbsolutePath() );
        }
        context.setLoader( webappLoader );

        File contextFile = contextXml != null ? contextXml : getContextFile();
        if ( contextFile != null )
        {
            context.setConfigFile( contextFile.toURI().toURL() );
        }

        contexts.add( context );
//        container.getHost().addChild(context);
    }

    private void createStaticContext( final Tomcat container, Context context, Host host )
    {
        if ( staticContextDocbase != null )
        {
            Context staticContext = container.addContext( staticContextPath, staticContextDocbase );
            staticContext.setPrivileged( true );
            Wrapper servlet = context.createWrapper();
            servlet.setServletClass( DefaultServlet.class.getName() );
            servlet.setName( "staticContent" );
            staticContext.addChild( servlet );
            staticContext.addServletMapping( "/", "staticContent" );
            // see https://issues.apache.org/jira/browse/MTOMCAT-238
            //host.addChild( staticContext );
        }
    }


    /**
     * Resolves the Artifact from the remote repository if necessary. If no version is specified, it will be retrieved
     * from the dependency list or from the DependencyManagement section of the pom.
     *
     * @param additionalWebapp containing information about artifact from plugin configuration.
     * @return Artifact object representing the specified file.
     * @throws MojoExecutionException with a message if the version can't be found in DependencyManagement.
     */
    protected Artifact getArtifact( AbstractWebapp additionalWebapp )
        throws MojoExecutionException
    {

        Artifact artifact;
        VersionRange vr;
        try
        {
            vr = VersionRange.createFromVersionSpec( additionalWebapp.getVersion() );
        }
        catch ( InvalidVersionSpecificationException e )
        {
            getLog().warn( "fail to create versionRange from version: " + additionalWebapp.getVersion(), e );
            vr = VersionRange.createFromVersion( additionalWebapp.getVersion() );
        }

        if ( StringUtils.isEmpty( additionalWebapp.getClassifier() ) )
        {
            artifact =
                factory.createDependencyArtifact( additionalWebapp.getGroupId(), additionalWebapp.getArtifactId(), vr,
                                                  additionalWebapp.getType(), null, Artifact.SCOPE_COMPILE );
        }
        else
        {
            artifact =
                factory.createDependencyArtifact( additionalWebapp.getGroupId(), additionalWebapp.getArtifactId(), vr,
                                                  additionalWebapp.getType(), additionalWebapp.getClassifier(),
                                                  Artifact.SCOPE_COMPILE );
        }

        try
        {
            resolver.resolve( artifact, project.getRemoteArtifactRepositories(), this.local );
        }
        catch ( ArtifactResolutionException e )
        {
            throw new MojoExecutionException( "Unable to resolve artifact.", e );
        }
        catch ( ArtifactNotFoundException e )
        {
            throw new MojoExecutionException( "Unable to find artifact.", e );
        }

        return artifact;
    }
}
