1 17 18 package org.apache.jasper.servlet; 19 20 import java.io.BufferedReader ; 21 import java.io.FileInputStream ; 22 import java.io.FileNotFoundException ; 23 import java.io.IOException ; 24 import java.io.InputStream ; 25 import java.io.InputStreamReader ; 26 import java.net.URL ; 27 import java.util.ArrayList ; 28 import java.util.List ; 29 30 import javax.servlet.Servlet ; 31 import javax.servlet.ServletConfig ; 32 import javax.servlet.ServletContext ; 33 import javax.servlet.ServletException ; 34 import javax.servlet.SingleThreadModel ; 35 import javax.servlet.UnavailableException ; 36 import javax.servlet.http.HttpServletRequest ; 37 import javax.servlet.http.HttpServletResponse ; 38 import javax.servlet.jsp.tagext.TagInfo ; 39 40 import org.apache.AnnotationProcessor; 41 import org.apache.commons.logging.Log; 42 import org.apache.commons.logging.LogFactory; 43 import org.apache.jasper.JasperException; 44 import org.apache.jasper.JspCompilationContext; 45 import org.apache.jasper.Options; 46 import org.apache.jasper.compiler.ErrorDispatcher; 47 import org.apache.jasper.compiler.JavacErrorDetail; 48 import org.apache.jasper.compiler.JspRuntimeContext; 49 import org.apache.jasper.compiler.Localizer; 50 import org.apache.jasper.runtime.JspSourceDependent; 51 52 69 70 public class JspServletWrapper { 71 72 private Log log = LogFactory.getLog(JspServletWrapper.class); 74 75 private Servlet theServlet; 76 private String jspUri; 77 private Class servletClass; 78 private Class tagHandlerClass; 79 private JspCompilationContext ctxt; 80 private long available = 0L; 81 private ServletConfig config; 82 private Options options; 83 private boolean firstTime = true; 84 private boolean reload = true; 85 private boolean isTagFile; 86 private int tripCount; 87 private JasperException compileException; 88 private long servletClassLastModifiedTime; 89 private long lastModificationTest = 0L; 90 91 94 public JspServletWrapper(ServletConfig config, Options options, String jspUri, 95 boolean isErrorPage, JspRuntimeContext rctxt) 96 throws JasperException { 97 98 this.isTagFile = false; 99 this.config = config; 100 this.options = options; 101 this.jspUri = jspUri; 102 ctxt = new JspCompilationContext(jspUri, isErrorPage, options, 103 config.getServletContext(), 104 this, rctxt); 105 } 106 107 110 public JspServletWrapper(ServletContext servletContext, 111 Options options, 112 String tagFilePath, 113 TagInfo tagInfo, 114 JspRuntimeContext rctxt, 115 URL tagFileJarUrl) 116 throws JasperException { 117 118 this.isTagFile = true; 119 this.config = null; this.options = options; 121 this.jspUri = tagFilePath; 122 this.tripCount = 0; 123 ctxt = new JspCompilationContext(jspUri, tagInfo, options, 124 servletContext, this, rctxt, 125 tagFileJarUrl); 126 } 127 128 public JspCompilationContext getJspEngineContext() { 129 return ctxt; 130 } 131 132 public void setReload(boolean reload) { 133 this.reload = reload; 134 } 135 136 public Servlet getServlet() 137 throws ServletException , IOException , FileNotFoundException 138 { 139 if (reload) { 140 synchronized (this) { 141 if (reload) { 144 destroy(); 146 147 try { 148 servletClass = ctxt.load(); 149 theServlet = (Servlet ) servletClass.newInstance(); 150 AnnotationProcessor annotationProcessor = (AnnotationProcessor) config.getServletContext().getAttribute(AnnotationProcessor.class.getName()); 151 if (annotationProcessor != null) { 152 annotationProcessor.processAnnotations(theServlet); 153 annotationProcessor.postConstruct(theServlet); 154 } 155 } catch (IllegalAccessException e) { 156 throw new JasperException(e); 157 } catch (InstantiationException e) { 158 throw new JasperException(e); 159 } catch (Exception e) { 160 throw new JasperException(e); 161 } 162 163 theServlet.init(config); 164 165 if (!firstTime) { 166 ctxt.getRuntimeContext().incrementJspReloadCount(); 167 } 168 169 reload = false; 170 } 171 } 172 } 173 return theServlet; 174 } 175 176 public ServletContext getServletContext() { 177 return config.getServletContext(); 178 } 179 180 185 public void setCompilationException(JasperException je) { 186 this.compileException = je; 187 } 188 189 195 public void setServletClassLastModifiedTime(long lastModified) { 196 if (this.servletClassLastModifiedTime < lastModified) { 197 synchronized (this) { 198 if (this.servletClassLastModifiedTime < lastModified) { 199 this.servletClassLastModifiedTime = lastModified; 200 reload = true; 201 } 202 } 203 } 204 } 205 206 209 public Class loadTagFile() throws JasperException { 210 211 try { 212 if (ctxt.isRemoved()) { 213 throw new FileNotFoundException (jspUri); 214 } 215 if (options.getDevelopment() || firstTime ) { 216 synchronized (this) { 217 firstTime = false; 218 ctxt.compile(); 219 } 220 } else { 221 if (compileException != null) { 222 throw compileException; 223 } 224 } 225 226 if (reload) { 227 tagHandlerClass = ctxt.load(); 228 reload = false; 229 } 230 } catch (FileNotFoundException ex) { 231 throw new JasperException(ex); 232 } 233 234 return tagHandlerClass; 235 } 236 237 243 public Class loadTagFilePrototype() throws JasperException { 244 245 ctxt.setPrototypeMode(true); 246 try { 247 return loadTagFile(); 248 } finally { 249 ctxt.setPrototypeMode(false); 250 } 251 } 252 253 256 public java.util.List getDependants() { 257 try { 258 Object target; 259 if (isTagFile) { 260 if (reload) { 261 tagHandlerClass = ctxt.load(); 262 reload = false; 263 } 264 target = tagHandlerClass.newInstance(); 265 } else { 266 target = getServlet(); 267 } 268 if (target != null && target instanceof JspSourceDependent) { 269 return ((java.util.List ) ((JspSourceDependent) target).getDependants()); 270 } 271 } catch (Throwable ex) { 272 } 273 return null; 274 } 275 276 public boolean isTagFile() { 277 return this.isTagFile; 278 } 279 280 public int incTripCount() { 281 return tripCount++; 282 } 283 284 public int decTripCount() { 285 return tripCount--; 286 } 287 288 public void service(HttpServletRequest request, 289 HttpServletResponse response, 290 boolean precompile) 291 throws ServletException , IOException , FileNotFoundException { 292 293 try { 294 295 if (ctxt.isRemoved()) { 296 throw new FileNotFoundException (jspUri); 297 } 298 299 if ((available > 0L) && (available < Long.MAX_VALUE)) { 300 response.setDateHeader("Retry-After", available); 301 response.sendError 302 (HttpServletResponse.SC_SERVICE_UNAVAILABLE, 303 Localizer.getMessage("jsp.error.unavailable")); 304 } 305 306 309 if (options.getDevelopment() || firstTime ) { 310 synchronized (this) { 311 firstTime = false; 312 313 ctxt.compile(); 315 } 316 } else { 317 if (compileException != null) { 318 throw compileException; 320 } 321 } 322 323 326 getServlet(); 327 328 if (precompile) { 330 return; 331 } 332 333 } catch (FileNotFoundException ex) { 334 ctxt.incrementRemoved(); 335 String includeRequestUri = (String ) 336 request.getAttribute("javax.servlet.include.request_uri"); 337 if (includeRequestUri != null) { 338 throw new ServletException (ex); 342 } else { 343 try { 344 response.sendError(HttpServletResponse.SC_NOT_FOUND, 345 ex.getMessage()); 346 } catch (IllegalStateException ise) { 347 log.error(Localizer.getMessage("jsp.error.file.not.found", 348 ex.getMessage()), 349 ex); 350 } 351 } 352 } catch (ServletException ex) { 353 if (options.getDevelopment()) { 354 throw handleJspException(ex); 355 } else { 356 throw ex; 357 } 358 } catch (IOException ex) { 359 if (options.getDevelopment()) { 360 throw handleJspException(ex); 361 } else { 362 throw ex; 363 } 364 } catch (IllegalStateException ex) { 365 if (options.getDevelopment()) { 366 throw handleJspException(ex); 367 } else { 368 throw ex; 369 } 370 } catch (Exception ex) { 371 if (options.getDevelopment()) { 372 throw handleJspException(ex); 373 } else { 374 throw new JasperException(ex); 375 } 376 } 377 378 try { 379 380 383 if (theServlet instanceof SingleThreadModel ) { 384 synchronized (this) { 387 theServlet.service(request, response); 388 } 389 } else { 390 theServlet.service(request, response); 391 } 392 393 } catch (UnavailableException ex) { 394 String includeRequestUri = (String ) 395 request.getAttribute("javax.servlet.include.request_uri"); 396 if (includeRequestUri != null) { 397 throw ex; 401 } else { 402 int unavailableSeconds = ex.getUnavailableSeconds(); 403 if (unavailableSeconds <= 0) { 404 unavailableSeconds = 60; } 406 available = System.currentTimeMillis() + 407 (unavailableSeconds * 1000L); 408 response.sendError 409 (HttpServletResponse.SC_SERVICE_UNAVAILABLE, 410 ex.getMessage()); 411 } 412 } catch (ServletException ex) { 413 if(options.getDevelopment()) { 414 throw handleJspException(ex); 415 } else { 416 throw ex; 417 } 418 } catch (IOException ex) { 419 if(options.getDevelopment()) { 420 throw handleJspException(ex); 421 } else { 422 throw ex; 423 } 424 } catch (IllegalStateException ex) { 425 if(options.getDevelopment()) { 426 throw handleJspException(ex); 427 } else { 428 throw ex; 429 } 430 } catch (Exception ex) { 431 if(options.getDevelopment()) { 432 throw handleJspException(ex); 433 } else { 434 throw new JasperException(ex); 435 } 436 } 437 } 438 439 public void destroy() { 440 if (theServlet != null) { 441 theServlet.destroy(); 442 AnnotationProcessor annotationProcessor = (AnnotationProcessor) config.getServletContext().getAttribute(AnnotationProcessor.class.getName()); 443 if (annotationProcessor != null) { 444 try { 445 annotationProcessor.preDestroy(theServlet); 446 } catch (Exception e) { 447 log.error(Localizer.getMessage("jsp.error.file.not.found", 449 e.getMessage()), e); 450 } 451 } 452 } 453 } 454 455 458 public long getLastModificationTest() { 459 return lastModificationTest; 460 } 461 464 public void setLastModificationTest(long lastModificationTest) { 465 this.lastModificationTest = lastModificationTest; 466 } 467 468 481 protected JasperException handleJspException(Exception ex) { 482 try { 483 Throwable realException = ex; 484 if (ex instanceof ServletException ) { 485 realException = ((ServletException ) ex).getRootCause(); 486 } 487 488 StackTraceElement [] frames = realException.getStackTrace(); 490 StackTraceElement jspFrame = null; 491 492 for (int i=0; i<frames.length; ++i) { 493 if ( frames[i].getClassName().equals(this.getServlet().getClass().getName()) ) { 494 jspFrame = frames[i]; 495 break; 496 } 497 } 498 499 if (jspFrame == null) { 500 return new JasperException(ex); 503 } 504 else { 505 int javaLineNumber = jspFrame.getLineNumber(); 506 JavacErrorDetail detail = ErrorDispatcher.createJavacError( 507 jspFrame.getMethodName(), 508 this.ctxt.getCompiler().getPageNodes(), 509 null, 510 javaLineNumber); 511 512 int jspLineNumber = detail.getJspBeginLineNumber(); 515 if (jspLineNumber < 1) { 516 throw new JasperException(ex); 517 } 518 519 if (options.getDisplaySourceFragment()) { 520 521 String [] jspLines = readFile 523 (this.ctxt.getResourceAsStream(this.ctxt.getJspFile())); 524 525 String [] javaLines = readFile 526 (new FileInputStream (this.ctxt.getServletJavaFileName())); 527 528 if (jspLines[jspLineNumber-1].lastIndexOf("<%") > 532 jspLines[jspLineNumber-1].lastIndexOf("%>")) { 533 String javaLine = javaLines[javaLineNumber-1].trim(); 534 535 for (int i=jspLineNumber-1; i<jspLines.length; i++) { 536 if (jspLines[i].indexOf(javaLine) != -1) { 537 jspLineNumber = i+1; 538 break; 539 } 540 } 541 } 542 543 StringBuffer buffer = new StringBuffer (1024); 545 int startIndex = Math.max(0, jspLineNumber-1-3); 546 int endIndex = Math.min(jspLines.length-1, jspLineNumber-1+3); 547 548 for (int i=startIndex;i<=endIndex; ++i) { 549 buffer.append(i+1); 550 buffer.append(": "); 551 buffer.append(jspLines[i]); 552 buffer.append("\n"); 553 } 554 555 return new JasperException(Localizer.getMessage 556 ("jsp.exception", detail.getJspFileName(), "" + jspLineNumber) + "\n" + buffer, ex); 557 558 } else { 559 return new JasperException(Localizer.getMessage 560 ("jsp.exception", detail.getJspFileName(), "" + jspLineNumber), ex); 561 } 562 } 563 } catch (Exception je) { 564 return new JasperException(ex); 566 } 567 } 568 569 573 private String [] readFile(InputStream s) throws IOException { 574 BufferedReader reader = new BufferedReader (new InputStreamReader (s)); 575 List lines = new ArrayList (); 576 String line; 577 578 while ( (line = reader.readLine()) != null ) { 579 lines.add(line); 580 } 581 582 return (String []) lines.toArray( new String [lines.size()] ); 583 } 584 585 } 586 | Popular Tags |