View Javadoc

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  
19  package org.eclipse.jetty.util;
20  
21  import java.io.PrintStream;
22  import java.io.PrintWriter;
23  import java.util.ArrayList;
24  import java.util.Collections;
25  import java.util.List;
26  
27  /** 
28   * Wraps multiple exceptions.
29   *
30   * Allows multiple exceptions to be thrown as a single exception.
31   */
32  @SuppressWarnings("serial")
33  public class MultiException extends Exception
34  {
35      private List<Throwable> nested;
36  
37      /* ------------------------------------------------------------ */
38      public MultiException()
39      {
40          super("Multiple exceptions");
41      }
42  
43      /* ------------------------------------------------------------ */
44      public void add(Throwable e)
45      {
46          if (e==null)
47              throw new IllegalArgumentException();
48          
49          if(nested == null)
50              nested = new ArrayList<>();
51          
52          if (e instanceof MultiException)
53          {
54              MultiException me = (MultiException)e;
55              nested.addAll(me.nested);
56          }
57          else
58              nested.add(e);
59      }
60  
61      /* ------------------------------------------------------------ */
62      public int size()
63      {
64          return (nested ==null)?0:nested.size();
65      }
66      
67      /* ------------------------------------------------------------ */
68      public List<Throwable> getThrowables()
69      {
70          if(nested == null) {
71              return Collections.emptyList();
72          }
73          return nested;
74      }
75      
76      /* ------------------------------------------------------------ */
77      public Throwable getThrowable(int i)
78      {
79          return nested.get(i);
80      }
81  
82      /* ------------------------------------------------------------ */
83      /** Throw a multiexception.
84       * If this multi exception is empty then no action is taken. If it
85       * contains a single exception that is thrown, otherwise the this
86       * multi exception is thrown. 
87       * @exception Exception 
88       */
89      public void ifExceptionThrow()
90          throws Exception
91      {
92          if(nested == null)
93              return;
94          
95          switch (nested.size())
96          {
97            case 0:
98                break;
99            case 1:
100               Throwable th=nested.get(0);
101               if (th instanceof Error)
102                   throw (Error)th;
103               if (th instanceof Exception)
104                   throw (Exception)th;
105           default:
106               throw this;
107         }
108     }
109     
110     /* ------------------------------------------------------------ */
111     /** Throw a Runtime exception.
112      * If this multi exception is empty then no action is taken. If it
113      * contains a single error or runtime exception that is thrown, otherwise the this
114      * multi exception is thrown, wrapped in a runtime exception. 
115      * @exception Error If this exception contains exactly 1 {@link Error} 
116      * @exception RuntimeException If this exception contains 1 {@link Throwable} but it is not an error,
117      *                             or it contains more than 1 {@link Throwable} of any type.
118      */
119     public void ifExceptionThrowRuntime()
120         throws Error
121     {
122         if(nested == null)
123             return;
124         
125         switch (nested.size())
126         {
127           case 0:
128               break;
129           case 1:
130               Throwable th=nested.get(0);
131               if (th instanceof Error)
132                   throw (Error)th;
133               else if (th instanceof RuntimeException)
134                   throw (RuntimeException)th;
135               else
136                   throw new RuntimeException(th);
137           default:
138               throw new RuntimeException(this);
139         }
140     }
141     
142     /* ------------------------------------------------------------ */
143     /** Throw a multiexception.
144      * If this multi exception is empty then no action is taken. If it
145      * contains a any exceptions then this
146      * multi exception is thrown. 
147      */
148     public void ifExceptionThrowMulti()
149         throws MultiException
150     {
151         if(nested == null)
152             return;
153         
154         if (nested.size()>0)
155             throw this;
156     }
157 
158     /* ------------------------------------------------------------ */
159     @Override
160     public String toString()
161     {
162         StringBuilder str = new StringBuilder();
163         str.append(MultiException.class.getSimpleName());
164         if((nested == null) || (nested.size()<=0)) {
165             str.append("[]");
166         } else {
167             str.append(nested);
168         }
169         return str.toString();
170     }
171 
172     /* ------------------------------------------------------------ */
173     @Override
174     public void printStackTrace()
175     {
176         super.printStackTrace();
177         if(nested != null) {
178             for(Throwable t: nested) {
179                 t.printStackTrace();
180             }
181         }
182     }
183    
184 
185     /* ------------------------------------------------------------------------------- */
186     /**
187      * @see java.lang.Throwable#printStackTrace(java.io.PrintStream)
188      */
189     @Override
190     public void printStackTrace(PrintStream out)
191     {
192         super.printStackTrace(out);
193         if(nested != null) {
194             for(Throwable t: nested) {
195                 t.printStackTrace(out);
196             }
197         }
198     }
199 
200     /* ------------------------------------------------------------------------------- */
201     /**
202      * @see java.lang.Throwable#printStackTrace(java.io.PrintWriter)
203      */
204     @Override
205     public void printStackTrace(PrintWriter out)
206     {
207         super.printStackTrace(out);
208         if(nested != null) {
209             for(Throwable t: nested) {
210                 t.printStackTrace(out);
211             }
212         }
213     }
214 
215 }