123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- /* *******************************************************************
- * Copyright (c) 1999-2001 Xerox Corporation,
- * 2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved.
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Xerox/PARC initial implementation
- * ******************************************************************/
-
- package org.aspectj.bridge;
-
- import java.io.PrintStream;
- import java.io.PrintWriter;
- import java.util.ArrayList;
-
- /**
- * Signal that a process was aborted before completion.
- * This may contain a structured IMessage which indicates
- * why the process was aborted (e.g., the underlying exception).
- * For processes using try/catch to complete a method abruptly
- * but complete the process normally (e.g., a test failure
- * causes the test to abort but the reporting and testing continues
- * normally), use the static methods to borrow and return a "porter"
- * to avoid the expense of constructing a stack trace each time.
- * A porter stack trace is invalid, and it should only be used
- * to convey a message. E.g., to print the stack of the
- * AbortException and any contained message:
- * <pre>catch (AbortException ae) {
- * IMessage m = ae.getMessage();
- * if (!ae.isPorter()) ae.printStackTrace(System.err);
- * Throwable thrown = ae.getThrown();
- * if (null != thrown) thrown.printStackTrace(System.err);
- * }</pre>
- */
- public class AbortException extends RuntimeException { // XXX move porters out, handle proxy better
-
- private static final long serialVersionUID = -7211791639898586417L;
-
- private boolean isSilent = false;
-
- /** used when message text is null */
- public static final String NO_MESSAGE_TEXT
- = "AbortException (no message)";
-
- private static final ArrayList porters = new ArrayList();
-
- /**
- * Get a porter exception from the pool.
- * Porter exceptions do <b>not</b> have valid stack traces.
- * They are used only to avoid generating stack traces when
- * using throw/catch to abruptly complete but continue.
- */
- public static AbortException borrowPorter(IMessage message) {
- AbortException result;
- synchronized(porters) {
- if (porters.size() > 0) {
- result = (AbortException) porters.get(0);
- } else {
- result = new AbortException();
- result.setIsSilent(false);
- }
- }
- result.setIMessage(message);
- result.isPorter = true;
- return result;
- }
-
- /**
- * Return (or add) a porter exception to the pool.
- */
- public static void returnPorter(AbortException porter) {
- synchronized(porters) {
- if (porters.contains(porter)) {
- throw new IllegalStateException("already have " + porter);
- } else {
- porters.add(porter);
- }
- }
- }
-
- /** @return NO_MESSAGE_TEXT or message.getMessage() if not null */
- private static String extractMessage(IMessage message) {
- if (null == message) {
- return NO_MESSAGE_TEXT;
- } else {
- String m = message.getMessage();
- if (null == m) {
- return NO_MESSAGE_TEXT;
- } else {
- return m;
- }
- }
- }
-
- /** structured message abort */
- protected IMessage message;
-
- /** true if this is a porter exception - only used to hold message */
- protected boolean isPorter;
-
- /** abort with default String message */
- public AbortException() {
- this("ABORT");
- isSilent = true;
- }
-
- /** abort with message */
- public AbortException(String s) {
- super(null != s ? s : NO_MESSAGE_TEXT);
- this.message = null;
- }
-
- /** abort with structured message */
- public AbortException(IMessage message) {
- super(extractMessage(message));
- this.message = message;
- }
-
- /** @return IMessage structured message, if set */
- public IMessage getIMessage() {
- return message;
- }
-
- /**
- * The stack trace of a porter is invalid; it is only used
- * to carry a message (which may itself have a wrapped exception).
- * @return true if this exception is only to carry exception
- */
- public boolean isPorter() {
- return isPorter;
- }
-
- /** @return Throwable at bottom of IMessage chain, if any */
- public Throwable getThrown() {
- Throwable result = null;
- IMessage m = getIMessage();
- if (null != m) {
- result = m.getThrown();
- if (result instanceof AbortException) {
- return ((AbortException) result).getThrown();
- }
- }
- return result;
- }
-
- private void setIMessage(IMessage message) {
- this.message = message;
- }
-
- // ----------- proxy attempts
- /**
- * Get message for this AbortException,
- * either associated explicitly as message
- * or implicitly as IMessage message or
- * its thrown message.
- * @see java.lang.Throwable#getMessage()
- */
- public String getMessage() {
- String message = super.getMessage();
- if ((null == message) || (NO_MESSAGE_TEXT == message)) {
- IMessage m = getIMessage();
- if (null != m) {
- message = m.getMessage();
- if (null == message) {
- Throwable thrown = m.getThrown();
- if (null != thrown) {
- message = thrown.getMessage();
- }
- }
- }
- if (null == message) {
- message = NO_MESSAGE_TEXT; // better than nothing
- }
- }
- return message;
- }
-
- /**
- * @see java.lang.Throwable#printStackTrace()
- */
- public void printStackTrace() {
- printStackTrace(System.out);
- }
-
- /**
- * Print the stack trace of any enclosed thrown
- * or this otherwise.
- * @see java.lang.Throwable#printStackTrace(PrintStream)
- */
- public void printStackTrace(PrintStream s) {
- IMessage m = getIMessage();
- Throwable thrown = (null == m? null : m.getThrown());
- if (!isPorter() || (null == thrown)) {
- s.println("Message: " + m);
- super.printStackTrace(s);
- } else {
- thrown.printStackTrace(s);
- }
- }
-
- /**
- * Print the stack trace of any enclosed thrown
- * or this otherwise.
- * @see java.lang.Throwable#printStackTrace(PrintWriter)
- */
- public void printStackTrace(PrintWriter s) {
- IMessage m = getIMessage();
- Throwable thrown = (null == m? null : m.getThrown());
- if (null == thrown) { // Always print
- if (isPorter()) {
- s.println("(Warning porter AbortException without thrown)");
- }
- s.println("Message: " + m);
- super.printStackTrace(s);
- } else {
- thrown.printStackTrace(s);
- }
- }
-
- public boolean isSilent() {
- return isSilent;
- }
-
- public void setIsSilent(boolean isSilent) {
- this.isSilent = isSilent;
- }
-
- }
|