/interpreter/tags/at2dist110511/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. */
  28. package edu.vub.at.exceptions;
  29. import edu.vub.at.eval.InvocationStack;
  30. import edu.vub.at.objects.ATObject;
  31. import edu.vub.at.objects.ATTypeTag;
  32. import edu.vub.at.objects.natives.NATException;
  33. import java.io.PrintStream;
  34. import java.io.PrintWriter;
  35. /**
  36. * TODO tvcutsem Shouldn't we parameterize NATExceptions with an ATContext and possibly
  37. * also an ATAbstractGrammar for evaluation errors. This allows the user to inspect
  38. * both which expression was evaluated at exception-raising-time and allows him to inspect
  39. * the context at exception-raising-time.
  40. *
  41. * @author smostinc
  42. */
  43. public abstract class InterpreterException extends Exception {
  44. private static final long serialVersionUID = 511962997881825680L;
  45. // The ambienttalk stack trace of the exception
  46. protected final InvocationStack runtimeStack_;
  47. private final Throwable cause_;
  48. /**
  49. * Constructs a new ad hoc InterpreterException instance for
  50. * a given type tag, with a given message.
  51. */
  52. public static InterpreterException forType(final ATTypeTag tag, final String msg) {
  53. return new InterpreterException(msg) {
  54. public ATTypeTag getType() {
  55. return tag;
  56. }
  57. };
  58. }
  59. /**
  60. * Default constructor which only captures the AmbientTalk invocation stack.
  61. */
  62. public InterpreterException() {
  63. super();
  64. runtimeStack_ = InvocationStack.captureInvocationStack();
  65. cause_ = null;
  66. }
  67. /**
  68. * Contructor which reports an exception with a given message and an underlying exception.
  69. * This constructor also captures the AmbientTalk invocation stack relating the exception
  70. * to the AmbientTalk code that triggered it.
  71. */
  72. public InterpreterException(String message, Throwable cause) {
  73. super(message);
  74. // Backport from JDK 1.4 to 1.3
  75. // super(message, cause);
  76. cause_ = cause;
  77. runtimeStack_ = InvocationStack.captureInvocationStack();
  78. }
  79. /**
  80. * Constructor which reports an exception with a given message which cannot be related to a
  81. * previously raised exception. This constructor captures the AmbientTalk invocation
  82. * stack to identify which code produced the error.
  83. */
  84. public InterpreterException(String message) {
  85. super(message);
  86. runtimeStack_ = InvocationStack.captureInvocationStack();
  87. cause_ = null;
  88. }
  89. /**
  90. * Constructor which creates a wrapper for an underlying exception. This constructor
  91. * captures the AmbientTalk invocation stack to relate the exception to the AmbientTalk
  92. * that it corresponds to.
  93. */
  94. public InterpreterException(Throwable cause) {
  95. // Backport from JDK 1.4 to 1.3
  96. // super(cause);
  97. cause_ = cause;
  98. runtimeStack_ = InvocationStack.captureInvocationStack();
  99. }
  100. /**
  101. * @return the stack trace at the time this exception was raised
  102. */
  103. public InvocationStack getAmbientTalkStackTrace() {
  104. return runtimeStack_;
  105. }
  106. /**
  107. * @param out
  108. */
  109. public void printAmbientTalkStackTrace(PrintStream out) {
  110. runtimeStack_.printStackTrace(out);
  111. }
  112. /**
  113. * Returns an ambienttalk representation of the exception. The returned object is a wrapper
  114. * object which provides access to the exception's message and the AmbientTalk stack trace.
  115. */
  116. public ATObject getAmbientTalkRepresentation() {
  117. return new NATException(this);
  118. }
  119. /**
  120. * Returns the native type tag corresponding to the exception class. The NativeTypeTags class
  121. * defines types for all native data types, including exceptions. For exceptions, these
  122. * types can be used to catch native exceptions and handle them. Therefore every exception
  123. * class should override this abstract method to supply the type equivalent of its class.
  124. */
  125. public abstract ATTypeTag getType();
  126. public String getMessage() {
  127. if (cause_ == null) {
  128. return super.getMessage();
  129. } else {
  130. return super.getMessage() + " caused by " + cause_.getMessage();
  131. }
  132. }
  133. /* backport from 1.4 interface to 1.3 */
  134. /**
  135. * As AmbientTalk targets Java 1.3, Interpreter exceptions need to provide explicit support
  136. * to report the exception that caused them. The default support for such a method was only
  137. * introduced in Java 1.4. This method returns the exception that caused a particular error
  138. * which can possibly be null.
  139. */
  140. public Throwable getCause() {
  141. return cause_;
  142. }
  143. public void printStackTrace(PrintStream out) {
  144. if (cause_ == null) {
  145. super.printStackTrace(out);
  146. } else {
  147. super.printStackTrace(out);
  148. out.print(" caused by:");
  149. cause_.printStackTrace(out);
  150. }
  151. }
  152. public void printStackTrace(PrintWriter out) {
  153. if (cause_ == null) {
  154. super.printStackTrace(out);
  155. } else {
  156. super.printStackTrace(out);
  157. out.print(" caused by:");
  158. cause_.printStackTrace(out);
  159. }
  160. }
  161. public String toString() {
  162. if (cause_ == null) {
  163. return super.toString();
  164. } else {
  165. return super.toString() + " caused by " + cause_.toString();
  166. }
  167. }
  168. }