001package Torello.HTML; 002 003import Torello.HTML.HTMLPage.Parser; 004 005import Torello.JavaDoc.Annotations.StaticFunctional; 006import Torello.JavaDoc.Annotations.StaticFunctional.Excuse; 007 008import java.io.*; 009 010import java.util.Vector; 011import java.net.URL; 012 013// This uses TimeUnit, Executors, and several exceptions. 014import java.util.concurrent.*; 015 016import java.util.concurrent.locks.Lock; 017import java.util.concurrent.locks.ReentrantLock; 018 019/** 020 * A carbon-copy of class {@link HTMLPage}, augmented with a mechanism for setting <B>a timeout</B> 021 * so that when scraping web-pages and {@code URL's} from servers that might have a tendency to hang, 022 * freeze, or delay - the Java Virtual Machine can skip and move-on when that timeout expires. 023 * 024 * <BR /><BR /> 025 * <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_MWT> 026 * <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE> 027 * 028 * @see Scrape#getHTML(BufferedReader, int, int) 029 * @see Scrape#getHTML(BufferedReader, String, String) 030 * @see HTMLPage 031 */ 032@Torello.JavaDoc.Annotations.StaticFunctional(Excused="parser", Excuses=Excuse.SINGLETON) 033@Torello.JavaDoc.Annotations.JDHeaderBackgroundImg 034public class HTMLPageMWT 035{ 036 private HTMLPageMWT() { } 037 038 /** 039 * If needing to "swap a proprietary parser" comes up, this is possible. 040 * It just needs to accept the same parameters as the current parser, and produce a 041 * {@code Vector<HTMLNode>.} This is not an advised step to take, but if an alternative 042 * parser has been tested and happens to be generating different results, it can be easily 043 * 'swapped out' for the one used now. 044 * @see HTMLPage.Parser 045 * @see HTMLPage.Parser#parse(CharSequence, boolean, String, String, String) 046 */ 047 public static Parser parser = ParserRE::parsePageTokens; 048 049 050 // ******************************************************************************************** 051 // ******************************************************************************************** 052 // These 6 functions presume that the HTML source is from a URL 053 // ******************************************************************************************** 054 // ******************************************************************************************** 055 056 057 /** 058 * Convenience Method. 059 * <BR />Accepts: {@code URL} and Time-Out Parameters {@code 'timeout' & 'unit'} 060 * <BR />Passes null to parameters 061 * {@code startTag, endTag, rawHTMLFile, matchesFile & justTextFile}. 062 * <BR />Invokes: {@link #getPageTokens(long, TimeUnit, URL, boolean, String, String, 063 * String, String, String)} 064 */ 065 public static Vector<HTMLNode> getPageTokens 066 (long timeout, TimeUnit unit, URL url, boolean eliminateHTMLTags) 067 throws IOException, InterruptedException 068 { 069 return getPageTokens(timeout, unit, url, eliminateHTMLTags, null, null, null, null, null); 070 } 071 072 /** 073 * Convenience Method. 074 * <BR />Accepts: {@code URL} and Time-Out Parameters {@code 'timeout' & 'unit'} 075 * <BR />And-Accepts: {@code 'startTag'} and {@code 'endTag'} 076 * <BR />Passes null to parameters {@code rawHTMLFile, matchesFile & justTextFile}. 077 * <BR />Invokes: {@link #getPageTokens(long, TimeUnit, URL, boolean, String, String, 078 * String, String, String)} 079 */ 080 public static Vector<HTMLNode> getPageTokens( 081 long timeout, TimeUnit unit, 082 URL url, boolean eliminateHTMLTags, 083 String startTag, String endTag 084 ) 085 throws IOException, InterruptedException 086 { 087 return getPageTokens 088 (timeout, unit, url, eliminateHTMLTags, startTag, endTag, null, null, null); 089 } 090 091 /** 092 * Convenience Method. 093 * <BR />Accepts: {@code URL} and Time-Out Parameters {@code 'timeout' & 'unit'} 094 * <BR />And-Accepts: {@code 'startLineNum'} and {@code 'endLineNum'} 095 * <BR />Passes null to parameters {@code rawHTMLFile, matchesFile & justTextFile}. 096 * <BR />Invokes: {@link #getPageTokens(long, TimeUnit, URL, boolean, int, int, 097 * String, String, String)} 098 */ 099 public static Vector<HTMLNode> getPageTokens( 100 long timeout, TimeUnit unit, 101 URL url, boolean eliminateHTMLTags, 102 int startLineNum, int endLineNum 103 ) 104 throws IOException, InterruptedException 105 { 106 return getPageTokens 107 (timeout, unit, url, eliminateHTMLTags, startLineNum, endLineNum, null, null, null); 108 } 109 110 /** 111 * Convenience Method. 112 * <BR />Accepts: {@code URL} and Time-Out Parameters {@code 'timeout' & 'unit'} 113 * <BR />Passes null to {@code startTag} & {@code endTag} parameters. 114 * <BR />Invokes: {@link #getPageTokens(long, TimeUnit, URL, boolean, String, String, 115 * String, String, String)} 116 */ 117 public static Vector<HTMLNode> getPageTokens( 118 long timeout, TimeUnit unit, 119 URL url, boolean eliminateHTMLTags, 120 String rawHTMLFile, String matchesFile, String justTextFile 121 ) 122 throws IOException, InterruptedException 123 { 124 return getPageTokens( 125 timeout, unit, url, eliminateHTMLTags, null, null, 126 rawHTMLFile, matchesFile, justTextFile 127 ); 128 } 129 130 131 // ******************************************************************************************** 132 // ******************************************************************************************** 133 // The next 6 functions presume that the input is from a BufferedReader 134 // ******************************************************************************************** 135 // ******************************************************************************************** 136 137 /** 138 * Convenience Method. 139 * <BR />Accepts: {@code BufferedReader} 140 * <BR />Passes null to parameters 141 * {@code startTag, endTag, rawHTMLFile, matchesFile & justTextFile}. 142 * <BR />Invokes: {@link #getPageTokens(long, TimeUnit, BufferedReader, boolean, 143 * String, String, String, String, String)} 144 */ 145 public static Vector<HTMLNode> getPageTokens 146 (long timeout, TimeUnit unit, BufferedReader br, boolean eliminateHTMLTags) 147 throws IOException, InterruptedException 148 { 149 return getPageTokens 150 (timeout, unit, br, eliminateHTMLTags, null, null, null, null, null); 151 } 152 153 /** 154 * Convenience Method. 155 * <BR />Accepts: {@code BufferedReader} 156 * <BR />And-Accepts: {@code 'startTag'} and {@code 'endTag'} 157 * <BR />Passes null to parameters {@code rawHTMLFile, matchesFile & justTextFile}. 158 * <BR />Invokes: {@link #getPageTokens(long, TimeUnit, BufferedReader, boolean, 159 * String, String, String, String, String)} 160 */ 161 public static Vector<HTMLNode> getPageTokens( 162 long timeout, TimeUnit unit, 163 BufferedReader br, boolean eliminateHTMLTags, String startTag, String endTag 164 ) 165 throws IOException, InterruptedException 166 { 167 return getPageTokens 168 (timeout, unit, br, eliminateHTMLTags, startTag, endTag, null, null, null); 169 } 170 171 /** 172 * Convenience Method. 173 * <BR />Accepts: {@code BufferedReader} 174 * <BR />And-Accepts: {@code 'startLineNum'} and {@code 'endLineNum'} 175 * <BR />Passes null to parameters {@code rawHTMLFile, matchesFile & justTextFile}. 176 * <BR />Invokes: {@link #getPageTokens(long, TimeUnit, BufferedReader, boolean, 177 * int, int, String, String, String)} 178 */ 179 public static Vector<HTMLNode> getPageTokens( 180 long timeout, TimeUnit unit, 181 BufferedReader br, boolean eliminateHTMLTags, 182 int startLineNum, int endLineNum 183 ) 184 throws IOException, InterruptedException 185 { 186 return getPageTokens 187 (timeout, unit, br, eliminateHTMLTags, startLineNum, endLineNum, null, null, null); 188 } 189 190 /** 191 * Convenience Method. 192 * <BR />Accepts: {@code BufferedReader} 193 * <BR />Passes null to {@code startTag} & {@code endTag} parameters. 194 * <BR />Invokes: {@link #getPageTokens(long, TimeUnit, BufferedReader, boolean, 195 * String, String, String, String, String)} 196 */ 197 public static Vector<HTMLNode> getPageTokens( 198 long timeout, TimeUnit unit, 199 BufferedReader br, boolean eliminateHTMLTags, 200 String rawHTMLFile, String matchesFile, String justTextFile 201 ) 202 throws IOException, InterruptedException 203 { 204 return getPageTokens 205 (timeout, unit, br, eliminateHTMLTags, null, null, rawHTMLFile, matchesFile, justTextFile); 206 } 207 208 209 // ******************************************************************************************** 210 // ******************************************************************************************** 211 // * Receives a "pre-instantiated" BufferedReader for the HTML Source parameter 212 // ******************************************************************************************** 213 // ******************************************************************************************** 214 215 216 private static final ExecutorService executor = Executors.newCachedThreadPool(); 217 private static final Lock lock = new ReentrantLock(); 218 219 /** 220 * If this class has been used to make "multi-threaded" calls that use a Time-Out wait-period, 221 * you might see your Java-Program hang for a few seconds when you would expect it to exit back 222 * to your O.S. normally. 223 * 224 * <BR /><BR /><B>Max Wait Time</B> operates by building a "Timeout & Monitor" thread, and 225 * therefore when a program you have written yourself reaches the end of its code, <I><B>if you 226 * have performed any Internet-Downloads using {@code class HTMLPageMWT}</B></I>, then your 227 * program <I>might not exit immediately,</I> but rather sit at the command-prompt for anywhere 228 * between 10 and 30 seconds before this Timeout-Thread, created in class HTMLPageMWT, dies. 229 * 230 * <BR /><BR /><B CLASS=JDDescLabel>Multi-Threaded:</B> 231 * 232 * <BR />You may also immediately terminate any additional threads that were started by using 233 * this method. 234 */ 235 public static void shutdownMWTThreads() { executor.shutdownNow(); } 236 237 /** 238 * Parses and Vectorizes HTML from a {@code BufferedReader} source. 239 * Spawns a <I>monitor-thread</I> that stops the download if a 240 * certain, user-specified, time-limit is exceeded. 241 * @param timeout <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_TIMEOUT> 242 * @param unit <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_UNIT> 243 * @param br <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_BR> 244 * @param eliminateHTMLTags <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_ELIM_HT> 245 * @param startTag <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_START_TAG> 246 * @param endTag <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_END_TAG> 247 * @param rawHTMLFile <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_RAW_HTML> 248 * @param matchesFile <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_MATCHES_F> 249 * @param justTextFile <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_JUST_TEXT> 250 * @return <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_RETURN> 251 * @throws ScrapeException <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_SCEX2> 252 * @throws IOException <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_IOEX> 253 * @throws InterruptedException <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_IEX> 254 * @throws RejectedExecutionException <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_REEX> 255 */ 256 public static Vector<HTMLNode> getPageTokens( 257 long timeout, TimeUnit unit, 258 BufferedReader br, boolean eliminateHTMLTags, 259 String startTag, String endTag, 260 String rawHTMLFile, String matchesFile, String justTextFile 261 ) 262 throws IOException, InterruptedException 263 { 264 Callable<Vector<HTMLNode>> threadDownloader = new Callable<Vector<HTMLNode>>() 265 { 266 public Vector<HTMLNode> call() throws Exception 267 { 268 return parser.parse( 269 Scrape.getHTML(br, startTag, endTag), 270 eliminateHTMLTags, rawHTMLFile, matchesFile, justTextFile 271 ); 272 } 273 }; 274 275 lock.lock(); 276 Future<Vector<HTMLNode>> future = executor.submit(threadDownloader); 277 lock.unlock(); 278 279 try 280 { return future.get(timeout, unit); } 281 282 catch (TimeoutException e) { return null; } 283 284 catch (ExecutionException e) 285 { 286 Throwable originalException = e.getCause(); 287 if (originalException == null) throw new RejectedExecutionException( 288 "An Execution Exception was thrown, but it did provide a cause throwable " + 289 "(e.getCause() returned null). See this exception's getCause() method to " + 290 "view the ExecutionException that has occurred.", 291 e 292 ); 293 294 if (originalException instanceof IOException) 295 throw (IOException) originalException; 296 297 if (originalException instanceof RuntimeException) 298 throw (RuntimeException) originalException; 299 300 throw new RejectedExecutionException( 301 "An Execution Exception occurred, but it was neither a RuntimeException, " + 302 "nor IOException. See this exception's getCause() method to view the " + 303 "underlying error that has occurred.", originalException 304 ); 305 } 306 } 307 308 /** 309 * Parses and Vectorizes HTML from a {@code BufferedReader} source. 310 * Spawns a <I>monitor-thread</I> that stops the download if a 311 * certain, user-specified, time-limit is exceeded. 312 * @param timeout <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_TIMEOUT> 313 * @param unit <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_UNIT> 314 * @param br <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_BR> 315 * @param eliminateHTMLTags <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_ELIM_HT> 316 * @param startLineNum <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_START_LN> 317 * @param endLineNum <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_END_LN> 318 * @param rawHTMLFile <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_RAW_HTML> 319 * @param matchesFile <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_MATCHES_F> 320 * @param justTextFile <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_JUST_TEXT> 321 * @return <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_RETURN> 322 * @throws IllegalArgumentException <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_IAEX> 323 * @throws ScrapeException <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_SCEX1> 324 * @throws IOException <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_IOEX> 325 * @throws InterruptedException <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_IEX> 326 * @throws RejectedExecutionException <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_REEX> 327 */ 328 public static Vector<HTMLNode> getPageTokens( 329 long timeout, TimeUnit unit, 330 BufferedReader br, boolean eliminateHTMLTags, 331 int startLineNum, int endLineNum, 332 String rawHTMLFile, String matchesFile, String justTextFile 333 ) 334 throws IOException, InterruptedException 335 { 336 Callable<Vector<HTMLNode>> threadDownloader = new Callable<Vector<HTMLNode>>() 337 { 338 public Vector<HTMLNode> call() throws Exception 339 { 340 return parser.parse( 341 Scrape.getHTML(br, startLineNum, endLineNum), 342 eliminateHTMLTags, rawHTMLFile, matchesFile, justTextFile 343 ); 344 } 345 }; 346 347 lock.lock(); 348 Future<Vector<HTMLNode>> future = executor.submit(threadDownloader); 349 lock.unlock(); 350 351 try 352 { return future.get(timeout, unit); } 353 354 catch (TimeoutException e) { return null; } 355 356 catch (ExecutionException e) 357 { 358 Throwable originalException = e.getCause(); 359 360 if (originalException == null) throw new RejectedExecutionException( 361 "An Execution Exception was thrown, but it did provide a cause throwable " + 362 "(e.getCause() returned null). See this exception's getCause() method to " + 363 "view the ExecutionException has that occurred.", 364 e 365 ); 366 367 if (originalException instanceof IOException) 368 throw (IOException) originalException; 369 370 if (originalException instanceof RuntimeException) 371 throw (RuntimeException) originalException; 372 373 throw new RejectedExecutionException( 374 "An Execution Exception occurred, but it was neither a RuntimeException, nor " + 375 "IOException. See this exception's getCause() method to view the underlying " + 376 "error that has occurred.", originalException 377 ); 378 } 379 } 380 381 382 // ******************************************************************************************** 383 // ******************************************************************************************** 384 // Receives a java.net.URL for the HTML Source parameter -- that could Timeout/Hang 385 // ******************************************************************************************** 386 // ******************************************************************************************** 387 388 389 // It must be opened within the Multi-Threaded "Timeout" code (and therefore requires a second 390 // version of these two methods - where Scrape.openConn(url) is *inside* the monitored 391 // downloading thread. 392 393 /** 394 * Parses and Vectorizes HTML from a URL source. 395 * Spawns a <I>monitor-thread</I> that stops the download if a certain, user-specified, 396 * time-limit is exceeded. 397 * @param timeout <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_TIMEOUT> 398 * @param unit <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_UNIT> 399 * @param url <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_URL> 400 * @param eliminateHTMLTags <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_ELIM_HT> 401 * @param startTag <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_START_TAG> 402 * @param endTag <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_END_TAG> 403 * @param rawHTMLFile <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_RAW_HTML> 404 * @param matchesFile <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_MATCHES_F> 405 * @param justTextFile <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_JUST_TEXT> 406 * @return <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_RETURN> 407 * @throws ScrapeException <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_SCEX2> 408 * @throws IOException <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_IOEX> 409 * @throws InterruptedException <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_IEX> 410 * @throws RejectedExecutionException <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_REEX> 411 */ 412 public static Vector<HTMLNode> getPageTokens( 413 long timeout, TimeUnit unit, 414 URL url, boolean eliminateHTMLTags, 415 String startTag, String endTag, 416 String rawHTMLFile, String matchesFile, String justTextFile 417 ) 418 throws IOException, InterruptedException 419 { 420 Callable<Vector<HTMLNode>> threadDownloader = new Callable<Vector<HTMLNode>>() 421 { 422 public Vector<HTMLNode> call() throws Exception 423 { 424 return parser.parse( 425 Scrape.getHTML(Scrape.openConn(url), startTag, endTag), 426 eliminateHTMLTags, rawHTMLFile, matchesFile, justTextFile 427 ); 428 } 429 }; 430 431 lock.lock(); 432 Future<Vector<HTMLNode>> future = executor.submit(threadDownloader); 433 lock.unlock(); 434 435 try 436 { return future.get(timeout, unit); } 437 438 catch (TimeoutException e) { return null; } 439 440 catch (ExecutionException e) 441 { 442 Throwable originalException = e.getCause(); 443 444 if (originalException == null) throw new RejectedExecutionException( 445 "An Execution Exception was thrown, but it did provide a cause throwable " + 446 "(e.getCause() returned null). See this exception's getCause() method to " + 447 "view the ExecutionException that has occurred.", e 448 ); 449 450 if (originalException instanceof IOException) 451 throw (IOException) originalException; 452 453 if (originalException instanceof RuntimeException) 454 throw (RuntimeException) originalException; 455 456 throw new RejectedExecutionException( 457 "An Execution Exception occurred, but it was neither a RuntimeException, " + 458 "nor IOException. See this exception's getCause() method to view the " + 459 "underlying error that has occurred.", originalException 460 ); 461 } 462 } 463 464 465 /** 466 * Parses and Vectorizes HTML from a URL source. 467 * Spawns a <I>monitor-thread</I> that stops the download if a certain, user-specified, 468 * time-limit is exceeded. 469 * @param timeout <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_TIMEOUT> 470 * @param unit <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_UNIT> 471 * @param url <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_URL> 472 * @param eliminateHTMLTags <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_ELIM_HT> 473 * @param startLineNum <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_START_LN> 474 * @param endLineNum <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_END_LN> 475 * @param rawHTMLFile <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_RAW_HTML> 476 * @param matchesFile <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_MATCHES_F> 477 * @param justTextFile <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_JUST_TEXT> 478 * @return <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_RETURN> 479 * @throws IllegalArgumentException <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_IAEX> 480 * @throws ScrapeException <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_SCEX1> 481 * @throws IOException <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_IOEX> 482 * @throws InterruptedException <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_IEX> 483 * @throws RejectedExecutionException <EMBED CLASS='external-html' DATA-FILE-ID=HTML_PAGE_REEX> 484 */ 485 public static Vector<HTMLNode> getPageTokens( 486 long timeout, TimeUnit unit, 487 URL url, boolean eliminateHTMLTags, 488 int startLineNum, int endLineNum, 489 String rawHTMLFile, String matchesFile, String justTextFile 490 ) 491 throws IOException, InterruptedException 492 { 493 Callable<Vector<HTMLNode>> threadDownloader = new Callable<Vector<HTMLNode>>() 494 { 495 public Vector<HTMLNode> call() throws Exception 496 { 497 return parser.parse( 498 Scrape.getHTML(Scrape.openConn(url), startLineNum, endLineNum), 499 eliminateHTMLTags, rawHTMLFile, matchesFile, justTextFile 500 ); 501 } 502 }; 503 504 lock.lock(); 505 Future<Vector<HTMLNode>> future = executor.submit(threadDownloader); 506 lock.unlock(); 507 508 try 509 { return future.get(timeout, unit); } 510 511 catch (TimeoutException e) { return null; } 512 513 catch (ExecutionException e) 514 { 515 Throwable originalException = e.getCause(); 516 517 if (originalException == null) throw new RejectedExecutionException( 518 "An Execution Exception was thrown, but it did provide a cause throwable " + 519 "(e.getCause() returned null). See this exception's getCause() method to " + 520 "view the ExecutionException has that occurred.", 521 e 522 ); 523 524 if (originalException instanceof IOException) 525 throw (IOException) originalException; 526 527 if (originalException instanceof RuntimeException) 528 throw (RuntimeException) originalException; 529 530 throw new RejectedExecutionException( 531 "An Execution Exception occurred, but it was neither a RuntimeException, nor " + 532 "IOException. See this exception's getCause() method to view the underlying " + 533 "error that has occurred.", originalException 534 ); 535 } 536 } 537}