1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 2000,2008 Oracle.  All rights reserved.
5 *
6 * $Id: ExceptionUnwrapper.java,v 12.7 2008/01/08 20:58:39 bostic Exp $
7 */
8
9package com.sleepycat.util;
10
11/**
12 * Unwraps nested exceptions by calling the {@link
13 * ExceptionWrapper#getCause()} method for exceptions that implement the
14 * {@link ExceptionWrapper} interface.  Does not currently support the Java 1.4
15 * <code>Throwable.getCause()</code> method.
16 *
17 * @author Mark Hayes
18 */
19public class ExceptionUnwrapper {
20
21    /**
22     * Unwraps an Exception and returns the underlying Exception, or throws an
23     * Error if the underlying Throwable is an Error.
24     *
25     * @param e is the Exception to unwrap.
26     *
27     * @return the underlying Exception.
28     *
29     * @throws Error if the underlying Throwable is an Error.
30     *
31     * @throws IllegalArgumentException if the underlying Throwable is not an
32     * Exception or an Error.
33     */
34    public static Exception unwrap(Exception e) {
35
36        Throwable t = unwrapAny(e);
37        if (t instanceof Exception) {
38            return (Exception) t;
39        } else if (t instanceof Error) {
40            throw (Error) t;
41        } else {
42            throw new IllegalArgumentException("Not Exception or Error: " + t);
43        }
44    }
45
46    /**
47     * Unwraps an Exception and returns the underlying Throwable.
48     *
49     * @param e is the Exception to unwrap.
50     *
51     * @return the underlying Throwable.
52     */
53    public static Throwable unwrapAny(Throwable e) {
54
55        while (true) {
56            if (e instanceof ExceptionWrapper) {
57                Throwable e2 = ((ExceptionWrapper) e).getCause();
58                if (e2 == null) {
59                    return e;
60                } else {
61                    e = e2;
62                }
63            } else {
64                return e;
65            }
66        }
67    }
68}
69