package org.apache.maven.plugins.war;

/*
 * 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.maven.artifact.handler.ArtifactHandler;
import org.apache.maven.plugin.testing.stubs.ArtifactStub;
import org.apache.maven.plugins.war.stub.AarArtifactStub;
import org.apache.maven.plugins.war.stub.EJBArtifactStub;
import org.apache.maven.plugins.war.stub.EJBArtifactStubWithClassifier;
import org.apache.maven.plugins.war.stub.EJBClientArtifactStub;
import org.apache.maven.plugins.war.stub.IncludeExcludeWarArtifactStub;
import org.apache.maven.plugins.war.stub.JarArtifactStub;
import org.apache.maven.plugins.war.stub.MarArtifactStub;
import org.apache.maven.plugins.war.stub.MavenProjectArtifactsStub;
import org.apache.maven.plugins.war.stub.MavenProjectBasicStub;
import org.apache.maven.plugins.war.stub.PARArtifactStub;
import org.apache.maven.plugins.war.stub.ResourceStub;
import org.apache.maven.plugins.war.stub.TLDArtifactStub;
import org.apache.maven.plugins.war.stub.WarArtifactStub;
import org.apache.maven.plugins.war.stub.XarArtifactStub;
import org.codehaus.plexus.util.FileUtils;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;

public class WarExplodedMojoTest
    extends AbstractWarExplodedMojoTest
{

    protected File getPomFile()
    {
        return new File( getBasedir(), "/target/test-classes/unit/warexplodedmojo/plugin-config.xml" );
    }

    protected File getTestDirectory()
    {
        return new File( getBasedir(), "target/test-classes/unit/warexplodedmojo/test-dir" );
    }

    /**
     * @throws Exception
     */
    public void testSimpleExplodedWar()
        throws Exception
    {
        // setup test data
        String testId = "SimpleExplodedWar";
        MavenProjectBasicStub project = new MavenProjectBasicStub();
        File webAppSource = createWebAppSource( testId );
        File classesDir = createClassesDir( testId, false );
        File webAppResource = new File( getTestDirectory(), testId + "-resources" );
        File webAppDirectory = new File( getTestDirectory(), testId );
        File sampleResource = new File( webAppResource, "pix/panis_na.jpg" );
        ResourceStub[] resources = new ResourceStub[] { new ResourceStub() };

        createFile( sampleResource );

        assertTrue( "sampeResource not found", sampleResource.exists() );

        // configure mojo
        resources[0].setDirectory( webAppResource.getAbsolutePath() );
        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
        setVariableValueToObject( mojo, "webResources", resources );
        mojo.execute();

        // validate operation
        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
        File expectedWebResourceFile = new File( webAppDirectory, "pix/panis_na.jpg" );
        File expectedWEBINFDir = new File( webAppDirectory, "WEB-INF" );
        File expectedMETAINFDir = new File( webAppDirectory, "META-INF" );

        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
        assertTrue( "resources doesn't exist: " + expectedWebResourceFile, expectedWebResourceFile.exists() );
        assertTrue( "WEB-INF not found", expectedWEBINFDir.exists() );
        assertTrue( "META-INF not found", expectedMETAINFDir.exists() );

        // house keeping
        expectedWebSourceFile.delete();
        expectedWebSource2File.delete();
        expectedWebResourceFile.delete();
    }

    /**
     * @throws Exception
     */
    public void testSimpleExplodedWarWTargetPath()
        throws Exception
    {
        // setup test data
        String testId = "SimpleExplodedWar";
        MavenProjectBasicStub project = new MavenProjectBasicStub();
        File webAppSource = createWebAppSource( testId );
        File classesDir = createClassesDir( testId, false );
        File webAppResource = new File( getTestDirectory(), "resources" );
        File webAppDirectory = new File( getTestDirectory(), testId );
        File sampleResource = new File( webAppResource, "pix/panis_na.jpg" );
        ResourceStub[] resources = new ResourceStub[] { new ResourceStub() };

        createFile( sampleResource );

        // configure mojo
        resources[0].setDirectory( webAppResource.getAbsolutePath() );
        resources[0].setTargetPath( "targetPath" );
        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
        setVariableValueToObject( mojo, "webResources", resources );
        mojo.execute();

        // validate operation
        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
        File expectedWebResourceFile = new File( webAppDirectory, "targetPath/pix/panis_na.jpg" );
        File expectedWEBINFDir = new File( webAppDirectory, "WEB-INF" );
        File expectedMETAINFDir = new File( webAppDirectory, "META-INF" );

        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
        assertTrue( "resources doesn't exist: " + expectedWebResourceFile, expectedWebResourceFile.exists() );
        assertTrue( "WEB-INF not found", expectedWEBINFDir.exists() );
        assertTrue( "META-INF not found", expectedMETAINFDir.exists() );

        // house keeping
        expectedWebSourceFile.delete();
        expectedWebSource2File.delete();
        expectedWebResourceFile.delete();
    }

    /**
     * @throws Exception
     */
    public void testExplodedWar_WithCustomWebXML()
        throws Exception
    {
        // setup test data
        String testId = "ExplodedWar_WithCustomWebXML";
        MavenProjectBasicStub project = new MavenProjectBasicStub();
        File webAppSource = createWebAppSource( testId );
        File classesDir = createClassesDir( testId, true );
        File xmlSource = createXMLConfigDir( testId, new String[] { "web.xml" } );
        File webAppDirectory = new File( getTestDirectory(), testId );

        // configure mojo
        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
        mojo.setWebXml( new File( xmlSource, "web.xml" ) );
        mojo.execute();

        // validate operation
        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
        File expectedWEBXMLFile = new File( webAppDirectory, "WEB-INF/web.xml" );
        File expectedMETAINFDir = new File( webAppDirectory, "META-INF" );

        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
        assertTrue( "WEB XML not found: " + expectedWEBXMLFile.toString(), expectedWEBXMLFile.exists() );
        assertTrue( "META-INF not found", expectedMETAINFDir.exists() );
        assertEquals( "WEB XML not correct", mojo.getWebXml().toString(), FileUtils.fileRead( expectedWEBXMLFile ) );

        // house keeping
        expectedWebSourceFile.delete();
        expectedWebSource2File.delete();
        expectedWEBXMLFile.delete();
        expectedMETAINFDir.delete();
    }

    /**
     * @throws Exception
     */
    public void testExplodedWar_WithContainerConfigXML()
        throws Exception
    {
        // setup test data
        String testId = "ExplodedWar_WithContainerConfigXML";
        MavenProjectBasicStub project = new MavenProjectBasicStub();
        File classesDir = createClassesDir( testId, true );
        File webAppSource = createWebAppSource( testId );
        File xmlSource = createXMLConfigDir( testId, new String[] { "config.xml" } );
        File webAppDirectory = new File( getTestDirectory(), testId );

        // configure mojo
        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
        mojo.setContainerConfigXML( new File( xmlSource, "config.xml" ) );
        mojo.execute();

        // validate operation
        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
        File expectedContainerConfigXMLFile = new File( webAppDirectory, "META-INF/config.xml" );
        File expectedWEBINFDir = new File( webAppDirectory, "WEB-INF" );

        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
        assertTrue( "WEB-INF not found", expectedWEBINFDir.exists() );
        assertTrue( "Container Config XML not found:" + expectedContainerConfigXMLFile.toString(),
                    expectedContainerConfigXMLFile.exists() );

        // house keeping
        expectedWebSourceFile.delete();
        expectedWebSource2File.delete();
        expectedContainerConfigXMLFile.delete();
        expectedWEBINFDir.delete();
    }

    /**
     * @throws Exception
     */
    public void testExplodedWar_WithSimpleExternalWARFile()
        throws Exception
    {
        // setup test data
        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
        WarArtifactStub warArtifact = new WarArtifactStub( getBasedir() );

        String testId = "ExplodedWar_WithSimpleExternalWARFile";
        File webAppDirectory = new File( getTestDirectory(), testId );
        File webAppSource = createWebAppSource( testId );
        File classesDir = createClassesDir( testId, true );
        File workDirectory = new File( getTestDirectory(), "/war/work-" + testId );
        File simpleWarFile = warArtifact.getFile();

        assertTrue( "simple war not found: " + simpleWarFile.toString(), simpleWarFile.exists() );

        createDir( workDirectory );

        // configure mojo
        project.addArtifact( warArtifact );
        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
        setVariableValueToObject( mojo, "workDirectory", workDirectory );
        mojo.execute();

        // validate operation - META-INF is automatically excluded so remove the file from the list
        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
        File expectedWEBXMLFile = new File( webAppDirectory, "WEB-INF/web.xml" );
        File expectedWARFile = new File( webAppDirectory, "/org/sample/company/test.jsp" );

        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
        // check simple.war in the unit test dir under resources to verify the list of files
        assertTrue( "web xml not found: " + expectedWEBXMLFile.toString(), expectedWEBXMLFile.exists() );
        assertTrue( "war file not found: " + expectedWARFile.toString(), expectedWARFile.exists() );

        // house keeping
        expectedWebSourceFile.delete();
        expectedWebSource2File.delete();
        expectedWEBXMLFile.delete();
        expectedWARFile.delete();
    }

    /**
     * Merge a dependent WAR when a file in the war source directory overrides one found in the WAR.
     */
    public void testExplodedWarMergeWarLocalFileOverride()
        throws Exception
    {
        // setup test data
        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
        WarArtifactStub warArtifact = new WarArtifactStub( getBasedir() );

        String testId = "testExplodedWarMergeWarLocalFileOverride";
        File webAppDirectory = new File( getTestDirectory(), testId );
        File webAppSource = getWebAppSource( testId );
        File simpleJSP = new File( webAppSource, "org/sample/company/test.jsp" );
        createFile( simpleJSP );

        File workDirectory = new File( getTestDirectory(), "/war/work-" + testId );
        createDir( workDirectory );

        File classesDir = createClassesDir( testId, true );

        // configure mojo
        project.addArtifact( warArtifact );
        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
        setVariableValueToObject( mojo, "workDirectory", workDirectory );
        mojo.execute();

        // validate operation
        File expectedFile = new File( webAppDirectory, "/org/sample/company/test.jsp" );

        assertTrue( "file not found: " + expectedFile.toString(), expectedFile.exists() );
        assertEquals( "file incorrect", simpleJSP.toString(), FileUtils.fileRead( expectedFile ) );

        // check when the merged war file is newer - so set an old time on the local file
        long time = new SimpleDateFormat( "yyyy-MM-dd", Locale.US ).parse( "2005-1-1" ).getTime();
        simpleJSP.setLastModified( time );
        expectedFile.setLastModified( time );

        project.addArtifact( warArtifact );
        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
        setVariableValueToObject( mojo, "workDirectory", workDirectory );
        mojo.execute();

        assertTrue( "file not found: " + expectedFile.toString(), expectedFile.exists() );
        assertEquals( "file incorrect", simpleJSP.toString(), FileUtils.fileRead( expectedFile ) );

        // house keeping
        expectedFile.delete();
    }

    // The last modified thingy behavior is not applicable anymore. This is the only test that
    // has been removed.
    // /**
    // * Merge a dependent WAR that gets updated since the last run.
    // */
    // public void testExplodedWarMergeWarUpdated()
    // throws Exception
    // {
    // // setup test data
    // MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
    // WarArtifactStub warArtifact = new WarArtifactStub( getBasedir() );
    //
    // String testId = "testExplodedWarMergeWarUpdated";
    // File webAppDirectory = new File( getTestDirectory(), testId );
    // FileUtils.deleteDirectory( webAppDirectory );
    //
    // File webAppSource = getWebAppSource( testId );
    //
    // File workDirectory = new File( getTestDirectory(), "/war/work-" + testId );
    // createDir( workDirectory );
    //
    // File classesDir = createClassesDir( testId, true );
    //
    // // configure mojo
    // project.addArtifact( warArtifact );
    // this.configureMojo( mojo, new LinkedList(), classesDir, webAppSource, webAppDirectory, project );
    // setVariableValueToObject( mojo, "workDirectory", workDirectory );
    // mojo.execute();
    //
    // // validate operation
    // File expectedFile = new File( webAppDirectory, "/org/sample/company/test.jsp" );
    //
    // assertTrue( "file not found: " + expectedFile.toString(), expectedFile.exists() );
    // assertEquals( "file incorrect", "", FileUtils.fileRead( expectedFile ) );
    //
    // // update file, so the local one is older
    // warArtifact.setFile( new File( warArtifact.getFile().getParentFile(), "simple-updated.war" ) );
    //
    // mojo.execute();
    //
    // assertTrue( "file not found: " + expectedFile.toString(), expectedFile.exists() );
    // assertEquals( "file incorrect", "updated\n", FileUtils.fileRead( expectedFile ) );
    //
    // // update file, so the local one is newer
    // warArtifact.setFile( new File( warArtifact.getFile().getParentFile(), "simple.war" ) );
    //
    // mojo.execute();
    //
    // assertTrue( "file not found: " + expectedFile.toString(), expectedFile.exists() );
    // assertEquals( "file incorrect", "updated\n", FileUtils.fileRead( expectedFile ) );
    //
    // // house keeping
    // expectedFile.delete();
    // }

    /**
     * @throws Exception
     */
    public void testExplodedWar_WithEJB()
        throws Exception
    {
        // setup test data
        String testId = "ExplodedWar_WithEJB";
        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
        File webAppDirectory = new File( getTestDirectory(), testId );
        File webAppSource = createWebAppSource( testId );
        File classesDir = createClassesDir( testId, true );
        EJBArtifactStub ejbArtifact = new EJBArtifactStub( getBasedir() );
        File ejbFile = ejbArtifact.getFile();

        assertTrue( "ejb jar not found: " + ejbFile.toString(), ejbFile.exists() );

        // configure mojo
        project.addArtifact( ejbArtifact );
        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
        mojo.execute();

        // validate operation
        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
        // final name form is <artifactId>-<version>.<type>
        File expectedEJBArtifact = new File( webAppDirectory, "WEB-INF/lib/ejbartifact-0.0-Test.jar" );
        // File expectedEJBArtifact = new File( webAppDirectory, "WEB-INF/lib/ejbartifact-0.0-Test.jar" );

        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
        assertTrue( "ejb artifact not found: " + expectedEJBArtifact.toString(), expectedEJBArtifact.exists() );

        // house keeping
        expectedWebSourceFile.delete();
        expectedWebSource2File.delete();
        expectedEJBArtifact.delete();
    }

    public void testExplodedWarWithJar()
        throws Exception
    {
        // setup test data
        String testId = "ExplodedWarWithJar";
        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
        File webAppDirectory = new File( getTestDirectory(), testId );
        File webAppSource = createWebAppSource( testId );
        File classesDir = createClassesDir( testId, true );
        ArtifactHandler artifactHandler = (ArtifactHandler) lookup( ArtifactHandler.ROLE, "jar" );
        ArtifactStub jarArtifact = new JarArtifactStub( getBasedir(), artifactHandler );
        File jarFile = jarArtifact.getFile();

        assertTrue( "jar not found: " + jarFile.toString(), jarFile.exists() );

        // configure mojo
        project.addArtifact( jarArtifact );
        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
        mojo.execute();

        // validate operation
        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
        // final name form is <artifactId>-<version>.<type>
        File expectedJarArtifact = new File( webAppDirectory, "WEB-INF/lib/jarartifact-0.0-Test.jar" );

        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
        assertTrue( "jar artifact not found: " + expectedJarArtifact.toString(), expectedJarArtifact.exists() );

        // house keeping
        expectedWebSourceFile.delete();
        expectedWebSource2File.delete();
        expectedJarArtifact.delete();
    }

    /**
     * @throws Exception
     */
    public void testExplodedWar_WithEJBClient()
        throws Exception
    {
        // setup test data
        String testId = "ExplodedWar_WithEJB";
        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
        File webAppDirectory = new File( getTestDirectory(), testId );
        File webAppSource = createWebAppSource( testId );
        File classesDir = createClassesDir( testId, true );
        EJBClientArtifactStub ejbArtifact = new EJBClientArtifactStub( getBasedir() );
        File ejbFile = ejbArtifact.getFile();

        assertTrue( "ejb jar not found: " + ejbFile.toString(), ejbFile.exists() );

        // configure mojo
        project.addArtifact( ejbArtifact );
        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
        mojo.execute();

        // validate operation
        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
        // final name form is <artifactId>-<version>.<type>
        File expectedEJBArtifact = new File( webAppDirectory, "WEB-INF/lib/ejbclientartifact-0.0-Test-client.jar" );

        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
        assertTrue( "ejb artifact not found: " + expectedEJBArtifact.toString(), expectedEJBArtifact.exists() );

        // house keeping
        expectedWebSourceFile.delete();
        expectedWebSource2File.delete();
        expectedEJBArtifact.delete();
    }

    /**
     * @throws Exception
     */
    public void testExplodedWar_WithTLD()
        throws Exception
    {
        // setup test data
        String testId = "ExplodedWar_WithTLD";
        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
        File webAppDirectory = new File( getTestDirectory(), testId );
        File webAppSource = createWebAppSource( testId );
        File classesDir = createClassesDir( testId, true );
        TLDArtifactStub tldArtifact = new TLDArtifactStub( getBasedir() );
        File tldFile = tldArtifact.getFile();

        assertTrue( "tld jar not found: " + tldFile.getAbsolutePath(), tldFile.exists() );

        // configure mojo
        project.addArtifact( tldArtifact );
        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
        mojo.execute();

        // validate operation
        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
        // final name form is <artifactId>-<version>.<type>
        File expectedTLDArtifact = new File( webAppDirectory, "WEB-INF/tld/tldartifact-0.0-Test.tld" );

        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
        assertTrue( "tld artifact not found: " + expectedTLDArtifact.toString(), expectedTLDArtifact.exists() );

        // house keeping
        expectedWebSourceFile.delete();
        expectedWebSource2File.delete();
        expectedTLDArtifact.delete();
    }

    /**
     * @throws Exception
     */
    public void testExplodedWar_WithPAR()
        throws Exception
    {
        // setup test data
        String testId = "ExplodedWar_WithPAR";
        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
        File webAppDirectory = new File( getTestDirectory(), testId );
        File webAppSource = createWebAppSource( testId );
        File classesDir = createClassesDir( testId, true );
        PARArtifactStub parartifact = new PARArtifactStub( getBasedir() );
        File parFile = parartifact.getFile();

        assertTrue( "par not found: " + parFile.getAbsolutePath(), parFile.exists() );

        // configure mojo
        project.addArtifact( parartifact );
        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
        mojo.execute();

        // validate operation
        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
        // final name form is <artifactId>-<version>.<type>
        File expectedPARArtifact = new File( webAppDirectory, "WEB-INF/lib/parartifact-0.0-Test.jar" );

        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
        assertTrue( "par artifact not found: " + expectedPARArtifact.toString(), expectedPARArtifact.exists() );

        // house keeping
        expectedWebSourceFile.delete();
        expectedWebSource2File.delete();
        expectedPARArtifact.delete();
    }

    public void testExplodedWarWithAar()
        throws Exception
    {
        // setup test data
        String testId = "ExplodedWarWithAar";
        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
        File webAppDirectory = new File( getTestDirectory(), testId );
        File webAppSource = createWebAppSource( testId );
        File classesDir = createClassesDir( testId, true );
        // Fake here since the aar artifact handler does not exist: no biggie
        ArtifactHandler artifactHandler = (ArtifactHandler) lookup( ArtifactHandler.ROLE, "jar" );
        ArtifactStub aarArtifact = new AarArtifactStub( getBasedir(), artifactHandler );
        File aarFile = aarArtifact.getFile();

        assertTrue( "jar not found: " + aarFile.toString(), aarFile.exists() );

        // configure mojo
        project.addArtifact( aarArtifact );
        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
        mojo.execute();

        // validate operation
        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
        // final name form is <artifactId>-<version>.<type>
        File expectedJarArtifact = new File( webAppDirectory, "WEB-INF/services/aarartifact-0.0-Test.jar" );

        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
        assertTrue( "jar artifact not found: " + expectedJarArtifact.toString(), expectedJarArtifact.exists() );

        // house keeping
        expectedWebSourceFile.delete();
        expectedWebSource2File.delete();
        expectedJarArtifact.delete();
    }

    public void testExplodedWarWithMar()
        throws Exception
    {
        // setup test data
        String testId = "ExplodedWarWithMar";
        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
        File webAppDirectory = new File( getTestDirectory(), testId );
        File webAppSource = createWebAppSource( testId );
        File classesDir = createClassesDir( testId, true );
        // Fake here since the mar artifact handler does not exist: no biggie
        ArtifactHandler artifactHandler = (ArtifactHandler) lookup( ArtifactHandler.ROLE, "jar" );
        ArtifactStub marArtifact = new MarArtifactStub( getBasedir(), artifactHandler );
        File marFile = marArtifact.getFile();

        assertTrue( "jar not found: " + marFile.toString(), marFile.exists() );

        // configure mojo
        project.addArtifact( marArtifact );
        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
        mojo.execute();

        // validate operation
        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
        // final name form is <artifactId>-<version>.<type>
        File expectedJarArtifact = new File( webAppDirectory, "WEB-INF/modules/marartifact-0.0-Test.jar" );

        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
        assertTrue( "jar artifact not found: " + expectedJarArtifact.toString(), expectedJarArtifact.exists() );

        // house keeping
        expectedWebSourceFile.delete();
        expectedWebSource2File.delete();
        expectedJarArtifact.delete();
    }

    public void testExplodedWarWithXar()
        throws Exception
    {
        // setup test data
        String testId = "ExplodedWarWithXar";
        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
        File webAppDirectory = new File( getTestDirectory(), testId );
        File webAppSource = createWebAppSource( testId );
        File classesDir = createClassesDir( testId, true );
        // Fake here since the xar artifact handler does not exist: no biggie
        ArtifactHandler artifactHandler = (ArtifactHandler) lookup( ArtifactHandler.ROLE, "jar" );
        ArtifactStub xarArtifact = new XarArtifactStub( getBasedir(), artifactHandler );
        File xarFile = xarArtifact.getFile();

        assertTrue( "jar not found: " + xarFile.toString(), xarFile.exists() );

        // configure mojo
        project.addArtifact( xarArtifact );
        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
        mojo.execute();

        // validate operation
        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
        // final name form is <artifactId>-<version>.<type>
        File expectedJarArtifact = new File( webAppDirectory, "WEB-INF/extensions/xarartifact-0.0-Test.jar" );

        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
        assertTrue( "jar artifact not found: " + expectedJarArtifact.toString(), expectedJarArtifact.exists() );

        // house keeping
        expectedWebSourceFile.delete();
        expectedWebSource2File.delete();
        expectedJarArtifact.delete();
    }

    /**
     * @throws Exception
     */
    public void testExplodedWar_WithDuplicateDependencies()
        throws Exception
    {
        // setup test data
        String testId = "ExplodedWar_WithDuplicateDependencies";
        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
        File webAppDirectory = new File( getTestDirectory(), testId );
        File webAppSource = createWebAppSource( testId );
        File classesDir = createClassesDir( testId, true );
        EJBArtifactStub ejbArtifact = new EJBArtifactStub( getBasedir() );
        EJBArtifactStub ejbArtifactDup = new EJBArtifactStub( getBasedir() );
        File ejbFile = ejbArtifact.getFile();

        // ejbArtifact has a hard coded file, only one assert is needed
        assertTrue( "ejb not found: " + ejbFile.getAbsolutePath(), ejbFile.exists() );

        // configure mojo
        ejbArtifact.setGroupId( "org.sample.ejb" );
        ejbArtifactDup.setGroupId( "org.dup.ejb" );
        project.addArtifact( ejbArtifact );
        project.addArtifact( ejbArtifactDup );
        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
        mojo.execute();

        // validate operation
        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
        // final name form is <artifactId>-<version>.<type>
        File expectedEJBArtifact = new File( webAppDirectory, "WEB-INF/lib/org.sample.ejb-ejbartifact-0.0-Test.jar" );
        File expectedEJBDupArtifact = new File( webAppDirectory, "WEB-INF/lib/org.dup.ejb-ejbartifact-0.0-Test.jar" );

        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
        assertTrue( "ejb artifact not found: " + expectedEJBArtifact.toString(), expectedEJBArtifact.exists() );
        assertTrue( "ejb dup artifact not found: " + expectedEJBDupArtifact.toString(), expectedEJBDupArtifact.exists() );

        // house keeping
        expectedWebSourceFile.delete();
        expectedWebSource2File.delete();
        expectedEJBArtifact.delete();
        expectedEJBDupArtifact.delete();
    }

    /**
     * @throws Exception
     */
    public void testExplodedWar_DuplicateWithClassifier()
        throws Exception
    {
        // setup test data
        String testId = "ExplodedWar_DuplicateWithClassifier";
        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
        File webAppDirectory = new File( getTestDirectory(), testId );
        File webAppSource = createWebAppSource( testId );
        File classesDir = createClassesDir( testId, true );
        EJBArtifactStub ejbArtifact = new EJBArtifactStub( getBasedir() );
        EJBArtifactStubWithClassifier ejbArtifactDup = new EJBArtifactStubWithClassifier( getBasedir() );

        File ejbFile = ejbArtifact.getFile();

        // ejbArtifact has a hard coded file, only one assert is needed
        assertTrue( "ejb not found: " + ejbFile.getAbsolutePath(), ejbFile.exists() );

        // configure mojo

        ejbArtifact.setGroupId( "org.sample.ejb" );
        ejbArtifactDup.setGroupId( "org.sample.ejb" );

        ejbArtifactDup.setClassifier( "classifier" );

        project.addArtifact( ejbArtifact );
        project.addArtifact( ejbArtifactDup );

        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
        mojo.execute();

        // validate operation
        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
        // final name form is <artifactId>-<version>.<type>
        File expectedEJBArtifact = new File( webAppDirectory, "WEB-INF/lib/ejbartifact-0.0-Test.jar" );
        File expectedEJBDupArtifact = new File( webAppDirectory, "WEB-INF/lib/ejbartifact-0.0-Test-classifier.jar" );

        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
        assertTrue( "ejb artifact not found: " + expectedEJBArtifact.toString(), expectedEJBArtifact.exists() );
        assertTrue( "ejb dup artifact not found: " + expectedEJBDupArtifact.toString(), expectedEJBDupArtifact.exists() );

        // house keeping
        expectedWebSourceFile.delete();
        expectedWebSource2File.delete();
        expectedEJBArtifact.delete();
        expectedEJBDupArtifact.delete();
    }

    /**
     * @throws Exception
     */
    public void testExplodedWar_WithClasses()
        throws Exception
    {
        // setup test data
        String testId = "ExplodedWar_WithClasses";
        MavenProjectBasicStub project = new MavenProjectBasicStub();
        File webAppDirectory = new File( getTestDirectory(), testId );
        File webAppSource = createWebAppSource( testId );
        File classesDir = createClassesDir( testId, false );

        // configure mojo
        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
        mojo.execute();

        // validate operation
        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
        // final name form is <artifactId>-<version>.<type>
        File expectedClass = new File( webAppDirectory, "WEB-INF/classes/sample-servlet.class" );

        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
        assertTrue( "classes not found: " + expectedClass.toString(), expectedClass.exists() );

        // house keeping
        expectedWebSourceFile.delete();
        expectedWebSource2File.delete();
        expectedClass.delete();
    }

    public void testExplodedWar_WithSourceIncludeExclude()
        throws Exception
    {
        // setup test data
        String testId = "ExplodedWar_WithSourceIncludeExclude";
        MavenProjectBasicStub project = new MavenProjectBasicStub();
        File webAppSource = createWebAppSource( testId );
        File classesDir = createClassesDir( testId, true );
        File webAppDirectory = new File( getTestDirectory(), testId );

        // configure mojo
        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
        setVariableValueToObject( mojo, "warSourceIncludes", "**/*sit.jsp" );
        setVariableValueToObject( mojo, "warSourceExcludes", "**/last*.*" );
        mojo.execute();

        // validate operation
        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
        File expectedWEBXMLDir = new File( webAppDirectory, "WEB-INF" );
        File expectedMETAINFDir = new File( webAppDirectory, "META-INF" );

        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
        assertFalse( "source files found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
        assertTrue( "WEB XML not found: " + expectedWEBXMLDir.toString(), expectedWEBXMLDir.exists() );
        assertTrue( "META-INF not found", expectedMETAINFDir.exists() );

        // house keeping
        expectedWebSourceFile.delete();
        expectedWebSource2File.delete();
        expectedWEBXMLDir.delete();
        expectedMETAINFDir.delete();
    }

    public void testExplodedWar_WithWarDependencyIncludeExclude()
        throws Exception
    {
        // setup test data
        String testId = "ExplodedWar_WithWarDependencyIncludeExclude";
        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
        IncludeExcludeWarArtifactStub includeexcludeWarArtifact = new IncludeExcludeWarArtifactStub( getBasedir() );
        File webAppDirectory = new File( getTestDirectory(), testId );
        File webAppSource = createWebAppSource( testId );
        File classesDir = createClassesDir( testId, true );
        File workDirectory = new File( getTestDirectory(), "/war/work-" + testId );
        File includeExcludeWarFile = includeexcludeWarArtifact.getFile();

        assertTrue( "war not found: " + includeExcludeWarFile.toString(), includeExcludeWarFile.exists() );

        createDir( workDirectory );

        // configure mojo
        project.addArtifact( includeexcludeWarArtifact );
        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
        setVariableValueToObject( mojo, "workDirectory", workDirectory );
        Overlay overlay = new Overlay( "wartests", "war-include-exclude" );
        overlay.setIncludes( "**/*Include.jsp,**/*.xml" );
        overlay.setExcludes( "**/*Exclude*,META-INF/MANIFEST.MF" );
        List<Overlay> overlays = new LinkedList<Overlay>();
        overlays.add( overlay );
        setVariableValueToObject( mojo, "overlays", overlays );
        mojo.execute();

        // validate operation
        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
        File expectedManifestFile = new File( webAppDirectory, "META-INF/MANIFEST.MF" );
        File expectedWEBXMLFile = new File( webAppDirectory, "WEB-INF/web.xml" );
        File expectedIncludedWARFile = new File( webAppDirectory, "/org/sample/company/testInclude.jsp" );
        File expectedExcludedWarfile = new File( webAppDirectory, "/org/sample/companyExclude/test.jsp" );

        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
        // check include-exclude.war in the unit test dir under resources to verify the list of files
        assertTrue( "web xml not found: " + expectedWEBXMLFile.toString(), expectedWEBXMLFile.exists() );
        assertFalse( "manifest file found: " + expectedManifestFile.toString(), expectedManifestFile.exists() );
        assertTrue( "war file not found: " + expectedIncludedWARFile.toString(), expectedIncludedWARFile.exists() );
        assertFalse( "war file not found: " + expectedExcludedWarfile.toString(), expectedExcludedWarfile.exists() );

        // house keeping
        expectedWebSourceFile.delete();
        expectedWebSource2File.delete();
        expectedManifestFile.delete();
        expectedWEBXMLFile.delete();
        expectedIncludedWARFile.delete();
        expectedExcludedWarfile.delete();
    }

    public void testExplodedWarWithSourceModificationCheck()
        throws Exception
    {
        // setup test data
        String testId = "ExplodedWarWithSourceModificationCheck";
        MavenProjectBasicStub project = new MavenProjectBasicStub();
        File webAppSource = createWebAppSource( testId );
        File classesDir = createClassesDir( testId, false );
        File webAppDirectory = new File( getTestDirectory(), testId );

        // configure mojo
        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );

        // destination file is already created manually containing an "error" string
        // source is newer than the destination file
        mojo.execute();

        // validate operation

        File expectedWEBINFDir = new File( webAppDirectory, "WEB-INF" );
        File expectedMETAINFDir = new File( webAppDirectory, "META-INF" );
        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );

        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
        assertTrue( "WEB-INF not found", expectedWEBINFDir.exists() );
        assertTrue( "META-INF not found", expectedMETAINFDir.exists() );

        // 1st phase destination is older than source
        // destination starts with a value of error replaced with a blank source
        assertFalse( "source files not updated with new copy: " + expectedWebSourceFile.toString(),
                     "error".equals( FileUtils.fileRead( expectedWebSourceFile ) ) );

        // TODO: uncomment when lastModified problem is resolved
        // FileWriter writer = new FileWriter(expectedWebSourceFile);
        //
        // // 2nd phase destination is newer than source
        // // destination should not be replaced with an blank source
        // writer.write("newdata");
        // mojo.execute();
        // reader = new FileReader(expectedWebSourceFile);
        // reader.read(data);
        // assertTrue("source file updated with old copy: "
        // +expectedWebSourceFile.toString(),String.valueOf(data).equals("newdata") ); }

        // house keeping
        expectedWEBINFDir.delete();
        expectedMETAINFDir.delete();
        expectedWebSourceFile.delete();
        expectedWebSource2File.delete();
    }

    public void testExplodedWarWithOutputFileNameMapping()
        throws Exception
    {
        // setup test data
        String testId = "ExplodedWarWithFileNameMapping";
        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
        File webAppDirectory = new File( getTestDirectory(), testId );
        File webAppSource = createWebAppSource( testId );
        File classesDir = createClassesDir( testId, true );
        ArtifactHandler artifactHandler = (ArtifactHandler) lookup( ArtifactHandler.ROLE, "jar" );
        ArtifactStub jarArtifact = new JarArtifactStub( getBasedir(), artifactHandler );
        File jarFile = jarArtifact.getFile();

        assertTrue( "jar not found: " + jarFile.toString(), jarFile.exists() );

        // configure mojo
        project.addArtifact( jarArtifact );
        mojo.setOutputFileNameMapping( "@{artifactId}@.@{extension}@" );
        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
        mojo.execute();

        // validate operation
        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
        // final name form is <artifactId>-<version>.<type>
        File expectedJarArtifact = new File( webAppDirectory, "WEB-INF/lib/jarartifact.jar" );

        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
        assertTrue( "jar artifact not found: " + expectedJarArtifact.toString(), expectedJarArtifact.exists() );

        // house keeping
        expectedWebSourceFile.delete();
        expectedWebSource2File.delete();
        expectedJarArtifact.delete();
    }

    /**
     * @throws Exception
     */
    public void testExplodedWarWithOutputFileNameMappingAndDuplicateDependencies()
        throws Exception
    {
        // setup test data
        String testId = "ExplodedWarWithFileNameMappingAndDuplicateDependencies";
        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
        File webAppDirectory = new File( getTestDirectory(), testId );
        File webAppSource = createWebAppSource( testId );
        File classesDir = createClassesDir( testId, true );
        EJBArtifactStub ejbArtifact = new EJBArtifactStub( getBasedir() );
        EJBArtifactStub ejbArtifactDup = new EJBArtifactStub( getBasedir() );
        File ejbFile = ejbArtifact.getFile();

        // ejbArtifact has a hard coded file, only one assert is needed
        assertTrue( "ejb not found: " + ejbFile.getAbsolutePath(), ejbFile.exists() );

        // configure mojo
        ejbArtifact.setGroupId( "org.sample.ejb" );
        ejbArtifactDup.setGroupId( "org.dup.ejb" );
        project.addArtifact( ejbArtifact );
        project.addArtifact( ejbArtifactDup );
        mojo.setOutputFileNameMapping( "@{artifactId}@.@{extension}@" );
        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
        mojo.execute();

        // validate operation
        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
        // final name form is <artifactId>-<version>.<type>
        File expectedEJBArtifact = new File( webAppDirectory, "WEB-INF/lib/org.sample.ejb-ejbartifact.jar" );
        File expectedEJBDupArtifact = new File( webAppDirectory, "WEB-INF/lib/org.dup.ejb-ejbartifact.jar" );

        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
        assertTrue( "ejb artifact not found: " + expectedEJBArtifact.toString(), expectedEJBArtifact.exists() );
        assertTrue( "ejb dup artifact not found: " + expectedEJBDupArtifact.toString(), expectedEJBDupArtifact.exists() );

        // house keeping
        expectedWebSourceFile.delete();
        expectedWebSource2File.delete();
        expectedEJBArtifact.delete();
        expectedEJBDupArtifact.delete();
    }

    /* --------------------- 2.1 Overlay tests ----------------------------------- */

    /*---------------------------*/

}
