/*
 * Copyright 2004-2005 The Apache Software Foundation or its licensors,
 *                     as applicable.
 *
 * 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 org.apache.jackrabbit;

import java.io.PrintStream;
import java.io.PrintWriter;

/**
 * The abstract class <code>BaseException</code> serves as the base class
 * for all exceptions that are specific to this JCR implementation and that
 * are not derived from <code>javax.jcr.RepositoryException</code>.
 */
public abstract class BaseException extends Exception {

    /**
     * Root failure cause
     */
    private final Throwable rootCause;

    /**
     * Constructs a new instance of this class with <code>null</code> as its
     * detail message.
     */
    public BaseException() {
        super();
        rootCause = null;
    }

    /**
     * Constructs a new instance of this class with the specified detail
     * message.
     *
     * @param message the detail message. The detail message is saved for
     *                later retrieval by the {@link #getMessage()} method.
     */
    public BaseException(String message) {
        super(message);
        rootCause = null;
    }

    /**
     * Constructs a new instance of this class with the specified detail
     * message and root cause.
     *
     * @param message   the detail message. The detail message is saved for
     *                  later retrieval by the {@link #getMessage()} method.
     * @param rootCause root failure cause
     */
    public BaseException(String message, Throwable rootCause) {
        super(message);
        this.rootCause = rootCause;
    }

    /**
     * Constructs a new instance of this class with the specified root cause.
     *
     * @param rootCause root failure cause
     */
    public BaseException(Throwable rootCause) {
        super();
        this.rootCause = rootCause;
    }

    /**
     * Returns the detail message, including the message from the nested
     * exception if there is one.
     *
     * @return the detail message (which may be <code>null</code>).
     */
    public String getMessage() {
        String s = super.getMessage();
        if (rootCause == null) {
            return s;
        } else if (s == null) {
            return rootCause.getMessage();
        } else {
            return s + ": " + rootCause.getMessage();
        }
    }

    /**
     * Creates a localized description of this exception.
     * Subclasses may override this method in order to produce a
     * locale-specific message. For subclasses that do not override this
     * method, the default implementation returns the same result as
     * <code>getMessage()</code>.
     *
     * @return The localized description of this exception.
     */
    public String getLocalizedMessage() {
        return getMessage();
    }

    /**
     * Returns the cause of this exception or <code>null</code> if the
     * cause is nonexistent or unknown. (The cause is the throwable that
     * caused this exception to get thrown.)
     *
     * @return the cause of this exception or <code>null</code> if the
     *         cause is nonexistent or unknown.
     */
    public Throwable getCause() {
        return rootCause;
    }

    /**
     * Prints this <code>RepositoryException</code> and its backtrace to the
     * standard error stream.
     */
    public void printStackTrace() {
        printStackTrace(System.err);
    }

    /**
     * Prints this <code>RepositoryException</code> and its backtrace to the
     * specified print stream.
     *
     * @param s <code>PrintStream</code> to use for output
     */
    public void printStackTrace(PrintStream s) {
        synchronized (s) {
            super.printStackTrace(s);
            if (rootCause != null) {
                rootCause.printStackTrace(s);
            }
        }
    }

    /**
     * Prints this <code>RepositoryException</code> and its backtrace to
     * the specified print writer.
     *
     * @param s <code>PrintWriter</code> to use for output
     */
    public void printStackTrace(PrintWriter s) {
        synchronized (s) {
            super.printStackTrace(s);
            if (rootCause != null) {
                rootCause.printStackTrace(s);
            }
        }
    }
}

@@ -705,65 +705,8 @@
 t;%0A%0A
-import java.io.PrintStream;%0Aimport java.io.PrintWriter;%0A%0A
 /**%0A
@@ -988,90 +988,8 @@
  %7B%0A%0A
-    /**%0A     * Root failure cause%0A     */%0A    private final Throwable rootCause;%0A%0A
     
@@ -1150,34 +1150,8 @@
 ();%0A
-        rootCause = null;%0A
     
@@ -1485,34 +1485,8 @@
 e);%0A
-        rootCause = null;%0A
     
@@ -1900,45 +1900,20 @@
 sage
-);%0A        this.rootCause = rootCause
+, rootCause)
 ;%0A  
@@ -2127,2436 +2127,25 @@
 per(
-);%0A        this.rootCause = rootCause;%0A    %7D%0A%0A    /**%0A     * Returns the detail message, including the message from the nested%0A     * exception if there is one.%0A     *%0A     * @return the detail message (which may be %3Ccode%3Enull%3C/code%3E).%0A     */%0A    public String getMessage() %7B%0A        String s = super.getMessage();%0A        if (rootCause == null) %7B%0A            return s;%0A        %7D else if (s == null) %7B%0A            return rootCause.getMessage();%0A        %7D else %7B%0A            return s + %22: %22 + rootCause.getMessage();%0A        %7D%0A    %7D%0A%0A    /**%0A     * Creates a localized description of this exception.%0A     * Subclasses may override this method in order to produce a%0A     * locale-specific message. For subclasses that do not override this%0A     * method, the default implementation returns the same result as%0A     * %3Ccode%3EgetMessage()%3C/code%3E.%0A     *%0A     * @return The localized description of this exception.%0A     */%0A    public String getLocalizedMessage() %7B%0A        return getMessage();%0A    %7D%0A%0A    /**%0A     * Returns the cause of this exception or %3Ccode%3Enull%3C/code%3E if the%0A     * cause is nonexistent or unknown. (The cause is the throwable that%0A     * caused this exception to get thrown.)%0A     *%0A     * @return the cause of this exception or %3Ccode%3Enull%3C/code%3E if the%0A     *         cause is nonexistent or unknown.%0A     */%0A    public Throwable getCause() %7B%0A        return rootCause;%0A    %7D%0A%0A    /**%0A     * Prints this %3Ccode%3ERepositoryException%3C/code%3E and its backtrace to the%0A     * standard error stream.%0A     */%0A    public void printStackTrace() %7B%0A        printStackTrace(System.err);%0A    %7D%0A%0A    /**%0A     * Prints this %3Ccode%3ERepositoryException%3C/code%3E and its backtrace to the%0A     * specified print stream.%0A     *%0A     * @param s %3Ccode%3EPrintStream%3C/code%3E to use for output%0A     */%0A    public void printStackTrace(PrintStream s) %7B%0A        synchronized (s) %7B%0A            super.printStackTrace(s);%0A            if (rootCause != null) %7B%0A                rootCause.printStackTrace(s);%0A            %7D%0A        %7D%0A    %7D%0A%0A    /**%0A     * Prints this %3Ccode%3ERepositoryException%3C/code%3E and its backtrace to%0A     * the specified print writer.%0A     *%0A     * @param s %3Ccode%3EPrintWriter%3C/code%3E to use for output%0A     */%0A    public void printStackTrace(PrintWriter s) %7B%0A        synchronized (s) %7B%0A            super.printStackTrace(s);%0A            if (rootCause != null) %7B%0A                rootCause.printStackTrace(s);%0A            %7D%0A        %7D%0A    %7D
+rootCause);%0A    %7D%0A
 %0A%7D%0A

Use the standard exception root cause mechanism included in JDK 1.4.