/**
 * JOnAS : Java(TM) OpenSource Application Server
 * Copyright (C) 1999-2004 Bull S.A.
 * Contact: jonas-team@ow2.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * --------------------------------------------------------------------------
 * $Id: JarArchive.java 15428 2008-10-07 11:20:29Z sauthieg $
 * --------------------------------------------------------------------------
 */

package org.ow2.jonas.generators.genbase.archive;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.List;
import java.util.Vector;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;

import org.ow2.jonas.generators.genbase.GenBaseException;



/**
 * A <code>JarArchive</code> is a wrapper for jar file.
 *
 * @author Guillaume Sauthier
 */
public class JarArchive extends AbsArchive {

    /** encapsulated Jar File */
    private JarFile jar;

    /**
     * Creates a new JarArchive object.
     *
     * @param jar the File corresponding to a JarFile
     *
     * @throws GenBaseException When Manifest cannot be found
     */
    public JarArchive(File jar) throws GenBaseException {
        super(jar);

        try {
            this.jar = new JarFile(jar);
            setManifest(this.jar.getManifest());
        } catch (IOException ioe) {
            String err = getI18n().getMessage("JarArchive.constr.jar", jar);
            throw new GenBaseException(err, ioe);
        }
    }

    /**
     * Returns an InputStream corresponding to the given filename.
     *
     * @param filename file name source of the InputStream
     *
     * @return the InputStream corresponding to the given filename.
     *
     * @throws IOException when InputStream of the filename cannot be found in
     *         the archive
     */
    public InputStream getInputStream(String filename) throws IOException {
        // try get the file from the map
        File file = (File) getFiles().get(filename);

        if (file == null) {
            // filename not found in added files
            // try jar search
            ZipEntry ze = jar.getEntry(filename);

            // Entry found ?
            if (ze == null) {
                return null;
            } else {
                return jar.getInputStream(ze);
            }
        } else {
            // file exists (in added files)
            return new FileInputStream(file);
        }
    }

    /**
     * Returns a List of all files contained in this archive. Original files in
     * jar, added Files are all included as String in this Enumeration.
     *
     * @return a List of all files contained in this archive.
     */
    public List getContainedFiles() {
        List list = new Vector(getFiles().keySet());

        // add files of the original archive
        for (Enumeration e = jar.entries(); e.hasMoreElements();) {
            ZipEntry ze = (ZipEntry) e.nextElement();
            list.add(ze.getName());
        }

        return list;
    }

    /**
     * Returns true if archive is packed or false if archive is unpacked.
     *
     * @return true if archive is packed or false if archive is unpacked.
     */
    public boolean isPacked() {
        return true;
    }

    /**
     * Close this archive
     */
    public void close() {
        super.close();
        try {
            jar.close();
        } catch (IOException ioe) {
            throw new RuntimeException("Cannot close file '" + jar + "'", ioe);
        }
        jar = null;
    }
}