// Get folder that a class was loaded from
/* Changes
7/28/05 - Added pathToJar
8/18/05 - Added leading / for Mac
9/26/06 - Added URLDecoder
5/16/08 - Added Linux code
*/
package NormsTools;
import java.net.URL;
import java.io.File;
import java.util.zip.*;
import java.util.Date;
import java.net.URLDecoder;
public final class FindOurHome {
final public static String Version = "FindOurHome 16 May 2008";
final static boolean debug = false; // For debug output
private static boolean setHomeLoc = false;
private static boolean homeLocInJar = false; // true if class file from jar
private static String URLStr = "";
private static String pathToJar = null;
// Here are the possible headers and id strings (see below):
private final static String JAVA_HDR1 = "file:/";
private final static String JAVA_HDR2 = "jar:";
private final static String JAVA_SEP = "!";
private final static String Percent = "%";
private final static String JVIEW_HDR1 = "systemresource:/FILE";
private final static String JVIEW_HDR2 = "systemresource:/ZIP";
private final static String JVIEW_SEP1 = "/+/";
private final static String JAR_EXT = ".jar";
private final static String MetaFILE = "META-INF/MANIFEST.MF";
private final static String OS_Win = "Win";
private final static String OS_Mac = "Mac";
private final static String OS_Linux = "Linux";
//-------------------------------------------------------------------
public final static String getHomeLoc(Object obj, String className) {
if(debug) {
System.out.println("FOH.getHomeLoc(): class is " + obj.getClass());
}
URL ourLoc = obj.getClass().getResource(className);
if (ourLoc == null) {
System.err.println("FOH.getHomeLoc(): getResource returned null for "
+ className + " with " + obj);
return "";
}
if (debug)
System.out.println("FOH.Loaded from=" + ourLoc
+ ",\n getProtocol()=" + ourLoc.getProtocol()
+ ",\n getHost()=" + ourLoc.getHost()
+ ",\n getFile()=" + ourLoc.getFile());
// Output when from a class file:
//JAVA >Loaded from file:/D:/JavaDevelopment/SlideShow/ImgIdxEditor.class,
// getFile=/D:/JavaDevelopment/SlideShow/ImgIdxEditor.class
//JVIEW>Loaded from systemresource:/FILED:\JavaDevelopment\SlideShow\/+/ImgIdxEditor.class,
// getFile=/FILED:\JavaDevelopment\SlideShow\/+/ImgIdxEditor.class
// Output when load from a jar:
//JAVA >Loaded from jar:file:/C:/My_Photos/SlideShowApp.jar!/ImgIdxEditor.class,
// getFile=file:/C:/My_Photos/SlideShowApp.jar!/ImgIdxEditor.class
//JVIEW>Loaded from systemresource:/ZIPC:\My_Photos\SlideShowApp.jar/+/ImgIdxEditor.class,
// getFile=/ZIPC:\My_Photos\SlideShowApp.jar/+/ImgIdxEditor.class
//JDK118>Loaded from=systemresource:/ZIP1/+/NormsTools/FindOurHome.class,
// getFile=/ZIP1/+/NormsTools/FindOurHome.class
// Linux: URLStr=jar:file:/home/norm/www/HTTPServer.jar!/HTTPServer/httpd.class
// On Mac: this pgm returned: 6/+/SlideShow/ when jar was in the folder: <?>SlideShow
URLStr = ourLoc.toString();
if(URLStr.indexOf(Percent) >= 0) {
try {
URLStr = URLDecoder.decode(URLStr, "UTF8"); // Doesn't work???
System.out.println("decode= " + URLStr);
}catch(Exception ex) {
ex.printStackTrace();
return "";
}
}
String propFolder = "";
int ix, iy;
homeLocInJar = false; // Reset
setHomeLoc = true;
String os = System.getProperty("os.name");
if(!os.startsWith(OS_Win) && !os.startsWith(OS_Mac) && !os.startsWith(OS_Linux)) {
System.err.println("Unknown OS - " + os);
}
// Parse depending on Java or JVIEW
if (URLStr.startsWith(JVIEW_HDR1)) {
// From a class file
ix = URLStr.indexOf(JVIEW_SEP1); // Get end of filename
propFolder = URLStr.substring(JVIEW_HDR1.length(), ix);
}else if (URLStr.startsWith(JVIEW_HDR2)) {
// From a jar file - get drive thru last /
ix = URLStr.lastIndexOf(File.separator);
if (ix > JVIEW_HDR2.length()) {
propFolder = URLStr.substring(JVIEW_HDR2.length(), ix+1);
homeLocInJar = true;
} else {
System.err.println("FOH.getHomeLoc(): Unknown format1: " + URLStr);
}
}else if ((iy = URLStr.indexOf(JAVA_HDR1)) >= 0) {
// Its Java program
if (URLStr.startsWith(JAVA_HDR2)) { // in a jar?
// Its in a jar file
ix = URLStr.indexOf(JAVA_SEP); // set ptr to end of path to jar
homeLocInJar = true;
}else {
ix = URLStr.length();
}
int iz = URLStr.lastIndexOf("/", ix); // Get sep that's before the jar fn
if (iz > JAVA_HDR1.length()) {
propFolder = URLStr.substring(iy
+ JAVA_HDR1.length(), iz+1).replace('/', File.separatorChar);
pathToJar = URLStr.substring(iy
+ JAVA_HDR1.length(), ix).replace('/', File.separatorChar);
}else {
System.err.println("FOH.getHomeLoc(): Unknown format2: " + URLStr);
}
if(os.startsWith(OS_Mac)) { // Quick and dirty code?????
// Need leading / on Mac
propFolder = File.separator + propFolder;
pathToJar = File.separator + pathToJar;
}else if(os.startsWith(OS_Linux)) {
// System.out.println("FindOurHome: URLStr=" + URLStr);
propFolder = File.separator + propFolder;
}
}else {
// Unknown program???
System.err.println("FOH.getHomeLoc(): Unknown format3: " + URLStr);
}
if (debug)
System.out.println("FOH.getHomeLoc(): FilePath=" + propFolder);
return propFolder;
} // end getHomeLoc()
//---------------------------------------------------------------
public static String getPathToJar(Object obj, String className) {
getHomeLoc(obj, className);
if(homeLocInJar)
return pathToJar;
else
return null;
} // end getPathToJar()
//---------------------------------------------------------
// Was class file in a jar?
public static boolean fromJar() {
if (!setHomeLoc)
throw new RuntimeException("Must call getHomeLoc() first");
return homeLocInJar;
}
final static long NO_DATE = 0L; // When no valid date found
//---------------------------------------------------------
// Get build date of a Jar file. Use the manifest's date!
// Args: object that was loaded from the jar. Currently NOT USED???
public static long getBuildDate(Object obj) {
if (!fromJar() || URLStr.indexOf(JAR_EXT) < 0) {
System.err.println("getBuildDate(): Class was not loaded from a jar");
return NO_DATE;
}
//Parse out the path to the jar file
int ixJar = URLStr.indexOf(JAR_EXT);
int lenHdr = JAVA_HDR1.length() + JAVA_HDR2.length(); // Assume java
if (URLStr.startsWith(JVIEW_HDR2)) {
lenHdr = JVIEW_HDR2.length();
}
if (ixJar < lenHdr) {
return NO_DATE;
}
String jarFN = URLStr.substring(lenHdr, ixJar+JAR_EXT.length());
try {
ZipFile zipF = new ZipFile(jarFN);
ZipEntry ze = zipF.getEntry(MetaFILE);
if (ze == null) {
System.err.println("getBuildDate(): Manifest file not found in jar.");
return NO_DATE;
}
long time = ze.getTime();
zipF.close();
return time; // Return the entry's time
}catch(Exception ex) {
ex.printStackTrace();
}
return NO_DATE; // if problem
} // end getBuildDate()
//----------------------------------------------------------------
// Following for testing. Comment out when done
/* public static void main(String[] args) {
if (args.length == 0) {
// Default
args = new String[]{"FindOurHome.class"};
}
// FindOurHome.debug = true;
FindOurHome foh = new FindOurHome(); // need an object
String theFN = FindOurHome.getHomeLoc(foh, args[0]);
File theFile = new File(theFN);
System.out.println(args[0] + " loaded from "
+ theFile + ", exists?" + theFile.exists()
+ ", in jar? " + FindOurHome.fromJar());
System.out.println("Build date: " + new Date(FindOurHome.getBuildDate(foh)));
// Now test what can be done with the raw URL
try {
URL ourLoc = foh.getClass().getResource(args[0]);
String fn = ourLoc.getFile();
File tf = new File(fn);
System.out.println("\nfile=" + fn +", exists? " + tf.exists() + ", size=" + tf.length());
ZipFile zf = new ZipFile(fn);
java.util.Enumeration en = zf.entries();
System.out.println("en has " + en.hasMoreElements());
}catch(Exception ex) {
System.out.println(ex);
}
} // end main */
} // end class
/* Output when run from a jar >>>>>>>
D:\JavaDevelopment\NormsTools\Testing>java.exe -jar FindOurHome.jar
getHomeLoc(): class is class NormsTools.FindOurHome
Loaded from=jar:file:/D:/JavaDevelopment/NormsTools/Testing/FindOurHome.jar!/NormsTools/FindOurHome.class,
getProtocol()=jar,
getHost()=,
getFile()=file:/D:/JavaDevelopment/NormsTools/Testing/FindOurHome.jar!/NormsTools/FindOurHome.class
getHomeLoc(): FilePath=D:\JavaDevelopment\NormsTools\Testing\
FindOurHome.class loaded from D:\JavaDevelopment\NormsTools\Testing\, in jar? true
Build date: Thu Aug 18 14:42:04 CDT 2005
>>>>>>>>From a class file
Running: java NormsTools.FindOurHome
getHomeLoc(): class is class NormsTools.FindOurHome
Loaded from=file:/D:/JavaDevelopment/NormsTools/FindOurHome.class,
getProtocol()=file,
getHost()=,
getFile()=/D:/JavaDevelopment/NormsTools/FindOurHome.class
getHomeLoc(): FilePath=D:\JavaDevelopment\NormsTools\
FindOurHome.class loaded from D:\JavaDevelopment\NormsTools\, in jar? false
getBuildDate(): Class was not loaded from a jar
Build date: Wed Dec 31 18:00:00 CST 1969
file=/D:/JavaDevelopment/NormsTools/FindOurHome.class, exists? true, size=4121
java.util.zip.ZipException: error in opening zip file
1 error(s)
>>>>>>> From a jar
D:\JavaDevelopment\NormsTools\Testing>java.exe -jar FindOurHome.jar
getHomeLoc(): class is class NormsTools.FindOurHome
Loaded from=jar:file:/D:/JavaDevelopment/NormsTools/Testing/FindOurHome.jar!/NormsTools/FindOurHome.class,
getProtocol()=jar,
getHost()=,
getFile()=file:/D:/JavaDevelopment/NormsTools/Testing/FindOurHome.jar!/NormsTools/FindOurHome.class
getHomeLoc(): FilePath=D:\JavaDevelopment\NormsTools\Testing\
FindOurHome.class loaded from D:\JavaDevelopment\NormsTools\Testing\, in jar? true
Build date: Thu Aug 18 15:05:58 CDT 2005
file=file:/D:/JavaDevelopment/NormsTools/Testing/FindOurHome.jar!/NormsTools/FindOurHome.class, exists? false, size=0
java.util.zip.ZipException: The system cannot find the path specified
*/