001 /* StackTraceElement.java -- One function call or call stack element 002 Copyright (C) 2001, 2002, 2004, 2005, 2006 Free Software Foundation, Inc. 003 004 This file is part of GNU Classpath. 005 006 GNU Classpath is free software; you can redistribute it and/or modify 007 it under the terms of the GNU General Public License as published by 008 the Free Software Foundation; either version 2, or (at your option) 009 any later version. 010 011 GNU Classpath is distributed in the hope that it will be useful, but 012 WITHOUT ANY WARRANTY; without even the implied warranty of 013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 General Public License for more details. 015 016 You should have received a copy of the GNU General Public License 017 along with GNU Classpath; see the file COPYING. If not, write to the 018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 019 02110-1301 USA. 020 021 Linking this library statically or dynamically with other modules is 022 making a combined work based on this library. Thus, the terms and 023 conditions of the GNU General Public License cover the whole 024 combination. 025 026 As a special exception, the copyright holders of this library give you 027 permission to link this library with independent modules to produce an 028 executable, regardless of the license terms of these independent 029 modules, and to copy and distribute the resulting executable under 030 terms of your choice, provided that you also meet, for each linked 031 independent module, the terms and conditions of the license of that 032 module. An independent module is a module which is not derived from 033 or based on this library. If you modify this library, you may extend 034 this exception to your version of the library, but you are not 035 obligated to do so. If you do not wish to do so, delete this 036 exception statement from your version. */ 037 038 039 package java.lang; 040 041 import java.io.Serializable; 042 043 /** 044 * One function call or stack trace element. Gives information about 045 * the execution point such as the source file name, the line number, 046 * the fully qualified class name, the method name and whether this method 047 * is native, if this information is known. 048 * 049 * @author Mark Wielaard (mark@klomp.org) 050 * @author Eric Blake (ebb9@email.byu.edu) 051 * @since 1.4 052 * @status updated to 1.5 053 */ 054 public final class StackTraceElement implements Serializable 055 { 056 /** 057 * Compatible with JDK 1.4+. 058 */ 059 private static final long serialVersionUID = 6992337162326171013L; 060 061 /** 062 * The name of the file, null if unknown. 063 * 064 * @serial the source code filename, if known 065 */ 066 private final String fileName; 067 068 /** 069 * The line number in the file, negative if unknown. 070 * 071 * @serial the source code line number, if known 072 */ 073 private final int lineNumber; 074 075 /** 076 * The fully qualified class name, null if unknown. 077 * 078 * @serial the enclosing class, if known 079 */ 080 private final String declaringClass; 081 082 /** 083 * The method name in the class, null if unknown. 084 * 085 * @serial the enclosing method, if known 086 */ 087 private final String methodName; 088 089 /** Whether the method is native. */ 090 private final transient boolean isNative; 091 092 /** 093 * A package local constructor for the StackTraceElement class, to be 094 * called by the Virtual Machine as part of Throwable.fillInStackTrace. 095 * There are no public constructors defined for this class. Creation 096 * of new elements is implementation specific. 097 * 098 * @param fileName the name of the file, null if unknown 099 * @param lineNumber the line in the file, negative if unknown 100 * @param className the fully qualified name of the class, null if unknown 101 * @param methodName the name of the method, null if unknown 102 * @param isNative true if native, false otherwise 103 */ 104 StackTraceElement(String fileName, int lineNumber, String className, 105 String methodName, boolean isNative) 106 { 107 this.fileName = fileName; 108 this.lineNumber = lineNumber; 109 this.declaringClass = className; 110 this.methodName = methodName; 111 this.isNative = isNative; 112 } 113 114 /** 115 * Create a new StackTraceElement representing a given source location. 116 * 117 * @param className the fully qualified name of the class 118 * @param methodName the name of the method 119 * @param fileName the name of the file, null if unknown 120 * @param lineNumber the line in the file, negative if unknown, or -2 121 * if this method is native 122 * 123 * @since 1.5 124 */ 125 public StackTraceElement(String className, String methodName, String fileName, 126 int lineNumber) 127 { 128 this(fileName, lineNumber, className, methodName, lineNumber == -2); 129 // The public constructor doesn't allow certain values to be null. 130 if (className == null || methodName == null) 131 throw new NullPointerException("invalid argument to constructor"); 132 } 133 134 /** 135 * Returns the name of the file, or null if unknown. This is usually 136 * obtained from the <code>SourceFile</code> attribute of the class file 137 * format, if present. 138 * 139 * @return the file name 140 */ 141 public String getFileName() 142 { 143 return fileName; 144 } 145 146 /** 147 * Returns the line number in the file, or a negative number if unknown. 148 * This is usually obtained from the <code>LineNumberTable</code> attribute 149 * of the method in the class file format, if present. 150 * 151 * @return the line number 152 */ 153 public int getLineNumber() 154 { 155 return lineNumber; 156 } 157 158 /** 159 * Returns the fully qualified class name, or null if unknown. 160 * 161 * @return the class name 162 */ 163 public String getClassName() 164 { 165 return declaringClass; 166 } 167 168 /** 169 * Returns the method name in the class, or null if unknown. If the 170 * execution point is in a constructor, the name is 171 * <code><init></code>; if the execution point is in the class 172 * initializer, the name is <code><clinit></code>. 173 * 174 * @return the method name 175 */ 176 public String getMethodName() 177 { 178 return methodName; 179 } 180 181 /** 182 * Returns true if the method is native, or false if it is not or unknown. 183 * 184 * @return whether the method is native 185 */ 186 public boolean isNativeMethod() 187 { 188 return isNative; 189 } 190 191 /** 192 * Returns a string representation of this stack trace element. The 193 * returned String is implementation specific. This implementation 194 * returns the following String: "[class][.][method]([file][:line])". 195 * If the fully qualified class name or the method is unknown it is 196 * omitted including the point seperator. If the source file name is 197 * unknown it is replaced by "Unknown Source" if the method is not native 198 * or by "Native Method" if the method is native. If the line number 199 * is unknown it and the colon are omitted. 200 * 201 * @return a string representation of this execution point 202 */ 203 public String toString() 204 { 205 StringBuilder sb = new StringBuilder(); 206 if (declaringClass != null) 207 { 208 sb.append(declaringClass); 209 if (methodName != null) 210 sb.append('.'); 211 } 212 if (methodName != null) 213 sb.append(methodName); 214 sb.append("("); 215 if (fileName != null) 216 sb.append(fileName); 217 else 218 sb.append(isNative ? "Native Method" : "Unknown Source"); 219 if (lineNumber >= 0) 220 sb.append(':').append(lineNumber); 221 sb.append(')'); 222 return sb.toString(); 223 } 224 225 /** 226 * Returns true if the given object is also a StackTraceElement and all 227 * attributes, except the native flag, are equal (either the same attribute 228 * between the two elments are null, or both satisfy Object.equals). 229 * 230 * @param o the object to compare 231 * @return true if the two are equal 232 */ 233 public boolean equals(Object o) 234 { 235 if (! (o instanceof StackTraceElement)) 236 return false; 237 StackTraceElement e = (StackTraceElement) o; 238 return equals(fileName, e.fileName) 239 && lineNumber == e.lineNumber 240 && equals(declaringClass, e.declaringClass) 241 && equals(methodName, e.methodName); 242 } 243 244 /** 245 * Returns the hashCode of this StackTraceElement. This implementation 246 * computes the hashcode by xor-ing the hashcode of all attributes except 247 * the native flag. 248 * 249 * @return the hashcode 250 */ 251 public int hashCode() 252 { 253 return hashCode(fileName) ^ lineNumber ^ hashCode(declaringClass) 254 ^ hashCode(methodName); 255 } 256 257 /** 258 * Compare two objects according to Collection semantics. 259 * 260 * @param o1 the first object 261 * @param o2 the second object 262 * @return o1 == null ? o2 == null : o1.equals(o2) 263 */ 264 private static boolean equals(Object o1, Object o2) 265 { 266 return o1 == null ? o2 == null : o1.equals(o2); 267 } 268 269 /** 270 * Hash an object according to Collection semantics. 271 * 272 * @param o the object to hash 273 * @return o1 == null ? 0 : o1.hashCode() 274 */ 275 private static int hashCode(Object o) 276 { 277 return o == null ? 0 : o.hashCode(); 278 } 279 }