00001 package de.fub.bytecode;
00002
00003 import java.util.*;
00004 import java.util.zip.*;
00005 import java.io.*;
00006
00007
00008
00009
00010
00011
00012
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
00022
00023 public abstract static class ClassFile {
00024
00025
00026 public abstract InputStream getInputStream() throws IOException;
00027
00028
00029
00030 public abstract String getPath();
00031
00032
00033
00034 public abstract long getTime();
00035
00036
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
00084
00085 public ClassPath() {
00086 this(getClassPath());
00087 }
00088
00089
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
00121
00122 public byte[] getBytes(String name) throws IOException {
00123 return getBytes(name, ".class");
00124 }
00125
00126
00127
00128
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
00145
00146
00147 public ClassFile getClassFile(String name) throws IOException {
00148 return getClassFile(name, ".class");
00149 }
00150
00151
00152
00153
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
00204
00205
00206 public InputStream getInputStream(String name) throws IOException {
00207 return getInputStream(name, ".class");
00208 }
00209
00210
00211
00212
00213
00214 public InputStream getInputStream(String name, String suffix) throws IOException {
00215 return getClassFile(name, suffix).getInputStream();
00216 }
00217
00218
00219
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
00234
00235
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 }