    View Javadoc
    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