/*
 * Copyright (c) 1999, 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.
 */
/*
 * Licensed Materials - Property of IBM
 * 5639-D57 (C) COPYRIGHT International Business Machines Corp. 1997,1998
 * RMI-IIOP v1.0
 *
 */

package com.sun.tools.corba.se.idl.som.cff;

import java.lang.Exception;
import java.lang.String;
import java.lang.System;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.IOException;
import java.util.Locale;
import java.util.NoSuchElementException;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.zip.*;

/**
 * FileLocator is an abstract class (one that cannot be instantiated) that
 * provides class methods for finding files in the directories or zip
 * archives that make up the CLASSPATH.
 *
 * @author      Larry K. Raper
 */
public abstract class FileLocator extends Object {

    /* Class variables */


    static final Properties pp = System.getProperties ();
    static final String classPath = pp.getProperty ("java.class.path", ".");
    static final String pathSeparator = pp.getProperty ("path.separator", ";");

    /* Instance variables */

    /* [None, no instances of this class are ever instantiated.] */

    /**
     * locateClassFile returns a DataInputStream with mark/reset
     * capability that can be used to read the requested class file.  The
     * CLASSPATH is used to locate the class.
     *
     * @param classFileName The name of the class to locate.  The class name
     * should be given in fully-qualified form, for example:
     * <pre>
     *     java.lang.Object
     *     java.io.DataInputStream
     * </pre>
     *
     * @exception java.io.FileNotFoundException The requested class file
     * could not be found.
     * @exception java.io.IOException The requested class file
     * could not be opened.
     */
    public static DataInputStream locateClassFile (String classFileName)
        throws FileNotFoundException, IOException {

        boolean notFound = true;
        StringTokenizer st;
        String path = "";
        String pathNameForm;
        File cf = null;
        NamedDataInputStream result;

        st = new StringTokenizer (classPath, pathSeparator, false);
        pathNameForm = classFileName.replace ('.', File.separatorChar) +
            ".class";

        while (st.hasMoreTokens () && notFound) {

            try {path = st.nextToken ();}
                catch (NoSuchElementException nse) {break;}
            int pLen = path.length ();
            String pathLast4 = pLen > 3 ? path.substring (pLen - 4) : "";
            if (pathLast4.equalsIgnoreCase (".zip") ||
                pathLast4.equalsIgnoreCase (".jar")) {

                try {

                    result = locateInZipFile (path, classFileName, true, true);
                    if (result == null)
                        continue;
                    return (DataInputStream) result;

                } catch (ZipException zfe) {
                    continue;
                } catch (IOException ioe) {
                    continue;
                }

            } else {
                try {cf = new File (path + File.separator + pathNameForm);
                } catch (NullPointerException npe) { continue; }
                if ((cf != null) && cf.exists ())
                    notFound = false;
            }
        }

        if (notFound) {

            /* Make one last attempt to find the file in the current
             * directory
             */

            int lastdot = classFileName.lastIndexOf ('.');
            String simpleName =
                (lastdot >= 0) ? classFileName.substring (lastdot+1) :
                classFileName;

            result = new NamedDataInputStream (new BufferedInputStream (
               new FileInputStream (simpleName + ".class")),
                   simpleName + ".class", false);
            return (DataInputStream) result;
        }

        result = new NamedDataInputStream (new BufferedInputStream (
            new FileInputStream (cf)), path + File.separator + pathNameForm,
                false);
        return (DataInputStream) result;

    }

    /**
     * locateLocaleSpecificFileInClassPath returns a DataInputStream that
     * can be used to read the requested file, but the name of the file is
     * determined using information from the current locale and the supplied
     * file name (which is treated as a "base" name, and is supplemented with
     * country and language related suffixes, obtained from the current
     * locale).  The CLASSPATH is used to locate the file.
     *
     * @param fileName The name of the file to locate.  The file name
     * may be qualified with a partial path name, using '/' as the separator
     * character or using separator characters appropriate for the host file
     * system, in which case each directory or zip file in the CLASSPATH will
     * be used as a base for finding the fully-qualified file.
     * Here is an example of how the supplied fileName is used as a base
     * for locating a locale-specific file:
     *
     * <pre>
     *     Supplied fileName: a/b/c/x.y,  current locale: US English
     *
     *                     Look first for: a/b/c/x_en_US.y
     *     (if that fails) Look next for:  a/b/c/x_en.y
     *     (if that fails) Look last for:  a/b/c/x.y
     *
     *     All elements of the class path are searched for each name,
     *     before the next possible name is tried.
     * </pre>
     *
     * @exception java.io.FileNotFoundException The requested class file
     * could not be found.
     * @exception java.io.IOException The requested class file
     * could not be opened.
     */
    public static DataInputStream locateLocaleSpecificFileInClassPath (
        String fileName) throws FileNotFoundException, IOException {

        String localeSuffix = "_" + Locale.getDefault ().toString ();
        int lastSlash = fileName.lastIndexOf ('/');
        int lastDot   = fileName.lastIndexOf ('.');
        String fnFront, fnEnd;
        DataInputStream result = null;
        boolean lastAttempt = false;

        if ((lastDot > 0) && (lastDot > lastSlash)) {
            fnFront = fileName.substring (0, lastDot);
            fnEnd   = fileName.substring (lastDot);
        } else {
            fnFront = fileName;
            fnEnd   = "";
        }

        while (true) {
            if (lastAttempt)
                result = locateFileInClassPath (fileName);
            else try {
                result = locateFileInClassPath (fnFront + localeSuffix + fnEnd);
            } catch (Exception e) { /* ignore */ }
            if ((result != null) || lastAttempt)
                break;
            int lastUnderbar = localeSuffix.lastIndexOf ('_');
            if (lastUnderbar > 0)
                localeSuffix = localeSuffix.substring (0, lastUnderbar);
            else
                lastAttempt = true;
        }
        return result;

    }

    /**
     * locateFileInClassPath returns a DataInputStream that can be used
     * to read the requested file.  The CLASSPATH is used to locate the file.
     *
     * @param fileName The name of the file to locate.  The file name
     * may be qualified with a partial path name, using '/' as the separator
     * character or using separator characters appropriate for the host file
     * system, in which case each directory or zip file in the CLASSPATH will
     * be used as a base for finding the fully-qualified file.
     *
     * @exception java.io.FileNotFoundException The requested class file
     * could not be found.
     * @exception java.io.IOException The requested class file
     * could not be opened.
     */
    public static DataInputStream locateFileInClassPath (String fileName)
        throws FileNotFoundException, IOException {

        boolean notFound = true;
        StringTokenizer st;
        String path = "";
        File cf = null;
        NamedDataInputStream result;

        String zipEntryName = File.separatorChar == '/' ? fileName :
            fileName.replace (File.separatorChar, '/');

        String localFileName = File.separatorChar == '/' ? fileName :
            fileName.replace ('/', File.separatorChar);

        st = new StringTokenizer (classPath, pathSeparator, false);

        while (st.hasMoreTokens () && notFound) {

            try {path = st.nextToken ();}
                catch (NoSuchElementException nse) {break;}
            int pLen = path.length ();
            String pathLast4 = pLen > 3 ? path.substring (pLen - 4) : "";
            if (pathLast4.equalsIgnoreCase (".zip") ||
                pathLast4.equalsIgnoreCase (".jar")) {

                try {

                    result = locateInZipFile (path, zipEntryName, false, false);
                    if (result == null)
                        continue;
                    return (DataInputStream) result;

                } catch (ZipException zfe) {
                    continue;
                } catch (IOException ioe) {
                    continue;
                }

            } else {
                try {cf = new File (path + File.separator + localFileName);
                } catch (NullPointerException npe) { continue; }
                if ((cf != null) && cf.exists ())
                    notFound = false;
            }
        }

        if (notFound) {

            /* Make one last attempt to find the file in the current
             * directory
             */

            int lastpart = localFileName.lastIndexOf (File.separator);
            String simpleName =
                (lastpart >= 0) ? localFileName.substring (lastpart+1) :
                localFileName;

            result = new NamedDataInputStream (new BufferedInputStream (
               new FileInputStream (simpleName)), simpleName, false);
            return (DataInputStream) result;
        }

        result = new NamedDataInputStream (new BufferedInputStream (
            new FileInputStream (cf)), path + File.separator + localFileName,
                false);
        return (DataInputStream) result;

    }

    /**
     * Returns the fully qualified file name associated with the passed
     * DataInputStream <i>if the DataInputStream was created using one
     * of the static locate methods supplied with this class</i>, otherwise
     * returns a zero length string.
     */
    public static String getFileNameFromStream (DataInputStream ds) {

        if (ds instanceof NamedDataInputStream)
            return ((NamedDataInputStream) ds).fullyQualifiedFileName;
        return "";

    }

    /**
     * Returns an indication of whether the passed DataInputStream is
     * associated with a member of a zip file <i>if the DataInputStream was
     * created using one of the static locate methods supplied with this
     * class</i>, otherwise returns false.
     */
    public static boolean isZipFileAssociatedWithStream (DataInputStream ds) {

        if (ds instanceof NamedDataInputStream)
            return ((NamedDataInputStream) ds).inZipFile;
        return false;

    }

    private static NamedDataInputStream locateInZipFile (String zipFileName,
        String fileName, boolean wantClass, boolean buffered)
        throws ZipException, IOException {

        ZipFile zf;
        ZipEntry ze;
        zf = new ZipFile (zipFileName);

        if (zf == null)
            return null;
        String zeName = wantClass ?
            fileName.replace ('.', '/') + ".class" :
            fileName;

        //  This code works with JDK 1.0 level SUN zip classes
        //

        //  ze = zf.get (zeName);
        //  if (ze == null)
        //      return null;
        //  return new NamedDataInputStream (
        //      new BufferedInputStream (new ZipInputStream (ze)),
        //          zipFileName + '(' +zeName + ')', true);

        //  This code works with JDK 1.0.2 and JDK 1.1 level SUN zip classes
        //

            ze = zf.getEntry (zeName);
            if (ze == null) {
                zf.close(); // D55355, D56419
                zf = null;
                return null;
            }
            InputStream istream = zf.getInputStream(ze);
            if (buffered)
                istream = new BufferedInputStream(istream);
            return new NamedDataInputStream (istream,
                    zipFileName + '(' + zeName + ')', true);

    }

}

/**
 * This class is used to associate a filename with a DataInputStream
 * The host platform's file naming conventions are assumed for the filename.
 *
 * @author      Larry K. Raper
 *
 */
/* default access */ class NamedDataInputStream extends DataInputStream {

    /* Instance variables */

    /**
     * The name of the file associated with the DataInputStream.
     */
    public String fullyQualifiedFileName;

    /**
     * Indicates whether or not the file is contained in a .zip file.
     */
    public boolean inZipFile;

    /* Constructors */

    protected NamedDataInputStream (InputStream in, String fullyQualifiedName,
        boolean inZipFile) {

        super (in);
        this.fullyQualifiedFileName = fullyQualifiedName;
        this.inZipFile = inZipFile;

    }

}
