001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.geronimo.jetty6;
019
020 import java.net.URL;
021 import java.util.ArrayList;
022 import java.util.Collection;
023 import java.util.EventListener;
024 import java.util.HashMap;
025 import java.util.HashSet;
026 import java.util.Hashtable;
027 import java.util.Map;
028 import java.util.Set;
029
030 import javax.management.MalformedObjectNameException;
031 import javax.management.ObjectName;
032 import javax.naming.Context;
033 import javax.security.auth.Subject;
034 import javax.security.auth.login.LoginException;
035 import javax.transaction.TransactionManager;
036
037 import org.apache.commons.logging.Log;
038 import org.apache.commons.logging.LogFactory;
039 import org.apache.geronimo.connector.outbound.connectiontracking.TrackedConnectionAssociator;
040 import org.apache.geronimo.gbean.GBeanInfo;
041 import org.apache.geronimo.gbean.GBeanInfoBuilder;
042 import org.apache.geronimo.gbean.GBeanLifecycle;
043 import org.apache.geronimo.j2ee.RuntimeCustomizer;
044 import org.apache.geronimo.j2ee.annotation.Holder;
045 import org.apache.geronimo.j2ee.annotation.LifecycleMethod;
046 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
047 import org.apache.geronimo.j2ee.management.impl.InvalidObjectNameException;
048 import org.apache.geronimo.jetty6.handler.AbstractImmutableHandler;
049 import org.apache.geronimo.jetty6.handler.ComponentContextHandler;
050 import org.apache.geronimo.jetty6.handler.InstanceContextHandler;
051 import org.apache.geronimo.jetty6.handler.JettySecurityHandler;
052 import org.apache.geronimo.jetty6.handler.LifecycleCommand;
053 import org.apache.geronimo.jetty6.handler.ThreadClassloaderHandler;
054 import org.apache.geronimo.jetty6.handler.TwistyWebAppContext;
055 import org.apache.geronimo.jetty6.handler.UserTransactionHandler;
056 import org.apache.geronimo.kernel.Kernel;
057 import org.apache.geronimo.kernel.ObjectNameUtil;
058 import org.apache.geronimo.management.J2EEApplication;
059 import org.apache.geronimo.management.J2EEServer;
060 import org.apache.geronimo.management.geronimo.WebContainer;
061 import org.apache.geronimo.management.geronimo.WebModule;
062 import org.apache.geronimo.naming.enc.EnterpriseNamingContext;
063 import org.apache.geronimo.security.jacc.RunAsSource;
064 import org.apache.geronimo.transaction.GeronimoUserTransaction;
065 import org.mortbay.jetty.Handler;
066 import org.mortbay.jetty.MimeTypes;
067 import org.mortbay.jetty.security.Authenticator;
068 import org.mortbay.jetty.servlet.ErrorPageErrorHandler;
069 import org.mortbay.jetty.servlet.ServletHandler;
070 import org.mortbay.jetty.servlet.ServletHolder;
071 import org.mortbay.jetty.servlet.ServletMapping;
072 import org.mortbay.jetty.servlet.SessionHandler;
073
074 /**
075 * Wrapper for a WebApplicationContext that sets up its J2EE environment.
076 *
077 * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
078 */
079 public class JettyWebAppContext implements GBeanLifecycle, JettyServletRegistration, WebModule {
080 private static Log log = LogFactory.getLog(JettyWebAppContext.class);
081
082 private final String originalSpecDD;
083 private final J2EEServer server;
084 private final J2EEApplication application;
085
086 private final ClassLoader webClassLoader;
087 private final JettyContainer jettyContainer;
088
089 private final String webAppRoot;
090 private final URL configurationBaseURL;
091 private String displayName;
092
093 private final String objectName;
094 private final TwistyWebAppContext webAppContext;//delegate
095 private final AbstractImmutableHandler lifecycleChain;
096 private final Context componentContext;
097 private final Holder holder;
098 private final RunAsSource runAsSource;
099
100 private final Set<String> servletNames = new HashSet<String>();
101
102 public JettyWebAppContext(String objectName,
103 String originalSpecDD,
104 Map<String, Object> componentContext,
105 ClassLoader classLoader,
106 URL configurationBaseUrl,
107 Set unshareableResources,
108 Set applicationManagedSecurityResources,
109 String displayName,
110 Map contextParamMap,
111 Collection<String> listenerClassNames,
112 boolean distributable,
113 Map mimeMap,
114 String[] welcomeFiles,
115 Map<String, String> localeEncodingMapping,
116 Map errorPages,
117 Authenticator authenticator,
118 String realmName,
119 Map<String, String> tagLibMap,
120 boolean compactPath,
121
122 int sessionTimeoutSeconds,
123 SessionHandlerFactory handlerFactory,
124 PreHandlerFactory preHandlerFactory,
125
126 String policyContextID,
127 String securityRealmName,
128
129 RunAsSource runAsSource, Holder holder,
130
131 Host host,
132 TransactionManager transactionManager,
133 TrackedConnectionAssociator trackedConnectionAssociator,
134 JettyContainer jettyContainer,
135 RuntimeCustomizer contextCustomizer,
136
137 J2EEServer server,
138 J2EEApplication application,
139 Kernel kernel) throws Exception {
140
141 assert componentContext != null;
142 assert classLoader != null;
143 assert configurationBaseUrl != null;
144 assert transactionManager != null;
145 assert trackedConnectionAssociator != null;
146 assert jettyContainer != null;
147
148 this.holder = holder == null ? Holder.EMPTY : holder;
149
150 this.runAsSource = runAsSource == null? RunAsSource.NULL: runAsSource;
151
152 SessionHandler sessionHandler;
153 if (null != handlerFactory) {
154 if (null == preHandlerFactory) {
155 throw new IllegalStateException("A preHandlerFactory must be set if an handler factory is set.");
156 }
157 PreHandler preHandler = preHandlerFactory.createHandler();
158 sessionHandler = handlerFactory.createHandler(preHandler);
159 } else {
160 sessionHandler = new SessionHandler();
161 }
162 JettySecurityHandler securityHandler = null;
163 if (securityRealmName != null) {
164 InternalJAASJettyRealm internalJAASJettyRealm = jettyContainer.addRealm(securityRealmName);
165 //wrap jetty realm with something that knows the dumb realmName
166 JAASJettyRealm realm = new JAASJettyRealm(realmName, internalJAASJettyRealm);
167 Subject defaultSubject = this.runAsSource.getDefaultSubject();
168 securityHandler = new JettySecurityHandler(authenticator, realm, policyContextID, defaultSubject);
169 }
170
171 ServletHandler servletHandler = new ServletHandler();
172
173 webAppContext = new TwistyWebAppContext(securityHandler, sessionHandler, servletHandler, null);
174 //See Jetty-386. Setting this to true can expose secured content.
175 webAppContext.setCompactPath(compactPath);
176
177 //wrap the web app context with the jndi handler
178 GeronimoUserTransaction userTransaction = new GeronimoUserTransaction(transactionManager);
179 this.componentContext = EnterpriseNamingContext.createEnterpriseNamingContext(componentContext, userTransaction, kernel, classLoader);
180
181 //install jasper injection support if required
182 if (contextCustomizer != null) {
183 Map<String, Object> servletContext = new HashMap<String, Object>();
184 Map<Class, Object> customizerContext = new HashMap<Class, Object>();
185 customizerContext.put(Map.class, servletContext);
186 customizerContext.put(Context.class, JettyWebAppContext.this.componentContext);
187 contextCustomizer.customize(customizerContext);
188 for (Map.Entry<String, Object> entry: servletContext.entrySet()) {
189 webAppContext.setAttribute(entry.getKey(), entry.getValue());
190 }
191 }
192
193 // localize access to next
194 {
195 //install the other handlers inside the web app context
196 Handler next = webAppContext.newTwistyHandler();
197 next = new ThreadClassloaderHandler(next, classLoader);
198
199 next = new InstanceContextHandler(next, unshareableResources, applicationManagedSecurityResources, trackedConnectionAssociator);
200 next = new UserTransactionHandler(next, userTransaction);
201 next = new ComponentContextHandler(next, this.componentContext);
202 webAppContext.setTwistyHandler(next);
203
204 lifecycleChain = (AbstractImmutableHandler) next;
205 }
206 MimeTypes mimeTypes = new MimeTypes();
207 mimeTypes.setMimeMap(mimeMap);
208 webAppContext.setMimeTypes(mimeTypes);
209
210 this.server = server;
211 this.application = application;
212 this.objectName = objectName;
213 if (objectName != null) {
214 ObjectName myObjectName = ObjectNameUtil.getObjectName(objectName);
215 verifyObjectName(myObjectName);
216 }
217 this.configurationBaseURL = configurationBaseUrl;
218 this.jettyContainer = jettyContainer;
219 this.originalSpecDD = originalSpecDD;
220
221 //DONT install the jetty TLD configuration as we find and create all the listeners ourselves
222 webAppContext.setConfigurationClasses(new String[]{});
223
224 webAppRoot = configurationBaseUrl.toString();
225 webClassLoader = classLoader;
226 webAppContext.setClassLoader(webClassLoader);
227
228 if (host != null) {
229 webAppContext.setConnectorNames(host.getHosts());
230 webAppContext.setVirtualHosts(host.getVirtualHosts());
231 }
232
233 //stuff from spec dd
234 webAppContext.setDisplayName(displayName);
235 webAppContext.setInitParams(contextParamMap);
236 setListenerClassNames(listenerClassNames);
237 webAppContext.setDistributable(distributable);
238 webAppContext.setWelcomeFiles(welcomeFiles);
239 setLocaleEncodingMapping(localeEncodingMapping);
240 setErrorPages(errorPages);
241 setTagLibMap(tagLibMap);
242
243 if (!distributable) {
244 setSessionTimeoutSeconds(sessionTimeoutSeconds);
245 }
246
247 }
248
249
250 public String getObjectName() {
251 return objectName;
252 }
253
254 public boolean isStateManageable() {
255 return true;
256 }
257
258 public boolean isStatisticsProvider() {
259 return false;
260 }
261
262 public boolean isEventProvider() {
263 return true;
264 }
265
266 public URL getWARDirectory() {
267 return configurationBaseURL;
268 }
269
270 public String getWARName() {
271 //todo: make this return something more consistent
272 try {
273 return ObjectName.getInstance(objectName).getKeyProperty(NameFactory.J2EE_NAME);
274 } catch (MalformedObjectNameException e) {
275 return null;
276 }
277 }
278
279 public WebContainer getContainer() {
280 return jettyContainer;
281 }
282
283 public void setContextPath(String path) {
284 if (path == null || !path.startsWith("/")) {
285 throw new IllegalArgumentException("context path must be non-null and start with '/', not " + path);
286 }
287 this.webAppContext.setContextPath(path);
288 }
289
290 public String getContextPath() {
291 return this.webAppContext.getContextPath();
292 }
293
294 public void setWorkDir(String workDir) {
295 if(workDir == null) {
296 return;
297 }
298 this.webAppContext.setTempDirectory(jettyContainer.resolveToJettyHome(workDir));
299 }
300
301 public ClassLoader getWebClassLoader() {
302 return webClassLoader;
303 }
304
305 public AbstractImmutableHandler getLifecycleChain() {
306 return lifecycleChain;
307 }
308
309 public Subject getSubjectForRole(String role) throws LoginException {
310 return runAsSource.getSubjectForRole(role);
311 }
312
313 public Object newInstance(String className) throws InstantiationException, IllegalAccessException {
314 if (className == null) {
315 throw new InstantiationException("no class loaded");
316 }
317 return holder.newInstance(className, webClassLoader, componentContext);
318 }
319
320 public void destroyInstance(Object o) throws Exception {
321 Class clazz = o.getClass();
322 if (holder != null) {
323 Map<String, LifecycleMethod> preDestroy = holder.getPreDestroy();
324 if (preDestroy != null) {
325 Holder.apply(o, clazz, preDestroy);
326 }
327 }
328 }
329
330 public void doStart() throws Exception {
331 // reset the classsloader... jetty likes to set it to null when stopping
332 this.webAppContext.setClassLoader(webClassLoader);
333 this.webAppContext.setWar(webAppRoot);
334
335 getLifecycleChain().lifecycleCommand(new StartCommand());
336 }
337
338 public void doStop() throws Exception {
339 getLifecycleChain().lifecycleCommand(new StopCommand());
340
341 // No more logging will occur for this ClassLoader. Inform the LogFactory to avoid a memory leak.
342 LogFactory.release(webClassLoader);
343
344 // need to release the JSF factories. Otherwise, we'll leak ClassLoaders.
345 //should be done in a myfaces gbean
346 // FactoryFinder.releaseFactories();
347
348 log.debug("JettyWebAppContext stopped");
349 }
350
351 public void doFail() {
352 try {
353 doStop();
354 } catch (Exception e) {
355 //ignore
356 }
357
358 log.warn("JettyWebAppContext failed");
359 }
360
361 public class StartCommand implements LifecycleCommand {
362
363 public void lifecycleMethod() throws Exception {
364 //order seems backwards... .maybe container is calling start itself???
365 jettyContainer.addContext(webAppContext);
366 webAppContext.start();
367 }
368 }
369
370 public class StopCommand implements LifecycleCommand {
371
372 public void lifecycleMethod() throws Exception {
373 webAppContext.stop();
374 //TODO is this order correct?
375 for (EventListener listener : webAppContext.getEventListeners()) {
376 destroyInstance(listener);
377 }
378 jettyContainer.removeContext(webAppContext);
379 }
380 }
381 //pass through attributes. They should be constructor params
382
383 public void setLocaleEncodingMapping(Map<String, String> localeEncodingMap) {
384 if (localeEncodingMap != null) {
385 for (Map.Entry<String, String> entry : localeEncodingMap.entrySet()) {
386 this.webAppContext.addLocaleEncoding(entry.getKey(), entry.getValue());
387 }
388 }
389 }
390
391 public void setListenerClassNames(Collection<String> eventListeners) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
392 if (eventListeners != null) {
393 Collection<EventListener> listeners = new ArrayList<EventListener>();
394 for (String listenerClassName : eventListeners) {
395 EventListener listener = (EventListener) newInstance(listenerClassName);
396 listeners.add(listener);
397 }
398 webAppContext.setEventListeners(listeners.toArray(new EventListener[listeners.size()]));
399 }
400 }
401
402 public void setErrorPages(Map errorPageMap) {
403 if (errorPageMap != null) {
404 ((ErrorPageErrorHandler) this.webAppContext.getErrorHandler()).setErrorPages(errorPageMap);
405 }
406 }
407
408 public void setTagLibMap(Map<String, String> tagLibMap) {
409 if (tagLibMap != null) {
410 for (Map.Entry<String, String> entry : tagLibMap.entrySet()) {
411 this.webAppContext.setResourceAlias(entry.getKey(), entry.getValue());
412 }
413 }
414 }
415
416 public void setSessionTimeoutSeconds(int seconds) {
417 this.webAppContext.getSessionHandler().getSessionManager().setMaxInactiveInterval(seconds);
418 }
419
420
421 //TODO this is really dumb, but jetty5 liked to set the displayname to null frequently.
422 //we need to re-check for jetty6
423 public String getDisplayName() {
424 return displayName;
425 }
426
427 public void setDisplayName(String displayName) {
428 this.displayName = displayName;
429 this.webAppContext.setDisplayName(displayName);
430 }
431
432 public String getDeploymentDescriptor() {
433 return originalSpecDD;
434 }
435
436 public String getServer() {
437 return server.getObjectName();
438 }
439
440 public String getApplication() {
441 if (application == null) {
442 return null;
443 }
444 return application.getObjectName();
445 }
446
447 public String[] getJavaVMs() {
448 return server.getJavaVMs();
449 }
450
451 public String[] getServlets() {
452 synchronized (servletNames) {
453 return servletNames.toArray(new String[servletNames.size()]);
454 }
455 }
456
457 public ServletHandler getServletHandler() {
458 return this.webAppContext.getServletHandler();
459 }
460
461 /**
462 * ObjectName must match this pattern:
463 * <p/>
464 * domain:j2eeType=WebModule,name=MyName,J2EEServer=MyServer,J2EEApplication=MyApplication
465 *
466 * @param objectName ObjectName to verify
467 */
468 private void verifyObjectName(ObjectName objectName) {
469 if (objectName.isPattern()) {
470 throw new InvalidObjectNameException("ObjectName can not be a pattern", objectName);
471 }
472 Hashtable keyPropertyList = objectName.getKeyPropertyList();
473 if (!NameFactory.WEB_MODULE.equals(keyPropertyList.get("j2eeType"))) {
474 throw new InvalidObjectNameException("WebModule object name j2eeType property must be 'WebModule'", objectName);
475 }
476 if (!keyPropertyList.containsKey(NameFactory.J2EE_NAME)) {
477 throw new InvalidObjectNameException("WebModule object must contain a name property", objectName);
478 }
479 if (!keyPropertyList.containsKey(NameFactory.J2EE_SERVER)) {
480 throw new InvalidObjectNameException("WebModule object name must contain a J2EEServer property", objectName);
481 }
482 if (!keyPropertyList.containsKey(NameFactory.J2EE_APPLICATION)) {
483 throw new InvalidObjectNameException("WebModule object name must contain a J2EEApplication property", objectName);
484 }
485 if (keyPropertyList.size() != 4) {
486 throw new InvalidObjectNameException("WebModule object name can only have j2eeType, name, J2EEApplication, and J2EEServer properties", objectName);
487 }
488 }
489
490 public void registerServletHolder(ServletHolder servletHolder, String servletName, Set<String> servletMappings, String objectName) throws Exception {
491 webAppContext.getServletHandler().addServlet(servletHolder);
492 if (servletMappings != null) {
493 for (String urlPattern : servletMappings) {
494 ServletMapping servletMapping = new ServletMapping();
495 servletMapping.setPathSpec(urlPattern);
496 servletMapping.setServletName(servletName);
497 this.webAppContext.getServletHandler().addServletMapping(servletMapping);
498 }
499 }
500 // LifecycleCommand lifecycleCommand = new LifecycleCommand.StartCommand(servletHolder);
501 // lifecycleChain.lifecycleCommand(lifecycleCommand);
502 if (objectName != null) {
503 synchronized (servletNames) {
504 servletNames.add(objectName);
505 }
506 }
507 }
508
509 public void unregisterServletHolder(ServletHolder servletHolder, String servletName, Set<String> servletMappings, String objectName) throws Exception {
510 //no way to remove servlets
511 // webAppContext.getServletHandler().removeServlet(servletHolder);
512 // if (servletMappings != null) {
513 // for (Iterator iterator = servletMappings.iterator(); iterator.hasNext();) {
514 // String urlPattern = (String) iterator.next();
515 // ServletMapping servletMapping = new ServletMapping();
516 // servletMapping.setPathSpec(urlPattern);
517 // servletMapping.setServletName(servletName);
518 // webAppContext.getServletHandler().removeServletMapping(servletMapping);
519 // }
520 // }
521 // LifecycleCommand lifecycleCommand = new LifecycleCommand.StopCommand(servletHolder);
522 // lifecycleChain.lifecycleCommand(lifecycleCommand);
523 if (objectName != null) {
524 synchronized (servletNames) {
525 servletNames.remove(objectName);
526 }
527 }
528 }
529
530 public static final GBeanInfo GBEAN_INFO;
531
532 public static final String GBEAN_ATTR_SESSION_TIMEOUT = "sessionTimeoutSeconds";
533
534 public static final String GBEAN_REF_SESSION_HANDLER_FACTORY = "SessionHandlerFactory";
535 public static final String GBEAN_REF_PRE_HANDLER_FACTORY = "PreHandlerFactory";
536
537 static {
538 GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic("Jetty WebApplication Context", JettyWebAppContext.class, NameFactory.WEB_MODULE);
539 infoBuilder.addAttribute("deploymentDescriptor", String.class, true);
540 //from jetty6's webapp context
541
542 infoBuilder.addAttribute("displayName", String.class, true);
543 infoBuilder.addAttribute("contextParamMap", Map.class, true);
544 infoBuilder.addAttribute("listenerClassNames", Collection.class, true);
545 infoBuilder.addAttribute("distributable", boolean.class, true);
546
547 infoBuilder.addAttribute("mimeMap", Map.class, true);
548 infoBuilder.addAttribute("welcomeFiles", String[].class, true);
549 infoBuilder.addAttribute("localeEncodingMapping", Map.class, true);
550 infoBuilder.addAttribute("errorPages", Map.class, true);
551 infoBuilder.addAttribute("authenticator", Authenticator.class, true);
552 infoBuilder.addAttribute("realmName", String.class, true);
553 infoBuilder.addAttribute("tagLibMap", Map.class, true);
554 infoBuilder.addAttribute(GBEAN_ATTR_SESSION_TIMEOUT, int.class, true);
555 infoBuilder.addReference(GBEAN_REF_SESSION_HANDLER_FACTORY, SessionHandlerFactory.class,
556 NameFactory.GERONIMO_SERVICE);
557 infoBuilder.addReference(GBEAN_REF_PRE_HANDLER_FACTORY, PreHandlerFactory.class, NameFactory.GERONIMO_SERVICE);
558
559 infoBuilder.addAttribute("componentContext", Map.class, true);
560 infoBuilder.addAttribute("classLoader", ClassLoader.class, false);
561 infoBuilder.addAttribute("configurationBaseUrl", URL.class, true);
562 infoBuilder.addAttribute("unshareableResources", Set.class, true);
563 infoBuilder.addAttribute("applicationManagedSecurityResources", Set.class, true);
564
565 infoBuilder.addAttribute("contextPath", String.class, true);
566 infoBuilder.addAttribute("compactPath", boolean.class, true);
567
568 infoBuilder.addAttribute("workDir", String.class, true);
569 infoBuilder.addReference("Host", Host.class, "Host");
570 infoBuilder.addReference("TransactionManager", TransactionManager.class, NameFactory.JTA_RESOURCE);
571 infoBuilder.addReference("TrackedConnectionAssociator", TrackedConnectionAssociator.class, NameFactory.JCA_CONNECTION_TRACKER);
572 infoBuilder.addReference("JettyContainer", JettyContainer.class, NameFactory.GERONIMO_SERVICE);
573 infoBuilder.addReference("ContextCustomizer", RuntimeCustomizer.class, NameFactory.GERONIMO_SERVICE);
574
575 infoBuilder.addInterface(JettyServletRegistration.class);
576
577 infoBuilder.addAttribute("policyContextID", String.class, true);
578 infoBuilder.addAttribute("securityRealmName", String.class, true);
579 infoBuilder.addReference("RunAsSource", RunAsSource.class, NameFactory.JACC_MANAGER);
580
581 infoBuilder.addAttribute("holder", Holder.class, true);
582
583 infoBuilder.addReference("J2EEServer", J2EEServer.class);
584 infoBuilder.addReference("J2EEApplication", J2EEApplication.class);
585
586 infoBuilder.addAttribute("kernel", Kernel.class, false);
587 infoBuilder.addAttribute("objectName", String.class, false);
588 infoBuilder.addAttribute("application", String.class, false);
589 infoBuilder.addAttribute("javaVMs", String[].class, false);
590 infoBuilder.addAttribute("servlets", String[].class, false);
591
592 infoBuilder.addInterface(WebModule.class);
593
594 infoBuilder.setConstructor(new String[]{
595 "objectName",
596 "deploymentDescriptor",
597 "componentContext",
598 "classLoader",
599 "configurationBaseUrl",
600 "unshareableResources",
601 "applicationManagedSecurityResources",
602
603 "displayName",
604 "contextParamMap",
605 "listenerClassNames",
606 "distributable",
607 "mimeMap",
608 "welcomeFiles",
609 "localeEncodingMapping",
610 "errorPages",
611 "authenticator",
612 "realmName",
613 "tagLibMap",
614 "compactPath",
615 GBEAN_ATTR_SESSION_TIMEOUT,
616 GBEAN_REF_SESSION_HANDLER_FACTORY,
617 GBEAN_REF_PRE_HANDLER_FACTORY,
618
619 "policyContextID",
620 "securityRealmName",
621 "RunAsSource",
622
623 "holder",
624
625 "Host",
626 "TransactionManager",
627 "TrackedConnectionAssociator",
628 "JettyContainer",
629 "ContextCustomizer",
630
631 "J2EEServer",
632 "J2EEApplication",
633 "kernel"
634 });
635
636 GBEAN_INFO = infoBuilder.getBeanInfo();
637 }
638
639 public static GBeanInfo getGBeanInfo() {
640 return GBEAN_INFO;
641 }
642
643 }