javap/src/main/java/sun/tools/javap/JavapEnvironment.java
author Jaroslav Tulach <jtulach@netbeans.org>
Fri, 09 Nov 2012 21:33:22 +0100
branchjavap
changeset 144 b06660b614db
permissions -rw-r--r--
javap as of revision jdk6-4ab5d66aaf2b
     1 /*
     2  * Copyright (c) 2002, 2006, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    25 
    26 
    27 package sun.tools.javap;
    28 
    29 import java.util.*;
    30 import java.io.*;
    31 import java.util.jar.*;
    32 
    33 
    34 /**
    35  * Strores flag values according to command line options
    36  * and sets path where to find classes.
    37  *
    38  * @author  Sucheta Dambalkar
    39  */
    40 public class JavapEnvironment {
    41 
    42     //Access flags
    43     public static final int PRIVATE = 0;
    44     public static final int PROTECTED  = 1;
    45     public static final int PACKAGE = 2;
    46     public static final int PUBLIC  = 3;
    47 
    48     //search path flags.
    49     private static final int start = 0;
    50     private static final int  cmdboot= 1;
    51     private static final int sunboot = 2;
    52     private static final int  javaclass= 3;
    53     private static final int  cmdextdir= 4;
    54     private static final int  javaext= 5;
    55     private static final int  cmdclasspath= 6;
    56     private static final int  envclasspath= 7;
    57     private static final int  javaclasspath= 8;
    58     private static final int  currentdir = 9;
    59 
    60 
    61     // JavapEnvironment flag settings
    62     boolean showLineAndLocal = false;
    63     int showAccess = PACKAGE;
    64     boolean showDisassembled = false;
    65     boolean showVerbose = false;
    66     boolean showInternalSigs = false;
    67     String classPathString = null;
    68     String bootClassPathString = null;
    69     String extDirsString = null;
    70     boolean extDirflag = false;
    71     boolean nothingToDo = true;
    72     boolean showallAttr = false;
    73     String classpath = null;
    74     int searchpath = start;
    75 
    76     /**
    77      *  According to which flags are set,
    78      *  returns file input stream for classfile to disassemble.
    79      */
    80 
    81     public InputStream getFileInputStream(String Name){
    82         InputStream fileInStream = null;
    83         searchpath = cmdboot;
    84         try{
    85             if(searchpath == cmdboot){
    86                 if(bootClassPathString != null){
    87                     //search in specified bootclasspath.
    88                     classpath = bootClassPathString;
    89                     if((fileInStream = resolvefilename(Name)) != null) return fileInStream;
    90                     //no classes found in search path.
    91                     else searchpath = cmdextdir;
    92                 }
    93                 else searchpath = sunboot;
    94             }
    95 
    96             if(searchpath == sunboot){
    97                 if(System.getProperty("sun.boot.class.path") != null){
    98                     //search in sun.boot.class.path
    99                     classpath = System.getProperty("sun.boot.class.path");
   100                     if((fileInStream = resolvefilename(Name)) != null) return fileInStream;
   101                     //no classes found in search path
   102                     else searchpath = cmdextdir;
   103                 }
   104                 else searchpath = javaclass;
   105             }
   106 
   107             if(searchpath == javaclass){
   108                 if(System.getProperty("java.class.path") != null){
   109                     //search in java.class.path
   110                     classpath =System.getProperty("java.class.path");
   111                     if((fileInStream = resolvefilename(Name)) != null) return fileInStream;
   112                     //no classes found in search path
   113                     else searchpath = cmdextdir;
   114                 }
   115                 else searchpath = cmdextdir;
   116             }
   117 
   118             if(searchpath == cmdextdir){
   119                 if(extDirsString != null){
   120                     //search in specified extdir.
   121                     classpath = extDirsString;
   122                     extDirflag = true;
   123                     if((fileInStream = resolvefilename(Name)) != null) return fileInStream;
   124                     //no classes found in search path
   125                     else {
   126                         searchpath = cmdclasspath;
   127                         extDirflag = false;
   128                     }
   129                 }
   130                 else searchpath = javaext;
   131             }
   132 
   133             if(searchpath == javaext){
   134                 if(System.getProperty("java.ext.dirs") != null){
   135                     //search in java.ext.dirs
   136                     classpath = System.getProperty("java.ext.dirs");
   137                     extDirflag = true;
   138                     if((fileInStream = resolvefilename(Name)) != null) return fileInStream;
   139                     //no classes found in search path
   140                     else {
   141                         searchpath = cmdclasspath;
   142                         extDirflag = false;
   143                     }
   144                 }
   145                 else searchpath = cmdclasspath;
   146             }
   147             if(searchpath == cmdclasspath){
   148                 if(classPathString != null){
   149                     //search in specified classpath.
   150                     classpath = classPathString;
   151                     if((fileInStream = resolvefilename(Name)) != null) return fileInStream;
   152                     //no classes found in search path
   153                     else searchpath = 8;
   154                 }
   155                 else searchpath = envclasspath;
   156             }
   157 
   158             if(searchpath == envclasspath){
   159                 if(System.getProperty("env.class.path")!= null){
   160                     //search in env.class.path
   161                     classpath = System.getProperty("env.class.path");
   162                     if((fileInStream = resolvefilename(Name)) != null) return fileInStream;
   163                     //no classes found in search path.
   164                     else searchpath = javaclasspath;
   165                 }
   166                 else searchpath = javaclasspath;
   167             }
   168 
   169             if(searchpath == javaclasspath){
   170                 if(("application.home") == null){
   171                     //search in java.class.path
   172                     classpath = System.getProperty("java.class.path");
   173                     if((fileInStream = resolvefilename(Name)) != null) return fileInStream;
   174                     //no classes found in search path.
   175                     else searchpath = currentdir;
   176                 }
   177                 else searchpath = currentdir;
   178             }
   179 
   180             if(searchpath == currentdir){
   181                 classpath = ".";
   182                 //search in current dir.
   183                 if((fileInStream = resolvefilename(Name)) != null) return fileInStream;
   184                 else {
   185                     //no classes found in search path.
   186                     error("Could not find "+ Name);
   187                     System.exit(1);
   188                 }
   189             }
   190         }catch(SecurityException excsec){
   191             excsec.printStackTrace();
   192             error("fatal exception");
   193         }catch(NullPointerException excnull){
   194             excnull.printStackTrace();
   195             error("fatal exception");
   196         }catch(IllegalArgumentException excill){
   197             excill.printStackTrace();
   198             error("fatal exception");
   199         }
   200 
   201         return null;
   202     }
   203 
   204 
   205     public void error(String msg) {
   206         System.err.println("ERROR:" +msg);
   207     }
   208 
   209     /**
   210      * Resolves file name for classfile to disassemble.
   211      */
   212     public InputStream resolvefilename(String name){
   213         String classname = name.replace('.', '/') + ".class";
   214         while (true) {
   215             InputStream instream = extDirflag
   216                 ? resolveExdirFilename(classname)
   217                 : resolveclasspath(classname);
   218             if (instream != null)
   219                 return instream;
   220             int lastindex = classname.lastIndexOf('/');
   221             if (lastindex == -1) return null;
   222             classname = classname.substring(0, lastindex) + "$" +
   223                 classname.substring(lastindex + 1);
   224         }
   225     }
   226 
   227     /**
   228      * Resolves file name for classfile to disassemble if flag exdir is set.
   229      */
   230     public InputStream resolveExdirFilename(String classname){
   231         if(classpath.indexOf(File.pathSeparator) != -1){
   232             //separates path
   233             StringTokenizer st = new StringTokenizer(classpath, File.pathSeparator);
   234             while(st.hasMoreTokens()){
   235                 String path = st.nextToken();
   236                 InputStream in = resolveExdirFilenamehelper(path, classname);
   237                 if (in != null)
   238                     return in;
   239             }
   240         }else return (resolveExdirFilenamehelper(classpath, classname));
   241 
   242         return null;
   243     }
   244 
   245     /**
   246      * Resolves file name for classfile to disassemble.
   247      */
   248     public InputStream resolveclasspath(String classname){
   249         if(classpath.indexOf(File.pathSeparator) != -1){
   250             StringTokenizer st = new StringTokenizer(classpath, File.pathSeparator);
   251             //separates path.
   252             while(st.hasMoreTokens()){
   253                 String path = (st.nextToken()).trim();
   254                 InputStream in = resolveclasspathhelper(path, classname);
   255                 if(in != null) return in;
   256 
   257             }
   258             return null;
   259         }
   260         else return (resolveclasspathhelper(classpath, classname));
   261     }
   262 
   263 
   264     /**
   265      * Returns file input stream for classfile to disassemble if exdir is set.
   266      */
   267     public InputStream resolveExdirFilenamehelper(String path, String classname){
   268         File fileobj = new File(path);
   269         if(fileobj.isDirectory()){
   270             // gets list of files in that directory.
   271             File[] filelist = fileobj.listFiles();
   272             for(int i = 0; i < filelist.length; i++){
   273                 try{
   274                     //file is a jar file.
   275                     if(filelist[i].toString().endsWith(".jar")){
   276                         JarFile jfile = new JarFile(filelist[i]);
   277                         if((jfile.getEntry(classname)) != null){
   278 
   279                             InputStream filein = jfile.getInputStream(jfile.getEntry(classname));
   280                             int bytearraysize = filein.available();
   281                             byte []b =  new byte[bytearraysize];
   282                             int totalread = 0;
   283                             while(totalread < bytearraysize){
   284                                 totalread += filein.read(b, totalread, bytearraysize-totalread);
   285                             }
   286                             InputStream inbyte = new ByteArrayInputStream(b);
   287                             filein.close();
   288                             return inbyte;
   289                         }
   290                     } else {
   291                         //not a jar file.
   292                         String filename = path+"/"+ classname;
   293                         File file = new File(filename);
   294                         if(file.isFile()){
   295                             return (new FileInputStream(file));
   296                         }
   297                     }
   298                 }catch(FileNotFoundException fnexce){
   299                     fnexce.printStackTrace();
   300                     error("cant read file");
   301                     error("fatal exception");
   302                 }catch(IOException ioexc){
   303                     ioexc.printStackTrace();
   304                     error("fatal exception");
   305                 }
   306             }
   307         }
   308 
   309         return null;
   310     }
   311 
   312 
   313     /**
   314      * Returns file input stream for classfile to disassemble.
   315      */
   316     public InputStream resolveclasspathhelper(String path, String classname){
   317         File fileobj = new File(path);
   318         try{
   319             if(fileobj.isDirectory()){
   320                 //is a directory.
   321                 String filename = path+"/"+ classname;
   322                 File file = new File(filename);
   323                 if(file.isFile()){
   324                     return (new FileInputStream(file));
   325                 }
   326 
   327             }else if(fileobj.isFile()){
   328                 if(fileobj.toString().endsWith(".jar")){
   329                     //is a jar file.
   330                     JarFile jfile = new JarFile(fileobj);
   331                     if((jfile.getEntry(classname)) != null){
   332                         InputStream filein = jfile.getInputStream(jfile.getEntry(classname));
   333                         int bytearraysize = filein.available();
   334                         byte []b =  new byte[bytearraysize];
   335                         int totalread = 0;
   336                         while(totalread < bytearraysize){
   337                                 totalread += filein.read(b, totalread, bytearraysize-totalread);
   338                         }
   339                         InputStream inbyte = new ByteArrayInputStream(b);
   340                         filein.close();
   341                          return inbyte;
   342                     }
   343                 }
   344             }
   345         }catch(FileNotFoundException fnexce){
   346             fnexce.printStackTrace();
   347             error("cant read file");
   348             error("fatal exception");
   349         }catch(IOException ioexce){
   350             ioexce.printStackTrace();
   351             error("fatal exception");
   352         }
   353         return null;
   354     }
   355 }