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