001 /*
002 * Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026
027 package sun.tools.javap;
028
029 import java.util.*;
030 import java.io.*;
031 import java.util.jar.*;
032
033
034 /**
035 * Strores flag values according to command line options
036 * and sets path where to find classes.
037 *
038 * @author Sucheta Dambalkar
039 */
040 public class JavapEnvironment {
041
042 //Access flags
043 public static final int PRIVATE = 0;
044 public static final int PROTECTED = 1;
045 public static final int PACKAGE = 2;
046 public static final int PUBLIC = 3;
047
048 //search path flags.
049 private static final int start = 0;
050 private static final int cmdboot= 1;
051 private static final int sunboot = 2;
052 private static final int javaclass= 3;
053 private static final int cmdextdir= 4;
054 private static final int javaext= 5;
055 private static final int cmdclasspath= 6;
056 private static final int envclasspath= 7;
057 private static final int javaclasspath= 8;
058 private static final int currentdir = 9;
059
060
061 // JavapEnvironment flag settings
062 boolean showLineAndLocal = false;
063 int showAccess = PACKAGE;
064 boolean showDisassembled = false;
065 boolean showVerbose = false;
066 boolean showInternalSigs = false;
067 String classPathString = null;
068 String bootClassPathString = null;
069 String extDirsString = null;
070 boolean extDirflag = false;
071 boolean nothingToDo = true;
072 boolean showallAttr = false;
073 String classpath = null;
074 int searchpath = start;
075
076 /**
077 * According to which flags are set,
078 * returns file input stream for classfile to disassemble.
079 */
080
081 public InputStream getFileInputStream(String Name){
082 InputStream fileInStream = null;
083 searchpath = cmdboot;
084 try{
085 if(searchpath == cmdboot){
086 if(bootClassPathString != null){
087 //search in specified bootclasspath.
088 classpath = bootClassPathString;
089 if((fileInStream = resolvefilename(Name)) != null) return fileInStream;
090 //no classes found in search path.
091 else searchpath = cmdextdir;
092 }
093 else searchpath = sunboot;
094 }
095
096 if(searchpath == sunboot){
097 if(System.getProperty("sun.boot.class.path") != null){
098 //search in sun.boot.class.path
099 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 }