/*
 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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 General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.net.www.protocol.jar;

import java.io.InputStream;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.io.BufferedInputStream;
import java.net.URL;
import java.net.URLConnection;
import java.net.MalformedURLException;
import java.net.UnknownServiceException;
import java.util.Enumeration;
import java.util.Map;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.security.Permission;

/**
 * @author Benjamin Renaud
 * @since 1.2
 */
public class JarURLConnection extends java.net.JarURLConnection {

    private static final boolean debug = false;

    /* the Jar file factory. It handles both retrieval and caching.
     */
    private static final JarFileFactory factory = JarFileFactory.getInstance();

    /* the url for the Jar file */
    private URL jarFileURL;

    /* the permission to get this JAR file. This is the actual, ultimate,
     * permission, returned by the jar file factory.
     */
    private Permission permission;

    /* the url connection for the JAR file */
    private URLConnection jarFileURLConnection;

    /* the entry name, if any */
    private String entryName;

    /* the JarEntry */
    private JarEntry jarEntry;

    /* the jar file corresponding to this connection */
    private JarFile jarFile;

    /* the content type for this connection */
    private String contentType;

    public JarURLConnection(URL url, Handler handler)
    throws MalformedURLException, IOException {
        super(url);

        jarFileURL = getJarFileURL();
        jarFileURLConnection = jarFileURL.openConnection();
        entryName = getEntryName();
    }

    public JarFile getJarFile() throws IOException {
        connect();
        return jarFile;
    }

    public JarEntry getJarEntry() throws IOException {
        connect();
        return jarEntry;
    }

    public Permission getPermission() throws IOException {
        return jarFileURLConnection.getPermission();
    }

    class JarURLInputStream extends java.io.FilterInputStream {
        JarURLInputStream (InputStream src) {
            super (src);
        }
        public void close () throws IOException {
            try {
                super.close();
            } finally {
                if (!getUseCaches()) {
                    jarFile.close();
                }
            }
        }
    }



    public void connect() throws IOException {
        if (!connected) {
            /* the factory call will do the security checks */
            jarFile = factory.get(getJarFileURL(), getUseCaches());

            /* we also ask the factory the permission that was required
             * to get the jarFile, and set it as our permission.
             */
            if (getUseCaches()) {
                boolean oldUseCaches = jarFileURLConnection.getUseCaches();
                jarFileURLConnection = factory.getConnection(jarFile);
                jarFileURLConnection.setUseCaches(oldUseCaches);
            }

            if ((entryName != null)) {
                jarEntry = (JarEntry)jarFile.getEntry(entryName);
                if (jarEntry == null) {
                    try {
                        if (!getUseCaches()) {
                            jarFile.close();
                        }
                    } catch (Exception e) {
                    }
                    throw new FileNotFoundException("JAR entry " + entryName +
                                                    " not found in " +
                                                    jarFile.getName());
                }
            }
            connected = true;
        }
    }

    public InputStream getInputStream() throws IOException {
        connect();

        InputStream result = null;

        if (entryName == null) {
            throw new IOException("no entry name specified");
        } else {
            if (jarEntry == null) {
                throw new FileNotFoundException("JAR entry " + entryName +
                                                " not found in " +
                                                jarFile.getName());
            }
            result = new JarURLInputStream (jarFile.getInputStream(jarEntry));
        }
        return result;
    }

    public int getContentLength() {
        long result = getContentLengthLong();
        if (result > Integer.MAX_VALUE)
            return -1;
        return (int) result;
    }

    public long getContentLengthLong() {
        long result = -1;
        try {
            connect();
            if (jarEntry == null) {
                /* if the URL referes to an archive */
                result = jarFileURLConnection.getContentLengthLong();
            } else {
                /* if the URL referes to an archive entry */
                result = getJarEntry().getSize();
            }
        } catch (IOException e) {
        }
        return result;
    }

    public Object getContent() throws IOException {
        Object result = null;

        connect();
        if (entryName == null) {
            result = jarFile;
        } else {
            result = super.getContent();
        }
        return result;
    }

    public String getContentType() {
        if (contentType == null) {
            if (entryName == null) {
                contentType = "x-java/jar";
            } else {
                try {
                    connect();
                    InputStream in = jarFile.getInputStream(jarEntry);
                    contentType = guessContentTypeFromStream(
                                        new BufferedInputStream(in));
                    in.close();
                } catch (IOException e) {
                    // don't do anything
                }
            }
            if (contentType == null) {
                contentType = guessContentTypeFromName(entryName);
            }
            if (contentType == null) {
                contentType = "content/unknown";
            }
        }
        return contentType;
    }

    public String getHeaderField(String name) {
        return jarFileURLConnection.getHeaderField(name);
    }

    /**
     * Sets the general request property.
     *
     * @param   key     the keyword by which the request is known
     *                  (e.g., "<code>accept</code>").
     * @param   value   the value associated with it.
     */
    public void setRequestProperty(String key, String value) {
        jarFileURLConnection.setRequestProperty(key, value);
    }

    /**
     * Returns the value of the named general request property for this
     * connection.
     *
     * @return  the value of the named general request property for this
     *           connection.
     */
    public String getRequestProperty(String key) {
        return jarFileURLConnection.getRequestProperty(key);
    }

    /**
     * Adds a general request property specified by a
     * key-value pair.  This method will not overwrite
     * existing values associated with the same key.
     *
     * @param   key     the keyword by which the request is known
     *                  (e.g., "<code>accept</code>").
     * @param   value   the value associated with it.
     */
    public void addRequestProperty(String key, String value) {
        jarFileURLConnection.addRequestProperty(key, value);
    }

    /**
     * Returns an unmodifiable Map of general request
     * properties for this connection. The Map keys
     * are Strings that represent the request-header
     * field names. Each Map value is a unmodifiable List
     * of Strings that represents the corresponding
     * field values.
     *
     * @return  a Map of the general request properties for this connection.
     */
    public Map<String,List<String>> getRequestProperties() {
        return jarFileURLConnection.getRequestProperties();
    }

    /**
     * Set the value of the <code>allowUserInteraction</code> field of
     * this <code>URLConnection</code>.
     *
     * @param   allowuserinteraction   the new value.
     * @see     java.net.URLConnection#allowUserInteraction
     */
    public void setAllowUserInteraction(boolean allowuserinteraction) {
        jarFileURLConnection.setAllowUserInteraction(allowuserinteraction);
    }

    /**
     * Returns the value of the <code>allowUserInteraction</code> field for
     * this object.
     *
     * @return  the value of the <code>allowUserInteraction</code> field for
     *          this object.
     * @see     java.net.URLConnection#allowUserInteraction
     */
    public boolean getAllowUserInteraction() {
        return jarFileURLConnection.getAllowUserInteraction();
    }

    /*
     * cache control
     */

    /**
     * Sets the value of the <code>useCaches</code> field of this
     * <code>URLConnection</code> to the specified value.
     * <p>
     * Some protocols do caching of documents.  Occasionally, it is important
     * to be able to "tunnel through" and ignore the caches (e.g., the
     * "reload" button in a browser).  If the UseCaches flag on a connection
     * is true, the connection is allowed to use whatever caches it can.
     *  If false, caches are to be ignored.
     *  The default value comes from DefaultUseCaches, which defaults to
     * true.
     *
     * @see     java.net.URLConnection#useCaches
     */
    public void setUseCaches(boolean usecaches) {
        jarFileURLConnection.setUseCaches(usecaches);
    }

    /**
     * Returns the value of this <code>URLConnection</code>'s
     * <code>useCaches</code> field.
     *
     * @return  the value of this <code>URLConnection</code>'s
     *          <code>useCaches</code> field.
     * @see     java.net.URLConnection#useCaches
     */
    public boolean getUseCaches() {
        return jarFileURLConnection.getUseCaches();
    }

    /**
     * Sets the value of the <code>ifModifiedSince</code> field of
     * this <code>URLConnection</code> to the specified value.
     *
     * @param   value   the new value.
     * @see     java.net.URLConnection#ifModifiedSince
     */
    public void setIfModifiedSince(long ifmodifiedsince) {
        jarFileURLConnection.setIfModifiedSince(ifmodifiedsince);
    }

   /**
     * Sets the default value of the <code>useCaches</code> field to the
     * specified value.
     *
     * @param   defaultusecaches   the new value.
     * @see     java.net.URLConnection#useCaches
     */
    public void setDefaultUseCaches(boolean defaultusecaches) {
        jarFileURLConnection.setDefaultUseCaches(defaultusecaches);
    }

   /**
     * Returns the default value of a <code>URLConnection</code>'s
     * <code>useCaches</code> flag.
     * <p>
     * Ths default is "sticky", being a part of the static state of all
     * URLConnections.  This flag applies to the next, and all following
     * URLConnections that are created.
     *
     * @return  the default value of a <code>URLConnection</code>'s
     *          <code>useCaches</code> flag.
     * @see     java.net.URLConnection#useCaches
     */
    public boolean getDefaultUseCaches() {
        return jarFileURLConnection.getDefaultUseCaches();
    }
}
