KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > jetty6 > deployment > JettyModuleBuilder


1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 package org.apache.geronimo.jetty6.deployment;
19
20 import java.io.File JavaDoc;
21 import java.io.FileNotFoundException JavaDoc;
22 import java.io.IOException JavaDoc;
23 import java.net.URL JavaDoc;
24 import java.security.Permission JavaDoc;
25 import java.security.PermissionCollection JavaDoc;
26 import java.security.Permissions JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.util.Collection JavaDoc;
29 import java.util.Collections JavaDoc;
30 import java.util.Comparator JavaDoc;
31 import java.util.Enumeration JavaDoc;
32 import java.util.HashMap JavaDoc;
33 import java.util.HashSet JavaDoc;
34 import java.util.Iterator JavaDoc;
35 import java.util.List JavaDoc;
36 import java.util.Map JavaDoc;
37 import java.util.Set JavaDoc;
38 import java.util.TreeSet JavaDoc;
39 import java.util.Arrays JavaDoc;
40 import java.util.jar.JarFile JavaDoc;
41
42 import javax.management.ObjectName JavaDoc;
43 import javax.servlet.Servlet JavaDoc;
44
45 import org.apache.commons.logging.Log;
46 import org.apache.commons.logging.LogFactory;
47 import org.apache.geronimo.common.DeploymentException;
48 import org.apache.geronimo.deployment.ModuleIDBuilder;
49 import org.apache.geronimo.deployment.NamespaceDrivenBuilder;
50 import org.apache.geronimo.deployment.NamespaceDrivenBuilderCollection;
51 import org.apache.geronimo.deployment.service.EnvironmentBuilder;
52 import org.apache.geronimo.deployment.util.DeploymentUtil;
53 import org.apache.geronimo.deployment.xbeans.EnvironmentType;
54 import org.apache.geronimo.deployment.xmlbeans.XmlBeansUtil;
55 import org.apache.geronimo.gbean.AbstractName;
56 import org.apache.geronimo.gbean.AbstractNameQuery;
57 import org.apache.geronimo.gbean.GBeanData;
58 import org.apache.geronimo.gbean.GBeanInfo;
59 import org.apache.geronimo.gbean.GBeanInfoBuilder;
60 import org.apache.geronimo.j2ee.deployment.EARContext;
61 import org.apache.geronimo.j2ee.deployment.Module;
62 import org.apache.geronimo.j2ee.deployment.ModuleBuilder;
63 import org.apache.geronimo.j2ee.deployment.WebModule;
64 import org.apache.geronimo.j2ee.deployment.WebServiceBuilder;
65 import org.apache.geronimo.j2ee.deployment.NamingBuilder;
66 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
67 //import org.apache.geronimo.jetty6.DefaultWebApplicationHandlerFactory;
68
import org.apache.geronimo.jetty6.Host;
69 import org.apache.geronimo.jetty6.JettyDefaultServletHolder;
70 import org.apache.geronimo.jetty6.JettyFilterHolder;
71 import org.apache.geronimo.jetty6.JettyFilterMapping;
72 import org.apache.geronimo.jetty6.JettyServletHolder;
73 import org.apache.geronimo.jetty6.JettyWebAppContext;
74 import org.apache.geronimo.jetty6.NonAuthenticator;
75 import org.apache.geronimo.kernel.GBeanAlreadyExistsException;
76 import org.apache.geronimo.kernel.GBeanNotFoundException;
77 import org.apache.geronimo.kernel.Kernel;
78 import org.apache.geronimo.kernel.Naming;
79 import org.apache.geronimo.kernel.config.ConfigurationData;
80 import org.apache.geronimo.kernel.config.Configuration;
81 import org.apache.geronimo.kernel.repository.Environment;
82 import org.apache.geronimo.naming.deployment.ENCConfigBuilder;
83 import org.apache.geronimo.naming.deployment.GBeanResourceEnvironmentBuilder;
84 import org.apache.geronimo.naming.deployment.ResourceEnvironmentSetter;
85 import org.apache.geronimo.security.deploy.DefaultPrincipal;
86 import org.apache.geronimo.security.deployment.SecurityConfiguration;
87 import org.apache.geronimo.security.jacc.ComponentPermissions;
88 import org.apache.geronimo.web25.deployment.AbstractWebModuleBuilder;
89 import org.apache.geronimo.web.deployment.GenericToSpecificPlanConverter;
90 import org.apache.geronimo.xbeans.geronimo.web.jetty.JettyWebAppDocument;
91 import org.apache.geronimo.xbeans.geronimo.web.jetty.JettyWebAppType;
92 import org.apache.geronimo.xbeans.geronimo.web.jetty.config.GerJettyDocument;
93 import org.apache.geronimo.xbeans.geronimo.j2ee.GerClusteringDocument;
94 import org.apache.geronimo.xbeans.javaee.DispatcherType;
95 import org.apache.geronimo.xbeans.javaee.ErrorPageType;
96 import org.apache.geronimo.xbeans.javaee.FilterMappingType;
97 import org.apache.geronimo.xbeans.javaee.FilterType;
98 import org.apache.geronimo.xbeans.javaee.FormLoginConfigType;
99 import org.apache.geronimo.xbeans.javaee.JspConfigType;
100 import org.apache.geronimo.xbeans.javaee.ListenerType;
101 import org.apache.geronimo.xbeans.javaee.LocaleEncodingMappingListType;
102 import org.apache.geronimo.xbeans.javaee.LocaleEncodingMappingType;
103 import org.apache.geronimo.xbeans.javaee.LoginConfigType;
104 import org.apache.geronimo.xbeans.javaee.MimeMappingType;
105 import org.apache.geronimo.xbeans.javaee.ParamValueType;
106 import org.apache.geronimo.xbeans.javaee.ServletMappingType;
107 import org.apache.geronimo.xbeans.javaee.ServletType;
108 import org.apache.geronimo.xbeans.javaee.TaglibType;
109 import org.apache.geronimo.xbeans.javaee.WebAppDocument;
110 import org.apache.geronimo.xbeans.javaee.WebAppType;
111 import org.apache.geronimo.xbeans.javaee.WelcomeFileListType;
112 import org.apache.geronimo.xbeans.javaee.UrlPatternType;
113 import org.apache.xmlbeans.XmlException;
114 import org.apache.xmlbeans.XmlObject;
115 import org.mortbay.jetty.security.BasicAuthenticator;
116 import org.mortbay.jetty.security.ClientCertAuthenticator;
117 import org.mortbay.jetty.security.DigestAuthenticator;
118 import org.mortbay.jetty.security.FormAuthenticator;
119
120
121 /**
122  * @version $Rev:385659 $ $Date: 2006-12-14 02:57:10 -0500 (Thu, 14 Dec 2006) $
123  */

124 public class JettyModuleBuilder extends AbstractWebModuleBuilder {
125     private final static Log log = LogFactory.getLog(JettyModuleBuilder.class);
126     private final Environment defaultEnvironment;
127     private final AbstractNameQuery jettyContainerObjectName;
128     private final Collection JavaDoc defaultServlets;
129     private final Collection JavaDoc defaultFilters;
130     private final Collection JavaDoc defaultFilterMappings;
131     private final GBeanData pojoWebServiceTemplate;
132
133     private final Collection JavaDoc webServiceBuilder;
134     protected final NamespaceDrivenBuilderCollection clusteringBuilders;
135
136     private final List JavaDoc defaultWelcomeFiles;
137     private final Integer JavaDoc defaultSessionTimeoutSeconds;
138
139     private static final String JavaDoc JETTY_NAMESPACE = JettyWebAppDocument.type.getDocumentElementName().getNamespaceURI();
140     private String JavaDoc jspServletClassName;
141
142     public JettyModuleBuilder(Environment defaultEnvironment,
143             Integer JavaDoc defaultSessionTimeoutSeconds,
144             List JavaDoc defaultWelcomeFiles,
145             AbstractNameQuery jettyContainerName,
146             String JavaDoc jspServletClassName, Collection JavaDoc defaultServlets,
147             Collection JavaDoc defaultFilters,
148             Collection JavaDoc defaultFilterMappings,
149             Object JavaDoc pojoWebServiceTemplate,
150             Collection JavaDoc webServiceBuilder,
151             Collection JavaDoc clusteringBuilders,
152             Collection JavaDoc securityBuilders,
153             Collection JavaDoc serviceBuilders,
154             NamingBuilder namingBuilders,
155             ResourceEnvironmentSetter resourceEnvironmentSetter,
156             Kernel kernel) throws GBeanNotFoundException {
157         super(kernel, securityBuilders, serviceBuilders, namingBuilders, resourceEnvironmentSetter);
158         this.defaultEnvironment = defaultEnvironment;
159         this.defaultSessionTimeoutSeconds = (defaultSessionTimeoutSeconds == null) ? new Integer JavaDoc(30 * 60) : defaultSessionTimeoutSeconds;
160         this.jettyContainerObjectName = jettyContainerName;
161         this.jspServletClassName = jspServletClassName;
162         this.defaultServlets = defaultServlets;
163         this.defaultFilters = defaultFilters;
164         this.defaultFilterMappings = defaultFilterMappings;
165         this.pojoWebServiceTemplate = getGBeanData(kernel, pojoWebServiceTemplate);
166         this.webServiceBuilder = webServiceBuilder;
167         this.clusteringBuilders = new NamespaceDrivenBuilderCollection(clusteringBuilders, GerClusteringDocument.type.getDocumentElementName());
168
169         //todo locale mappings
170

171         this.defaultWelcomeFiles = defaultWelcomeFiles;
172     }
173
174     private static GBeanData getGBeanData(Kernel kernel, Object JavaDoc template) throws GBeanNotFoundException {
175         if (template == null) {
176             return null;
177         }
178         AbstractName templateName = kernel.getAbstractNameFor(template);
179         return kernel.getGBeanData(templateName);
180     }
181
182     protected Module createModule(Object JavaDoc plan, JarFile JavaDoc moduleFile, String JavaDoc targetPath, URL JavaDoc specDDUrl, boolean standAlone, String JavaDoc contextRoot, AbstractName earName, Naming naming, ModuleIDBuilder idBuilder) throws DeploymentException {
183         assert moduleFile != null: "moduleFile is null";
184         assert targetPath != null: "targetPath is null";
185         assert !targetPath.endsWith("/"): "targetPath must not end with a '/'";
186
187         // parse the spec dd
188
String JavaDoc specDD;
189         WebAppType webApp;
190         try {
191             if (specDDUrl == null) {
192                 specDDUrl = DeploymentUtil.createJarURL(moduleFile, "WEB-INF/web.xml");
193             }
194
195             // read in the entire specDD as a string, we need this for getDeploymentDescriptor
196
// on the J2ee management object
197
specDD = DeploymentUtil.readAll(specDDUrl);
198         } catch (Exception JavaDoc e) {
199             //no web.xml, not for us
200
return null;
201         }
202         //we found web.xml, if it won't parse that's an error.
203
try {
204             // parse it
205
XmlObject parsed = XmlBeansUtil.parse(specDD);
206             WebAppDocument webAppDoc = convertToServletSchema(parsed);
207             webApp = webAppDoc.getWebApp();
208         } catch (XmlException xmle) {
209             // Output the target path in the error to make it clearer to the user which webapp
210
// has the problem. The targetPath is used, as moduleFile may have an unhelpful
211
// value such as C:\geronimo-1.1\var\temp\geronimo-deploymentUtil22826.tmpdir
212
throw new DeploymentException("Error parsing web.xml for " + targetPath, xmle);
213         }
214         check(webApp);
215
216         // parse vendor dd
217
JettyWebAppType jettyWebApp = getJettyWebApp(plan, moduleFile, standAlone, targetPath, webApp);
218         if (contextRoot == null || contextRoot.trim().equals("")) {
219             if (jettyWebApp.isSetContextRoot()) {
220                 contextRoot = jettyWebApp.getContextRoot();
221             } else {
222                 contextRoot = determineDefaultContextRoot(webApp, standAlone, moduleFile, targetPath);
223             }
224         }
225
226         contextRoot = contextRoot.trim();
227
228         EnvironmentType environmentType = jettyWebApp.getEnvironment();
229         Environment environment = EnvironmentBuilder.buildEnvironment(environmentType, defaultEnvironment);
230
231         Boolean JavaDoc distributable = webApp.getDistributableArray().length == 1 ? Boolean.TRUE : Boolean.FALSE;
232         if (Boolean.TRUE == distributable) {
233             clusteringBuilders.buildEnvironment(jettyWebApp, environment);
234         }
235
236         getNamingBuilders().buildEnvironment(webApp, jettyWebApp, environment);
237
238         // Note: logic elsewhere depends on the default artifact ID being the file name less extension (ConfigIDExtractor)
239
String JavaDoc warName = new File JavaDoc(moduleFile.getName()).getName();
240         if (warName.lastIndexOf('.') > -1) {
241             warName = warName.substring(0, warName.lastIndexOf('.'));
242         }
243         idBuilder.resolve(environment, warName, "war");
244
245         Map JavaDoc servletNameToPathMap = buildServletNameToPathMap(webApp, contextRoot);
246
247         Map JavaDoc sharedContext = new HashMap JavaDoc();
248         for (Iterator JavaDoc iterator = webServiceBuilder.iterator(); iterator.hasNext();) {
249             WebServiceBuilder serviceBuilder = (WebServiceBuilder) iterator.next();
250             serviceBuilder.findWebServices(moduleFile, false, servletNameToPathMap, environment, sharedContext);
251         }
252         AbstractName moduleName;
253         if (earName == null) {
254             earName = naming.createRootName(environment.getConfigId(), NameFactory.NULL, NameFactory.J2EE_APPLICATION);
255             moduleName = naming.createChildName(earName, environment.getConfigId().toString(), NameFactory.WEB_MODULE);
256         } else {
257             moduleName = naming.createChildName(earName, targetPath, NameFactory.WEB_MODULE);
258         }
259
260         return new WebModule(standAlone, moduleName, environment, moduleFile, targetPath, webApp, jettyWebApp, specDD, contextRoot, sharedContext, JETTY_NAMESPACE);
261     }
262
263     JettyWebAppType getJettyWebApp(Object JavaDoc plan, JarFile JavaDoc moduleFile, boolean standAlone, String JavaDoc targetPath, WebAppType webApp) throws DeploymentException {
264         XmlObject rawPlan = null;
265         try {
266             // load the geronimo-web.xml from either the supplied plan or from the earFile
267
try {
268                 if (plan instanceof XmlObject) {
269                     rawPlan = (XmlObject) plan;
270                 } else {
271                     if (plan != null) {
272                         rawPlan = XmlBeansUtil.parse(((File JavaDoc) plan).toURL(), getClass().getClassLoader());
273                     } else {
274                         URL JavaDoc path = DeploymentUtil.createJarURL(moduleFile, "WEB-INF/geronimo-web.xml");
275                         try {
276                             rawPlan = XmlBeansUtil.parse(path, getClass().getClassLoader());
277                         } catch (FileNotFoundException JavaDoc e) {
278                             path = DeploymentUtil.createJarURL(moduleFile, "WEB-INF/geronimo-jetty.xml");
279                             try {
280                                 rawPlan = XmlBeansUtil.parse(path, getClass().getClassLoader());
281                             } catch (FileNotFoundException JavaDoc e1) {
282                                 log.warn("Web application " + targetPath + " does not contain a WEB-INF/geronimo-web.xml deployment plan. This may or may not be a problem, depending on whether you have things like resource references that need to be resolved. You can also give the deployer a separate deployment plan file on the command line.");
283                             }
284                         }
285                     }
286                 }
287             } catch (IOException JavaDoc e) {
288                 log.warn(e);
289             }
290
291             JettyWebAppType jettyWebApp;
292             if (rawPlan != null) {
293                 XmlObject webPlan = new GenericToSpecificPlanConverter(GerJettyDocument.type.getDocumentElementName().getNamespaceURI(),
294                         JettyWebAppDocument.type.getDocumentElementName().getNamespaceURI(), "jetty").convertToSpecificPlan(rawPlan);
295                 jettyWebApp = (JettyWebAppType) webPlan.changeType(JettyWebAppType.type);
296                 XmlBeansUtil.validateDD(jettyWebApp);
297             } else {
298                 String JavaDoc defaultContextRoot = determineDefaultContextRoot(webApp, standAlone, moduleFile, targetPath);
299                 jettyWebApp = createDefaultPlan(defaultContextRoot);
300             }
301             return jettyWebApp;
302         } catch (XmlException e) {
303             throw new DeploymentException("xml problem for web app " + targetPath, e);
304         }
305     }
306
307     private JettyWebAppType createDefaultPlan(String JavaDoc contextRoot) {
308         JettyWebAppType jettyWebApp = JettyWebAppType.Factory.newInstance();
309         jettyWebApp.setContextRoot(contextRoot);
310         return jettyWebApp;
311     }
312
313     public void initContext(EARContext earContext, Module module, ClassLoader JavaDoc cl) throws DeploymentException {
314         WebAppType webApp = (WebAppType) module.getSpecDD();
315 // MessageDestinationType[] messageDestinations = webApp.getMessageDestinationArray();
316
JettyWebAppType gerWebApp = (JettyWebAppType) module.getVendorDD();
317 // GerMessageDestinationType[] gerMessageDestinations = gerWebApp.getMessageDestinationArray();
318

319 // ENCConfigBuilder.registerMessageDestinations(earContext, module.getName(), messageDestinations, gerMessageDestinations);
320
getNamingBuilders().initContext(webApp, gerWebApp, module.getEarContext().getConfiguration(), earContext.getConfiguration(), module);
321         if ((webApp.getSecurityConstraintArray().length > 0 || webApp.getSecurityRoleArray().length > 0) &&
322                 !gerWebApp.isSetSecurityRealmName()) {
323             throw new DeploymentException("web.xml for web app " + module.getName() + " includes security elements but Geronimo deployment plan is not provided or does not contain <security-realm-name> element necessary to configure security accordingly.");
324         }
325         boolean hasSecurityRealmName = gerWebApp.isSetSecurityRealmName();
326         buildSubstitutionGroups(gerWebApp, hasSecurityRealmName, module, earContext);
327     }
328
329     public void addGBeans(EARContext earContext, Module module, ClassLoader JavaDoc cl, Collection JavaDoc repository) throws DeploymentException {
330         EARContext moduleContext = module.getEarContext();
331         ClassLoader JavaDoc moduleClassLoader = moduleContext.getClassLoader();
332         AbstractName moduleName = moduleContext.getModuleName();
333         WebModule webModule = (WebModule) module;
334
335         WebAppType webApp = (WebAppType) webModule.getSpecDD();
336         JettyWebAppType jettyWebApp = (JettyWebAppType) webModule.getVendorDD();
337
338         //N.B. we use the ear context which has all the gbeans we could possibly be looking up from this ear.
339
Map JavaDoc buildingContext = new HashMap JavaDoc();
340         buildingContext.put(NamingBuilder.JNDI_KEY, new HashMap JavaDoc());
341         buildingContext.put(NamingBuilder.GBEAN_NAME_KEY, moduleName);
342         Configuration earConfiguration = earContext.getConfiguration();
343         getNamingBuilders().buildNaming(webApp, jettyWebApp, earConfiguration, earConfiguration, (Module) webModule, buildingContext);
344         Map JavaDoc compContext = (Map JavaDoc) buildingContext.get(NamingBuilder.JNDI_KEY);
345
346
347         GBeanData webModuleData = new GBeanData(moduleName, JettyWebAppContext.GBEAN_INFO);
348         try {
349             moduleContext.addGBean(webModuleData);
350             if (moduleContext.getServerName() != null) {
351                 webModuleData.setReferencePattern("J2EEServer", moduleContext.getServerName());
352             }
353             if (!module.isStandAlone()) {
354                 webModuleData.setReferencePattern("J2EEApplication", earContext.getModuleName());
355             }
356
357             webModuleData.setAttribute("deploymentDescriptor", module.getOriginalSpecDD());
358             Set JavaDoc securityRoles = collectRoleNames(webApp);
359             Map JavaDoc rolePermissions = new HashMap JavaDoc();
360
361             // configure hosts and virtual-hosts
362
configureHosts(earContext, jettyWebApp, webModuleData);
363
364             //Add dependencies on managed connection factories and ejbs in this app
365
//This is overkill, but allows for people not using java:comp context (even though we don't support it)
366
//and sidesteps the problem of circular references between ejbs.
367
Set JavaDoc dependencies = findGBeanDependencies(earContext);
368             webModuleData.addDependencies(dependencies);
369
370             webModuleData.setAttribute("componentContext", compContext);
371             //classpath may have been augmented with enhanced classes
372
// webModuleData.setAttribute("webClassPath", webModule.getWebClasspath());
373
// unsharableResources, applicationManagedSecurityResources
374
GBeanResourceEnvironmentBuilder rebuilder = new GBeanResourceEnvironmentBuilder(webModuleData);
375             //N.B. use earContext not moduleContext
376
//TODO fix this for javaee 5 !!!
377
resourceEnvironmentSetter.setResourceEnvironment(rebuilder, webApp.getResourceRefArray(), jettyWebApp.getResourceRefArray());
378
379             String JavaDoc contextPath = webModule.getContextRoot();
380             if (contextPath == null) {
381                 throw new DeploymentException("null contextPath");
382             }
383             if (!contextPath.startsWith("/")) {
384                 contextPath = "/" + contextPath;
385             }
386             webModuleData.setAttribute("contextPath", contextPath);
387
388             webModuleData.setReferencePattern("TransactionManager", moduleContext.getTransactionManagerName());
389             webModuleData.setReferencePattern("TrackedConnectionAssociator", moduleContext.getConnectionTrackerName());
390             if (jettyWebApp.isSetWebContainer()) {
391                 AbstractNameQuery webContainerName = ENCConfigBuilder.getGBeanQuery(NameFactory.GERONIMO_SERVICE, jettyWebApp.getWebContainer());
392                 webModuleData.setReferencePattern("JettyContainer", webContainerName);
393             } else {
394                 webModuleData.setReferencePattern("JettyContainer", jettyContainerObjectName);
395             }
396             //stuff that jetty6 used to do
397
if (webApp.getDisplayNameArray().length > 0) {
398                 webModuleData.setAttribute("displayName", webApp.getDisplayNameArray()[0].getStringValue());
399             }
400
401             // configure context parameters.
402
configureContextParams(webApp, webModuleData);
403
404             // configure listeners.
405
configureListeners(webApp, webModuleData);
406
407             Boolean JavaDoc distributable = webApp.getDistributableArray().length == 1 ? Boolean.TRUE : Boolean.FALSE;
408             webModuleData.setAttribute("distributable", distributable);
409             if (Boolean.TRUE == distributable) {
410                 clusteringBuilders.build(jettyWebApp, earContext, moduleContext);
411                 if (webModuleData.getReferencePatterns(JettyWebAppContext.GBEAN_REF_SESSION_HANDLER_FACTORY) == null)
412                 {
413                     log.warn("No clustering builders configured: app will not be clustered");
414                     configureNoClustering(moduleContext, webModuleData);
415                 }
416             } else {
417                 configureNoClustering(moduleContext, webModuleData);
418             }
419
420             webModuleData.setAttribute("sessionTimeoutSeconds",
421                     (webApp.getSessionConfigArray().length == 1 && webApp.getSessionConfigArray(0).getSessionTimeout() != null) ?
422                             new Integer JavaDoc(webApp.getSessionConfigArray(0).getSessionTimeout().getBigIntegerValue().intValue() * 60) :
423                             defaultSessionTimeoutSeconds);
424
425             // configure mime mappings.
426
configureMimeMappings(webApp, webModuleData);
427
428             // configure welcome file lists.
429
configureWelcomeFileLists(webApp, webModuleData);
430
431             // configure local encoding mapping lists.
432
configureLocalEncodingMappingLists(webApp, webModuleData);
433
434             // configure error pages.
435
configureErrorPages(webApp, webModuleData);
436
437             // configure tag libs.
438
configureTagLibs(module, webApp, webModuleData);
439
440             // configure login configs.
441
configureLoginConfigs(module, webApp, jettyWebApp, webModuleData);
442
443             // Make sure that servlet mappings point to available servlets and never add a duplicate pattern.
444
Set JavaDoc knownServletMappings = new HashSet JavaDoc();
445             Map JavaDoc servletMappings = new HashMap JavaDoc();
446
447             buildServletMappings(module, webApp, servletMappings, knownServletMappings);
448
449             //"previous" filter mapping for linked list to keep dd's ordering.
450
AbstractName previous = null;
451
452             //add default filters
453
if (defaultFilters != null) {
454                 previous = addDefaultFiltersGBeans(earContext, moduleContext, moduleName, previous);
455             }
456
457             //add default filtermappings
458
// if (defaultFilterMappings != null) {
459
// for (Iterator iterator = defaultFilterMappings.iterator(); iterator.hasNext();) {
460
// Object defaultFilterMapping = iterator.next();
461
// GBeanData filterMappingGBeanData = getGBeanData(kernel, defaultFilterMapping);
462
// String filterName = (String) filterMappingGBeanData.getAttribute("filterName");
463
// ObjectName defaultFilterMappingObjectName;
464
// if (filterMappingGBeanData.getAttribute("urlPattern") != null) {
465
// String urlPattern = (String) filterMappingGBeanData.getAttribute("urlPattern");
466
// defaultFilterMappingObjectName = NameFactory.getWebFilterMappingName(null, null, null, null, filterName, null, urlPattern, moduleName);
467
// } else {
468
// Set servletNames = filterMappingGBeanData.getReferencePatterns("Servlet");
469
// if (servletNames == null || servletNames.size() != 1) {
470
// throw new DeploymentException("Exactly one servlet name must be supplied");
471
// }
472
// ObjectName servletObjectName = (ObjectName) servletNames.iterator().next();
473
// String servletName = servletObjectName.getKeyProperty("name");
474
// defaultFilterMappingObjectName = NameFactory.getWebFilterMappingName(null, null, null, null, filterName, servletName, null, moduleName);
475
// }
476
// filterMappingGBeanData.setName(defaultFilterMappingObjectName);
477
// filterMappingGBeanData.setReferencePattern("JettyFilterMappingRegistration", webModuleName);
478
// moduleContext.addGBean(filterMappingGBeanData);
479
// }
480
// }
481

482             // add filter mapping GBeans.
483
addFilterMappingsGBeans(earContext, moduleContext, moduleName, webApp, previous);
484
485             // add filter GBeans.
486
addFiltersGBeans(earContext, moduleContext, moduleName, webApp);
487
488             //add default servlets
489
if (defaultServlets != null) {
490                 addDefaultServletsGBeans(earContext, moduleContext, moduleName, knownServletMappings);
491             }
492
493             //set up servlet gbeans.
494

495             ServletType[] servletTypes = webApp.getServletArray();
496             addServlets(moduleName, webModule, servletTypes, servletMappings, securityRoles, rolePermissions, moduleContext);
497
498             if (jettyWebApp.isSetSecurityRealmName()) {
499                 configureSecurityRealm(earContext, webApp, jettyWebApp, webModuleData, securityRoles, rolePermissions);
500             }
501             if (!module.isStandAlone()) {
502                 ConfigurationData moduleConfigurationData = moduleContext.getConfigurationData();
503                 earContext.addChildConfiguration(module.getTargetPath(), moduleConfigurationData);
504             }
505         } catch (DeploymentException de) {
506             throw de;
507         } catch (Exception JavaDoc e) {
508             throw new DeploymentException("Unable to initialize webapp GBean for " + module.getName(), e);
509         }
510     }
511
512     private void configureNoClustering(EARContext moduleContext, GBeanData webModuleData) throws GBeanAlreadyExistsException {
513 // AbstractName name = moduleContext.getNaming().createChildName(moduleContext.getModuleName(),
514
// "DefaultWebApplicationHandlerFactory",
515
// NameFactory.GERONIMO_SERVICE);
516
// GBeanData beanData = new GBeanData(name, DefaultWebApplicationHandlerFactory.GBEAN_INFO);
517
// webModuleData.setReferencePattern(JettyWebAppContext.GBEAN_REF_WEB_APPLICATION_HANDLER_FACTORY, name);
518
// moduleContext.addGBean(beanData);
519
}
520
521     private void configureSecurityRealm(EARContext earContext, WebAppType webApp, JettyWebAppType jettyWebApp, GBeanData webModuleData, Set JavaDoc securityRoles, Map JavaDoc rolePermissions) throws DeploymentException {
522         AbstractName moduleName = webModuleData.getAbstractName();
523         if (earContext.getSecurityConfiguration() == null) {
524             throw new DeploymentException("You have specified a <security-realm-name> for the webapp " + moduleName + " but no <security> configuration (role mapping) is supplied in the Geronimo plan for the web application (or the Geronimo plan for the EAR if the web app is in an EAR)");
525         }
526         String JavaDoc securityRealmName = jettyWebApp.getSecurityRealmName().trim();
527         webModuleData.setAttribute("securityRealmName", securityRealmName);
528
529         /**
530          * TODO - go back to commented version when possible.
531          */

532         String JavaDoc policyContextID = moduleName.toString().replaceAll("[, :]", "_");
533         //String policyContextID = webModuleName.getCanonicalName();
534
webModuleData.setAttribute("policyContextID", policyContextID);
535
536         ComponentPermissions componentPermissions = buildSpecSecurityConfig(webApp, securityRoles, rolePermissions);
537         webModuleData.setAttribute("excludedPermissions", componentPermissions.getExcludedPermissions());
538         PermissionCollection JavaDoc checkedPermissions = new Permissions JavaDoc();
539         for (Iterator JavaDoc iterator = rolePermissions.values().iterator(); iterator.hasNext();) {
540             PermissionCollection JavaDoc permissionsForRole = (PermissionCollection JavaDoc) iterator.next();
541             for (Enumeration JavaDoc iterator2 = permissionsForRole.elements(); iterator2.hasMoreElements();) {
542                 Permission JavaDoc permission = (Permission JavaDoc) iterator2.nextElement();
543                 checkedPermissions.add(permission);
544             }
545         }
546         webModuleData.setAttribute("checkedPermissions", checkedPermissions);
547
548         earContext.addSecurityContext(policyContextID, componentPermissions);
549         DefaultPrincipal defaultPrincipal = ((SecurityConfiguration) earContext.getSecurityConfiguration()).getDefaultPrincipal();
550         webModuleData.setAttribute("defaultPrincipal", defaultPrincipal);
551     }
552
553     private void addDefaultServletsGBeans(EARContext earContext, EARContext moduleContext, AbstractName moduleName, Set JavaDoc knownServletMappings) throws GBeanNotFoundException, GBeanAlreadyExistsException {
554         for (Iterator JavaDoc iterator = defaultServlets.iterator(); iterator.hasNext();) {
555             Object JavaDoc defaultServlet = iterator.next();
556             GBeanData servletGBeanData = getGBeanData(kernel, defaultServlet);
557             AbstractName defaultServletObjectName = earContext.getNaming().createChildName(moduleName, (String JavaDoc) servletGBeanData.getAttribute("servletName"), NameFactory.SERVLET);
558             servletGBeanData.setAbstractName(defaultServletObjectName);
559             servletGBeanData.setReferencePattern("JettyServletRegistration", moduleName);
560             Set JavaDoc defaultServletMappings = new HashSet JavaDoc((Collection JavaDoc) servletGBeanData.getAttribute("servletMappings"));
561             defaultServletMappings.removeAll(knownServletMappings);
562             servletGBeanData.setAttribute("servletMappings", defaultServletMappings);
563             moduleContext.addGBean(servletGBeanData);
564         }
565     }
566
567     private void addFiltersGBeans(EARContext earContext, EARContext moduleContext, AbstractName moduleName, WebAppType webApp) throws GBeanAlreadyExistsException {
568         FilterType[] filterArray = webApp.getFilterArray();
569         for (int i = 0; i < filterArray.length; i++) {
570             FilterType filterType = filterArray[i];
571             String JavaDoc filterName = filterType.getFilterName().getStringValue().trim();
572             AbstractName filterAbstractName = earContext.getNaming().createChildName(moduleName, filterName, NameFactory.WEB_FILTER);
573             GBeanData filterData = new GBeanData(filterAbstractName, JettyFilterHolder.GBEAN_INFO);
574             filterData.setAttribute("filterName", filterName);
575             filterData.setAttribute("filterClass", filterType.getFilterClass().getStringValue().trim());
576             Map JavaDoc initParams = new HashMap JavaDoc();
577             ParamValueType[] initParamArray = filterType.getInitParamArray();
578             for (int j = 0; j < initParamArray.length; j++) {
579                 ParamValueType paramValueType = initParamArray[j];
580                 initParams.put(paramValueType.getParamName().getStringValue().trim(), paramValueType.getParamValue().getStringValue().trim());
581             }
582             filterData.setAttribute("initParams", initParams);
583             filterData.setReferencePattern("JettyServletRegistration", moduleName);
584             moduleContext.addGBean(filterData);
585         }
586     }
587
588     private void addFilterMappingsGBeans(EARContext earContext, EARContext moduleContext, AbstractName moduleName, WebAppType webApp, AbstractName previous) throws GBeanAlreadyExistsException {
589         FilterMappingType[] filterMappingArray = webApp.getFilterMappingArray();
590         for (int i = 0; i < filterMappingArray.length; i++) {
591             FilterMappingType filterMappingType = filterMappingArray[i];
592             String JavaDoc filterName = filterMappingType.getFilterName().getStringValue().trim();
593             GBeanData filterMappingData = new GBeanData(JettyFilterMapping.GBEAN_INFO);
594             if (previous != null) {
595                 filterMappingData.addDependency(previous);
596             }
597             filterMappingData.setReferencePattern("JettyServletRegistration", moduleName);
598             AbstractName filterAbstractName = earContext.getNaming().createChildName(moduleName, filterName, NameFactory.WEB_FILTER);
599
600             AbstractName filterMappingName = null;
601             if (filterMappingType.sizeOfUrlPatternArray() > 0) {
602                 String JavaDoc[] urlPatterns = new String JavaDoc[filterMappingType.sizeOfUrlPatternArray()];
603                 for (int j = 0; j < urlPatterns.length; j++) {
604                     urlPatterns[j] = filterMappingType.getUrlPatternArray(j).getStringValue().trim();
605                 }
606
607                 filterMappingData.setAttribute("urlPatterns", urlPatterns);
608                 filterMappingName = earContext.getNaming().createChildName(filterAbstractName, ObjectName.quote(Arrays.deepToString(urlPatterns)), NameFactory.URL_WEB_FILTER_MAPPING);
609             }
610             if (filterMappingType.sizeOfServletNameArray() > 0) {
611                 Set JavaDoc servletNameSet = new HashSet JavaDoc();
612                 for (int j = 0; j < filterMappingType.sizeOfServletNameArray(); j++) {
613                     String JavaDoc servletName = filterMappingType.getServletNameArray(j).getStringValue().trim();
614                     AbstractName abstractServletName = earContext.getNaming().createChildName(moduleName, servletName, NameFactory.SERVLET);
615                     servletNameSet.add(abstractServletName);
616                     filterMappingData.addDependency(abstractServletName);
617                 }
618
619                 filterMappingData.setReferencePatterns("Servlets", servletNameSet);
620                 filterMappingName = earContext.getNaming().createChildName(filterAbstractName, ObjectName.quote(Arrays.deepToString(servletNameSet.toArray())), NameFactory.SERVLET_WEB_FILTER_MAPPING);
621
622             }
623             filterMappingData.setAbstractName(filterMappingName);
624             previous = filterMappingName;
625
626             boolean request = filterMappingType.getDispatcherArray().length == 0;
627             boolean forward = false;
628             boolean include = false;
629             boolean error = false;
630             for (int j = 0; j < filterMappingType.getDispatcherArray().length; j++) {
631                 DispatcherType dispatcherType = filterMappingType.getDispatcherArray()[j];
632                 if (dispatcherType.getStringValue().equals("REQUEST")) {
633                     request = true;
634                 } else if (dispatcherType.getStringValue().equals("FORWARD")) {
635                     forward = true;
636                 } else if (dispatcherType.getStringValue().equals("INCLUDE")) {
637                     include = true;
638                 } else if (dispatcherType.getStringValue().equals("ERROR")) {
639                     error = true;
640                 }
641             }
642             filterMappingData.setAttribute("requestDispatch", Boolean.valueOf(request));
643             filterMappingData.setAttribute("forwardDispatch", Boolean.valueOf(forward));
644             filterMappingData.setAttribute("includeDispatch", Boolean.valueOf(include));
645             filterMappingData.setAttribute("errorDispatch", Boolean.valueOf(error));
646             filterMappingData.setReferencePattern("Filter", filterAbstractName);
647             moduleContext.addGBean(filterMappingData);
648         }
649     }
650
651     private AbstractName addDefaultFiltersGBeans(EARContext earContext, EARContext moduleContext, AbstractName moduleName, AbstractName previous) throws GBeanNotFoundException, GBeanAlreadyExistsException {
652         for (Iterator JavaDoc iterator = defaultFilters.iterator(); iterator.hasNext();) {
653             Object JavaDoc defaultFilter = iterator.next();
654             GBeanData filterGBeanData = getGBeanData(kernel, defaultFilter);
655             String JavaDoc filterName = (String JavaDoc) filterGBeanData.getAttribute("filterName");
656             AbstractName defaultFilterAbstractName = earContext.getNaming().createChildName(moduleName, filterName, NameFactory.WEB_FILTER);
657             filterGBeanData.setAbstractName(defaultFilterAbstractName);
658             filterGBeanData.setReferencePattern("JettyServletRegistration", moduleName);
659             moduleContext.addGBean(filterGBeanData);
660             //add a mapping to /*
661

662             GBeanData filterMappingGBeanData = new GBeanData(JettyFilterMapping.GBEAN_INFO);
663             if (previous != null) {
664                 filterMappingGBeanData.addDependency(previous);
665             }
666             filterMappingGBeanData.setReferencePattern("JettyServletRegistration", moduleName);
667             String JavaDoc urlPattern = "/*";
668             filterMappingGBeanData.setAttribute("urlPattern", urlPattern);
669             AbstractName filterMappingName = earContext.getNaming().createChildName(defaultFilterAbstractName, urlPattern, NameFactory.URL_WEB_FILTER_MAPPING);
670             filterMappingGBeanData.setAbstractName(filterMappingName);
671             previous = filterMappingName;
672
673
674             filterMappingGBeanData.setAttribute("requestDispatch", Boolean.TRUE);
675             filterMappingGBeanData.setAttribute("forwardDispatch", Boolean.TRUE);
676             filterMappingGBeanData.setAttribute("includeDispatch", Boolean.TRUE);
677             filterMappingGBeanData.setAttribute("errorDispatch", Boolean.FALSE);
678             filterMappingGBeanData.setReferencePattern("Filter", defaultFilterAbstractName);
679             moduleContext.addGBean(filterMappingGBeanData);
680         }
681         return previous;
682     }
683
684     private Map JavaDoc buildServletMappings(Module module, WebAppType webApp, Map JavaDoc servletMappings, Set JavaDoc knownServletMappings) throws DeploymentException {
685         ServletType[] servletTypes = webApp.getServletArray();
686         Set JavaDoc knownServlets = new HashSet JavaDoc();
687         for (int i = 0; i < servletTypes.length; i++) {
688             ServletType type = servletTypes[i];
689             knownServlets.add(type.getServletName().getStringValue().trim());
690         }
691
692         ServletMappingType[] servletMappingArray = webApp.getServletMappingArray();
693         for (int i = 0; i < servletMappingArray.length; i++) {
694             ServletMappingType servletMappingType = servletMappingArray[i];
695             String JavaDoc servletName = servletMappingType.getServletName().getStringValue().trim();
696             if (!knownServlets.contains(servletName)) {
697                 throw new DeploymentException("Web app " + module.getName() +
698                         " contains a servlet mapping that refers to servlet '" + servletName +
699                         "' but no such servlet was found!");
700             }
701             UrlPatternType[] urlPatterns = servletMappingType.getUrlPatternArray();
702             for (int j = 0; j < urlPatterns.length; j++) {
703                 String JavaDoc urlPattern = urlPatterns[j].getStringValue().trim();
704                 if (!knownServletMappings.contains(urlPattern)) {
705                     knownServletMappings.add(urlPattern);
706                     checkString(urlPattern);
707                     Set JavaDoc urlsForServlet = (Set JavaDoc) servletMappings.get(servletName);
708                     if (urlsForServlet == null) {
709                         urlsForServlet = new HashSet JavaDoc();
710                         servletMappings.put(servletName, urlsForServlet);
711                     }
712                     urlsForServlet.add(urlPattern);
713                 }
714             }
715         }
716
717         return servletMappings;
718     }
719
720     private void configureLoginConfigs(Module module, WebAppType webApp, JettyWebAppType jettyWebApp, GBeanData webModuleData) throws DeploymentException {
721         LoginConfigType[] loginConfigArray = webApp.getLoginConfigArray();
722         if (loginConfigArray.length > 1) {
723             throw new DeploymentException("Web app " + module.getName() + " cannot have more than one login-config element. Currently has " + loginConfigArray.length + " login-config elements.");
724         }
725         if (loginConfigArray.length == 1) {
726             LoginConfigType loginConfig = loginConfigArray[0];
727             if (loginConfig.isSetAuthMethod()) {
728                 String JavaDoc authMethod = loginConfig.getAuthMethod().getStringValue();
729                 if ("BASIC".equals(authMethod)) {
730                     webModuleData.setAttribute("authenticator", new BasicAuthenticator());
731                 } else if ("DIGEST".equals(authMethod)) {
732                     webModuleData.setAttribute("authenticator", new DigestAuthenticator());
733                 } else if ("FORM".equals(authMethod)) {
734
735                     FormAuthenticator formAuthenticator = new FormAuthenticator();
736                     webModuleData.setAttribute("authenticator", formAuthenticator);
737                     if (loginConfig.isSetFormLoginConfig()) {
738                         FormLoginConfigType formLoginConfig = loginConfig.getFormLoginConfig();
739                         formAuthenticator.setLoginPage(formLoginConfig.getFormLoginPage().getStringValue());
740                         formAuthenticator.setErrorPage(formLoginConfig.getFormErrorPage().getStringValue());
741                     }
742                 } else if ("CLIENT-CERT".equals(authMethod)) {
743                     webModuleData.setAttribute("authenticator", new ClientCertAuthenticator());
744                 }
745             }
746             if (loginConfig.isSetRealmName()) {
747                 webModuleData.setAttribute("realmName", loginConfig.getRealmName().getStringValue());
748             }
749
750         } else if (jettyWebApp.isSetSecurityRealmName()) {
751             webModuleData.setAttribute("authenticator", new NonAuthenticator());
752         }
753     }
754
755     private void configureTagLibs(Module module, WebAppType webApp, GBeanData webModuleData) throws DeploymentException {
756         JspConfigType[] jspConfigArray = webApp.getJspConfigArray();
757         if (jspConfigArray.length > 1) {
758             throw new DeploymentException("Web app " + module.getName() + " cannot have more than one jsp-config element. Currently has " + jspConfigArray.length + " jsp-config elements.");
759         }
760         Map JavaDoc tagLibMap = new HashMap JavaDoc();
761         for (int i = 0; i < jspConfigArray.length; i++) {
762             TaglibType[] tagLibArray = jspConfigArray[i].getTaglibArray();
763             for (int j = 0; j < tagLibArray.length; j++) {
764                 TaglibType taglib = tagLibArray[j];
765                 tagLibMap.put(taglib.getTaglibUri().getStringValue().trim(), taglib.getTaglibLocation().getStringValue().trim());
766             }
767         }
768         webModuleData.setAttribute("tagLibMap", tagLibMap);
769     }
770
771     private void configureErrorPages(WebAppType webApp, GBeanData webModuleData) {
772         ErrorPageType[] errorPageArray = webApp.getErrorPageArray();
773         Map JavaDoc errorPageMap = new HashMap JavaDoc();
774         for (int i = 0; i < errorPageArray.length; i++) {
775             ErrorPageType errorPageType = errorPageArray[i];
776             if (errorPageType.isSetErrorCode()) {
777                 errorPageMap.put(errorPageType.getErrorCode().getStringValue(), errorPageType.getLocation().getStringValue());
778             } else {
779                 errorPageMap.put(errorPageType.getExceptionType().getStringValue(), errorPageType.getLocation().getStringValue());
780             }
781         }
782         webModuleData.setAttribute("errorPages", errorPageMap);
783     }
784
785     private void configureLocalEncodingMappingLists(WebAppType webApp, GBeanData webModuleData) {
786         LocaleEncodingMappingListType[] localeEncodingMappingListArray = webApp.getLocaleEncodingMappingListArray();
787         Map JavaDoc localeEncodingMappingMap = new HashMap JavaDoc();
788         for (int i = 0; i < localeEncodingMappingListArray.length; i++) {
789             LocaleEncodingMappingType[] localeEncodingMappingArray = localeEncodingMappingListArray[i].getLocaleEncodingMappingArray();
790             for (int j = 0; j < localeEncodingMappingArray.length; j++) {
791                 LocaleEncodingMappingType localeEncodingMapping = localeEncodingMappingArray[j];
792                 localeEncodingMappingMap.put(localeEncodingMapping.getLocale(), localeEncodingMapping.getEncoding());
793             }
794         }
795         webModuleData.setAttribute("localeEncodingMapping", localeEncodingMappingMap);
796     }
797
798     private void configureWelcomeFileLists(WebAppType webApp, GBeanData webModuleData) {
799         WelcomeFileListType[] welcomeFileArray = webApp.getWelcomeFileListArray();
800         List JavaDoc welcomeFiles;
801         if (welcomeFileArray.length > 0) {
802             welcomeFiles = new ArrayList JavaDoc();
803             for (int i = 0; i < welcomeFileArray.length; i++) {
804                 String JavaDoc[] welcomeFileListType = welcomeFileArray[i].getWelcomeFileArray();
805                 for (int j = 0; j < welcomeFileListType.length; j++) {
806                     String JavaDoc welcomeFile = welcomeFileListType[j].trim();
807                     welcomeFiles.add(welcomeFile);
808                 }
809             }
810         } else {
811             welcomeFiles = new ArrayList JavaDoc(defaultWelcomeFiles);
812         }
813         webModuleData.setAttribute("welcomeFiles", welcomeFiles.toArray(new String JavaDoc[welcomeFiles.size()]));
814     }
815
816     private void configureMimeMappings(WebAppType webApp, GBeanData webModuleData) {
817         MimeMappingType[] mimeMappingArray = webApp.getMimeMappingArray();
818         Map JavaDoc mimeMappingMap = new HashMap JavaDoc();
819         for (int i = 0; i < mimeMappingArray.length; i++) {
820             MimeMappingType mimeMappingType = mimeMappingArray[i];
821             mimeMappingMap.put(mimeMappingType.getExtension().getStringValue(), mimeMappingType.getMimeType().getStringValue());
822         }
823         webModuleData.setAttribute("mimeMap", mimeMappingMap);
824     }
825
826     private void configureListeners(WebAppType webApp, GBeanData webModuleData) {
827         ListenerType[] listenerArray = webApp.getListenerArray();
828         Collection JavaDoc listeners = new ArrayList JavaDoc();
829         for (int i = 0; i < listenerArray.length; i++) {
830             ListenerType listenerType = listenerArray[i];
831             listeners.add(listenerType.getListenerClass().getStringValue());
832         }
833         webModuleData.setAttribute("listenerClassNames", listeners);
834     }
835
836     private void configureContextParams(WebAppType webApp, GBeanData webModuleData) {
837         ParamValueType[] contextParamArray = webApp.getContextParamArray();
838         Map JavaDoc contextParams = new HashMap JavaDoc();
839         for (int i = 0; i < contextParamArray.length; i++) {
840             ParamValueType contextParam = contextParamArray[i];
841             contextParams.put(contextParam.getParamName().getStringValue().trim(), contextParam.getParamValue().getStringValue().trim());
842         }
843         webModuleData.setAttribute("contextParamMap", contextParams);
844     }
845
846     private void configureHosts(EARContext earContext, JettyWebAppType jettyWebApp, GBeanData webModuleData) throws GBeanAlreadyExistsException {
847         String JavaDoc[] hosts = jettyWebApp.getHostArray();
848         for (int i = 0; i < hosts.length; i++) {
849             hosts[i] = hosts[i].trim();
850         }
851         String JavaDoc[] virtualHosts = jettyWebApp.getVirtualHostArray();
852         for (int i = 0; i < virtualHosts.length; i++) {
853             virtualHosts[i] = virtualHosts[i].trim();
854         }
855         if (hosts.length > 0 || virtualHosts.length > 0) {
856             //use name same as module
857
AbstractName hostName = earContext.getNaming().createChildName(webModuleData.getAbstractName(), "Host", "Host");
858             GBeanData hostData = new GBeanData(hostName, Host.GBEAN_INFO);
859             hostData.setAttribute("hosts", hosts);
860             hostData.setAttribute("virtualHosts", virtualHosts);
861             earContext.addGBean(hostData);
862             webModuleData.setReferencePattern("Host", hostName);
863         }
864     }
865
866     public String JavaDoc getSchemaNamespace() {
867         return JETTY_NAMESPACE;
868     }
869
870     /**
871      * Adds the provided servlets, taking into account the load-on-startup ordering.
872      *
873      * @param webModuleName an <code>ObjectName</code> value
874      * @param module a <code>Module</code> value
875      * @param servletTypes a <code>ServletType[]</code> value, contains the <code>servlet</code> entries from <code>web.xml</code>.
876      * @param servletMappings a <code>Map</code> value
877      * @param securityRoles a <code>Set</code> value
878      * @param rolePermissions a <code>Map</code> value
879      * @param moduleContext an <code>EARContext</code> value
880      * @throws DeploymentException if an error occurs
881      */

882     private void addServlets(AbstractName webModuleName,
883             Module module,
884             ServletType[] servletTypes,
885             Map JavaDoc servletMappings,
886             Set JavaDoc securityRoles,
887             Map JavaDoc rolePermissions,
888             EARContext moduleContext) throws DeploymentException {
889
890         // this TreeSet will order the ServletTypes based on whether
891
// they have a load-on-startup element and what its value is
892
TreeSet JavaDoc loadOrder = new TreeSet JavaDoc(new StartupOrderComparator());
893
894         // add all of the servlets to the sorted set
895
for (int i = 0; i < servletTypes.length; i++) {
896             loadOrder.add(servletTypes[i]);
897         }
898
899         // now that they're sorted, read them in order and add them to
900
// the context. we'll use a GBean reference to enforce the
901
// load order. Each servlet GBean (except the first) has a
902
// reference to the previous GBean. The kernel will ensure
903
// that each "previous" GBean is running before it starts any
904
// other GBeans that reference it. See also
905
// o.a.g.jetty6.JettyFilterMapping which provided the example
906
// of how to do this.
907
// http://issues.apache.org/jira/browse/GERONIMO-645
908
AbstractName previousServlet = null;
909         for (Iterator JavaDoc servlets = loadOrder.iterator(); servlets.hasNext();) {
910             ServletType servletType = (ServletType) servlets.next();
911             previousServlet = addServlet(webModuleName, module, previousServlet, servletType, servletMappings, securityRoles, rolePermissions, moduleContext);
912         }
913
914         // JACC v1.0 secion B.19
915
addUnmappedJSPPermissions(securityRoles, rolePermissions);
916     }
917
918     /**
919      * @param webModuleName
920      * @param module
921      * @param previousServlet
922      * @param servletType
923      * @param servletMappings
924      * @param securityRoles
925      * @param rolePermissions
926      * @param moduleContext
927      * @return AbstractName of servlet gbean added
928      * @throws DeploymentException
929      */

930     private AbstractName addServlet(AbstractName webModuleName,
931             Module module,
932             AbstractName previousServlet,
933             ServletType servletType,
934             Map JavaDoc servletMappings,
935             Set JavaDoc securityRoles,
936             Map JavaDoc rolePermissions,
937             EARContext moduleContext) throws DeploymentException {
938         String JavaDoc servletName = servletType.getServletName().getStringValue().trim();
939         AbstractName servletAbstractName = moduleContext.getNaming().createChildName(webModuleName, servletName, NameFactory.SERVLET);
940         GBeanData servletData;
941         Map JavaDoc initParams = new HashMap JavaDoc();
942         if (servletType.isSetServletClass()) {
943             ClassLoader JavaDoc webClassLoader = moduleContext.getClassLoader();
944             String JavaDoc servletClassName = servletType.getServletClass().getStringValue().trim();
945             Class JavaDoc servletClass;
946             try {
947                 servletClass = webClassLoader.loadClass(servletClassName);
948             } catch (ClassNotFoundException JavaDoc e) {
949                 throw new DeploymentException("Could not load servlet class " + servletClassName, e); // TODO identify web app in message
950
}
951             Class JavaDoc baseServletClass;
952             try {
953                 baseServletClass = webClassLoader.loadClass(Servlet JavaDoc.class.getName());
954             } catch (ClassNotFoundException JavaDoc e) {
955                 throw new DeploymentException("Could not load javax.servlet.Servlet in web classloader", e); // TODO identify web app in message
956
}
957             if (baseServletClass.isAssignableFrom(servletClass)) {
958                 servletData = new GBeanData(servletAbstractName, JettyServletHolder.GBEAN_INFO);
959                 servletData.setAttribute("servletClass", servletClassName);
960             } else {
961                 servletData = new GBeanData(pojoWebServiceTemplate);
962                 servletData.setAbstractName(servletAbstractName);
963                 //let the web service builder deal with configuring the gbean with the web service stack
964
// Object portInfo = portMap.get(servletName);
965
// if (portInfo == null) {
966
// throw new DeploymentException("No web service deployment info for servlet name " + servletName); // TODO identify web app in message
967
// }
968
boolean configured = false;
969                 for (Iterator JavaDoc iterator = webServiceBuilder.iterator(); iterator.hasNext();) {
970                     WebServiceBuilder serviceBuilder = (WebServiceBuilder) iterator.next();
971                     if (serviceBuilder.configurePOJO(servletData, servletName, module, servletClassName, moduleContext)) {
972                         configured = true;
973                         break;
974                     }
975                 }
976                 if (!configured) {
977                     throw new DeploymentException("POJO web service: " + servletName + " not configured by any web service builder");
978                 }
979             }
980         } else if (servletType.isSetJspFile()) {
981             servletData = new GBeanData(servletAbstractName, JettyServletHolder.GBEAN_INFO);
982             servletData.setAttribute("jspFile", servletType.getJspFile().getStringValue().trim());
983             //TODO MAKE THIS CONFIGURABLE!!! Jetty uses the servlet mapping set up from the default-web.xml
984
servletData.setAttribute("servletClass", jspServletClassName);
985             initParams.put("development", "false");
986         } else {
987             throw new DeploymentException("Neither servlet class nor jsp file is set for " + servletName); // TODO identify web app in message
988
}
989
990         // link to previous servlet, if there is one, so that we
991
// preserve the <load-on-startup> ordering.
992
// http://issues.apache.org/jira/browse/GERONIMO-645
993
if (null != previousServlet) {
994             servletData.addDependency(previousServlet);
995         }
996
997         //TODO in init param setter, add classpath if jspFile is not null.
998
servletData.setReferencePattern("JettyServletRegistration", webModuleName);
999         servletData.setAttribute("servletName", servletName);
1000        ParamValueType[] initParamArray = servletType.getInitParamArray();
1001        for (int j = 0; j < initParamArray.length; j++) {
1002            ParamValueType paramValueType = initParamArray[j];
1003            initParams.put(paramValueType.getParamName().getStringValue().trim(), paramValueType.getParamValue().getStringValue().trim());
1004        }
1005        servletData.setAttribute("initParams", initParams);
1006        if (servletType.isSetLoadOnStartup()) {
1007            Integer JavaDoc loadOnStartup = new Integer JavaDoc(servletType.xgetLoadOnStartup().getStringValue());
1008            servletData.setAttribute("loadOnStartup", loadOnStartup);
1009        }
1010
1011        Set JavaDoc mappings = (Set JavaDoc) servletMappings.get(servletName);
1012        servletData.setAttribute("servletMappings", mappings == null ? Collections.EMPTY_SET : mappings);
1013
1014        //run-as
1015
if (servletType.isSetRunAs()) {
1016            servletData.setAttribute("runAsRole", servletType.getRunAs().getRoleName().getStringValue().trim());
1017        }
1018
1019        processRoleRefPermissions(servletType, securityRoles, rolePermissions);
1020
1021        try {
1022            moduleContext.addGBean(servletData);
1023        } catch (GBeanAlreadyExistsException e) {
1024            throw new DeploymentException("Could not add servlet gbean to context", e); // TODO identify web app in message
1025
}
1026        return servletAbstractName;
1027    }
1028
1029    public static final GBeanInfo GBEAN_INFO;
1030
1031    static {
1032        GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(JettyModuleBuilder.class, NameFactory.MODULE_BUILDER);
1033        infoBuilder.addAttribute("defaultEnvironment", Environment.class, true, true);
1034        infoBuilder.addAttribute("defaultSessionTimeoutSeconds", Integer JavaDoc.class, true, true);
1035        infoBuilder.addAttribute("defaultWelcomeFiles", List JavaDoc.class, true, true);
1036        infoBuilder.addAttribute("jettyContainerObjectName", AbstractNameQuery.class, true, true);
1037        infoBuilder.addAttribute("jspServletClassName", String JavaDoc.class, true, true);
1038        infoBuilder.addReference("DefaultServlets", JettyDefaultServletHolder.class, NameFactory.SERVLET_TEMPLATE);
1039        infoBuilder.addReference("DefaultFilters", Object JavaDoc.class);
1040        infoBuilder.addReference("DefaultFilterMappings", Object JavaDoc.class);
1041        infoBuilder.addReference("PojoWebServiceTemplate", Object JavaDoc.class, NameFactory.SERVLET_WEB_SERVICE_TEMPLATE);
1042        infoBuilder.addReference("WebServiceBuilder", WebServiceBuilder.class, NameFactory.MODULE_BUILDER);
1043        infoBuilder.addReference("ClusteringBuilders", NamespaceDrivenBuilder.class, NameFactory.MODULE_BUILDER);
1044        infoBuilder.addReference("SecurityBuilders", NamespaceDrivenBuilder.class, NameFactory.MODULE_BUILDER);
1045        infoBuilder.addReference("ServiceBuilders", NamespaceDrivenBuilder.class, NameFactory.MODULE_BUILDER);
1046        infoBuilder.addReference("NamingBuilders", NamingBuilder.class, NameFactory.MODULE_BUILDER);
1047        infoBuilder.addReference("ResourceEnvironmentSetter", ResourceEnvironmentSetter.class, NameFactory.MODULE_BUILDER);
1048        infoBuilder.addAttribute("kernel", Kernel.class, false);
1049        infoBuilder.addInterface(ModuleBuilder.class);
1050
1051        infoBuilder.setConstructor(new String JavaDoc[]{
1052                "defaultEnvironment",
1053                "defaultSessionTimeoutSeconds",
1054                "defaultWelcomeFiles",
1055                "jettyContainerObjectName",
1056                "jspServletClassName",
1057                "DefaultServlets",
1058                "DefaultFilters",
1059                "DefaultFilterMappings",
1060                "PojoWebServiceTemplate",
1061                "WebServiceBuilder",
1062                "ClusteringBuilders",
1063                "SecurityBuilders",
1064                "ServiceBuilders",
1065                "NamingBuilders",
1066                "ResourceEnvironmentSetter",
1067                "kernel"});
1068        GBEAN_INFO = infoBuilder.getBeanInfo();
1069    }
1070
1071    public static GBeanInfo getGBeanInfo() {
1072        return GBEAN_INFO;
1073    }
1074
1075    static class StartupOrderComparator implements Comparator JavaDoc {
1076        /**
1077         * comparator that compares first on the basis of startup order, and then on the lexicographical
1078         * ordering of servlet name. Since the servlet names have a uniqueness constraint, this should
1079         * provide a total ordering consistent with equals. All servlets with no startup order are after
1080         * all servlets with a startup order.
1081         *
1082         * @param o1 first ServletType object
1083         * @param o2 second ServletType object
1084         * @return an int < 0 if o1 precedes o2, 0 if they are equal, and > 0 if o2 preceeds o1.
1085         */

1086        public int compare(Object JavaDoc o1, Object JavaDoc o2) {
1087            ServletType s1 = (ServletType) o1;
1088            ServletType s2 = (ServletType) o2;
1089
1090            // load-on-startup is set for neither. the
1091
// ordering at this point doesn't matter, but we
1092
// should return "0" only if the two objects say
1093
// they are equal
1094
if (!s1.isSetLoadOnStartup() && !s2.isSetLoadOnStartup()) {
1095                return s1.equals(s2) ? 0 : s1.getServletName().getStringValue().trim().compareTo(s2.getServletName().getStringValue().trim());
1096            }
1097
1098            // load-on-startup is set for one but not the
1099
// other. whichever one is set will be "less
1100
// than", i.e. it will be loaded first
1101
if (s1.isSetLoadOnStartup() && !s2.isSetLoadOnStartup()) {
1102                return -1;
1103            }
1104            if (!s1.isSetLoadOnStartup() && s2.isSetLoadOnStartup()) {
1105                return 1;
1106            }
1107
1108            // load-on-startup is set for both. whichever one
1109
// has a smaller value is "less than"
1110
int comp = new Integer JavaDoc(s1.xgetLoadOnStartup().getStringValue()).compareTo(new Integer JavaDoc(s2.xgetLoadOnStartup().getStringValue()));
1111            if (comp == 0) {
1112                return s1.getServletName().getStringValue().trim().compareTo(s2.getServletName().getStringValue().trim());
1113            }
1114            return comp;
1115        }
1116    }
1117}
1118
Popular Tags