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 }