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