All Downloads are FREE. Search and download functionalities are using the official Maven repository.

protoj.lang.internal.UncaughtExceptionPolicy.aj Maven / Gradle / Ivy

The newest version!
/**
 * Copyright 2009 Ashley Williams
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License. You may
 * obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */
package protoj.lang.internal;

import java.awt.GraphicsEnvironment;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.Thread.UncaughtExceptionHandler;

import javax.swing.WindowConstants;

import org.apache.log4j.Logger;

import protoj.lang.ProtoLogger;


/**
 * Responds to exceptions that haven't been caught in the rest of the
 * application, by simply logging them and reporting them at the command line
 * and optionally displaying them in a window. This aspect is registered before
 * any main() method execution matched by the
 * mainCodebase() pointcut, so override that pointcut in order to
 * restrict the handler to your application.
 * 
 * @author Ashley Williams
 * 
 */
public abstract aspect UncaughtExceptionPolicy implements
		UncaughtExceptionHandler {

	/**
	 * The exception handler is registered with the vm only in main methods
	 * matched by this pointcut. An example override value would be
	 * within(com.mypackage..*).
	 */
	public abstract pointcut mainCodebase();

	/**
	 * Any throwables thrown from a matched main() method are
	 * handled in a standard way.
	 * 
	 * @param mainArgs
	 */
	before(String[] mainArgs) : execution(* main(String[])) && args(mainArgs) && mainCodebase() {
		Thread.setDefaultUncaughtExceptionHandler(this);
	}

	after(ProtoLogger logger) returning() : execution(ProtoLogger.new(..)) && this(logger) {
		this.logger = logger.getProtoLogger();
	}

	private boolean exceptionWindow = false;

	private Logger logger;

	public UncaughtExceptionPolicy() {
		super();
	}

	/**
	 * Use this to configure whether exceptions should additionally be reported
	 * in a window, off by default. Exceptions are always logged and reported at
	 * the console.
	 * 
	 * @param exceptionWindow
	 */
	public void setExceptionWindow(boolean exceptionWindow) {
		this.exceptionWindow = exceptionWindow;
	}

	public boolean isExceptionWindow() {
		return exceptionWindow;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * java.lang.Thread.UncaughtExceptionHandler#uncaughtException(java.lang
	 * .Thread, java.lang.Throwable)
	 */
	public void uncaughtException(Thread t, Throwable e) {
		try {
			if (isExceptionWindow()) {
				if (GraphicsEnvironment.isHeadless()) {
					StringBuilder message = new StringBuilder(
							"\ncan't show the exception in a window when in a headless environment");
					logger.error(message);
					System.err.println(message.toString());
				} else {
					StringBuilder report = createExceptionReport(e);
					MessageFrame messageFrame = new MessageFrame();
					messageFrame.setTitle("Error Report");
					messageFrame
							.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
					messageFrame.pack();
					messageFrame.getMessageContainer().setText(
							report.toString());
					messageFrame.setVisible(true);
				}
			}

			StringBuilder report = new StringBuilder();
			report.append("\n\n\n\n\n");
			report.append(createExceptionReport(e));
			report.append("\n\n\n\n\n");
			System.err.println(report);
			logger.error(report);
		} catch (Throwable th) {
			e.printStackTrace();
			th.printStackTrace();
		}
	}

	/**
	 * Formats the given exception suitable for reporting to a user.
	 * 
	 * @param e
	 * @return
	 */
	private StringBuilder createExceptionReport(Throwable e) {
		StringBuilder report = new StringBuilder();
		report.append("An application fault has been detected.\n");
		report
				.append("It may be possible to continue using it, but doing so may result in further problems.\n");
		report.append("Here is the cause of the fault:\n");
		StringWriter stringWriter = new StringWriter();
		PrintWriter printWriter = new PrintWriter(stringWriter);
		try {
			e.printStackTrace(printWriter);
		} finally {
			printWriter.close();
		}
		report.append(stringWriter.getBuffer());
		return report;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy