View Javadoc

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