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.tomcat.deployment;
019
020 import java.io.File;
021 import java.io.FileNotFoundException;
022 import java.io.FileWriter;
023 import java.io.IOException;
024 import java.net.URL;
025 import java.security.PermissionCollection;
026 import java.util.Collection;
027 import java.util.HashMap;
028 import java.util.Map;
029 import java.util.Set;
030 import java.util.jar.JarFile;
031
032 import javax.servlet.Servlet;
033
034 import org.apache.commons.logging.Log;
035 import org.apache.commons.logging.LogFactory;
036 import org.apache.geronimo.common.DeploymentException;
037 import org.apache.geronimo.deployment.ModuleIDBuilder;
038 import org.apache.geronimo.deployment.NamespaceDrivenBuilder;
039 import org.apache.geronimo.deployment.service.EnvironmentBuilder;
040 import org.apache.geronimo.deployment.util.DeploymentUtil;
041 import org.apache.geronimo.deployment.xbeans.EnvironmentType;
042 import org.apache.geronimo.deployment.xmlbeans.XmlBeansUtil;
043 import org.apache.geronimo.gbean.AbstractName;
044 import org.apache.geronimo.gbean.AbstractNameQuery;
045 import org.apache.geronimo.gbean.GBeanData;
046 import org.apache.geronimo.gbean.GBeanInfo;
047 import org.apache.geronimo.gbean.GBeanInfoBuilder;
048 import org.apache.geronimo.gbean.ReferencePatterns;
049 import org.apache.geronimo.j2ee.deployment.EARContext;
050 import org.apache.geronimo.j2ee.deployment.Module;
051 import org.apache.geronimo.j2ee.deployment.ModuleBuilder;
052 import org.apache.geronimo.j2ee.deployment.ModuleBuilderExtension;
053 import org.apache.geronimo.j2ee.deployment.NamingBuilder;
054 import org.apache.geronimo.j2ee.deployment.WebModule;
055 import org.apache.geronimo.j2ee.deployment.WebServiceBuilder;
056 import org.apache.geronimo.j2ee.deployment.annotation.AnnotatedWebApp;
057 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
058 import org.apache.geronimo.kernel.Kernel;
059 import org.apache.geronimo.kernel.Naming;
060 import org.apache.geronimo.kernel.config.ConfigurationData;
061 import org.apache.geronimo.kernel.repository.Environment;
062 import org.apache.geronimo.naming.deployment.ENCConfigBuilder;
063 import org.apache.geronimo.naming.deployment.GBeanResourceEnvironmentBuilder;
064 import org.apache.geronimo.naming.deployment.ResourceEnvironmentSetter;
065 import org.apache.geronimo.security.jacc.ComponentPermissions;
066 import org.apache.geronimo.tomcat.cluster.CatalinaClusterGBean;
067 import org.apache.geronimo.tomcat.LifecycleListenerGBean;
068 import org.apache.geronimo.tomcat.ManagerGBean;
069 import org.apache.geronimo.tomcat.RealmGBean;
070 import org.apache.geronimo.tomcat.TomcatWebAppContext;
071 import org.apache.geronimo.tomcat.ValveGBean;
072 import org.apache.geronimo.tomcat.util.SecurityHolder;
073 import org.apache.geronimo.web.deployment.GenericToSpecificPlanConverter;
074 import org.apache.geronimo.web25.deployment.AbstractWebModuleBuilder;
075 import org.apache.geronimo.xbeans.geronimo.web.tomcat.TomcatWebAppDocument;
076 import org.apache.geronimo.xbeans.geronimo.web.tomcat.TomcatWebAppType;
077 import org.apache.geronimo.xbeans.geronimo.web.tomcat.config.GerTomcatDocument;
078 import org.apache.geronimo.xbeans.javaee.EjbLocalRefType;
079 import org.apache.geronimo.xbeans.javaee.EjbRefType;
080 import org.apache.geronimo.xbeans.javaee.EnvEntryType;
081 import org.apache.geronimo.xbeans.javaee.LifecycleCallbackType;
082 import org.apache.geronimo.xbeans.javaee.MessageDestinationRefType;
083 import org.apache.geronimo.xbeans.javaee.MessageDestinationType;
084 import org.apache.geronimo.xbeans.javaee.PersistenceContextRefType;
085 import org.apache.geronimo.xbeans.javaee.PersistenceUnitRefType;
086 import org.apache.geronimo.xbeans.javaee.ResourceEnvRefType;
087 import org.apache.geronimo.xbeans.javaee.ResourceRefType;
088 import org.apache.geronimo.xbeans.javaee.ServiceRefType;
089 import org.apache.geronimo.xbeans.javaee.ServletType;
090 import org.apache.geronimo.xbeans.javaee.WebAppDocument;
091 import org.apache.geronimo.xbeans.javaee.WebAppType;
092 import org.apache.xmlbeans.XmlCursor;
093 import org.apache.xmlbeans.XmlException;
094 import org.apache.xmlbeans.XmlObject;
095 import org.apache.xmlbeans.XmlOptions;
096
097 /**
098 * @version $Rev:385659 $ $Date: 2007-08-02 17:23:23 -0400 (Thu, 02 Aug 2007) $
099 */
100 public class TomcatModuleBuilder extends AbstractWebModuleBuilder {
101
102 private static final Log log = LogFactory.getLog(TomcatModuleBuilder.class);
103
104 private final Environment defaultEnvironment;
105 private final AbstractNameQuery tomcatContainerName;
106
107 private static final String TOMCAT_NAMESPACE = TomcatWebAppDocument.type.getDocumentElementName().getNamespaceURI();
108 private static final String IS_JAVAEE = "IS_JAVAEE";
109
110 public TomcatModuleBuilder(Environment defaultEnvironment,
111 AbstractNameQuery tomcatContainerName,
112 Collection<WebServiceBuilder> webServiceBuilder,
113 Collection securityBuilders,
114 Collection serviceBuilders,
115 NamingBuilder namingBuilders,
116 Collection<ModuleBuilderExtension> moduleBuilderExtensions,
117 ResourceEnvironmentSetter resourceEnvironmentSetter,
118 Kernel kernel) {
119 super(kernel, securityBuilders, serviceBuilders, namingBuilders, resourceEnvironmentSetter, webServiceBuilder, moduleBuilderExtensions);
120 this.defaultEnvironment = defaultEnvironment;
121
122 this.tomcatContainerName = tomcatContainerName;
123 }
124
125 protected Module createModule(Object plan, JarFile moduleFile, String targetPath, URL specDDUrl, boolean standAlone, String contextRoot, AbstractName earName, Naming naming, ModuleIDBuilder idBuilder) throws DeploymentException {
126 assert moduleFile != null : "moduleFile is null";
127 assert targetPath != null : "targetPath is null";
128 assert !targetPath.endsWith("/") : "targetPath must not end with a '/'";
129
130 // parse the spec dd
131 String specDD = null;
132 WebAppType webApp = null;
133 Boolean isJavaee;
134 try {
135 if (specDDUrl == null) {
136 specDDUrl = DeploymentUtil.createJarURL(moduleFile, "WEB-INF/web.xml");
137 }
138
139 // read in the entire specDD as a string, we need this for getDeploymentDescriptor
140 // on the J2ee management object
141 specDD = DeploymentUtil.readAll(specDDUrl);
142
143 // we found web.xml, if it won't parse that's an error.
144 XmlObject parsed = XmlBeansUtil.parse(specDD);
145 //Dont save updated xml if it isn't javaee
146 XmlCursor cursor = parsed.newCursor();
147 try {
148 cursor.toStartDoc();
149 cursor.toFirstChild();
150 isJavaee = "http://java.sun.com/xml/ns/javaee".equals(cursor.getName().getNamespaceURI());
151 } finally {
152 cursor.dispose();
153 }
154 WebAppDocument webAppDoc = convertToServletSchema(parsed);
155 webApp = webAppDoc.getWebApp();
156 check(webApp);
157 } catch (XmlException e) {
158 // Output the target path in the error to make it clearer to the user which webapp
159 // has the problem. The targetPath is used, as moduleFile may have an unhelpful
160 // value such as C:\geronimo-1.1\var\temp\geronimo-deploymentUtil22826.tmpdir
161 throw new DeploymentException("Error parsing web.xml for " + targetPath, e);
162 } catch (Exception e) {
163 if (!moduleFile.getName().endsWith(".war")) {
164 //not for us
165 return null;
166 }
167 isJavaee = true;
168 //else ignore as jee5 allows optional spec dd for .war's
169 }
170
171 if (webApp == null)
172 webApp = WebAppType.Factory.newInstance();
173
174 // parse vendor dd
175 TomcatWebAppType tomcatWebApp = getTomcatWebApp(plan, moduleFile, standAlone, targetPath, webApp);
176 contextRoot = getContextRoot(tomcatWebApp, contextRoot, webApp, standAlone, moduleFile, targetPath);
177
178
179 EnvironmentType environmentType = tomcatWebApp.getEnvironment();
180 Environment environment = EnvironmentBuilder.buildEnvironment(environmentType, defaultEnvironment);
181
182 // Note: logic elsewhere depends on the default artifact ID being the file name less extension (ConfigIDExtractor)
183 String warName = "";
184 File temp = new File(moduleFile.getName());
185 if (temp.isFile()) {
186 warName = temp.getName();
187 if (warName.lastIndexOf('.') > -1) {
188 warName = warName.substring(0, warName.lastIndexOf('.'));
189 }
190 } else {
191 try {
192 warName = temp.getCanonicalFile().getName();
193 if (warName.equals("")) {
194 // Root directory
195 warName = "$root-dir$";
196 }
197 } catch (IOException e) {
198 //really?
199 }
200 }
201 idBuilder.resolve(environment, warName, "war");
202
203 AbstractName moduleName;
204 if (earName == null) {
205 earName = naming.createRootName(environment.getConfigId(), NameFactory.NULL, NameFactory.J2EE_APPLICATION);
206 moduleName = naming.createChildName(earName, environment.getConfigId().toString(), NameFactory.WEB_MODULE);
207 } else {
208 moduleName = naming.createChildName(earName, targetPath, NameFactory.WEB_MODULE);
209 }
210
211 // Create the AnnotatedApp interface for the WebModule
212 AnnotatedWebApp annotatedWebApp = new AnnotatedWebApp(webApp);
213
214 WebModule module = new WebModule(standAlone, moduleName, environment, moduleFile, targetPath, webApp, tomcatWebApp, specDD, contextRoot, TOMCAT_NAMESPACE, annotatedWebApp);
215 for (ModuleBuilderExtension mbe : moduleBuilderExtensions) {
216 mbe.createModule(module, plan, moduleFile, targetPath, specDDUrl, environment, contextRoot, earName, naming, idBuilder);
217 }
218 module.getSharedContext().put(IS_JAVAEE, isJavaee);
219 return module;
220 }
221
222 private String getContextRoot(TomcatWebAppType tomcatWebApp, String contextRoot, WebAppType webApp, boolean standAlone, JarFile moduleFile, String targetPath) {
223 //If we have a context root, override everything
224 if (tomcatWebApp.isSetContextRoot()) {
225 contextRoot = tomcatWebApp.getContextRoot();
226 } else if (contextRoot == null || contextRoot.trim().equals("")) {
227 //Otherwise if no contextRoot was passed in from the ear, then make up a default
228 contextRoot = determineDefaultContextRoot(webApp, standAlone, moduleFile, targetPath);
229 }
230 contextRoot = contextRoot.trim();
231 if (!contextRoot.startsWith("/")) {
232 //I'm not sure if we should always fix up peculiar context roots.
233 contextRoot = "/" + contextRoot;
234 }
235 return contextRoot;
236 }
237
238
239 TomcatWebAppType getTomcatWebApp(Object plan, JarFile moduleFile, boolean standAlone, String targetPath, WebAppType webApp) throws DeploymentException {
240 XmlObject rawPlan = null;
241 try {
242 // load the geronimo-web.xml from either the supplied plan or from the earFile
243 try {
244 if (plan instanceof XmlObject) {
245 rawPlan = (XmlObject) plan;
246 } else {
247 if (plan != null) {
248 rawPlan = XmlBeansUtil.parse(((File) plan).toURL(), getClass().getClassLoader());
249 } else {
250 URL path = DeploymentUtil.createJarURL(moduleFile, "WEB-INF/geronimo-web.xml");
251 try {
252 rawPlan = XmlBeansUtil.parse(path, getClass().getClassLoader());
253 } catch (FileNotFoundException e) {
254 path = DeploymentUtil.createJarURL(moduleFile, "WEB-INF/geronimo-tomcat.xml");
255 try {
256 rawPlan = XmlBeansUtil.parse(path, getClass().getClassLoader());
257 } catch (FileNotFoundException e1) {
258 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.");
259 }
260 }
261 }
262 }
263 } catch (IOException e) {
264 log.warn(e);
265 }
266
267 TomcatWebAppType tomcatWebApp;
268 if (rawPlan != null) {
269 XmlObject webPlan = new GenericToSpecificPlanConverter(GerTomcatDocument.type.getDocumentElementName().getNamespaceURI(),
270 TomcatWebAppDocument.type.getDocumentElementName().getNamespaceURI(), "tomcat").convertToSpecificPlan(rawPlan);
271 tomcatWebApp = (TomcatWebAppType) webPlan.changeType(TomcatWebAppType.type);
272 XmlBeansUtil.validateDD(tomcatWebApp);
273 } else {
274 tomcatWebApp = createDefaultPlan();
275 }
276 return tomcatWebApp;
277 } catch (XmlException e) {
278 throw new DeploymentException("xml problem for web app " + targetPath, e);
279 }
280 }
281
282 private TomcatWebAppType createDefaultPlan() {
283 return TomcatWebAppType.Factory.newInstance();
284 }
285
286
287 public void initContext(EARContext earContext, Module module, ClassLoader cl) throws DeploymentException {
288 TomcatWebAppType gerWebApp = (TomcatWebAppType) module.getVendorDD();
289 boolean hasSecurityRealmName = gerWebApp.isSetSecurityRealmName();
290 basicInitContext(earContext, module, gerWebApp, hasSecurityRealmName);
291 for (ModuleBuilderExtension mbe : moduleBuilderExtensions) {
292 mbe.initContext(earContext, module, cl);
293 }
294 }
295
296 public void addGBeans(EARContext earContext, Module module, ClassLoader cl, Collection repository) throws DeploymentException {
297 EARContext moduleContext = module.getEarContext();
298 ClassLoader webClassLoader = moduleContext.getClassLoader();
299 AbstractName moduleName = moduleContext.getModuleName();
300 WebModule webModule = (WebModule) module;
301
302 WebAppType webApp = (WebAppType) webModule.getSpecDD();
303
304 TomcatWebAppType tomcatWebApp = (TomcatWebAppType) webModule.getVendorDD();
305
306 GBeanData webModuleData = new GBeanData(moduleName, TomcatWebAppContext.GBEAN_INFO);
307 configureBasicWebModuleAttributes(webApp, tomcatWebApp, moduleContext, earContext, webModule, webModuleData);
308 try {
309 moduleContext.addGBean(webModuleData);
310 Set<String> securityRoles = collectRoleNames(webApp);
311 Map<String, PermissionCollection> rolePermissions = new HashMap<String, PermissionCollection>();
312 webModuleData.setAttribute("contextPath", webModule.getContextRoot());
313 // unsharableResources, applicationManagedSecurityResources
314 GBeanResourceEnvironmentBuilder rebuilder = new GBeanResourceEnvironmentBuilder(webModuleData);
315 //N.B. use earContext not moduleContext
316 resourceEnvironmentSetter.setResourceEnvironment(rebuilder, webApp.getResourceRefArray(), tomcatWebApp.getResourceRefArray());
317
318 if (tomcatWebApp.isSetWebContainer()) {
319 AbstractNameQuery webContainerName = ENCConfigBuilder.getGBeanQuery(NameFactory.GERONIMO_SERVICE, tomcatWebApp.getWebContainer());
320 webModuleData.setReferencePattern("Container", webContainerName);
321 } else {
322 webModuleData.setReferencePattern("Container", tomcatContainerName);
323 }
324 // Process the Tomcat container-config elements
325 if (tomcatWebApp.isSetHost()) {
326 String virtualServer = tomcatWebApp.getHost().trim();
327 webModuleData.setAttribute("virtualServer", virtualServer);
328 }
329 if (tomcatWebApp.isSetCrossContext()) {
330 webModuleData.setAttribute("crossContext", Boolean.TRUE);
331 }
332 if (tomcatWebApp.isSetDisableCookies()) {
333 webModuleData.setAttribute("disableCookies", Boolean.TRUE);
334 }
335 if (tomcatWebApp.isSetTomcatRealm()) {
336 String tomcatRealm = tomcatWebApp.getTomcatRealm().trim();
337 AbstractName realmName = earContext.getNaming().createChildName(moduleName, tomcatRealm, RealmGBean.GBEAN_INFO.getJ2eeType());
338 webModuleData.setReferencePattern("TomcatRealm", realmName);
339 }
340 if (tomcatWebApp.isSetValveChain()) {
341 String valveChain = tomcatWebApp.getValveChain().trim();
342 AbstractName valveName = earContext.getNaming().createChildName(moduleName, valveChain, ValveGBean.J2EE_TYPE);
343 webModuleData.setReferencePattern("TomcatValveChain", valveName);
344 }
345
346 if (tomcatWebApp.isSetListenerChain()) {
347 String listenerChain = tomcatWebApp.getListenerChain().trim();
348 AbstractName listenerName = earContext.getNaming().createChildName(moduleName, listenerChain, LifecycleListenerGBean.J2EE_TYPE);
349 webModuleData.setReferencePattern("LifecycleListenerChain", listenerName);
350 }
351
352 if (tomcatWebApp.isSetCluster()) {
353 String cluster = tomcatWebApp.getCluster().trim();
354 AbstractName clusterName = earContext.getNaming().createChildName(moduleName, cluster, CatalinaClusterGBean.J2EE_TYPE);
355 webModuleData.setReferencePattern("Cluster", clusterName);
356 }
357
358 if (tomcatWebApp.isSetManager()) {
359 String manager = tomcatWebApp.getManager().trim();
360 AbstractName managerName = earContext.getNaming().createChildName(moduleName, manager, ManagerGBean.J2EE_TYPE);
361 webModuleData.setReferencePattern("Manager", managerName);
362 }
363
364 //Handle the role permissions and webservices on the servlets.
365 ServletType[] servletTypes = webApp.getServletArray();
366 Map<String, AbstractName> webServices = new HashMap<String, AbstractName>();
367 Class baseServletClass;
368 try {
369 baseServletClass = webClassLoader.loadClass(Servlet.class.getName());
370 } catch (ClassNotFoundException e) {
371 throw new DeploymentException("Could not load javax.servlet.Servlet in web classloader", e); // TODO identify web app in message
372 }
373 for (ServletType servletType : servletTypes) {
374 //Handle the Role Ref Permissions
375 processRoleRefPermissions(servletType, securityRoles, rolePermissions);
376
377 if (servletType.isSetServletClass()) {
378 String servletName = servletType.getServletName().getStringValue().trim();
379 String servletClassName = servletType.getServletClass().getStringValue().trim();
380 Class servletClass;
381 try {
382 servletClass = webClassLoader.loadClass(servletClassName);
383 } catch (ClassNotFoundException e) {
384 throw new DeploymentException("Could not load servlet class " + servletClassName, e); // TODO identify web app in message
385 }
386 if (!baseServletClass.isAssignableFrom(servletClass)) {
387 //fake servletData
388 AbstractName servletAbstractName = moduleContext.getNaming().createChildName(moduleName, servletName, NameFactory.SERVLET);
389 GBeanData servletData = new GBeanData();
390 servletData.setAbstractName(servletAbstractName);
391 //let the web service builder deal with configuring the gbean with the web service stack
392 //Here we just extract the factory reference
393 boolean configured = false;
394 for (WebServiceBuilder serviceBuilder : webServiceBuilder) {
395 if (serviceBuilder.configurePOJO(servletData, servletName, module, servletClassName, moduleContext)) {
396 configured = true;
397 break;
398 }
399 }
400 if (!configured) {
401 throw new DeploymentException("POJO web service: " + servletName + " not configured by any web service builder");
402 }
403 ReferencePatterns patterns = servletData.getReferencePatterns("WebServiceContainerFactory");
404 AbstractName wsContainerFactoryName = patterns.getAbstractName();
405 webServices.put(servletName, wsContainerFactoryName);
406 //force all the factories to start before the web app that needs them.
407 webModuleData.addDependency(wsContainerFactoryName);
408 }
409
410 }
411 }
412
413 // JACC v1.0 secion B.19
414 addUnmappedJSPPermissions(securityRoles, rolePermissions);
415
416 webModuleData.setAttribute("webServices", webServices);
417
418 if (tomcatWebApp.isSetSecurityRealmName()) {
419 if (earContext.getSecurityConfiguration() == null) {
420 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)");
421 }
422
423 SecurityHolder securityHolder = new SecurityHolder();
424 securityHolder.setSecurityRealm(tomcatWebApp.getSecurityRealmName().trim());
425
426 webModuleData.setReferencePattern("RunAsSource", earContext.getJaccManagerName());
427
428 /**
429 * TODO - go back to commented version when possible.
430 */
431 String policyContextID = moduleName.toString().replaceAll("[, :]", "_");
432 securityHolder.setPolicyContextID(policyContextID);
433
434 ComponentPermissions componentPermissions = buildSpecSecurityConfig(webApp, securityRoles, rolePermissions);
435 earContext.addSecurityContext(policyContextID, componentPermissions);
436 //TODO WTF is this for?
437 securityHolder.setSecurity(true);
438
439 webModuleData.setAttribute("securityHolder", securityHolder);
440 }
441
442 //listeners added directly to the StandardContext will get loaded by the tomcat classloader, not the app classloader!
443 //TODO this may definitely not be the best place for this!
444 for (ModuleBuilderExtension mbe : moduleBuilderExtensions) {
445 mbe.addGBeans(earContext, module, cl, repository);
446 }
447 //not truly metadata complete until MBEs have run
448 if (!webApp.getMetadataComplete()) {
449 webApp.setMetadataComplete(true);
450 module.setOriginalSpecDD(module.getSpecDD().toString());
451 webModuleData.setAttribute("deploymentDescriptor", module.getOriginalSpecDD());
452 }
453 /**
454 * This next bit of code is kind of a kludge to get Tomcat to get a default
455 * web.xml if one does not exist. This is primarily for jaxws. This code is
456 * necessary because Tomcat either has a bug or there is a problem dynamically
457 * adding a wrapper to an already running context. Although the wrapper
458 * can be added, the url mappings do not get picked up at the proper level
459 * and therefore Tomcat cannot dispatch the request. Hence, creating and
460 * writing out a web.xml to the deployed location is the only way around this
461 * until Tomcat fixes that bug.
462 *
463 * For myfaces/jsf, the spec dd may have been updated with a listener. So, we need to write it out again whether or not
464 * there originally was one. This might not work on windows due to file locking problems.
465 */
466
467 if ((Boolean)module.getSharedContext().get(IS_JAVAEE)) {
468 WebAppType shortWebApp = (WebAppType) webApp.copy();
469 shortWebApp.setEjbLocalRefArray(new EjbLocalRefType[0]);
470 shortWebApp.setEjbRefArray(new EjbRefType[0]);
471 shortWebApp.setEnvEntryArray(new EnvEntryType[0]);
472 shortWebApp.setMessageDestinationArray(new MessageDestinationType[0]);
473 shortWebApp.setMessageDestinationRefArray(new MessageDestinationRefType[0]);
474 shortWebApp.setPersistenceContextRefArray(new PersistenceContextRefType[0]);
475 shortWebApp.setPersistenceUnitRefArray(new PersistenceUnitRefType[0]);
476 shortWebApp.setPostConstructArray(new LifecycleCallbackType[0]);
477 shortWebApp.setPreDestroyArray(new LifecycleCallbackType[0]);
478 shortWebApp.setResourceEnvRefArray(new ResourceEnvRefType[0]);
479 shortWebApp.setResourceRefArray(new ResourceRefType[0]);
480 shortWebApp.setServiceRefArray(new ServiceRefType[0]);
481 // TODO Tomcat will fail web services tck tests if the following security settings are set in shortWebApp
482 // need to figure out why...
483 //One clue is that without this stuff tomcat does not install an authenticator.... so there's no security
484 // shortWebApp.setSecurityConstraintArray(new SecurityConstraintType[0]);
485 // shortWebApp.setSecurityRoleArray(new SecurityRoleType[0]);
486 File webXml = new File(moduleContext.getBaseDir(), "/WEB-INF/web.xml");
487 File inPlaceDir = moduleContext.getInPlaceConfigurationDir();
488 if (inPlaceDir != null) {
489 webXml = new File(inPlaceDir, "/WEB-INF/web.xml");
490 }
491 // boolean webXmlExists = (inPlaceDir != null && new File(inPlaceDir,"/WEB-INF/web.xml").exists()) || webXml.exists();
492 // if (!webXmlExists) {
493 webXml.getParentFile().mkdirs();
494 try {
495 FileWriter outFile = new FileWriter(webXml);
496
497 XmlOptions opts = new XmlOptions();
498 opts.setSaveAggressiveNamespaces();
499 opts.setSaveSyntheticDocumentElement(WebAppDocument.type.getDocumentElementName());
500 opts.setUseDefaultNamespace();
501 opts.setSavePrettyPrint();
502
503 // WebAppDocument doc = WebAppDocument.Factory.newInstance();
504 // doc.setWebApp(webApp);
505
506 outFile.write(shortWebApp.xmlText(opts));
507 outFile.flush();
508 outFile.close();
509 } catch (Exception e) {
510 throw new DeploymentException(e);
511 }
512 // }
513 }
514
515 if (!module.isStandAlone()) {
516 ConfigurationData moduleConfigurationData = moduleContext.getConfigurationData();
517 earContext.addChildConfiguration(module.getTargetPath(), moduleConfigurationData);
518 }
519 } catch (DeploymentException de) {
520 throw de;
521 } catch (Exception e) {
522 throw new DeploymentException("Unable to initialize GBean for web app " + module.getName(), e);
523 }
524 }
525
526 public String getSchemaNamespace() {
527 return TOMCAT_NAMESPACE;
528 }
529
530
531 public static final GBeanInfo GBEAN_INFO;
532
533 static {
534 GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(TomcatModuleBuilder.class, NameFactory.MODULE_BUILDER);
535 infoBuilder.addAttribute("defaultEnvironment", Environment.class, true, true);
536 infoBuilder.addAttribute("tomcatContainerName", AbstractNameQuery.class, true, true);
537 infoBuilder.addReference("WebServiceBuilder", WebServiceBuilder.class, NameFactory.MODULE_BUILDER);
538 infoBuilder.addReference("SecurityBuilders", NamespaceDrivenBuilder.class, NameFactory.MODULE_BUILDER);
539 infoBuilder.addReference("ServiceBuilders", NamespaceDrivenBuilder.class, NameFactory.MODULE_BUILDER);
540 infoBuilder.addReference("NamingBuilders", NamingBuilder.class, NameFactory.MODULE_BUILDER);
541 infoBuilder.addReference("ModuleBuilderExtensions", ModuleBuilderExtension.class, NameFactory.MODULE_BUILDER);
542 infoBuilder.addReference("ResourceEnvironmentSetter", ResourceEnvironmentSetter.class, NameFactory.MODULE_BUILDER);
543 infoBuilder.addAttribute("kernel", Kernel.class, false);
544 infoBuilder.addInterface(ModuleBuilder.class);
545
546 infoBuilder.setConstructor(new String[]{
547 "defaultEnvironment",
548 "tomcatContainerName",
549 "WebServiceBuilder",
550 "SecurityBuilders",
551 "ServiceBuilders",
552 "NamingBuilders",
553 "ModuleBuilderExtensions",
554 "ResourceEnvironmentSetter",
555 "kernel"});
556 GBEAN_INFO = infoBuilder.getBeanInfo();
557 }
558
559 public static GBeanInfo getGBeanInfo() {
560 return GBEAN_INFO;
561 }
562
563 }