Main Page   Packages   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

ClassPath.java

00001 package de.fub.bytecode;
00002 
00003 import java.util.*;
00004 import java.util.zip.*;
00005 import java.io.*;
00006 
00007 /**
00008  * Responsible for loading (class) files from CLASSPATH. Inspired by
00009  * sun.tools.ClassPath.
00010  *
00011  * @version $Id: ClassPath.java,v 1.1.1.1 2002/01/24 03:41:37 pserver Exp $
00012  * @author  <A HREF="http://www.inf.fu-berlin.de/~dahm">M. Dahm</A>
00013  */
00014 public class ClassPath {
00015   private PathEntry[] paths;
00016 
00017   private static abstract class PathEntry {
00018     abstract ClassFile getClassFile(String name, String suffix) throws IOException;
00019   }
00020 
00021   /** Contains information about file/ZIP entry of the Java class.
00022    */
00023   public abstract static class ClassFile {
00024     /** @return input stream for class file.
00025      */
00026     public abstract InputStream getInputStream() throws IOException;
00027 
00028     /** @return canonical path to class file.
00029      */
00030     public abstract String getPath();
00031 
00032     /** @return modification time of class file.
00033      */
00034     public abstract long getTime();
00035 
00036     /** @return size of class file.
00037      */
00038     public abstract long getSize();
00039   }
00040     
00041   private static class Dir extends PathEntry {
00042     private String dir;
00043 
00044     Dir(String d) { dir = d; }
00045 
00046     ClassFile getClassFile(String name, String suffix) throws IOException {
00047       final File file = new File(dir + File.separatorChar +
00048                  name.replace('.', File.separatorChar) + suffix);
00049       
00050       return file.exists()? new ClassFile() {
00051     public InputStream getInputStream() throws IOException { return new FileInputStream(file); }
00052 
00053     public String      getPath()        { try {
00054       return file.getCanonicalPath(); 
00055     } catch(IOException e) { return null; }
00056 
00057     }
00058     public long        getTime()        { return file.lastModified(); }
00059     public long        getSize()        { return file.length(); }
00060       } : null;
00061     }
00062 
00063     public String toString() { return dir; }
00064   }
00065 
00066   private static class Zip extends PathEntry {
00067     private ZipFile zip;
00068 
00069     Zip(ZipFile z) { zip = z; }
00070 
00071     ClassFile getClassFile(String name, String suffix) throws IOException {
00072       final ZipEntry entry = zip.getEntry(name.replace('.', '/') + suffix);
00073 
00074       return (entry != null)? new ClassFile() {
00075     public InputStream getInputStream() throws IOException { return zip.getInputStream(entry); }
00076     public String      getPath()        { return entry.toString(); }
00077     public long        getTime()        { return entry.getTime(); }
00078     public long        getSize()       { return entry.getSize(); }
00079       } : null;
00080     }
00081   }
00082   /**
00083    * Search for classes in CLASSPATH.
00084    */
00085   public ClassPath() {
00086     this(getClassPath());
00087   }  
00088   /**
00089    * Search for classes in given path.
00090    */
00091   public ClassPath(String class_path) {
00092     Vector vec = new Vector();
00093 
00094     for(StringTokenizer tok=new StringTokenizer(class_path,
00095                         System.getProperty("path.separator"));
00096     tok.hasMoreTokens();)
00097     {
00098       String path = tok.nextToken();
00099       
00100       if(!path.equals("")) {
00101     File file = new File(path);
00102 
00103     try {
00104       if(file.exists()) {
00105         if(file.isDirectory())
00106           vec.addElement(new Dir(path));
00107         else
00108           vec.addElement(new Zip(new ZipFile(file)));
00109       }
00110     } catch(IOException e) {
00111       System.err.println("CLASSPATH component " + file + ": " + e);
00112     }
00113       }
00114     }
00115 
00116     paths = new PathEntry[vec.size()];
00117     vec.copyInto(paths);
00118   }  
00119   /**
00120    * @return byte array for class
00121    */
00122   public byte[] getBytes(String name) throws IOException {
00123     return getBytes(name, ".class");
00124   }  
00125   /**
00126    * @param name fully qualified file name, e.g. java/lang/String
00127    * @param suffix file name ends with suffix, e.g. .java
00128    * @return byte array for file on class path
00129    */
00130   public byte[] getBytes(String name, String suffix) throws IOException {
00131     InputStream is = getInputStream(name, suffix);
00132     
00133     if(is == null)
00134       throw new IOException("Couldn't find: " + name + suffix);
00135 
00136     DataInputStream dis   = new DataInputStream(is);
00137     byte[]          bytes = new byte[is.available()];
00138     dis.readFully(bytes);
00139     dis.close(); is.close();
00140 
00141     return bytes;
00142   }  
00143   /**
00144    * @param name fully qualified class name, e.g. java.lang.String
00145    * @return input stream for class
00146    */
00147   public ClassFile getClassFile(String name) throws IOException {
00148     return getClassFile(name, ".class");
00149   }  
00150   /**
00151    * @param name fully qualified file name, e.g. java/lang/String
00152    * @param suffix file name ends with suff, e.g. .java
00153    * @return class file for the java class
00154    */
00155   public ClassFile getClassFile(String name, String suffix) throws IOException {
00156     for(int i=0; i < paths.length; i++) {
00157       ClassFile cf;
00158 
00159       if((cf = paths[i].getClassFile(name, suffix)) != null)
00160     return cf;
00161     }
00162 
00163     throw new IOException("Couldn't find: " + name + suffix);
00164   }  
00165   private static final String getClassPath() {
00166     String class_path = System.getProperty("java.class.path");
00167     String boot_path  = System.getProperty("sun.boot.class.path");
00168     String ext_path   = System.getProperty("java.ext.dirs");
00169 
00170     Vector list = new Vector();
00171 
00172     getPathComponents(class_path, list);
00173     getPathComponents(boot_path, list);
00174 
00175     Vector dirs = new Vector();
00176     getPathComponents(ext_path, dirs);
00177 
00178     for(Enumeration e = dirs.elements(); e.hasMoreElements(); ) {
00179       File     ext_dir     = new File((String)e.nextElement());
00180       String[] extensions = ext_dir.list(new FilenameFilter() {
00181     public boolean accept(File dir, String name) {
00182       return name.endsWith(".zip") || name.endsWith(".jar");
00183     }
00184       });
00185 
00186       if(extensions != null)
00187     for(int i=0; i < extensions.length; i++)
00188       list.addElement(ext_path + File.separatorChar + extensions[i]);
00189     }
00190 
00191     StringBuffer buf = new StringBuffer();
00192 
00193     for(Enumeration e = list.elements(); e.hasMoreElements(); ) {
00194       buf.append((String)e.nextElement());
00195 
00196       if(e.hasMoreElements())
00197     buf.append(File.pathSeparatorChar);
00198     }
00199 
00200     return buf.toString();
00201   }  
00202   /**
00203    * @param name fully qualified class name, e.g. java.lang.String
00204    * @return input stream for class
00205    */
00206   public InputStream getInputStream(String name) throws IOException {
00207     return getInputStream(name, ".class");
00208   }  
00209   /**
00210    * @param name fully qualified file name, e.g. java/lang/String
00211    * @param suffix file name ends with suff, e.g. .java
00212    * @return input stream for file on class path
00213    */
00214   public InputStream getInputStream(String name, String suffix) throws IOException {
00215     return getClassFile(name, suffix).getInputStream();
00216   }  
00217   /**
00218    * @param name name of file to search for, e.g. java/lang/String.java
00219    * @return full (canonical) path for file
00220    */
00221   public String getPath(String name) throws IOException {
00222     int    index  = name.lastIndexOf('.');
00223     String suffix = "";
00224 
00225     if(index > 0) {
00226       suffix = name.substring(index);
00227       name   = name.substring(0, index);
00228     }
00229     
00230     return getPath(name, suffix);
00231   }  
00232   /**
00233    * @param name name of file to search for, e.g. java/lang/String
00234    * @param suffix file name suffix, e.g. .java
00235    * @return full (canonical) path for file, if it exists
00236    */
00237   public String getPath(String name, String suffix) throws IOException {
00238     return getClassFile(name, suffix).getPath();
00239   }  
00240   private static final void getPathComponents(String path, Vector list) {
00241     if(path != null) {
00242       StringTokenizer tok = new StringTokenizer(path, File.pathSeparator);
00243 
00244       while(tok.hasMoreTokens()) {
00245         String name = tok.nextToken();
00246         File   file = new File(name);
00247 
00248     if(file.exists())
00249       list.addElement(name);
00250       }
00251     }
00252   }  
00253 }

Generated at Thu Feb 7 06:42:28 2002 for Bandera by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001