1 16 package org.mortbay.jetty.servlet; 17 18 import java.io.IOException ; 19 import java.security.Principal ; 20 import java.util.Enumeration ; 21 import java.util.HashMap ; 22 import java.util.Map ; 23 import java.util.Stack ; 24 25 import javax.servlet.Servlet ; 26 import javax.servlet.ServletConfig ; 27 import javax.servlet.ServletContext ; 28 import javax.servlet.ServletException ; 29 import javax.servlet.ServletRequest ; 30 import javax.servlet.ServletResponse ; 31 import javax.servlet.UnavailableException ; 32 33 import org.apache.commons.logging.Log; 34 import org.mortbay.log.LogFactory; 35 import org.mortbay.http.HttpRequest; 36 import org.mortbay.http.UserRealm; 37 38 39 40 49 public class ServletHolder extends Holder 50 implements Comparable 51 { 52 private static Log log = LogFactory.getLog(ServletHolder.class); 53 54 55 56 private int _initOrder; 57 private boolean _initOnStartup=false; 58 private Map _roleMap; 59 private String _forcedPath; 60 private String _runAs; 61 private UserRealm _realm; 62 63 64 private transient Stack _servlets; 65 private transient Servlet _servlet; 66 private transient Config _config; 67 private transient long _unavailable; 68 private transient UnavailableException _unavailableEx; 69 70 71 72 74 public ServletHolder() 75 {} 76 77 78 79 84 public ServletHolder(ServletHandler handler, 85 String name, 86 String className) 87 { 88 super(handler,(name==null)?className:name,className); 89 } 90 91 92 100 public ServletHolder(ServletHandler handler, 101 String name, 102 String className, 103 String forcedPath) 104 { 105 this(handler,(name==null)?className:name,className); 106 _forcedPath=forcedPath; 107 } 108 109 110 111 public int getInitOrder() 112 { 113 return _initOrder; 114 } 115 116 117 122 public void setInitOrder(int order) 123 { 124 _initOnStartup=true; 125 _initOrder = order; 126 } 127 128 129 131 public int compareTo(Object o) 132 { 133 if (o instanceof ServletHolder) 134 { 135 ServletHolder sh= (ServletHolder)o; 136 if (sh==this) 137 return 0; 138 if (sh._initOrder<_initOrder) 139 return 1; 140 if (sh._initOrder>_initOrder) 141 return -1; 142 int c=_className.compareTo(sh._className); 143 if (c==0) 144 c=_name.compareTo(sh._name); 145 if (c==0) 146 c=this.hashCode()>o.hashCode()?1:-1; 147 return c; 148 } 149 return 1; 150 } 151 152 153 public boolean equals(Object o) 154 { 155 return compareTo(o)==0; 156 } 157 158 159 public int hashCode() 160 { 161 return _name.hashCode(); 162 } 163 164 165 public ServletContext getServletContext() 166 { 167 return ((ServletHandler)_httpHandler).getServletContext(); 168 } 169 170 171 177 public synchronized void setUserRoleLink(String name,String link) 178 { 179 if (_roleMap==null) 180 _roleMap=new HashMap (); 181 _roleMap.put(name,link); 182 } 183 184 185 190 public String getUserRoleLink(String name) 191 { 192 if (_roleMap==null) 193 return name; 194 String link=(String )_roleMap.get(name); 195 return (link==null)?name:link; 196 } 197 198 199 203 public void setRunAs(String role) 204 { 205 _runAs=role; 206 } 207 208 209 public String getRunAs() 210 { 211 return _runAs; 212 } 213 214 215 public void start() 216 throws Exception 217 { 218 _unavailable=0; 219 super.start(); 220 221 if (!javax.servlet.Servlet .class 222 .isAssignableFrom(_class)) 223 { 224 Exception ex = new IllegalStateException ("Servlet "+_class+ 225 " is not a javax.servlet.Servlet"); 226 super.stop(); 227 throw ex; 228 } 229 230 _config=new Config (); 231 if (_runAs!=null) 232 _realm=_httpHandler.getHttpContext().getRealm(); 233 234 if (javax.servlet.SingleThreadModel .class 235 .isAssignableFrom(_class)) 236 _servlets=new Stack (); 237 238 if (_initOnStartup) 239 { 240 _servlet=(Servlet )newInstance(); 241 try 242 { 243 initServlet(_servlet,_config); 244 } 245 catch(Throwable e) 246 { 247 _servlet=null; 248 _config=null; 249 if (e instanceof Exception ) 250 throw (Exception ) e; 251 else if (e instanceof Error ) 252 throw (Error )e; 253 else 254 throw new ServletException (e); 255 } 256 } 257 } 258 259 260 public void stop() 261 { 262 Principal user=null; 263 try 264 { 265 if (_runAs!=null && _realm!=null) 267 user=_realm.pushRole(null,_runAs); 268 269 if (_servlet!=null) 270 _servlet.destroy(); 271 _servlet=null; 272 273 while (_servlets!=null && _servlets.size()>0) 274 { 275 Servlet s = (Servlet )_servlets.pop(); 276 s.destroy(); 277 } 278 _config=null; 279 } 280 finally 281 { 282 super.stop(); 283 if (_runAs!=null && _realm!=null && user!=null) 285 _realm.popRole(user); 286 } 287 } 288 289 290 291 294 public synchronized Servlet getServlet() 295 throws ServletException 296 { 297 if (_unavailable!=0) 299 { 300 if (_unavailable<0 || _unavailable>0 && System.currentTimeMillis()<_unavailable) 301 throw _unavailableEx; 302 _unavailable=0; 303 _unavailableEx=null; 304 } 305 306 try 307 { 308 if (_servlets!=null) 309 { 310 Servlet servlet=null; 311 if (_servlets.size()==0) 312 { 313 servlet= (Servlet )newInstance(); 314 if (_config==null) 315 _config=new Config (); 316 initServlet(servlet,_config); 317 } 318 else 319 servlet = (Servlet )_servlets.pop(); 320 321 return servlet; 322 } 323 324 if (_servlet==null) 325 { 326 _servlet=(Servlet )newInstance(); 327 if (_config==null) 328 _config=new Config (); 329 initServlet(_servlet,_config); 330 } 331 332 return _servlet; 333 } 334 catch(UnavailableException e) 335 { 336 _servlet=null; 337 _config=null; 338 return makeUnavailable(e); 339 } 340 catch(ServletException e) 341 { 342 _servlet=null; 343 _config=null; 344 throw e; 345 } 346 catch(Throwable e) 347 { 348 _servlet=null; 349 _config=null; 350 throw new ServletException ("init",e); 351 } 352 } 353 354 355 private Servlet makeUnavailable(UnavailableException e) 356 throws UnavailableException 357 { 358 _unavailableEx=e; 359 _unavailable=-1; 360 if (e.isPermanent()) 361 _unavailable=-1; 362 else 363 { 364 if (_unavailableEx.getUnavailableSeconds()>0) 365 _unavailable=System.currentTimeMillis()+1000*_unavailableEx.getUnavailableSeconds(); 366 else 367 _unavailable=System.currentTimeMillis()+5000; } 369 370 throw _unavailableEx; 371 } 372 373 374 private void initServlet(Servlet servlet, ServletConfig config) 375 throws ServletException 376 { 377 Principal user=null; 378 try 379 { 380 if (_runAs!=null && _realm!=null) 382 user=_realm.pushRole(null,_runAs); 383 servlet.init(config); 384 } 385 finally 386 { 387 if (_runAs!=null && _realm!=null && user!=null) 389 _realm.popRole(user); 390 } 391 } 392 393 394 396 public void handle(ServletRequest request, 397 ServletResponse response) 398 throws ServletException , 399 UnavailableException , 400 IOException 401 { 402 if (_class==null) 403 throw new UnavailableException ("Servlet Not Initialized"); 404 405 Servlet servlet=(!_initOnStartup||_servlets!=null)?getServlet():_servlet; 406 if (servlet==null) 407 throw new UnavailableException ("Could not instantiate "+_class); 408 409 boolean servlet_error=true; 411 Principal user=null; 412 HttpRequest http_request=null; 413 try 414 { 415 if (_forcedPath!=null) 417 request.setAttribute("org.apache.catalina.jsp_file",_forcedPath); 419 420 if (_runAs!=null && _realm!=null) 422 { 423 http_request=getHttpContext().getHttpConnection().getRequest(); 424 user=_realm.pushRole(http_request.getUserPrincipal(),_runAs); 425 http_request.setUserPrincipal(user); 426 } 427 428 servlet.service(request,response); 429 servlet_error=false; 430 } 431 catch(UnavailableException e) 432 { 433 if (_servlets!=null && servlet!=null) 434 stop(); 435 makeUnavailable(e); 436 } 437 finally 438 { 439 if (_runAs!=null && _realm!=null && user!=null) 441 { 442 user=_realm.popRole(user); 443 http_request.setUserPrincipal(user); 444 } 445 446 if (servlet_error) 448 request.setAttribute("javax.servlet.error.servlet_name",getName()); 449 450 synchronized(this) 452 { 453 if (_servlets!=null && servlet!=null) 454 _servlets.push(servlet); 455 } 456 } 457 } 458 459 460 461 462 463 class Config implements ServletConfig 464 { 465 466 public String getServletName() 467 { 468 return getName(); 469 } 470 471 472 public ServletContext getServletContext() 473 { 474 return ((ServletHandler)_httpHandler).getServletContext(); 475 } 476 477 478 public String getInitParameter(String param) 479 { 480 return ServletHolder.this.getInitParameter(param); 481 } 482 483 484 public Enumeration getInitParameterNames() 485 { 486 return ServletHolder.this.getInitParameterNames(); 487 } 488 } 489 } 490 491 492 493 494 495 | Popular Tags |