PageRenderTime 9ms CodeModel.GetById 1ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 0ms

/interpreter/tags/at2dist220411/src/edu/vub/at/exceptions/InterpreterException.java

http://ambienttalk.googlecode.com/
Java | 188 lines | 83 code | 20 blank | 85 comment | 12 complexity | 1faa7d1bcf2db5ac9e97d8712961c3a8 MD5 | raw file
  1/**
  2 * AmbientTalk/2 Project
  3 * ATException.java created on Jul 13, 2006 at 8:24:20 PM
  4 * (c) Programming Technology Lab, 2006 - 2007
  5 * Authors: Tom Van Cutsem & Stijn Mostinckx
  6 * 
  7 * Permission is hereby granted, free of charge, to any person
  8 * obtaining a copy of this software and associated documentation
  9 * files (the "Software"), to deal in the Software without
 10 * restriction, including without limitation the rights to use,
 11 * copy, modify, merge, publish, distribute, sublicense, and/or
 12 * sell copies of the Software, and to permit persons to whom the
 13 * Software is furnished to do so, subject to the following
 14 * conditions:
 15 *
 16 * The above copyright notice and this permission notice shall be
 17 * included in all copies or substantial portions of the Software.
 18 *
 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 21 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 22 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 23 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 26 * OTHER DEALINGS IN THE SOFTWARE.
 27 */
 28package edu.vub.at.exceptions;
 29
 30import edu.vub.at.eval.InvocationStack;
 31import edu.vub.at.objects.ATObject;
 32import edu.vub.at.objects.ATTypeTag;
 33import edu.vub.at.objects.natives.NATException;
 34
 35import java.io.PrintStream;
 36import java.io.PrintWriter;
 37
 38/**
 39 * TODO tvcutsem Shouldn't we parameterize NATExceptions with an ATContext and possibly
 40 * also an ATAbstractGrammar for evaluation errors. This allows the user to inspect
 41 * both which expression was evaluated at exception-raising-time and allows him to inspect
 42 * the context at exception-raising-time.
 43 * 
 44 * @author smostinc
 45 */
 46public abstract class InterpreterException extends Exception {
 47
 48	private static final long serialVersionUID = 511962997881825680L;
 49
 50	// The ambienttalk stack trace of the exception
 51	protected final InvocationStack runtimeStack_;
 52
 53	private final Throwable cause_;
 54
 55	/**
 56	 * Constructs a new ad hoc InterpreterException instance for
 57	 * a given type tag, with a given message.
 58	 */
 59	public static InterpreterException forType(final ATTypeTag tag, final String msg) {
 60		return new InterpreterException(msg) {
 61			public ATTypeTag getType() {
 62				return tag;
 63			}
 64		};
 65	}
 66	
 67	/**
 68	 * Default constructor which only captures the AmbientTalk invocation stack.
 69	 */
 70	public InterpreterException() {
 71		super();
 72		runtimeStack_ = InvocationStack.captureInvocationStack();
 73		cause_ = null;
 74	}
 75
 76	/**
 77	 * Contructor which reports an exception with a given message and an underlying exception. 
 78	 * This constructor also captures the AmbientTalk invocation stack relating the exception
 79	 * to the AmbientTalk code that triggered it.
 80	 */
 81	public InterpreterException(String message, Throwable cause) {
 82		super(message);
 83		// Backport from JDK 1.4 to 1.3
 84		// super(message, cause);
 85		cause_ = cause;
 86		runtimeStack_ = InvocationStack.captureInvocationStack();
 87	}
 88
 89	/**
 90	 * Constructor which reports an exception with a given message which cannot be related to a
 91	 * previously raised exception. This constructor captures the AmbientTalk invocation 
 92	 * stack to identify which code produced the error.
 93	 */
 94	public InterpreterException(String message) {
 95		super(message);
 96		runtimeStack_ = InvocationStack.captureInvocationStack();
 97		cause_ = null;
 98	}
 99
100	/**
101	 * Constructor which creates a wrapper for an underlying exception. This constructor 
102	 * captures the AmbientTalk invocation stack to relate the exception to the AmbientTalk
103	 * that it corresponds to.
104	 */
105	public InterpreterException(Throwable cause) {
106		// Backport from JDK 1.4 to 1.3
107		// super(cause);
108		cause_ = cause;
109		runtimeStack_ = InvocationStack.captureInvocationStack();
110	}
111
112	/**
113	 * @return the stack trace at the time this exception was raised
114	 */
115	public InvocationStack getAmbientTalkStackTrace() {
116		return runtimeStack_;
117	}
118	
119	/**
120	 * @param out
121	 */
122	public void printAmbientTalkStackTrace(PrintStream out) {
123		runtimeStack_.printStackTrace(out);
124	}
125
126	/**
127	 * Returns an ambienttalk representation of the exception. The returned object is a wrapper
128	 * object which provides access to the exception's message and the AmbientTalk stack trace.
129	 */
130	public ATObject getAmbientTalkRepresentation() {
131		return new NATException(this);
132	}
133
134	/**
135	 * Returns the native type tag corresponding to the exception class. The NativeTypeTags class 
136	 * defines types for all native data types, including exceptions. For exceptions, these 
137	 * types can be used to catch native exceptions and handle them. Therefore every exception
138	 * class should override this abstract method to supply the type equivalent of its class.
139	 */
140	public abstract ATTypeTag getType();
141
142	public String getMessage() {
143		if (cause_ == null) {
144			return super.getMessage();
145		} else {
146			return super.getMessage() + " caused by " + cause_.getMessage();
147		}
148	}
149
150	/* backport from 1.4 interface to 1.3 */
151	/**
152	 * As AmbientTalk targets Java 1.3, Interpreter exceptions need to provide explicit support
153	 * to report the exception that caused them. The default support for such a method was only 
154	 * introduced in Java 1.4. This method returns the exception that caused a particular error
155	 * which can possibly be null.
156	 */
157	public Throwable getCause() {
158		return cause_;
159	}
160
161	public void printStackTrace(PrintStream out) {
162		if (cause_ == null) {
163			super.printStackTrace(out);
164		} else {
165			super.printStackTrace(out);
166			out.print(" caused by:");
167			cause_.printStackTrace(out);
168		}
169	}
170
171	public void printStackTrace(PrintWriter out) {
172		if (cause_ == null) {
173			super.printStackTrace(out);
174		} else {
175			super.printStackTrace(out);
176			out.print(" caused by:");
177			cause_.printStackTrace(out);
178		}
179	}
180
181	public String toString() {
182		if (cause_ == null) {
183			return super.toString();
184		} else {
185			return super.toString() + " caused by " + cause_.toString();
186		}
187	}
188}