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