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