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: package sun.tools.javap;
027:
028: import java.util.*;
029: import java.io.*;
030: import java.util.jar.*;
031:
032: /**
033: * Strores flag values according to command line options
034: * and sets path where to find classes.
035: *
036: * @author Sucheta Dambalkar
037: */
038: public class JavapEnvironment {
039:
040: //Access flags
041: public static final int PRIVATE = 0;
042: public static final int PROTECTED = 1;
043: public static final int PACKAGE = 2;
044: public static final int PUBLIC = 3;
045:
046: //search path flags.
047: private static final int start = 0;
048: private static final int cmdboot = 1;
049: private static final int sunboot = 2;
050: private static final int javaclass = 3;
051: private static final int cmdextdir = 4;
052: private static final int javaext = 5;
053: private static final int cmdclasspath = 6;
054: private static final int envclasspath = 7;
055: private static final int javaclasspath = 8;
056: private static final int currentdir = 9;
057:
058: // JavapEnvironment flag settings
059: boolean showLineAndLocal = false;
060: int showAccess = PACKAGE;
061: boolean showDisassembled = false;
062: boolean showVerbose = false;
063: boolean showInternalSigs = false;
064: String classPathString = null;
065: String bootClassPathString = null;
066: String extDirsString = null;
067: boolean extDirflag = false;
068: boolean nothingToDo = true;
069: boolean showallAttr = false;
070: String classpath = null;
071: int searchpath = start;
072:
073: /**
074: * According to which flags are set,
075: * returns file input stream for classfile to disassemble.
076: */
077:
078: public InputStream getFileInputStream(String Name) {
079: InputStream fileInStream = null;
080: searchpath = cmdboot;
081: try {
082: if (searchpath == cmdboot) {
083: if (bootClassPathString != null) {
084: //search in specified bootclasspath.
085: classpath = bootClassPathString;
086: if ((fileInStream = resolvefilename(Name)) != null)
087: return fileInStream;
088: //no classes found in search path.
089: else
090: searchpath = cmdextdir;
091: } else
092: searchpath = sunboot;
093: }
094:
095: if (searchpath == sunboot) {
096: if (System.getProperty("sun.boot.class.path") != null) {
097: //search in sun.boot.class.path
098: classpath = System
099: .getProperty("sun.boot.class.path");
100: if ((fileInStream = resolvefilename(Name)) != null)
101: return fileInStream;
102: //no classes found in search path
103: else
104: searchpath = cmdextdir;
105: } else
106: searchpath = javaclass;
107: }
108:
109: if (searchpath == javaclass) {
110: if (System.getProperty("java.class.path") != null) {
111: //search in java.class.path
112: classpath = System.getProperty("java.class.path");
113: if ((fileInStream = resolvefilename(Name)) != null)
114: return fileInStream;
115: //no classes found in search path
116: else
117: searchpath = cmdextdir;
118: } else
119: searchpath = cmdextdir;
120: }
121:
122: if (searchpath == cmdextdir) {
123: if (extDirsString != null) {
124: //search in specified extdir.
125: classpath = extDirsString;
126: extDirflag = true;
127: if ((fileInStream = resolvefilename(Name)) != null)
128: return fileInStream;
129: //no classes found in search path
130: else {
131: searchpath = cmdclasspath;
132: extDirflag = false;
133: }
134: } else
135: searchpath = javaext;
136: }
137:
138: if (searchpath == javaext) {
139: if (System.getProperty("java.ext.dirs") != null) {
140: //search in java.ext.dirs
141: classpath = System.getProperty("java.ext.dirs");
142: extDirflag = true;
143: if ((fileInStream = resolvefilename(Name)) != null)
144: return fileInStream;
145: //no classes found in search path
146: else {
147: searchpath = cmdclasspath;
148: extDirflag = false;
149: }
150: } else
151: searchpath = cmdclasspath;
152: }
153: if (searchpath == cmdclasspath) {
154: if (classPathString != null) {
155: //search in specified classpath.
156: classpath = classPathString;
157: if ((fileInStream = resolvefilename(Name)) != null)
158: return fileInStream;
159: //no classes found in search path
160: else
161: searchpath = 8;
162: } else
163: searchpath = envclasspath;
164: }
165:
166: if (searchpath == envclasspath) {
167: if (System.getProperty("env.class.path") != null) {
168: //search in env.class.path
169: classpath = System.getProperty("env.class.path");
170: if ((fileInStream = resolvefilename(Name)) != null)
171: return fileInStream;
172: //no classes found in search path.
173: else
174: searchpath = javaclasspath;
175: } else
176: searchpath = javaclasspath;
177: }
178:
179: if (searchpath == javaclasspath) {
180: if (("application.home") == null) {
181: //search in java.class.path
182: classpath = System.getProperty("java.class.path");
183: if ((fileInStream = resolvefilename(Name)) != null)
184: return fileInStream;
185: //no classes found in search path.
186: else
187: searchpath = currentdir;
188: } else
189: searchpath = currentdir;
190: }
191:
192: if (searchpath == currentdir) {
193: classpath = ".";
194: //search in current dir.
195: if ((fileInStream = resolvefilename(Name)) != null)
196: return fileInStream;
197: else {
198: //no classes found in search path.
199: error("Could not find " + Name);
200: System.exit(1);
201: }
202: }
203: } catch (SecurityException excsec) {
204: excsec.printStackTrace();
205: error("fatal exception");
206: } catch (NullPointerException excnull) {
207: excnull.printStackTrace();
208: error("fatal exception");
209: } catch (IllegalArgumentException excill) {
210: excill.printStackTrace();
211: error("fatal exception");
212: }
213:
214: return null;
215: }
216:
217: public void error(String msg) {
218: System.err.println("ERROR:" + msg);
219: }
220:
221: /**
222: * Resolves file name for classfile to disassemble.
223: */
224: public InputStream resolvefilename(String name) {
225: String classname = name.replace('.', '/') + ".class";
226: while (true) {
227: InputStream instream = extDirflag ? resolveExdirFilename(classname)
228: : resolveclasspath(classname);
229: if (instream != null)
230: return instream;
231: int lastindex = classname.lastIndexOf('/');
232: if (lastindex == -1)
233: return null;
234: classname = classname.substring(0, lastindex) + "$"
235: + classname.substring(lastindex + 1);
236: }
237: }
238:
239: /**
240: * Resolves file name for classfile to disassemble if flag exdir is set.
241: */
242: public InputStream resolveExdirFilename(String classname) {
243: if (classpath.indexOf(File.pathSeparator) != -1) {
244: //separates path
245: StringTokenizer st = new StringTokenizer(classpath,
246: File.pathSeparator);
247: while (st.hasMoreTokens()) {
248: String path = st.nextToken();
249: InputStream in = resolveExdirFilenamehelper(path,
250: classname);
251: if (in != null)
252: return in;
253: }
254: } else
255: return (resolveExdirFilenamehelper(classpath, classname));
256:
257: return null;
258: }
259:
260: /**
261: * Resolves file name for classfile to disassemble.
262: */
263: public InputStream resolveclasspath(String classname) {
264: if (classpath.indexOf(File.pathSeparator) != -1) {
265: StringTokenizer st = new StringTokenizer(classpath,
266: File.pathSeparator);
267: //separates path.
268: while (st.hasMoreTokens()) {
269: String path = (st.nextToken()).trim();
270: InputStream in = resolveclasspathhelper(path, classname);
271: if (in != null)
272: return in;
273:
274: }
275: return null;
276: } else
277: return (resolveclasspathhelper(classpath, classname));
278: }
279:
280: /**
281: * Returns file input stream for classfile to disassemble if exdir is set.
282: */
283: public InputStream resolveExdirFilenamehelper(String path,
284: String classname) {
285: File fileobj = new File(path);
286: if (fileobj.isDirectory()) {
287: // gets list of files in that directory.
288: File[] filelist = fileobj.listFiles();
289: for (int i = 0; i < filelist.length; i++) {
290: try {
291: //file is a jar file.
292: if (filelist[i].toString().endsWith(".jar")) {
293: JarFile jfile = new JarFile(filelist[i]);
294: if ((jfile.getEntry(classname)) != null) {
295:
296: InputStream filein = jfile
297: .getInputStream(jfile
298: .getEntry(classname));
299: int bytearraysize = filein.available();
300: byte[] b = new byte[bytearraysize];
301: int totalread = 0;
302: while (totalread < bytearraysize) {
303: totalread += filein.read(b, totalread,
304: bytearraysize - totalread);
305: }
306: InputStream inbyte = new ByteArrayInputStream(
307: b);
308: filein.close();
309: return inbyte;
310: }
311: } else {
312: //not a jar file.
313: String filename = path + "/" + classname;
314: File file = new File(filename);
315: if (file.isFile()) {
316: return (new FileInputStream(file));
317: }
318: }
319: } catch (FileNotFoundException fnexce) {
320: fnexce.printStackTrace();
321: error("cant read file");
322: error("fatal exception");
323: } catch (IOException ioexc) {
324: ioexc.printStackTrace();
325: error("fatal exception");
326: }
327: }
328: }
329:
330: return null;
331: }
332:
333: /**
334: * Returns file input stream for classfile to disassemble.
335: */
336: public InputStream resolveclasspathhelper(String path,
337: String classname) {
338: File fileobj = new File(path);
339: try {
340: if (fileobj.isDirectory()) {
341: //is a directory.
342: String filename = path + "/" + classname;
343: File file = new File(filename);
344: if (file.isFile()) {
345: return (new FileInputStream(file));
346: }
347:
348: } else if (fileobj.isFile()) {
349: if (fileobj.toString().endsWith(".jar")) {
350: //is a jar file.
351: JarFile jfile = new JarFile(fileobj);
352: if ((jfile.getEntry(classname)) != null) {
353: InputStream filein = jfile.getInputStream(jfile
354: .getEntry(classname));
355: int bytearraysize = filein.available();
356: byte[] b = new byte[bytearraysize];
357: int totalread = 0;
358: while (totalread < bytearraysize) {
359: totalread += filein.read(b, totalread,
360: bytearraysize - totalread);
361: }
362: InputStream inbyte = new ByteArrayInputStream(b);
363: filein.close();
364: return inbyte;
365: }
366: }
367: }
368: } catch (FileNotFoundException fnexce) {
369: fnexce.printStackTrace();
370: error("cant read file");
371: error("fatal exception");
372: } catch (IOException ioexce) {
373: ioexce.printStackTrace();
374: error("fatal exception");
375: }
376: return null;
377: }
378: }
|