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