package org.apache.tomcat.maven.plugin.tomcat7.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.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.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.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.naming.NamingEntry;
import org.apache.naming.resources.FileDirContext;
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.tomcat7.AbstractTomcat7Mojo;
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.naming.NamingException;
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 AbstractTomcat7Mojo
{
    // ---------------------------------------------------------------------
    // 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
     */
    @Component
    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;
    }

    /**
     * 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() ) );

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

        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 );
        }

        // https://issues.apache.org/jira/browse/MTOMCAT-255
        if(context instanceof StandardContext)
        { 
            ((StandardContext) context).setAddWebinfClassesResources(true); 
            ((StandardContext) context).setAliases( "/WEB-INF/classes=" + project.getBuild().getOutputDirectory());     
        }         

        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 );
        }
    }


    private static class MyDirContext
        extends FileDirContext
    {
        String buildOutputDirectory;

        MyDirContext( String buildOutputDirectory )
        {
            this.buildOutputDirectory = buildOutputDirectory;
        }

        @Override
        protected List<NamingEntry> doListBindings( String name )
            throws NamingException
        {
            if ( "/WEB-INF/classes".equals( name ) )
            {
                if ( !new File( buildOutputDirectory ).exists() )
                {
                    return Collections.emptyList();
                }
                FileDirContext fileDirContext = new FileDirContext();
                fileDirContext.setDocBase( buildOutputDirectory );
                NamingEntry namingEntry = new NamingEntry( "/WEB-INF/classes", fileDirContext, -1 );
                return Collections.singletonList( namingEntry );
            }

            return super.doListBindings( name );
        }
    }

    /**
     * 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
    {
        if ( useSeparateTomcatClassLoader )
        {
            return ( isContextReloadable() )
                ? new ExternalRepositoriesReloadableWebappLoader( getTomcatClassLoader(), getLog() )
                : new WebappLoader( getTomcatClassLoader() );
        }

        return ( isContextReloadable() )
            ? new ExternalRepositoriesReloadableWebappLoader( Thread.currentThread().getContextClassLoader(), getLog() )
            : new WebappLoader( Thread.currentThread().getContextClassLoader() );
    }

    /**
     * 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 tomcat7
     * 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.setConfig( 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.setDefaultRealm( 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 ( @SuppressWarnings("rawtypes") Iterator i = pluginArtifacts.iterator(); i.hasNext(); )
            {
                Artifact pluginArtifact = (Artifact) 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 );
            Tomcat.initWebappDefaults(staticContext);
            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;
    }
}
