123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- /* *******************************************************************
- * 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>
- *
- * @author PARC
- * @author Andy Clement
- */
- 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<AbortException> 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 = 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;
- }
-
- }
|