| /* |
| * 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 resource is located in the java.corba |
| * module or if not found, then the CLASSPATH is searched. |
| * |
| * @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 { |
| |
| // The resource should be in the java.corba module |
| InputStream in = FileLocator.class.getResourceAsStream("/" + fileName); |
| if (in != null) { |
| return new DataInputStream(in); |
| } |
| |
| 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; |
| |
| } |
| |
| } |