/*
 * Copyright  2001-2004 The Apache Software Foundation
 *
 *  Licensed 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.
 *
 */
package org.codehaus.plexus.archiver.ear;

import javax.inject.Named;

import java.io.File;
import java.io.IOException;
import org.codehaus.plexus.archiver.ArchiveEntry;
import org.codehaus.plexus.archiver.ArchiverException;
import org.codehaus.plexus.archiver.jar.JarArchiver;
import org.codehaus.plexus.archiver.util.ResourceUtils;
import org.codehaus.plexus.archiver.zip.ConcurrentJarCreator;

/**
 * Creates a EAR archive. Based on WAR task
 */
@Named( "ear" )
public class EarArchiver
    extends JarArchiver
{

    private File deploymentDescriptor;

    private boolean descriptorAdded;

    /**
     * Create an Ear.
     */
    public EarArchiver()
    {
        super();
        archiveType = "ear";
    }

    /**
     * File to incorporate as application.xml.
     */
    public void setAppxml( File descr )
        throws ArchiverException
    {
        deploymentDescriptor = descr;
        if ( !deploymentDescriptor.exists() )
        {
            throw new ArchiverException( "Deployment descriptor: " + deploymentDescriptor + " does not exist." );
        }

        addFile( descr, "META-INF/application.xml" );
    }

    /**
     * Adds archive.
     */
    public void addArchive( File fileName )
        throws ArchiverException
    {
        addDirectory( fileName.getParentFile(), "/",
                      new String[]
                      {
                          fileName.getName()
                      }, null );

    }

    /**
     * Adds archives.
     */
    public void addArchives( File directoryName, String[] includes, String[] excludes )
        throws ArchiverException
    {
        addDirectory( directoryName, "/", includes, excludes );
    }

    @Override
    protected void initZipOutputStream( ConcurrentJarCreator zOut )
        throws ArchiverException, IOException
    {
        // If no webxml file is specified, it's an error.
        if ( deploymentDescriptor == null && !isInUpdateMode() )
        {
            throw new ArchiverException( "appxml attribute is required" );
        }

        super.initZipOutputStream( zOut );
    }

    /**
     * Overridden from ZipArchiver class to deal with application.xml
     */
    protected void zipFile( ArchiveEntry entry, ConcurrentJarCreator zOut, String vPath, int mode )
        throws IOException, ArchiverException
    {
        // If the file being added is META-INF/application.xml, we
        // warn if it's not the one specified in the "appxml"
        // attribute - or if it's being added twice, meaning the same
        // file is specified by the "appxml" attribute and in a
        // <fileset> element.
        if ( vPath.equalsIgnoreCase( "META-INF/application.xml" ) )
        {
            if ( deploymentDescriptor == null
                     || !ResourceUtils.isCanonicalizedSame( entry.getResource(), deploymentDescriptor )
                     || descriptorAdded )
            {
                getLogger().warn( "Warning: selected " + archiveType
                                      + " files include a META-INF/application.xml which will be ignored "
                                      + "(please use appxml attribute to " + archiveType + " task)" );
            }
            else
            {
                super.zipFile( entry, zOut, vPath );
                descriptorAdded = true;
            }
        }
        else
        {
            super.zipFile( entry, zOut, vPath );
        }
    }

    /**
     * Make sure we don't think we already have a application.xml next
     * time this task gets executed.
     */
    @Override
    protected void cleanUp()
        throws IOException
    {
        descriptorAdded = false;
        super.cleanUp();
    }

}
