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 java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.List;

import org.apache.maven.archiver.MavenArchiver;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
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.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.plugins.war.util.ClassesPackager;
import org.apache.maven.project.MavenProjectHelper;
import org.codehaus.plexus.archiver.Archiver;
import org.codehaus.plexus.archiver.ArchiverException;
import org.codehaus.plexus.archiver.jar.ManifestException;
import org.codehaus.plexus.archiver.war.WarArchiver;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.StringUtils;

/**
 * Build a WAR file.
 *
 * @author <a href="evenisse@apache.org">Emmanuel Venisse</a>
 * @version $Id$
 */
// CHECKSTYLE_OFF: LineLength
@Mojo( name = "war", defaultPhase = LifecyclePhase.PACKAGE, threadSafe = true, requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME )
// CHECKSTYLE_ON: LineLength
public class WarMojo
    extends AbstractWarMojo
{
    /**
     * The directory for the generated WAR.
     */
    @Parameter( defaultValue = "${project.build.directory}", required = true )
    private String outputDirectory;

    /**
     * The name of the generated WAR.
     */
    @Parameter( defaultValue = "${project.build.finalName}", required = true, readonly = true )
    private String warName;

    /**
     * Classifier to add to the generated WAR. If given, the artifact will be an attachment instead. The classifier will
     * not be applied to the JAR file of the project - only to the WAR file.
     */
    @Parameter
    private String classifier;

    /**
     * The comma separated list of tokens to exclude from the WAR before packaging. This option may be used to implement
     * the skinny WAR use case. Note that you can use the Java Regular Expressions engine to include and exclude
     * specific pattern using the expression %regex[]. Hint: read the about (?!Pattern).
     *
     * @since 2.1-alpha-2
     */
    @Parameter
    private String packagingExcludes;

    /**
     * The comma separated list of tokens to include in the WAR before packaging. By default everything is included.
     * This option may be used to implement the skinny WAR use case. Note that you can use the Java Regular Expressions
     * engine to include and exclude specific pattern using the expression %regex[].
     *
     * @since 2.1-beta-1
     */
    @Parameter
    private String packagingIncludes;

    /**
     * The WAR archiver.
     */
    @Component( role = Archiver.class, hint = "war" )
    private WarArchiver warArchiver;

    /**
     */
    @Component
    private MavenProjectHelper projectHelper;

    /**
     * Whether this is the main artifact being built. Set to <code>false</code> if you don't want to install or deploy
     * it to the local repository instead of the default one in an execution.
     */
    @Parameter( defaultValue = "true" )
    private boolean primaryArtifact;

    /**
     * Whether or not to fail the build if the <code>web.xml</code> file is missing. Set to <code>false</code> if you
     * want your WAR built without a <code>web.xml</code> file. This may be useful if you are building an overlay that
     * has no web.xml file.
     * <p>
     * Starting with <b>3.0.1</b>, this property defaults to <code>false</code> if the project depends on the Servlet
     * 3.0 API or newer.
     *
     * @since 2.1-alpha-2
     */
    @Parameter
    private Boolean failOnMissingWebXml;

    /**
     * Whether classes (that is the content of the WEB-INF/classes directory) should be attached to the project as an
     * additional artifact.
     * <p>
     * By default the classifier for the additional artifact is 'classes'. You can change it with the
     * <code><![CDATA[<classesClassifier>someclassifier</classesClassifier>]]></code> parameter.
     * </p>
     * <p>
     * If this parameter true, another project can depend on the classes by writing something like:
     * 
     * <pre>
     * <![CDATA[<dependency>
     *   <groupId>myGroup</groupId>
     *   <artifactId>myArtifact</artifactId>
     *   <version>myVersion</myVersion>
     *   <classifier>classes</classifier>
     * </dependency>]]>
     * </pre>
     * </p>
     *
     * @since 2.1-alpha-2
     */
    @Parameter( defaultValue = "false" )
    private boolean attachClasses;

    /**
     * The classifier to use for the attached classes artifact.
     *
     * @since 2.1-alpha-2
     */
    @Parameter( defaultValue = "classes" )
    private String classesClassifier;

    /**
     * You can skip the execution of the plugin if you need to. Its use is NOT RECOMMENDED, but quite convenient on
     * occasion.
     * 
     * @since 3.0.0
     */
    @Parameter( property = "maven.war.skip", defaultValue = "false" )
    private boolean skip;

    // ----------------------------------------------------------------------
    // Implementation
    // ----------------------------------------------------------------------

    /**
     * Executes the WarMojo on the current project.
     *
     * @throws MojoExecutionException if an error occurred while building the webapp
     * @throws MojoFailureException if an error.
     */
    public void execute()
        throws MojoExecutionException, MojoFailureException
    {

        if ( isSkip() )
        {
            getLog().info( "Skipping the execution." );
            return;
        }

        File warFile = getTargetWarFile();

        try
        {
            performPackaging( warFile );
        }
        catch ( DependencyResolutionRequiredException e )
        {
            throw new MojoExecutionException( "Error assembling WAR: " + e.getMessage(), e );
        }
        catch ( ManifestException e )
        {
            throw new MojoExecutionException( "Error assembling WAR", e );
        }
        catch ( IOException e )
        {
            throw new MojoExecutionException( "Error assembling WAR", e );
        }
        catch ( ArchiverException e )
        {
            throw new MojoExecutionException( "Error assembling WAR: " + e.getMessage(), e );
        }
    }

    /**
     * Generates the webapp according to the <tt>mode</tt> attribute.
     *
     * @param warFile the target WAR file
     * @throws IOException if an error occurred while copying files
     * @throws ArchiverException if the archive could not be created
     * @throws ManifestException if the manifest could not be created
     * @throws DependencyResolutionRequiredException if an error occurred while resolving the dependencies
     * @throws MojoExecutionException if the execution failed
     * @throws MojoFailureException if a fatal exception occurred
     */
    private void performPackaging( File warFile )
        throws IOException, ManifestException, DependencyResolutionRequiredException, MojoExecutionException,
        MojoFailureException
    {
        getLog().info( "Packaging webapp" );

        buildExplodedWebapp( getWebappDirectory() );

        MavenArchiver archiver = new MavenArchiver();

        archiver.setArchiver( warArchiver );

        archiver.setOutputFile( warFile );

        // CHECKSTYLE_OFF: LineLength
        getLog().debug( "Excluding " + Arrays.asList( getPackagingExcludes() )
            + " from the generated webapp archive." );
        getLog().debug( "Including " + Arrays.asList( getPackagingIncludes() ) + " in the generated webapp archive." );
        // CHECKSTYLE_ON: LineLength

        warArchiver.addDirectory( getWebappDirectory(), getPackagingIncludes(), getPackagingExcludes() );

        final File webXmlFile = new File( getWebappDirectory(), "WEB-INF/web.xml" );
        if ( webXmlFile.exists() )
        {
            warArchiver.setWebxml( webXmlFile );
        }

        warArchiver.setRecompressAddedZips( isRecompressZippedFiles() );

        warArchiver.setIncludeEmptyDirs( isIncludeEmptyDirectories() );

        if ( Boolean.FALSE.equals( failOnMissingWebXml )
            || ( failOnMissingWebXml == null && isProjectUsingAtLeastServlet30() ) )
        {
            getLog().debug( "Build won't fail if web.xml file is missing." );
            warArchiver.setExpectWebXml( false );
        }

        // create archive
        archiver.createArchive( getSession(), getProject(), getArchive() );

        // create the classes to be attached if necessary
        if ( isAttachClasses() )
        {
            if ( isArchiveClasses() && getJarArchiver().getDestFile() != null )
            {
                // special handling in case of archived classes: MWAR-240
                File targetClassesFile = getTargetClassesFile();
                FileUtils.copyFile( getJarArchiver().getDestFile(), targetClassesFile );
                projectHelper.attachArtifact( getProject(), "jar", getClassesClassifier(), targetClassesFile );
            }
            else
            {
                ClassesPackager packager = new ClassesPackager();
                final File classesDirectory = packager.getClassesDirectory( getWebappDirectory() );
                if ( classesDirectory.exists() )
                {
                    getLog().info( "Packaging classes" );
                    packager.packageClasses( classesDirectory, getTargetClassesFile(), getJarArchiver(), getSession(),
                                             getProject(), getArchive() );
                    projectHelper.attachArtifact( getProject(), "jar", getClassesClassifier(), getTargetClassesFile() );
                }
            }
        }

        if ( this.classifier != null )
        {
            projectHelper.attachArtifact( getProject(), "war", this.classifier, warFile );
        }
        else
        {
            Artifact artifact = getProject().getArtifact();
            if ( primaryArtifact )
            {
                artifact.setFile( warFile );
            }
            else if ( artifact.getFile() == null || artifact.getFile().isDirectory() )
            {
                artifact.setFile( warFile );
            }
        }
    }

    /**
     * Determines if the current Maven project being built uses the Servlet 3.0 API (JSR 315). If it does then the
     * <code>web.xml</code> file can be omitted.
     * <p>
     * This is done by checking if the interface <code>javax.servlet.annotation.WebServlet</code> is in the compile-time
     * dependencies (which includes provided dependencies) of the Maven project.
     * 
     * @return <code>true</code> if the project being built depends on Servlet 3.0 API, <code>false</code> otherwise.
     * @throws DependencyResolutionRequiredException if the compile elements can't be resolved.
     * @throws MalformedURLException if the path to a dependency file can't be transformed to a URL.
     */
    private boolean isProjectUsingAtLeastServlet30()
        throws DependencyResolutionRequiredException, MalformedURLException
    {
        List<String> classpathElements = getProject().getCompileClasspathElements();
        URL[] urls = new URL[classpathElements.size()];
        for ( int i = 0; i < urls.length; i++ )
        {
            urls[i] = new File( classpathElements.get( i ) ).toURI().toURL();
        }
        ClassLoader loader = new URLClassLoader( urls, Thread.currentThread().getContextClassLoader() );
        try
        {
            Class.forName( "javax.servlet.annotation.WebServlet", false, loader );
            return true;
        }
        catch ( ClassNotFoundException e )
        {
            return false;
        }
    }

    /**
     * @param basedir The basedir
     * @param finalName The finalName
     * @param classifier The classifier.
     * @param type The type.
     * @return {@link File}
     */
    protected static File getTargetFile( File basedir, String finalName, String classifier, String type )
    {
        if ( classifier == null )
        {
            classifier = "";
        }
        else if ( classifier.trim().length() > 0 && !classifier.startsWith( "-" ) )
        {
            classifier = "-" + classifier;
        }

        return new File( basedir, finalName + classifier + "." + type );
    }

    /**
     * @return The war {@link File}
     */
    protected File getTargetWarFile()
    {
        return getTargetFile( new File( getOutputDirectory() ), getWarName(), getClassifier(), "war" );

    }

    /**
     * @return The target class {@link File}
     */
    protected File getTargetClassesFile()
    {
        return getTargetFile( new File( getOutputDirectory() ), getWarName(), getClassesClassifier(), "jar" );
    }

    // Getters and Setters

    /**
     * @return {@link #classifier}
     */
    public String getClassifier()
    {
        return classifier;
    }

    /**
     * @param classifier {@link #classifier}
     */
    public void setClassifier( String classifier )
    {
        this.classifier = classifier;
    }

    /**
     * @return The package excludes.
     */
    public String[] getPackagingExcludes()
    {
        if ( StringUtils.isEmpty( packagingExcludes ) )
        {
            return new String[0];
        }
        else
        {
            return StringUtils.split( packagingExcludes, "," );
        }
    }

    /**
     * @param packagingExcludes {@link #packagingExcludes}
     */
    public void setPackagingExcludes( String packagingExcludes )
    {
        this.packagingExcludes = packagingExcludes;
    }

    /**
     * @return The packaging includes.
     */
    public String[] getPackagingIncludes()
    {
        if ( StringUtils.isEmpty( packagingIncludes ) )
        {
            return new String[] { "**" };
        }
        else
        {
            return StringUtils.split( packagingIncludes, "," );
        }
    }

    /**
     * @param packagingIncludes {@link #packagingIncludes}
     */
    public void setPackagingIncludes( String packagingIncludes )
    {
        this.packagingIncludes = packagingIncludes;
    }

    /**
     * @return {@link #outputDirectory}
     */
    public String getOutputDirectory()
    {
        return outputDirectory;
    }

    /**
     * @param outputDirectory {@link #outputDirectory}
     */
    public void setOutputDirectory( String outputDirectory )
    {
        this.outputDirectory = outputDirectory;
    }

    /**
     * @return {@link #warName}
     */
    public String getWarName()
    {
        return warName;
    }

    /**
     * @param warName {@link #warName}
     */
    public void setWarName( String warName )
    {
        this.warName = warName;
    }

    /**
     * @return {@link #warArchiver}
     */
    public WarArchiver getWarArchiver()
    {
        return warArchiver;
    }

    /**
     * @param warArchiver {@link #warArchiver}
     */
    public void setWarArchiver( WarArchiver warArchiver )
    {
        this.warArchiver = warArchiver;
    }

    /**
     * @return {@link #projectHelper}
     */
    public MavenProjectHelper getProjectHelper()
    {
        return projectHelper;
    }

    /**
     * @param projectHelper {@link #projectHelper}
     */
    public void setProjectHelper( MavenProjectHelper projectHelper )
    {
        this.projectHelper = projectHelper;
    }

    /**
     * @return {@link #primaryArtifact}
     */
    public boolean isPrimaryArtifact()
    {
        return primaryArtifact;
    }

    /**
     * @param primaryArtifact {@link #primaryArtifact}
     */
    public void setPrimaryArtifact( boolean primaryArtifact )
    {
        this.primaryArtifact = primaryArtifact;
    }

    /**
     * @return {@link #attachClasses}
     */
    public boolean isAttachClasses()
    {
        return attachClasses;
    }

    /**
     * @param attachClasses {@link #attachClasses}
     */
    public void setAttachClasses( boolean attachClasses )
    {
        this.attachClasses = attachClasses;
    }

    /**
     * @return {@link #classesClassifier}
     */
    public String getClassesClassifier()
    {
        return classesClassifier;
    }

    /**
     * @param classesClassifier {@link #classesClassifier}
     */
    public void setClassesClassifier( String classesClassifier )
    {
        this.classesClassifier = classesClassifier;
    }

    /**
     * @return {@link #failOnMissingWebXml}
     */
    public boolean isFailOnMissingWebXml()
    {
        return failOnMissingWebXml;
    }

    /**
     * @param failOnMissingWebXml {@link #failOnMissingWebXml}
     */
    public void setFailOnMissingWebXml( boolean failOnMissingWebXml )
    {
        this.failOnMissingWebXml = failOnMissingWebXml;
    }

    public boolean isSkip()
    {
        return skip;
    }
}
