1//
2//  ========================================================================
3//  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
4//  ------------------------------------------------------------------------
5//  All rights reserved. This program and the accompanying materials
6//  are made available under the terms of the Eclipse Public License v1.0
7//  and Apache License v2.0 which accompanies this distribution.
8//
9//      The Eclipse Public License is available at
10//      http://www.eclipse.org/legal/epl-v10.html
11//
12//      The Apache License v2.0 is available at
13//      http://www.opensource.org/licenses/apache2.0.php
14//
15//  You may elect to redistribute this code under either of these licenses.
16//  ========================================================================
17//
18
19package org.eclipse.jetty.util;
20import java.io.PrintStream;
21import java.io.PrintWriter;
22import java.util.List;
23
24
25/* ------------------------------------------------------------ */
26/** Wraps multiple exceptions.
27 *
28 * Allows multiple exceptions to be thrown as a single exception.
29 *
30 *
31 */
32@SuppressWarnings("serial")
33public class MultiException extends Exception
34{
35    private Object nested;
36
37    /* ------------------------------------------------------------ */
38    public MultiException()
39    {
40        super("Multiple exceptions");
41    }
42
43    /* ------------------------------------------------------------ */
44    public void add(Throwable e)
45    {
46        if (e instanceof MultiException)
47        {
48            MultiException me = (MultiException)e;
49            for (int i=0;i<LazyList.size(me.nested);i++)
50                nested=LazyList.add(nested,LazyList.get(me.nested,i));
51        }
52        else
53            nested=LazyList.add(nested,e);
54    }
55
56    /* ------------------------------------------------------------ */
57    public int size()
58    {
59        return LazyList.size(nested);
60    }
61
62    /* ------------------------------------------------------------ */
63    public List<Throwable> getThrowables()
64    {
65        return LazyList.getList(nested);
66    }
67
68    /* ------------------------------------------------------------ */
69    public Throwable getThrowable(int i)
70    {
71        return (Throwable) LazyList.get(nested,i);
72    }
73
74    /* ------------------------------------------------------------ */
75    /** Throw a multiexception.
76     * If this multi exception is empty then no action is taken. If it
77     * contains a single exception that is thrown, otherwise the this
78     * multi exception is thrown.
79     * @exception Exception
80     */
81    public void ifExceptionThrow()
82        throws Exception
83    {
84        switch (LazyList.size(nested))
85        {
86          case 0:
87              break;
88          case 1:
89              Throwable th=(Throwable)LazyList.get(nested,0);
90              if (th instanceof Error)
91                  throw (Error)th;
92              if (th instanceof Exception)
93                  throw (Exception)th;
94          default:
95              throw this;
96        }
97    }
98
99    /* ------------------------------------------------------------ */
100    /** Throw a Runtime exception.
101     * If this multi exception is empty then no action is taken. If it
102     * contains a single error or runtime exception that is thrown, otherwise the this
103     * multi exception is thrown, wrapped in a runtime exception.
104     * @exception Error If this exception contains exactly 1 {@link Error}
105     * @exception RuntimeException If this exception contains 1 {@link Throwable} but it is not an error,
106     *                             or it contains more than 1 {@link Throwable} of any type.
107     */
108    public void ifExceptionThrowRuntime()
109        throws Error
110    {
111        switch (LazyList.size(nested))
112        {
113          case 0:
114              break;
115          case 1:
116              Throwable th=(Throwable)LazyList.get(nested,0);
117              if (th instanceof Error)
118                  throw (Error)th;
119              else if (th instanceof RuntimeException)
120                  throw (RuntimeException)th;
121              else
122                  throw new RuntimeException(th);
123          default:
124              throw new RuntimeException(this);
125        }
126    }
127
128    /* ------------------------------------------------------------ */
129    /** Throw a multiexception.
130     * If this multi exception is empty then no action is taken. If it
131     * contains a any exceptions then this
132     * multi exception is thrown.
133     */
134    public void ifExceptionThrowMulti()
135        throws MultiException
136    {
137        if (LazyList.size(nested)>0)
138            throw this;
139    }
140
141    /* ------------------------------------------------------------ */
142    @Override
143    public String toString()
144    {
145        if (LazyList.size(nested)>0)
146            return MultiException.class.getSimpleName()+
147                LazyList.getList(nested);
148        return MultiException.class.getSimpleName()+"[]";
149    }
150
151    /* ------------------------------------------------------------ */
152    @Override
153    public void printStackTrace()
154    {
155        super.printStackTrace();
156        for (int i=0;i<LazyList.size(nested);i++)
157            ((Throwable)LazyList.get(nested,i)).printStackTrace();
158    }
159
160
161    /* ------------------------------------------------------------------------------- */
162    /**
163     * @see java.lang.Throwable#printStackTrace(java.io.PrintStream)
164     */
165    @Override
166    public void printStackTrace(PrintStream out)
167    {
168        super.printStackTrace(out);
169        for (int i=0;i<LazyList.size(nested);i++)
170            ((Throwable)LazyList.get(nested,i)).printStackTrace(out);
171    }
172
173    /* ------------------------------------------------------------------------------- */
174    /**
175     * @see java.lang.Throwable#printStackTrace(java.io.PrintWriter)
176     */
177    @Override
178    public void printStackTrace(PrintWriter out)
179    {
180        super.printStackTrace(out);
181        for (int i=0;i<LazyList.size(nested);i++)
182            ((Throwable)LazyList.get(nested,i)).printStackTrace(out);
183    }
184
185}
186