1   package org.apache.bcel.util;
2   
3   /* ====================================================================
4    * The Apache Software License, Version 1.1
5    *
6    * Copyright (c) 2001 The Apache Software Foundation.  All rights
7    * reserved.
8    *
9    * Redistribution and use in source and binary forms, with or without
10   * modification, are permitted provided that the following conditions
11   * are met:
12   *
13   * 1. Redistributions of source code must retain the above copyright
14   *    notice, this list of conditions and the following disclaimer.
15   *
16   * 2. Redistributions in binary form must reproduce the above copyright
17   *    notice, this list of conditions and the following disclaimer in
18   *    the documentation and/or other materials provided with the
19   *    distribution.
20   *
21   * 3. The end-user documentation included with the redistribution,
22   *    if any, must include the following acknowledgment:
23   *       "This product includes software developed by the
24   *        Apache Software Foundation (http://www.apache.org/)."
25   *    Alternately, this acknowledgment may appear in the software itself,
26   *    if and wherever such third-party acknowledgments normally appear.
27   *
28   * 4. The names "Apache" and "Apache Software Foundation" and
29   *    "Apache BCEL" must not be used to endorse or promote products
30   *    derived from this software without prior written permission. For
31   *    written permission, please contact apache@apache.org.
32   *
33   * 5. Products derived from this software may not be called "Apache",
34   *    "Apache BCEL", nor may "Apache" appear in their name, without
35   *    prior written permission of the Apache Software Foundation.
36   *
37   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48   * SUCH DAMAGE.
49   * ====================================================================
50   *
51   * This software consists of voluntary contributions made by many
52   * individuals on behalf of the Apache Software Foundation.  For more
53   * information on the Apache Software Foundation, please see
54   * <http://www.apache.org/>.
55   */
56  
57  import java.util.*;
58  import java.util.zip.*;
59  import java.io.*;
60  
61  /***
62   * Responsible for loading (class) files from the CLASSPATH. Inspired by
63   * sun.tools.ClassPath.
64   *
65   * @version $Id: ClassPath.java,v 1.7 2002/11/10 18:30:05 mdahm Exp $
66   * @author  <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
67   */
68  public class ClassPath implements Serializable {
69    public static final ClassPath SYSTEM_CLASS_PATH = new ClassPath();
70  
71    private PathEntry[] paths;
72    private String      class_path;
73  
74    /***
75     * Search for classes in given path.
76     */
77    public ClassPath(String class_path) {
78      this.class_path = class_path;
79  
80      ArrayList vec = new ArrayList();
81  
82      for(StringTokenizer tok=new StringTokenizer(class_path,
83  						System.getProperty("path.separator"));
84  	tok.hasMoreTokens();)
85      {
86        String path = tok.nextToken();
87        
88        if(!path.equals("")) {
89  	File file = new File(path);
90  
91  	try {
92  	  if(file.exists()) {
93  	    if(file.isDirectory())
94  	      vec.add(new Dir(path));
95  	    else
96  	      vec.add(new Zip(new ZipFile(file)));
97  	  }
98  	} catch(IOException e) {
99  	  System.err.println("CLASSPATH component " + file + ": " + e);
100 	}
101       }
102     }
103 
104     paths = new PathEntry[vec.size()];
105     vec.toArray(paths);
106   }
107 
108   /***
109    * Search for classes in CLASSPATH.
110    * @deprecated Use SYSTEM_CLASS_PATH constant
111    */
112   public ClassPath() {
113     this(getClassPath());
114   }
115 
116   /*** @return used class path string
117    */
118   public String toString() {
119     return class_path;
120   }
121   
122   public int hashCode() {
123     return class_path.hashCode();
124   }
125 
126   public boolean equals(Object o) {
127     if(o instanceof ClassPath) {
128       return class_path.equals(((ClassPath)o).class_path);
129     }
130 
131     return false;
132   }
133 
134   private static final void getPathComponents(String path, ArrayList list) {
135     if(path != null) {
136       StringTokenizer tok = new StringTokenizer(path, File.pathSeparator);
137 
138       while(tok.hasMoreTokens()) {
139         String name = tok.nextToken();
140         File   file = new File(name);
141 
142 	if(file.exists())
143 	  list.add(name);
144       }
145     }
146   }
147 
148   /*** Checks for class path components in the following properties:
149    * "java.class.path", "sun.boot.class.path", "java.ext.dirs"
150    *
151    * @return class path as used by default by BCEL
152    */
153   public static final String getClassPath() {
154     String class_path = System.getProperty("java.class.path");
155     String boot_path  = System.getProperty("sun.boot.class.path");
156     String ext_path   = System.getProperty("java.ext.dirs");
157 
158     ArrayList list = new ArrayList();
159 
160     getPathComponents(class_path, list);
161     getPathComponents(boot_path, list);
162 
163     ArrayList dirs = new ArrayList();
164     getPathComponents(ext_path, dirs);
165 
166     for(Iterator e = dirs.iterator(); e.hasNext(); ) {
167       File     ext_dir    = new File((String)e.next());
168       String[] extensions = ext_dir.list(new FilenameFilter() {
169 	public boolean accept(File dir, String name) {
170 	  name = name.toLowerCase();
171 	  return name.endsWith(".zip") || name.endsWith(".jar");
172 	}
173       });
174 
175       if(extensions != null)
176 	for(int i=0; i < extensions.length; i++)
177 	  list.add(ext_path + File.separatorChar + extensions[i]);
178     }
179 
180     StringBuffer buf = new StringBuffer();
181 
182     for(Iterator e = list.iterator(); e.hasNext(); ) {
183       buf.append((String)e.next());
184 
185       if(e.hasNext())
186 	buf.append(File.pathSeparatorChar);
187     }
188 
189     return buf.toString().intern();
190   }
191 
192   /***
193    * @param name fully qualified class name, e.g. java.lang.String
194    * @return input stream for class
195    */
196   public InputStream getInputStream(String name) throws IOException {
197     return getInputStream(name, ".class");
198   }
199     
200   /***
201    * Return stream for class or resource on CLASSPATH.
202    *
203    * @param name fully qualified file name, e.g. java/lang/String
204    * @param suffix file name ends with suff, e.g. .java
205    * @return input stream for file on class path
206    */
207   public InputStream getInputStream(String name, String suffix) throws IOException {
208     InputStream is = null;
209 
210     try {
211       is = getClass().getClassLoader().getResourceAsStream(name + suffix);
212     } catch(Exception e) { }
213 
214     if(is != null)
215       return is;
216     
217     return getClassFile(name, suffix).getInputStream();
218   }
219 
220   /***
221    * @param name fully qualified file name, e.g. java/lang/String
222    * @param suffix file name ends with suff, e.g. .java
223    * @return class file for the java class
224    */
225   public ClassFile getClassFile(String name, String suffix) throws IOException {
226     for(int i=0; i < paths.length; i++) {
227       ClassFile cf;
228 
229       if((cf = paths[i].getClassFile(name, suffix)) != null)
230 	return cf;
231     }
232 
233     throw new IOException("Couldn't find: " + name + suffix);
234   }
235 
236   /***
237    * @param name fully qualified class name, e.g. java.lang.String
238    * @return input stream for class
239    */
240   public ClassFile getClassFile(String name) throws IOException {
241     return getClassFile(name, ".class");
242   }
243 
244   /***
245    * @param name fully qualified file name, e.g. java/lang/String
246    * @param suffix file name ends with suffix, e.g. .java
247    * @return byte array for file on class path
248    */
249   public byte[] getBytes(String name, String suffix) throws IOException {
250     InputStream is = getInputStream(name, suffix);
251     
252     if(is == null)
253       throw new IOException("Couldn't find: " + name + suffix);
254 
255     DataInputStream dis   = new DataInputStream(is);
256     byte[]          bytes = new byte[is.available()];
257     dis.readFully(bytes);
258     dis.close(); is.close();
259 
260     return bytes;
261   }
262 
263   /***
264    * @return byte array for class
265    */
266   public byte[] getBytes(String name) throws IOException {
267     return getBytes(name, ".class");
268   }
269 
270   /***
271    * @param name name of file to search for, e.g. java/lang/String.java
272    * @return full (canonical) path for file
273    */
274   public String getPath(String name) throws IOException {
275     int    index  = name.lastIndexOf('.');
276     String suffix = "";
277 
278     if(index > 0) {
279       suffix = name.substring(index);
280       name   = name.substring(0, index);
281     }
282     
283     return getPath(name, suffix);
284   }
285 
286   /***
287    * @param name name of file to search for, e.g. java/lang/String
288    * @param suffix file name suffix, e.g. .java
289    * @return full (canonical) path for file, if it exists
290    */
291   public String getPath(String name, String suffix) throws IOException {
292     return getClassFile(name, suffix).getPath();
293   }
294 
295   private static abstract class PathEntry implements Serializable {
296     abstract ClassFile getClassFile(String name, String suffix) throws IOException;
297   }
298 
299   /*** Contains information about file/ZIP entry of the Java class.
300    */
301   public interface ClassFile {
302     /*** @return input stream for class file.
303      */
304     public abstract InputStream getInputStream() throws IOException;
305 
306     /*** @return canonical path to class file.
307      */
308     public abstract String getPath();
309 
310     /*** @return base path of found class, i.e. class is contained relative
311      * to that path, which may either denote a directory, or zip file
312      */
313     public abstract String getBase();
314 
315     /*** @return modification time of class file.
316      */
317     public abstract long getTime();
318 
319     /*** @return size of class file.
320      */
321     public abstract long getSize();
322   }
323     
324   private static class Dir extends PathEntry {
325     private String dir;
326 
327     Dir(String d) { dir = d; }
328 
329     ClassFile getClassFile(String name, String suffix) throws IOException {
330       final File file = new File(dir + File.separatorChar +
331 				 name.replace('.', File.separatorChar) + suffix);
332       
333       return file.exists()? new ClassFile() {
334 	public InputStream getInputStream() throws IOException { return new FileInputStream(file); }
335 
336 	public String      getPath()        { try {
337 	  return file.getCanonicalPath(); 
338 	} catch(IOException e) { return null; }
339 
340 	}
341 	public long        getTime()        { return file.lastModified(); }
342 	public long        getSize()        { return file.length(); }
343         public String getBase() {  return dir;  }
344 
345       } : null;
346     }
347 
348     public String toString() { return dir; }
349   }
350 
351   private static class Zip extends PathEntry {
352     private ZipFile zip;
353 
354     Zip(ZipFile z) { zip = z; }
355 
356     ClassFile getClassFile(String name, String suffix) throws IOException {
357       final ZipEntry entry = zip.getEntry(name.replace('.', '/') + suffix);
358 
359       return (entry != null)? new ClassFile() {
360 	public InputStream getInputStream() throws IOException { return zip.getInputStream(entry); }
361 	public String      getPath()        { return entry.toString(); }
362 	public long        getTime()        { return entry.getTime(); }
363 	public long        getSize()       { return entry.getSize(); }
364         public String getBase() {
365 	  return zip.getName();
366 	}
367       } : null;
368     }
369   }
370 }
371 
372 
This page was automatically generated by Maven