1 package net.sf.openrocket.logging;
6 * An exception that is used to store a stack trace. On modern computers
7 * instantiation of an exception takes on the order of one microsecond, while
8 * examining the trace typically takes several times longer. Therefore the
9 * exception should be stored and the stack trace examined only when necessary.
11 * The {@link #getMessage()} method returns a description of the position
12 * where this exception has been instantiated. The position is provided
13 * as many levels upwards from the instantiation position as provided to the
16 * @author Sampo Niskanen <sampo.niskanen@iki.fi>
18 public class TraceException extends Exception {
20 private static final String STANDARD_PACKAGE_PREFIX = "net.sf.openrocket.";
22 private final int minLevel;
23 private final int maxLevel;
24 private volatile String message = null;
28 * Instantiate exception that provides the line of instantiation as a message.
30 public TraceException() {
35 * Instantiate exception that provides the provided number of levels upward
36 * from the instantiation location as a message. The level provided
37 * is how many levels upward should be examined to find the stack trace
38 * position for the exception message.
40 * @param level how many levels upward to examine the stack trace to find
41 * the correct message.
43 public TraceException(int level) {
49 * Instantiate exception that provides a range of levels upward from the
50 * instantiation location as a message. This is useful to identify the
51 * next level of callers upward.
53 * @param minLevel the first level which to include.
54 * @param maxLevel the last level which to include.
56 public TraceException(int minLevel, int maxLevel) {
57 if (minLevel > maxLevel || minLevel < 0) {
58 throw new IllegalArgumentException("minLevel=" + minLevel + " maxLevel=" + maxLevel);
60 this.minLevel = minLevel;
61 this.maxLevel = maxLevel;
66 * Construct an exception with the specified message.
68 * @param message the message for the exception.
70 public TraceException(String message) {
72 this.message = message;
77 * Get the description of the code position as provided in the constructor.
80 public String getMessage() {
81 if (message == null) {
82 StackTraceElement[] elements = this.getStackTrace();
84 StringBuilder sb = new StringBuilder();
85 if (minLevel < elements.length) {
88 sb.append(toString(elements[minLevel]));
89 for (int i = minLevel + 1; i <= maxLevel; i++) {
90 if (i < elements.length) {
91 sb.append(' ').append(toString(elements[i]));
96 } else if (elements.length == 0) {
98 sb.append("(no stack trace)");
103 sb.append(toString(elements[0]));
104 for (int i = 1; i < elements.length; i++) {
105 sb.append(' ').append(toString(elements[i]));
107 sb.append(" level=").append(minLevel).append(')');
110 message = sb.toString();
116 private static String toString(StackTraceElement element) {
117 if (element.getClassName().startsWith(STANDARD_PACKAGE_PREFIX)) {
118 return element.getFileName() + ":" + element.getLineNumber();
120 return element.toString();