blob: 939de10038224958a914f5d7b687989c61855e19 [file] [log] [blame]
/*
* 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;
}
}