1 17 18 package org.apache.geronimo.jetty; 19 20 import java.io.IOException ; 21 import java.net.URI ; 22 import java.net.URL ; 23 import java.security.PermissionCollection ; 24 import java.util.Collection ; 25 import java.util.EventListener ; 26 import java.util.Hashtable ; 27 import java.util.Iterator ; 28 import java.util.Map ; 29 import java.util.Set ; 30 import javax.management.MalformedObjectNameException ; 31 import javax.management.ObjectName ; 32 import javax.naming.Context ; 33 34 import org.apache.commons.logging.Log; 35 import org.apache.commons.logging.LogFactory; 36 import org.apache.geronimo.gbean.GBeanInfo; 37 import org.apache.geronimo.gbean.GBeanInfoBuilder; 38 import org.apache.geronimo.gbean.GBeanLifecycle; 39 import org.apache.geronimo.j2ee.j2eeobjectnames.J2eeContext; 40 import org.apache.geronimo.j2ee.j2eeobjectnames.J2eeContextImpl; 41 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory; 42 import org.apache.geronimo.j2ee.management.J2EEApplication; 43 import org.apache.geronimo.j2ee.management.J2EEServer; 44 import org.apache.geronimo.j2ee.management.impl.InvalidObjectNameException; 45 import org.apache.geronimo.j2ee.management.impl.Util; 46 import org.apache.geronimo.jetty.interceptor.BeforeAfter; 47 import org.apache.geronimo.jetty.interceptor.ComponentContextBeforeAfter; 48 import org.apache.geronimo.jetty.interceptor.InstanceContextBeforeAfter; 49 import org.apache.geronimo.jetty.interceptor.RequestWrappingBeforeAfter; 50 import org.apache.geronimo.jetty.interceptor.SecurityContextBeforeAfter; 51 import org.apache.geronimo.jetty.interceptor.ThreadClassloaderBeforeAfter; 52 import org.apache.geronimo.jetty.interceptor.TransactionContextBeforeAfter; 53 import org.apache.geronimo.jetty.interceptor.WebApplicationContextBeforeAfter; 54 import org.apache.geronimo.kernel.Kernel; 55 import org.apache.geronimo.kernel.jmx.JMXUtil; 56 import org.apache.geronimo.naming.java.SimpleReadOnlyContext; 57 import org.apache.geronimo.naming.reference.ClassLoaderAwareReference; 58 import org.apache.geronimo.naming.reference.KernelAwareReference; 59 import org.apache.geronimo.security.deploy.DefaultPrincipal; 60 import org.apache.geronimo.security.jacc.RoleDesignateSource; 61 import org.apache.geronimo.transaction.TrackedConnectionAssociator; 62 import org.apache.geronimo.transaction.context.OnlineUserTransaction; 63 import org.apache.geronimo.transaction.context.TransactionContextManager; 64 import org.mortbay.http.Authenticator; 65 import org.mortbay.http.HttpException; 66 import org.mortbay.http.HttpRequest; 67 import org.mortbay.http.HttpResponse; 68 import org.mortbay.jetty.servlet.AbstractSessionManager; 69 import org.mortbay.jetty.servlet.Dispatcher; 70 import org.mortbay.jetty.servlet.FilterHolder; 71 import org.mortbay.jetty.servlet.JSR154Filter; 72 import org.mortbay.jetty.servlet.ServletHolder; 73 import org.mortbay.jetty.servlet.WebApplicationContext; 74 import org.mortbay.jetty.servlet.WebApplicationHandler; 75 76 81 public class JettyWebAppContext extends WebApplicationContext implements GBeanLifecycle, JettyServletRegistration { 82 private static Log log = LogFactory.getLog(JettyWebAppContext.class); 83 84 private final Kernel kernel; 85 private final J2eeContext moduleContext; 87 private final String originalSpecDD; 88 private final J2EEServer server; 89 private final J2EEApplication application; 90 91 private final ClassLoader webClassLoader; 92 private final JettyContainer jettyContainer; 93 94 private final URI webAppRoot; 95 private final WebApplicationHandler handler; 96 private String displayName; 97 private final String [] welcomeFiles; 98 99 private final BeforeAfter chain; 100 private final int contextLength; 101 private final SecurityContextBeforeAfter securityInterceptor; 102 private static final String [] J2EE_TYPES = {NameFactory.SERVLET}; 103 104 107 public JettyWebAppContext() { 108 kernel = null; 109 server = null; 110 application = null; 111 moduleContext = null; 112 originalSpecDD = null; 113 webClassLoader = null; 114 jettyContainer = null; 115 webAppRoot = null; 116 handler = null; 117 chain = null; 118 contextLength = 0; 119 securityInterceptor = null; 120 welcomeFiles = null; 121 122 } 123 124 public JettyWebAppContext(String objectName, 125 String originalSpecDD, 126 URI uri, 127 Map componentContext, 128 OnlineUserTransaction userTransaction, 129 ClassLoader classLoader, 130 URI [] webClassPath, 131 boolean contextPriorityClassLoader, 132 URL configurationBaseUrl, 133 Set unshareableResources, 134 Set applicationManagedSecurityResources, 135 136 String displayName, 137 Map contextParamMap, 138 Collection listenerClassNames, 139 boolean distributable, 140 Map mimeMap, 141 String [] welcomeFiles, 142 Map localeEncodingMapping, 143 Map errorPages, 144 Authenticator authenticator, 145 String realmName, 146 Map tagLibMap, 147 int sessionTimeoutSeconds, 148 149 String policyContextID, 150 String securityRealmName, 151 DefaultPrincipal defaultPrincipal, 152 PermissionCollection checkedPermissions, 153 PermissionCollection excludedPermissions, 154 155 TransactionContextManager transactionContextManager, 156 TrackedConnectionAssociator trackedConnectionAssociator, 157 JettyContainer jettyContainer, 158 RoleDesignateSource roleDesignateSource, 159 J2EEServer server, 160 J2EEApplication application, 161 Kernel kernel) throws Exception , IllegalAccessException , InstantiationException , ClassNotFoundException { 162 163 assert uri != null; 164 assert componentContext != null; 165 assert userTransaction != null; 166 assert classLoader != null; 167 assert webClassPath != null; 168 assert configurationBaseUrl != null; 169 assert transactionContextManager != null; 170 assert trackedConnectionAssociator != null; 171 assert jettyContainer != null; 172 173 this.kernel = kernel; 174 this.server = server; 175 this.application = application; 176 ObjectName myObjectName = JMXUtil.getObjectName(objectName); 177 verifyObjectName(myObjectName); 178 moduleContext = J2eeContextImpl.newContext(myObjectName, NameFactory.WEB_MODULE); 179 180 this.jettyContainer = jettyContainer; 181 182 this.originalSpecDD = originalSpecDD; 183 184 setConfigurationClassNames(new String []{}); 185 186 URI root = URI.create(configurationBaseUrl.toString()); 187 webAppRoot = root.resolve(uri); 188 URL webAppRootURL = webAppRoot.toURL(); 189 190 URL [] urls = new URL [webClassPath.length]; 191 for (int i = 0; i < webClassPath.length; i++) { 192 URI classPathEntry = webClassPath[i]; 193 classPathEntry = root.resolve(classPathEntry); 194 urls[i] = classPathEntry.toURL(); 195 } 196 this.webClassLoader = new JettyClassLoader(urls, webAppRootURL, classLoader, contextPriorityClassLoader); 197 setClassLoader(this.webClassLoader); 198 199 handler = new WebApplicationHandler(); 200 addHandler(handler); 201 202 userTransaction.setUp(transactionContextManager, trackedConnectionAssociator); 203 204 setDisplayName(displayName); 206 setContextParamMap(contextParamMap); 207 setListenerClassNames(listenerClassNames); 208 setDistributable(distributable); 209 setMimeMap(mimeMap); 210 this.welcomeFiles = welcomeFiles; 211 setLocaleEncodingMapping(localeEncodingMapping); 212 setErrorPages(errorPages); 213 setAuthenticator(authenticator); 214 setRealmName(realmName); 215 setTagLibMap(tagLibMap); 216 setSessionTimeoutSeconds(sessionTimeoutSeconds); 217 218 Context enc = null; 220 if (componentContext != null) { 221 for (Iterator iterator = componentContext.values().iterator(); iterator.hasNext();) { 222 Object value = iterator.next(); 223 if (value instanceof KernelAwareReference) { 224 ((KernelAwareReference) value).setKernel(kernel); 225 } 226 if (value instanceof ClassLoaderAwareReference) { 227 ((ClassLoaderAwareReference) value).setClassLoader(this.webClassLoader); 228 } 229 } 230 enc = new SimpleReadOnlyContext(componentContext); 231 } 232 233 int index = 0; 234 BeforeAfter interceptor = new InstanceContextBeforeAfter(null, index++, unshareableResources, applicationManagedSecurityResources, trackedConnectionAssociator); 235 interceptor = new TransactionContextBeforeAfter(interceptor, index++, index++, transactionContextManager); 236 interceptor = new ComponentContextBeforeAfter(interceptor, index++, enc); 237 interceptor = new ThreadClassloaderBeforeAfter(interceptor, index++, index++, this.webClassLoader); 238 interceptor = new WebApplicationContextBeforeAfter(interceptor, index++, this); 239 if (securityRealmName != null) { 241 if (roleDesignateSource == null) { 242 throw new IllegalArgumentException ("RoleDesignateSource must be supplied for a secure web app"); 243 } 244 Map roleDesignates = roleDesignateSource.getRoleDesignateMap(); 245 JAASJettyRealm realm = new JAASJettyRealm(realmName, securityRealmName); 247 setRealm(realm); 248 this.securityInterceptor = new SecurityContextBeforeAfter(interceptor, index++, index++, policyContextID, defaultPrincipal, authenticator, checkedPermissions, excludedPermissions, roleDesignates, realm); 249 interceptor = this.securityInterceptor; 250 } else { 251 securityInterceptor = null; 252 } 253 interceptor = new RequestWrappingBeforeAfter(interceptor, handler); 255 chain = interceptor; 256 contextLength = index; 257 258 FilterHolder jsr154FilterHolder = new FilterHolder(handler, "jsr154", JSR154Filter.class.getName()); 260 handler.addFilterHolder(jsr154FilterHolder); 261 jsr154FilterHolder.setInitParameter("unwrappedDispatch", "true"); 262 handler.addFilterPathMapping("/*", "jsr154", Dispatcher.__REQUEST | Dispatcher.__FORWARD | Dispatcher.__INCLUDE | Dispatcher.__ERROR ); 263 } 264 265 public Object enterContextScope(HttpRequest httpRequest, HttpResponse httpResponse) { 266 Object [] context = new Object [contextLength]; 267 chain.before(context, httpRequest, httpResponse); 268 return context; 269 } 270 271 public void leaveContextScope(HttpRequest httpRequest, HttpResponse httpResponse, Object oldScope) { 272 Object [] context = (Object []) oldScope; 273 chain.after(context, httpRequest, httpResponse); 274 } 275 276 277 public ClassLoader getWebClassLoader() { 278 return webClassLoader; 279 } 280 281 public void doStart() throws Exception { 282 setClassLoader(webClassLoader); 284 285 if (!isStarting()) { 287 super.start(); 288 return; 289 } 290 291 ((AbstractSessionManager)getServletHandler().getSessionManager()).setUseRequestedId(true); 292 293 setWAR(webAppRoot.toString()); 294 295 jettyContainer.addContext(this); 296 297 Object context = enterContextScope(null, null); 298 try { 299 super.doStart(); 300 } finally { 301 leaveContextScope(null, null, context); 302 } 303 setWelcomeFiles(welcomeFiles); 305 306 log.info("JettyWebAppContext started"); 307 } 308 309 public void doStop() throws Exception { 310 if (!isStopping()) { 312 super.stop(); 313 return; 314 } 315 316 if (securityInterceptor != null) { 317 securityInterceptor.stop(); 318 } 319 Object context = enterContextScope(null, null); 320 try { 321 super.doStop(); 322 } finally { 323 leaveContextScope(null, null, context); 324 jettyContainer.removeContext(this); 325 } 326 log.info("JettyWebAppContext stopped"); 327 } 328 329 public void doFail() { 330 try { 331 super.stop(); 333 } catch (InterruptedException e) { 334 } 335 336 log.info("JettyWebAppContext failed"); 337 } 338 339 340 342 public void setContextParamMap(Map initParameters) { 344 if (initParameters != null) { 345 for (Iterator iterator = initParameters.entrySet().iterator(); iterator.hasNext();) { 346 Map.Entry entry = (Map.Entry ) iterator.next(); 347 setInitParameter((String ) entry.getKey(), (String ) entry.getValue()); 348 } 349 } 350 } 351 352 public void setLocaleEncodingMapping(Map localeEncodingMap) { 353 if (localeEncodingMap != null) { 354 for (Iterator iterator = localeEncodingMap.entrySet().iterator(); iterator.hasNext();) { 355 Map.Entry entry = (Map.Entry ) iterator.next(); 356 addLocaleEncoding((String ) entry.getKey(), (String ) entry.getValue()); 357 } 358 } 359 } 360 361 public void setListenerClassNames(Collection eventListeners) throws ClassNotFoundException , IllegalAccessException , InstantiationException { 362 if (eventListeners != null) { 363 for (Iterator iterator = eventListeners.iterator(); iterator.hasNext();) { 364 String listenerClassName = (String ) iterator.next(); 365 Class clazz = loadClass(listenerClassName); 366 EventListener listener = (EventListener ) clazz.newInstance(); 367 addEventListener(listener); 368 handler.addEventListener(listener); 369 } 370 } 371 } 372 373 public void setErrorPages(Map errorPageMap) { 374 if (errorPageMap != null) { 375 for (Iterator iterator = errorPageMap.entrySet().iterator(); iterator.hasNext();) { 376 Map.Entry entry = (Map.Entry ) iterator.next(); 377 setErrorPage((String ) entry.getKey(), (String ) entry.getValue()); 378 } 379 } 380 } 381 382 public void setTagLibMap(Map tagLibMap) { 383 if (tagLibMap != null) { 384 for (Iterator iterator = tagLibMap.entrySet().iterator(); iterator.hasNext();) { 385 Map.Entry entry = (Map.Entry ) iterator.next(); 386 setResourceAlias((String ) entry.getKey(), (String ) entry.getValue()); 387 } 388 } 389 } 390 391 public void setSessionTimeoutSeconds(int seconds) { 392 handler.setSessionInactiveInterval(seconds); 393 } 394 395 396 public String getDisplayName() { 398 return displayName; 399 } 400 401 public void setDisplayName(String displayName) { 402 this.displayName = displayName; 403 super.setDisplayName(displayName); 404 } 405 406 public String getDeploymentDescriptor() { 407 return originalSpecDD; 408 } 409 410 public String getServer() { 411 return server.getObjectName(); 412 } 413 414 public String getApplication() { 415 if (application == null) { 416 return null; 417 } 418 return application.getObjectName(); 419 } 420 421 public String [] getJavaVMs() { 422 return server.getJavaVMs(); 423 } 424 425 public String [] getServlets() throws MalformedObjectNameException { 426 return Util.getObjectNames(kernel, moduleContext, J2EE_TYPES); 427 } 428 429 434 private void verifyObjectName(ObjectName objectName) { 435 if (objectName.isPattern()) { 436 throw new InvalidObjectNameException("ObjectName can not be a pattern", objectName); 437 } 438 Hashtable keyPropertyList = objectName.getKeyPropertyList(); 439 if (!NameFactory.WEB_MODULE.equals(keyPropertyList.get("j2eeType"))) { 440 throw new InvalidObjectNameException("WebModule object name j2eeType property must be 'WebModule'", objectName); 441 } 442 if (!keyPropertyList.containsKey(NameFactory.J2EE_NAME)) { 443 throw new InvalidObjectNameException("WebModule object must contain a name property", objectName); 444 } 445 if (!keyPropertyList.containsKey(NameFactory.J2EE_SERVER)) { 446 throw new InvalidObjectNameException("WebModule object name must contain a J2EEServer property", objectName); 447 } 448 if (!keyPropertyList.containsKey(NameFactory.J2EE_APPLICATION)) { 449 throw new InvalidObjectNameException("WebModule object name must contain a J2EEApplication property", objectName); 450 } 451 if (keyPropertyList.size() != 4) { 452 throw new InvalidObjectNameException("WebModule object name can only have j2eeType, name, J2EEApplication, and J2EEServer properties", objectName); 453 } 454 } 455 public void registerServletHolder(ServletHolder servletHolder, String servletName, Set servletMappings, Map webRoleRefPermissions) throws Exception { 456 handler.addServletHolder(servletHolder); 458 if (servletMappings != null) { 459 for (Iterator iterator = servletMappings.iterator(); iterator.hasNext();) { 460 String urlPattern = (String ) iterator.next(); 461 handler.mapPathToServlet(urlPattern, servletName); 462 } 463 } 464 Object context = enterContextScope(null, null); 468 try { 469 servletHolder.start(); 470 } finally { 471 leaveContextScope(null, null, context); 472 } 473 } 474 475 public boolean checkSecurityConstraints(String pathInContext, HttpRequest request, HttpResponse response) throws HttpException, IOException { 476 if (securityInterceptor != null) { 477 return securityInterceptor.checkSecurityConstraints(pathInContext, request, response); 478 } 479 return super.checkSecurityConstraints(pathInContext, request, response); 480 } 481 482 483 public static final GBeanInfo GBEAN_INFO; 484 485 static { 486 GBeanInfoBuilder infoBuilder = new GBeanInfoBuilder("Jetty WebApplication Context", JettyWebAppContext.class, NameFactory.WEB_MODULE); 487 infoBuilder.addAttribute("deploymentDescriptor", String .class, true); 488 490 infoBuilder.addAttribute("displayName", String .class, true); 491 infoBuilder.addAttribute("contextParamMap", Map .class, true); 492 infoBuilder.addAttribute("listenerClassNames", Collection .class, true); 493 infoBuilder.addAttribute("distributable", boolean.class, true); 494 495 infoBuilder.addAttribute("mimeMap", Map .class, true); 496 infoBuilder.addAttribute("welcomeFiles", String [].class, true); 497 infoBuilder.addAttribute("localeEncodingMapping", Map .class, true); 498 infoBuilder.addAttribute("errorPages", Map .class, true); 499 infoBuilder.addAttribute("authenticator", Authenticator.class, true); 500 infoBuilder.addAttribute("realmName", String .class, true); 501 infoBuilder.addAttribute("tagLibMap", Map .class, true); 502 infoBuilder.addAttribute("sessionTimeoutSeconds", int.class, true); 503 504 505 infoBuilder.addAttribute("uri", URI .class, true); 506 infoBuilder.addAttribute("componentContext", Map .class, true); 507 infoBuilder.addAttribute("userTransaction", OnlineUserTransaction.class, true); 508 infoBuilder.addAttribute("classLoader", ClassLoader .class, false); 509 infoBuilder.addAttribute("webClassPath", URI [].class, true); 510 infoBuilder.addAttribute("contextPriorityClassLoader", boolean.class, true); 511 infoBuilder.addAttribute("configurationBaseUrl", URL .class, true); 512 infoBuilder.addAttribute("unshareableResources", Set .class, true); 513 infoBuilder.addAttribute("applicationManagedSecurityResources", Set .class, true); 514 515 infoBuilder.addAttribute("contextPath", String .class, true); 516 517 infoBuilder.addReference("TransactionContextManager", TransactionContextManager.class, NameFactory.JTA_RESOURCE); 518 infoBuilder.addReference("TrackedConnectionAssociator", TrackedConnectionAssociator.class, NameFactory.JCA_RESOURCE); 519 infoBuilder.addReference("JettyContainer", JettyContainer.class, NameFactory.GERONIMO_SERVICE); 520 infoBuilder.addReference("RoleDesignateSource", RoleDesignateSource.class, NameFactory.JACC_MANAGER); 521 522 infoBuilder.addInterface(JettyServletRegistration.class); 523 524 infoBuilder.addAttribute("policyContextID", String .class, true); 525 infoBuilder.addAttribute("securityRealmName", String .class, true); 526 infoBuilder.addAttribute("defaultPrincipal", DefaultPrincipal.class, true); 527 528 infoBuilder.addAttribute("checkedPermissions", PermissionCollection .class, true); 529 infoBuilder.addAttribute("excludedPermissions", PermissionCollection .class, true); 530 531 infoBuilder.addReference("J2EEServer", J2EEServer.class); 532 infoBuilder.addReference("J2EEApplication", J2EEApplication.class); 533 534 infoBuilder.addAttribute("kernel", Kernel.class, false); 535 infoBuilder.addAttribute("objectName", String .class, false); 536 infoBuilder.addAttribute("server", String .class, false); 537 infoBuilder.addAttribute("application", String .class, false); 538 infoBuilder.addAttribute("javaVMs", String [].class, false); 539 infoBuilder.addAttribute("servlets", String [].class, false); 540 541 infoBuilder.setConstructor(new String []{ 542 "objectName", 543 "deploymentDescriptor", 544 "uri", 545 "componentContext", 546 "userTransaction", 547 "classLoader", 548 "webClassPath", 549 "contextPriorityClassLoader", 550 "configurationBaseUrl", 551 "unshareableResources", 552 "applicationManagedSecurityResources", 553 554 "displayName", 555 "contextParamMap", 556 "listenerClassNames", 557 "distributable", 558 "mimeMap", 559 "welcomeFiles", 560 "localeEncodingMapping", 561 "errorPages", 562 "authenticator", 563 "realmName", 564 "tagLibMap", 565 "sessionTimeoutSeconds", 566 567 "policyContextID", 568 "securityRealmName", 569 "defaultPrincipal", 570 571 "checkedPermissions", 572 "excludedPermissions", 573 574 "TransactionContextManager", 575 "TrackedConnectionAssociator", 576 "JettyContainer", 577 "RoleDesignateSource", 578 579 "J2EEServer", 580 "J2EEApplication", 581 "kernel" 582 }); 583 584 GBEAN_INFO = infoBuilder.getBeanInfo(); 585 } 586 587 public static GBeanInfo getGBeanInfo() { 588 return GBEAN_INFO; 589 } 590 591 } 592 | Popular Tags |