/* XXL: The eXtensible and fleXible Library for data processing Copyright (C) 2000-2011 Prof. Dr. Bernhard Seeger Head of the Database Research Group Department of Mathematics and Computer Science University of Marburg Germany This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; If not, see <http://www.gnu.org/licenses/>. http://code.google.com/p/xxl/ */ package xxl.core.util; import java.io.PrintStream; import java.io.PrintWriter; /** * This Exception is useful for wrapping arbitrary Exceptions. <br> * A RuntimeException can be thrown at any place in the code * and does not have to be declared in the throws-clause. <br> * This means that by catching a non-RuntimeException and wrapping it, * this exception can be thrown at any place in the code even in * constructors.<br> * More detailled: This class is a subclass of the class <tt>RuntimeException</tt>, * therefore a method is not required to declare in its <code>throws</code> * clause any subclasses of <code>RuntimeException</code> that might * be thrown during the execution of the method but not caught. <p> * * <b>Note:</b> The <code>Throwable</code> class is the superclass of all errors * and exceptions in the Java language. Only objects that are * instances of this class (or of one of its subclasses) are thrown * by the Java Virtual Machine or can be thrown by the Java * <code>throw</code> statement. Similarly, only this class or one of * its subclasses can be the argument type in a <code>catch</code> * clause. * <p> * Instances of two subclasses, {@link java.lang.Error} and * {@link java.lang.Exception}, are conventionally used to indicate * that exceptional situations have occurred. Typically, these instances * are freshly created in the context of the exceptional situation so * as to include relevant information (such as stack trace data). * <p> * By convention, class <code>Throwable</code> and its subclasses have * two constructors, one that takes no arguments and one that takes a * <code>String</code> argument that can be used to produce an error * message. * <p> * A <code>Throwable</code> class contains a snapshot of the * execution stack of its thread at the time it was created. It can * also contain a message string that gives more information about * the error.<p> * * A WrappingRuntimeExcpetion passes by all method calls to it using the methods * of the exception to be wrapped. * * Example demonstrating the usage of a WrappingRuntimeException: * <br><br> * <code><pre> * class TestWrappingRuntimeException { * * // common handling of exceptions * public void handlingNoRuntimeExceptions (int i) throws IOException, NoSuchMethodException, IllegalAccessException { * switch(i) { * case 1: throw new IOException("IOException geworfen!"); * case 2: throw new NoSuchMethodException("NoSuchMethodException geworfen!"); * case 3: throw new IllegalAccessException("IllegalAccessException geworfen!"); * } * } * * // using a WrappingRuntimeException instead * public void usingWrappingRuntimeException (int i) { * try { * switch(i) { * case 1: throw new IOException("IOException geworfen!"); * case 2: throw new NoSuchMethodException("NoSuchMethodException geworfen!"); * case 3: throw new IllegalAccessException("IllegalAccessException geworfen!"); * } * } * catch (Exception e) { * throw new WrappingRuntimeException(e); * } * } * * public static void main (String[] args) { * * TestWrappingRuntimeException t = new TestWrappingRuntimeException(); * * for(int i=1; i<=3; i++) { * * // common handling of exceptions * try { * t.handlingNoRuntimeExceptions(i); * } * catch (IOException ie) { * System.out.println(ie.toString()); * } * catch (NoSuchMethodException nsme) { * System.out.println(nsme.toString()); * } * catch (IllegalAccessException iae) { * System.out.println(iae.toString()); * } * * // using a WrappingRuntimeException instead * try { * t.usingWrappingRuntimeException(i); * } * catch (WrappingRuntimeException e) { * System.out.println(e.toString()); * } * } * } * } * </code></pre> * This is example shows the difference between the * handling with NonRuntimeException and using a WrappingRuntimeException * which wraps these NonRuntimeExceptions to a RuntimeException that * can be catched later with the intention to extract the original error * message.<p> * This action is especially useful if the user does not want (or even is * not able) to declare the possibly thrown Non-Runtime-Exceptions * in each method. For example a method may throw a Non-Runtime-Exception * and this method is used in an other method of an other class. Now the * user does not want to handle this Non-Runtime-Exception explicitely, so * he can use a WrappingRuntimeException instead and therefore he is able * throw an exception without declaring it in the throws-clause. * Later, even in an other class, a method can catch this WrappingRuntimeException * and extract the original error message calling the WrappingRuntimeException's * method <code>toString</code>. * * @see java.lang.Throwable * @see java.lang.Exception * @see java.lang.RuntimeException * @see xxl.core.io */ public class WrappingRuntimeException extends RuntimeException { /** The exception to be wrapped to a <tt>RuntimeException</tt>. */ public final Throwable throwable; /** * Creates a new WrappingRuntimeException. * * @param throwable the non-RuntimeException to be wrapped. */ public WrappingRuntimeException (Throwable throwable) { this.throwable = throwable; } /** * Returns the message string of the wrapped exception (a throwable object). <br> * The call is passed by, i.e. <code>throwable.getMessage()</code> is returned. * * @return the error message string of the wrapped exception * if it was {@link java.lang.Throwable#Throwable(String) created} with an * error message string; or <code>null</code> if it was * {@link java.lang.Throwable#Throwable() created} with no error message. */ public String getMessage () { return throwable.getMessage(); } /** * Returns the localized description of the wrapped exception in order to produce a * locale-specific message. <br>If the class of the wrapped exception does not override this * method, the default implementation returns the same result as * <code>getMessage()</code>. * The call is passed by, i.e. <code>throwable.getLocalizedMessage()</code> is returned. * * @return the localized description of the wrapped exception. */ public String getLocalizedMessage () { return throwable.getLocalizedMessage(); } /** * Returns a short description of the wrapped exception. <br> * If the wrapped exception was * {@link java.lang.Throwable#Throwable(String) created} with an error message string, * then the result is the concatenation of three strings: * <ul> * <li>The name of the actual class of this object * <li>": " (a colon and a space) * <li>The result of the {@link #getMessage()} method for this object * </ul> * If the wrapped exception was {@link java.lang.Throwable#Throwable() created} * with no error message string, then the name of the actual class of * this object is returned. * The call is passed by, i.e. <code>throwable.toString()</code> is returned. * * @return a string representation of the wrapped exception. */ public String toString () { return throwable.toString(); } /** * Prints the wrapped exception and its backtrace to the * standard error stream. <br>This method prints a stack trace for the * wrapped exception object on the error output stream that is * the value of the field <code>System.err</code>. The first line of * output contains the result of the {@link #toString()} method for * this object. Remaining lines represent data previously recorded by * the method {@link #fillInStackTrace()}. <br>The format of this * information depends on the implementation, but the following * example may be regarded as typical: * <blockquote><pre> * java.lang.NullPointerException * at MyClass.mash(MyClass.java:9) * at MyClass.crunch(MyClass.java:6) * at MyClass.main(MyClass.java:3) * </pre></blockquote> * This example was produced by running the program: * <blockquote><pre> * * class MyClass { * * public static void main(String[] argv) { * crunch(null); * } * static void crunch(int[] a) { * mash(a); * } * * static void mash(int[] b) { * System.out.println(b[0]); * } * } * </pre></blockquote> * The call is passed by, i.e. <code>throwable.printStackTrace()</code> is returned. * * @see java.lang.System#err err */ public void printStackTrace () { throwable.printStackTrace(); } /** * Prints the wrapped excpetion and its backtrace to the * specified print stream. <br> * The call is passed by, i.e. <code>throwable.printStackTrace(s)</code> is returned. * @param s output print stream */ public void printStackTrace (PrintStream s) { throwable.printStackTrace(s); } /** * Prints the wrapped exception and its backtrace to the specified * print writer. <br> * The call is passed by, i.e. <code>throwable.printStackTrace(s)</code> is returned. * @param s output print writer */ public void printStackTrace (PrintWriter s) { throwable.printStackTrace(s); } /** * Fills in the execution stack trace. This method records within * this Throwable object information about the current state of * the stack frames for the current thread. * @see java.lang.Throwable#fillInStackTrace() */ public synchronized Throwable fillInStackTrace() { if (throwable==null) return super.fillInStackTrace(); else return throwable.fillInStackTrace(); } /** * Returns the cause of this throwable or null if the cause is * nonexistent or unknown. (The cause is the throwable that * caused this throwable to get thrown.) * @see java.lang.Throwable#getCause() */ public Throwable getCause() { return throwable.getCause(); } /** * Provides programmatic access to the stack trace information * printed by printStackTrace(). Returns an array of stack trace * elements, each representing one stack frame. The zeroth element * of the array (assuming the array's length is non-zero) * represents the top of the stack, which is the last method * invocation in the sequence. Typically, this is the point * at which this throwable was created and thrown. The last * element of the array (assuming the array's length is non-zero) * represents the bottom of the stack, which is the first method * invocation in the sequence. * @see java.lang.Throwable#getStackTrace() */ public StackTraceElement[] getStackTrace() { return throwable.getStackTrace(); } /** * Initializes the cause of this throwable to the specified * value. (The cause is the throwable that caused this * throwable to get thrown.) * @see java.lang.Throwable#initCause(java.lang.Throwable) */ public synchronized Throwable initCause(Throwable cause) { return throwable.initCause(cause); } /** * Sets the stack trace elements that will be returned by * getStackTrace() and printed by printStackTrace() and related * methods. This method, which is designed for use by RPC * frameworks and other advanced systems, allows the client * to override the default stack trace that is either generated * by fillInStackTrace() when a throwable is constructed or * deserialized when a throwable is read from a serialization * stream. * @see java.lang.Throwable#setStackTrace(java.lang.StackTraceElement[]) */ public void setStackTrace(StackTraceElement[] stackTrace) { throwable.setStackTrace(stackTrace); } }