Home » geronimo-2.2-source-release » org.apache.geronimo.tomcat.deployment » [javadoc | source]

    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.tomcat.deployment;
   19   
   20   import static java.lang.Boolean.FALSE;
   21   import static java.lang.Boolean.TRUE;
   22   
   23   import java.io.File;
   24   import java.io.FileNotFoundException;
   25   import java.io.FileWriter;
   26   import java.io.IOException;
   27   import java.net.URL;
   28   import java.util.Collection;
   29   import java.util.Collections;
   30   import java.util.HashMap;
   31   import java.util.Map;
   32   import java.util.jar.JarFile;
   33   
   34   import javax.servlet.Servlet;
   35   
   36   import org.apache.geronimo.common.DeploymentException;
   37   import org.apache.geronimo.deployment.ModuleIDBuilder;
   38   import org.apache.geronimo.deployment.NamespaceDrivenBuilder;
   39   import org.apache.geronimo.deployment.NamespaceDrivenBuilderCollection;
   40   import org.apache.geronimo.deployment.service.EnvironmentBuilder;
   41   import org.apache.geronimo.deployment.util.DeploymentUtil;
   42   import org.apache.geronimo.deployment.xbeans.EnvironmentType;
   43   import org.apache.geronimo.deployment.xmlbeans.XmlBeansUtil;
   44   import org.apache.geronimo.gbean.AbstractName;
   45   import org.apache.geronimo.gbean.AbstractNameQuery;
   46   import org.apache.geronimo.gbean.GBeanData;
   47   import org.apache.geronimo.gbean.GBeanInfo;
   48   import org.apache.geronimo.gbean.GBeanInfoBuilder;
   49   import org.apache.geronimo.gbean.GBeanLifecycle;
   50   import org.apache.geronimo.gbean.ReferencePatterns;
   51   import org.apache.geronimo.j2ee.deployment.EARContext;
   52   import org.apache.geronimo.j2ee.deployment.Module;
   53   import org.apache.geronimo.j2ee.deployment.ModuleBuilder;
   54   import org.apache.geronimo.j2ee.deployment.ModuleBuilderExtension;
   55   import org.apache.geronimo.j2ee.deployment.NamingBuilder;
   56   import org.apache.geronimo.j2ee.deployment.WebModule;
   57   import org.apache.geronimo.j2ee.deployment.WebServiceBuilder;
   58   import org.apache.geronimo.j2ee.deployment.annotation.AnnotatedWebApp;
   59   import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
   60   import org.apache.geronimo.kernel.Kernel;
   61   import org.apache.geronimo.kernel.Naming;
   62   import org.apache.geronimo.kernel.config.ConfigurationData;
   63   import org.apache.geronimo.kernel.repository.Environment;
   64   import org.apache.geronimo.naming.deployment.ENCConfigBuilder;
   65   import org.apache.geronimo.naming.deployment.GBeanResourceEnvironmentBuilder;
   66   import org.apache.geronimo.naming.deployment.ResourceEnvironmentSetter;
   67   import org.apache.geronimo.security.jaas.ConfigurationFactory;
   68   import org.apache.geronimo.security.jacc.ComponentPermissions;
   69   import org.apache.geronimo.tomcat.LifecycleListenerGBean;
   70   import org.apache.geronimo.tomcat.ManagerGBean;
   71   import org.apache.geronimo.tomcat.RealmGBean;
   72   import org.apache.geronimo.tomcat.TomcatWebAppContext;
   73   import org.apache.geronimo.tomcat.ValveGBean;
   74   import org.apache.geronimo.tomcat.cluster.CatalinaClusterGBean;
   75   import org.apache.geronimo.tomcat.util.SecurityHolder;
   76   import org.apache.geronimo.web.deployment.GenericToSpecificPlanConverter;
   77   import org.apache.geronimo.web25.deployment.AbstractWebModuleBuilder;
   78   import org.apache.geronimo.web25.deployment.security.AuthenticationWrapper;
   79   import org.apache.geronimo.xbeans.geronimo.jaspi.JaspiAuthModuleType;
   80   import org.apache.geronimo.xbeans.geronimo.jaspi.JaspiConfigProviderType;
   81   import org.apache.geronimo.xbeans.geronimo.jaspi.JaspiServerAuthConfigType;
   82   import org.apache.geronimo.xbeans.geronimo.jaspi.JaspiServerAuthContextType;
   83   import org.apache.geronimo.xbeans.geronimo.web.tomcat.TomcatAuthenticationType;
   84   import org.apache.geronimo.xbeans.geronimo.web.tomcat.TomcatWebAppDocument;
   85   import org.apache.geronimo.xbeans.geronimo.web.tomcat.TomcatWebAppType;
   86   import org.apache.geronimo.xbeans.geronimo.web.tomcat.config.GerTomcatDocument;
   87   import org.apache.geronimo.xbeans.javaee.EjbLocalRefType;
   88   import org.apache.geronimo.xbeans.javaee.EjbRefType;
   89   import org.apache.geronimo.xbeans.javaee.EnvEntryType;
   90   import org.apache.geronimo.xbeans.javaee.LifecycleCallbackType;
   91   import org.apache.geronimo.xbeans.javaee.MessageDestinationRefType;
   92   import org.apache.geronimo.xbeans.javaee.MessageDestinationType;
   93   import org.apache.geronimo.xbeans.javaee.PersistenceContextRefType;
   94   import org.apache.geronimo.xbeans.javaee.PersistenceUnitRefType;
   95   import org.apache.geronimo.xbeans.javaee.ResourceEnvRefType;
   96   import org.apache.geronimo.xbeans.javaee.ResourceRefType;
   97   import org.apache.geronimo.xbeans.javaee.ServiceRefType;
   98   import org.apache.geronimo.xbeans.javaee.ServletType;
   99   import org.apache.geronimo.xbeans.javaee.WebAppDocument;
  100   import org.apache.geronimo.xbeans.javaee.WebAppType;
  101   import org.apache.xmlbeans.XmlCursor;
  102   import org.apache.xmlbeans.XmlException;
  103   import org.apache.xmlbeans.XmlObject;
  104   import org.apache.xmlbeans.XmlOptions;
  105   import org.slf4j.Logger;
  106   import org.slf4j.LoggerFactory;
  107   
  108   /**
  109    * @version $Rev:385659 $ $Date: 2009-10-27 17:57:20 -0700 (Tue, 27 Oct 2009) $
  110    */
  111   public class TomcatModuleBuilder extends AbstractWebModuleBuilder implements GBeanLifecycle {
  112   
  113       private static final Logger log = LoggerFactory.getLogger(TomcatModuleBuilder.class);
  114       static final String ROLE_MAPPER_DATA_NAME = "roleMapperDataName";
  115   
  116       private static final String TOMCAT_NAMESPACE = TomcatWebAppDocument.type.getDocumentElementName().getNamespaceURI();
  117       private static final String IS_JAVAEE = "IS_JAVAEE";
  118       private static final Map<String, String> NAMESPACE_UPDATES = new HashMap<String, String>();
  119       static {
  120           NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/web", "http://geronimo.apache.org/xml/ns/j2ee/web-2.0.1");
  121           NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/j2ee/web-1.1", "http://geronimo.apache.org/xml/ns/j2ee/web-2.0.1");
  122           NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/j2ee/web-1.2", "http://geronimo.apache.org/xml/ns/j2ee/web-2.0.1");
  123           NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/j2ee/web-2.0", "http://geronimo.apache.org/xml/ns/j2ee/web-2.0.1");
  124           NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/web/tomcat", "http://geronimo.apache.org/xml/ns/j2ee/web/tomcat-2.0.1");
  125           NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/j2ee/web/tomcat-1.1", "http://geronimo.apache.org/xml/ns/j2ee/web/tomcat-2.0.1");
  126           NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/j2ee/web/tomcat-1.2", "http://geronimo.apache.org/xml/ns/j2ee/web/tomcat-2.0.1");
  127           NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/j2ee/web/tomcat-2.0", "http://geronimo.apache.org/xml/ns/j2ee/web/tomcat-2.0.1");
  128           NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/web/tomcat/config", "http://geronimo.apache.org/xml/ns/j2ee/web/tomcat/config-1.0");
  129       }
  130   
  131       private final Environment defaultEnvironment;
  132       private final AbstractNameQuery tomcatContainerName;
  133       protected final NamespaceDrivenBuilderCollection clusteringBuilders;
  134   
  135       public TomcatModuleBuilder(Environment defaultEnvironment,
  136               AbstractNameQuery tomcatContainerName,
  137               Collection<WebServiceBuilder> webServiceBuilder,
  138               Collection<NamespaceDrivenBuilder> serviceBuilders,
  139               NamingBuilder namingBuilders,
  140               Collection<NamespaceDrivenBuilder> clusteringBuilders,
  141               Collection<ModuleBuilderExtension> moduleBuilderExtensions,
  142               ResourceEnvironmentSetter resourceEnvironmentSetter,
  143               Kernel kernel) {
  144           super(kernel, serviceBuilders, namingBuilders, resourceEnvironmentSetter, webServiceBuilder, moduleBuilderExtensions);
  145           this.defaultEnvironment = defaultEnvironment;
  146           this.clusteringBuilders = new NamespaceDrivenBuilderCollection(clusteringBuilders);
  147           this.tomcatContainerName = tomcatContainerName;
  148       }
  149   
  150       public void doStart() throws Exception {
  151           XmlBeansUtil.registerNamespaceUpdates(NAMESPACE_UPDATES);
  152       }
  153   
  154       public void doStop() {
  155           XmlBeansUtil.unregisterNamespaceUpdates(NAMESPACE_UPDATES);
  156       }
  157   
  158       public void doFail() {
  159           doStop();
  160       }
  161   
  162       protected Module createModule(Object plan, JarFile moduleFile, String targetPath, URL specDDUrl, boolean standAlone, String contextRoot, AbstractName earName, Naming naming, ModuleIDBuilder idBuilder) throws DeploymentException {
  163           assert moduleFile != null : "moduleFile is null";
  164           assert targetPath != null : "targetPath is null";
  165           assert !targetPath.endsWith("/") : "targetPath must not end with a '/'";
  166   
  167           // parse the spec dd
  168           String specDD = null;
  169           WebAppType webApp = null;
  170           Boolean isJavaee;
  171           try {
  172               if (specDDUrl == null) {
  173                   specDDUrl = DeploymentUtil.createJarURL(moduleFile, "WEB-INF/web.xml");
  174               }
  175   
  176               // read in the entire specDD as a string, we need this for getDeploymentDescriptor
  177               // on the J2ee management object
  178               specDD = DeploymentUtil.readAll(specDDUrl);
  179   
  180               // we found web.xml, if it won't parse that's an error.
  181               XmlObject parsed = XmlBeansUtil.parse(specDD);
  182               //Dont save updated xml if it isn't javaee
  183               XmlCursor cursor = parsed.newCursor();
  184               try {
  185                   cursor.toStartDoc();
  186                   cursor.toFirstChild();
  187                   isJavaee = "http://java.sun.com/xml/ns/javaee".equals(cursor.getName().getNamespaceURI());
  188               } finally {
  189                   cursor.dispose();
  190               }
  191               WebAppDocument webAppDoc = convertToServletSchema(parsed);
  192               webApp = webAppDoc.getWebApp();
  193               check(webApp);
  194           } catch (XmlException e) {
  195               // Output the target path in the error to make it clearer to the user which webapp
  196               // has the problem.  The targetPath is used, as moduleFile may have an unhelpful
  197               // value such as C:\geronimo-1.1\var\temp\geronimo-deploymentUtil22826.tmpdir
  198               throw new DeploymentException("Error parsing web.xml for " + targetPath, e);
  199           } catch (Exception e) {
  200               if (!moduleFile.getName().endsWith(".war")) {
  201                   //not for us
  202                   return null;
  203               }
  204               //else ignore as jee5 allows optional spec dd for .war's
  205               if (e instanceof FileNotFoundException) {
  206                   log.warn("Web application " + targetPath + " does not contain a WEB-INF/web.xml. This may indicate a mis-assembled web app.");
  207               }
  208               isJavaee = true;
  209           }
  210   
  211           if (webApp == null)
  212               webApp = WebAppType.Factory.newInstance();
  213   
  214           // parse vendor dd
  215           TomcatWebAppType tomcatWebApp = getTomcatWebApp(plan, moduleFile, standAlone, targetPath, webApp);
  216           contextRoot = getContextRoot(tomcatWebApp, contextRoot, webApp, standAlone, moduleFile, targetPath);
  217   
  218           EnvironmentType environmentType = tomcatWebApp.getEnvironment();
  219           Environment environment = EnvironmentBuilder.buildEnvironment(environmentType, defaultEnvironment);
  220   
  221           Boolean distributable = webApp.getDistributableArray().length == 1 ? TRUE : FALSE;
  222           if (TRUE == distributable) {
  223               clusteringBuilders.buildEnvironment(tomcatWebApp, environment);
  224           }
  225           
  226           // Note: logic elsewhere depends on the default artifact ID being the file name less extension (ConfigIDExtractor)
  227           String warName = "";
  228           File temp = new File(moduleFile.getName());
  229           if (temp.isFile()) {
  230               warName = temp.getName();
  231               if (warName.lastIndexOf('.') > -1) {
  232                   warName = warName.substring(0, warName.lastIndexOf('.'));
  233               }
  234           } else {
  235               try {
  236                   warName = temp.getCanonicalFile().getName();
  237                   if (warName.equals("")) {
  238                       // Root directory
  239                       warName = "$root-dir$";
  240                   }
  241               } catch (IOException e) {
  242                   //really?
  243               }
  244           }
  245           idBuilder.resolve(environment, warName, "car");
  246   
  247           AbstractName moduleName;
  248           if (earName == null) {
  249               earName = naming.createRootName(environment.getConfigId(), NameFactory.NULL, NameFactory.J2EE_APPLICATION);
  250               moduleName = naming.createChildName(earName, environment.getConfigId().toString(), NameFactory.WEB_MODULE);
  251           } else {
  252               moduleName = naming.createChildName(earName, targetPath, NameFactory.WEB_MODULE);
  253           }
  254   
  255           // Create the AnnotatedApp interface for the WebModule
  256           AnnotatedWebApp annotatedWebApp = new AnnotatedWebApp(webApp);
  257   
  258           WebModule module = new WebModule(standAlone, moduleName, environment, moduleFile, targetPath, webApp, tomcatWebApp, specDD, contextRoot, TOMCAT_NAMESPACE, annotatedWebApp);
  259           for (ModuleBuilderExtension mbe : moduleBuilderExtensions) {
  260               mbe.createModule(module, plan, moduleFile, targetPath, specDDUrl, environment, contextRoot, earName, naming, idBuilder);
  261           }
  262           module.getSharedContext().put(IS_JAVAEE, isJavaee);
  263           return module;
  264       }
  265   
  266       private String getContextRoot(TomcatWebAppType tomcatWebApp, String contextRoot, WebAppType webApp, boolean standAlone, JarFile moduleFile, String targetPath) {
  267           //If we have a context root, override everything
  268           if (tomcatWebApp.isSetContextRoot()) {
  269               contextRoot = tomcatWebApp.getContextRoot();
  270           } else if (contextRoot == null || contextRoot.trim().equals("")) {
  271               //Otherwise if no contextRoot was passed in from the ear, then make up a default
  272               contextRoot = determineDefaultContextRoot(webApp, standAlone, moduleFile, targetPath);
  273           }
  274           contextRoot = contextRoot.trim();
  275           if (contextRoot.length() > 0) {
  276               // only force the context root to start with a forward slash
  277               // if it is not null
  278               if (!contextRoot.startsWith("/")) {
  279                   //I'm not sure if we should always fix up peculiar context roots.
  280                   contextRoot = "/" + contextRoot;
  281               }
  282           }
  283           return contextRoot;
  284       }
  285   
  286   
  287       TomcatWebAppType getTomcatWebApp(Object plan, JarFile moduleFile, boolean standAlone, String targetPath, WebAppType webApp) throws DeploymentException {
  288           XmlObject rawPlan = null;
  289           try {
  290               // load the geronimo-web.xml from either the supplied plan or from the earFile
  291               try {
  292                   if (plan instanceof XmlObject) {
  293                       rawPlan = (XmlObject) plan;
  294                   } else {
  295                       if (plan != null) {
  296                           rawPlan = XmlBeansUtil.parse(((File) plan).toURL(), getClass().getClassLoader());
  297                       } else {
  298                           URL path = DeploymentUtil.createJarURL(moduleFile, "WEB-INF/geronimo-web.xml");
  299                           try {
  300                               rawPlan = XmlBeansUtil.parse(path, getClass().getClassLoader());
  301                           } catch (FileNotFoundException e) {
  302                               path = DeploymentUtil.createJarURL(moduleFile, "WEB-INF/geronimo-tomcat.xml");
  303                               try {
  304                                   rawPlan = XmlBeansUtil.parse(path, getClass().getClassLoader());
  305                               } catch (FileNotFoundException e1) {
  306                                   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.");
  307                               }
  308                           }
  309                       }
  310                   }
  311               } catch (IOException e) {
  312                   log.warn("Failed to load geronimo-web.xml", e);
  313               }
  314   
  315               TomcatWebAppType tomcatWebApp;
  316               if (rawPlan != null) {
  317                   XmlObject webPlan = new GenericToSpecificPlanConverter(GerTomcatDocument.type.getDocumentElementName().getNamespaceURI(),
  318                           TomcatWebAppDocument.type.getDocumentElementName().getNamespaceURI(), "tomcat").convertToSpecificPlan(rawPlan);
  319                   tomcatWebApp = (TomcatWebAppType) webPlan.changeType(TomcatWebAppType.type);
  320                   XmlBeansUtil.validateDD(tomcatWebApp);
  321               } else {
  322                   tomcatWebApp = createDefaultPlan();
  323               }
  324               return tomcatWebApp;
  325           } catch (XmlException e) {
  326               throw new DeploymentException("xml problem for web app " + targetPath, e);
  327           }
  328       }
  329   
  330       private TomcatWebAppType createDefaultPlan() {
  331           return TomcatWebAppType.Factory.newInstance();
  332       }
  333   
  334   
  335       public void initContext(EARContext earContext, Module module, ClassLoader cl) throws DeploymentException {
  336           TomcatWebAppType gerWebApp = (TomcatWebAppType) module.getVendorDD();
  337           boolean hasSecurityRealmName = gerWebApp.isSetSecurityRealmName();
  338           basicInitContext(earContext, module, gerWebApp, hasSecurityRealmName);
  339           for (ModuleBuilderExtension mbe : moduleBuilderExtensions) {
  340               mbe.initContext(earContext, module, cl);
  341           }
  342       }
  343   
  344       public void addGBeans(EARContext earContext, Module module, ClassLoader cl, Collection repository) throws DeploymentException {
  345           EARContext moduleContext = module.getEarContext();
  346           ClassLoader webClassLoader = moduleContext.getClassLoader();
  347           AbstractName moduleName = moduleContext.getModuleName();
  348           WebModule webModule = (WebModule) module;
  349   
  350           WebAppType webApp = (WebAppType) webModule.getSpecDD();
  351   
  352           TomcatWebAppType tomcatWebApp = (TomcatWebAppType) webModule.getVendorDD();
  353   
  354           GBeanData webModuleData = new GBeanData(moduleName, TomcatWebAppContext.GBEAN_INFO);
  355           configureBasicWebModuleAttributes(webApp, tomcatWebApp, moduleContext, earContext, webModule, webModuleData);
  356           String contextPath = webModule.getContextRoot();
  357           try {
  358               moduleContext.addGBean(webModuleData);
  359               webModuleData.setAttribute("contextPath", contextPath);
  360               // unsharableResources, applicationManagedSecurityResources
  361               GBeanResourceEnvironmentBuilder rebuilder = new GBeanResourceEnvironmentBuilder(webModuleData);
  362               //N.B. use earContext not moduleContext
  363               resourceEnvironmentSetter.setResourceEnvironment(rebuilder, webApp.getResourceRefArray(), tomcatWebApp.getResourceRefArray());
  364   
  365               if (tomcatWebApp.isSetWebContainer()) {
  366                   AbstractNameQuery webContainerName = ENCConfigBuilder.getGBeanQuery(GBeanInfoBuilder.DEFAULT_J2EE_TYPE, tomcatWebApp.getWebContainer());
  367                   webModuleData.setReferencePattern("Container", webContainerName);
  368               } else {
  369                   webModuleData.setReferencePattern("Container", tomcatContainerName);
  370               }
  371               
  372               //get Tomcat display-name
  373               if (webApp.getDisplayNameArray().length > 0) {
  374                   webModuleData.setAttribute("displayName", webApp.getDisplayNameArray()[0].getStringValue());
  375               }
  376               
  377               // Process the Tomcat container-config elements
  378               if (tomcatWebApp.isSetHost()) {
  379                   String virtualServer = tomcatWebApp.getHost().trim();
  380                   webModuleData.setAttribute("virtualServer", virtualServer);
  381               }
  382               if (tomcatWebApp.isSetCrossContext()) {
  383                   webModuleData.setAttribute("crossContext", Boolean.TRUE);
  384               }
  385               if (tomcatWebApp.isSetWorkDir()) {
  386                   String workDir = tomcatWebApp.getWorkDir();
  387                   webModuleData.setAttribute("workDir", workDir);
  388               }
  389               if (tomcatWebApp.isSetDisableCookies()) {
  390                   webModuleData.setAttribute("disableCookies", Boolean.TRUE);
  391               }
  392               if (tomcatWebApp.isSetTomcatRealm()) {
  393                   String tomcatRealm = tomcatWebApp.getTomcatRealm().trim();
  394                   AbstractName realmName = earContext.getNaming().createChildName(moduleName, tomcatRealm, RealmGBean.GBEAN_INFO.getJ2eeType());
  395                   webModuleData.setReferencePattern("TomcatRealm", realmName);
  396               }
  397               if (tomcatWebApp.isSetValveChain()) {
  398                   String valveChain = tomcatWebApp.getValveChain().trim();
  399                   AbstractName valveName = earContext.getNaming().createChildName(moduleName, valveChain, ValveGBean.J2EE_TYPE);
  400                   webModuleData.setReferencePattern("TomcatValveChain", valveName);
  401               }
  402               
  403               if (tomcatWebApp.isSetListenerChain()) {
  404                   String listenerChain = tomcatWebApp.getListenerChain().trim();
  405                   AbstractName listenerName = earContext.getNaming().createChildName(moduleName, listenerChain, LifecycleListenerGBean.J2EE_TYPE);
  406                   webModuleData.setReferencePattern("LifecycleListenerChain", listenerName);
  407               }
  408   
  409               if (tomcatWebApp.isSetCluster()) {
  410                   String cluster = tomcatWebApp.getCluster().trim();
  411                   AbstractName clusterName = earContext.getNaming().createChildName(moduleName, cluster, CatalinaClusterGBean.J2EE_TYPE);
  412                   webModuleData.setReferencePattern("Cluster", clusterName);
  413               }
  414   
  415               if (tomcatWebApp.isSetManager()) {
  416                   String manager = tomcatWebApp.getManager().trim();
  417                   AbstractName managerName = earContext.getNaming().createChildName(moduleName, manager, ManagerGBean.J2EE_TYPE);
  418                   webModuleData.setReferencePattern(TomcatWebAppContext.GBEAN_REF_MANAGER_RETRIEVER, managerName);
  419               }
  420               
  421               Boolean distributable = webApp.getDistributableArray().length == 1 ? TRUE : FALSE;
  422               if (TRUE == distributable) {
  423                   clusteringBuilders.build(tomcatWebApp, earContext, moduleContext);
  424                   if (null == webModuleData.getReferencePatterns(TomcatWebAppContext.GBEAN_REF_CLUSTERED_VALVE_RETRIEVER)) {
  425                       log.warn("No clustering builders configured: app will not be clustered");
  426                   }
  427               }
  428   
  429               //Handle the role permissions and webservices on the servlets.
  430               ServletType[] servletTypes = webApp.getServletArray();
  431               Map<String, AbstractName> webServices = new HashMap<String, AbstractName>();
  432               Class baseServletClass;
  433               try {
  434                   baseServletClass = webClassLoader.loadClass(Servlet.class.getName());
  435               } catch (ClassNotFoundException e) {
  436                   throw new DeploymentException("Could not load javax.servlet.Servlet in web classloader", e); // TODO identify web app in message
  437               }
  438               for (ServletType servletType : servletTypes) {
  439   
  440                   if (servletType.isSetServletClass()) {
  441                       String servletName = servletType.getServletName().getStringValue().trim();
  442                       String servletClassName = servletType.getServletClass().getStringValue().trim();
  443                       Class servletClass;
  444                       try {
  445                           servletClass = webClassLoader.loadClass(servletClassName);
  446                       } catch (ClassNotFoundException e) {
  447                           throw new DeploymentException("Could not load servlet class " + servletClassName, e); // TODO identify web app in message
  448                       }
  449                       if (!baseServletClass.isAssignableFrom(servletClass)) {
  450                           //fake servletData
  451                           AbstractName servletAbstractName = moduleContext.getNaming().createChildName(moduleName, servletName, NameFactory.SERVLET);
  452                           GBeanData servletData = new GBeanData();
  453                           servletData.setAbstractName(servletAbstractName);
  454                           //let the web service builder deal with configuring the gbean with the web service stack
  455                           //Here we just extract the factory reference
  456                           boolean configured = false;
  457                           for (WebServiceBuilder serviceBuilder : webServiceBuilder) {
  458                               if (serviceBuilder.configurePOJO(servletData, servletName, module, servletClassName, moduleContext)) {
  459                                   configured = true;
  460                                   break;
  461                               }
  462                           }
  463                           if (!configured) {
  464                               throw new DeploymentException("POJO web service: " + servletName + " not configured by any web service builder");
  465                           }
  466                           ReferencePatterns patterns = servletData.getReferencePatterns("WebServiceContainerFactory");
  467                           AbstractName wsContainerFactoryName = patterns.getAbstractName();
  468                           webServices.put(servletName, wsContainerFactoryName);
  469                           //force all the factories to start before the web app that needs them.
  470                           webModuleData.addDependency(wsContainerFactoryName);
  471                       }
  472   
  473                   }
  474               }
  475   
  476   
  477               webModuleData.setAttribute("webServices", webServices);
  478   
  479               if (tomcatWebApp.isSetSecurityRealmName()) {
  480                   if (earContext.getSecurityConfiguration() == null) {
  481                       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)");
  482                   }
  483   
  484                   SecurityHolder securityHolder = new SecurityHolder();
  485                   String securityRealmName = tomcatWebApp.getSecurityRealmName().trim();
  486   
  487                   webModuleData.setReferencePattern("RunAsSource", (AbstractNameQuery)earContext.getGeneralData().get(ROLE_MAPPER_DATA_NAME));
  488                   webModuleData.setReferencePattern("ConfigurationFactory", new AbstractNameQuery(null, Collections.singletonMap("name", securityRealmName), ConfigurationFactory.class.getName()));
  489   
  490                   /**
  491                    * TODO - go back to commented version when possible.
  492                    */
  493                   String policyContextID = moduleName.toString().replaceAll("[, :]", "_");
  494                   securityHolder.setPolicyContextID(policyContextID);
  495   
  496                   ComponentPermissions componentPermissions = buildSpecSecurityConfig(webApp);
  497                   earContext.addSecurityContext(policyContextID, componentPermissions);
  498                   //TODO WTF is this for?
  499                   securityHolder.setSecurity(true);
  500   
  501                   webModuleData.setAttribute("securityHolder", securityHolder);
  502                   //local jaspic configuration
  503                   if (tomcatWebApp.isSetAuthentication()) {
  504                       AuthenticationWrapper authType = new TomcatAuthenticationWrapper(tomcatWebApp.getAuthentication());
  505                       configureLocalJaspicProvider(authType, contextPath, module, webModuleData);
  506                   }
  507   
  508               }
  509   
  510               //listeners added directly to the StandardContext will get loaded by the tomcat classloader, not the app classloader!
  511               //TODO this may definitely not be the best place for this!
  512               for (ModuleBuilderExtension mbe : moduleBuilderExtensions) {
  513                   mbe.addGBeans(earContext, module, cl, repository);
  514               }
  515               //not truly metadata complete until MBEs have run
  516               if (!webApp.getMetadataComplete()) {
  517                   webApp.setMetadataComplete(true);
  518                   module.setOriginalSpecDD(module.getSpecDD().toString());
  519               }
  520               webModuleData.setAttribute("deploymentDescriptor", module.getOriginalSpecDD());
  521               /**
  522                * This next bit of code is kind of a kludge to get Tomcat to get a default
  523                * web.xml if one does not exist.  This is primarily for jaxws.  This code is
  524                * necessary because Tomcat either has a bug or there is a problem dynamically
  525                * adding a wrapper to an already running context.  Although the wrapper
  526                * can be added, the url mappings do not get picked up at the proper level
  527                * and therefore Tomcat cannot dispatch the request.  Hence, creating and
  528                * writing out a web.xml to the deployed location is the only way around this
  529                * until Tomcat fixes that bug.
  530                *
  531                * For myfaces/jsf, the spec dd may have been updated with a listener.  So, we need to write it out again whether or not
  532                * there originally was one. This might not work on windows due to file locking problems.
  533                */
  534   
  535               if ((Boolean)module.getSharedContext().get(IS_JAVAEE)) {
  536                   WebAppType shortWebApp = (WebAppType) webApp.copy();
  537                   shortWebApp.setEjbLocalRefArray(new EjbLocalRefType[0]);
  538                   shortWebApp.setEjbRefArray(new EjbRefType[0]);
  539                   shortWebApp.setEnvEntryArray(new EnvEntryType[0]);
  540                   shortWebApp.setMessageDestinationArray(new MessageDestinationType[0]);
  541                   shortWebApp.setMessageDestinationRefArray(new MessageDestinationRefType[0]);
  542                   shortWebApp.setPersistenceContextRefArray(new PersistenceContextRefType[0]);
  543                   shortWebApp.setPersistenceUnitRefArray(new PersistenceUnitRefType[0]);
  544                   shortWebApp.setPostConstructArray(new LifecycleCallbackType[0]);
  545                   shortWebApp.setPreDestroyArray(new LifecycleCallbackType[0]);
  546                   shortWebApp.setResourceEnvRefArray(new ResourceEnvRefType[0]);
  547                   shortWebApp.setResourceRefArray(new ResourceRefType[0]);
  548                   shortWebApp.setServiceRefArray(new ServiceRefType[0]);
  549                   // TODO Tomcat will fail web services tck tests if the following security settings are set in shortWebApp
  550                   // need to figure out why...
  551                   //One clue is that without this stuff tomcat does not install an authenticator.... so there's no security
  552   //                 shortWebApp.setSecurityConstraintArray(new SecurityConstraintType[0]);
  553   //                 shortWebApp.setSecurityRoleArray(new SecurityRoleType[0]);
  554                   File webXml = new File(moduleContext.getBaseDir(), "/WEB-INF/web.xml");
  555                   File inPlaceDir = moduleContext.getInPlaceConfigurationDir();
  556                   if (inPlaceDir != null) {
  557                       webXml = new File(inPlaceDir, "/WEB-INF/web.xml");
  558                   }
  559   //        boolean webXmlExists = (inPlaceDir != null && new File(inPlaceDir,"/WEB-INF/web.xml").exists()) || webXml.exists();
  560   //        if (!webXmlExists) {
  561                   webXml.getParentFile().mkdirs();
  562                   try {
  563                       FileWriter outFile = new FileWriter(webXml);
  564   
  565                       XmlOptions opts = new XmlOptions();
  566                       opts.setSaveAggressiveNamespaces();
  567                       opts.setSaveSyntheticDocumentElement(WebAppDocument.type.getDocumentElementName());
  568                       opts.setUseDefaultNamespace();
  569                       opts.setSavePrettyPrint();
  570   
  571       //                WebAppDocument doc = WebAppDocument.Factory.newInstance();
  572       //                doc.setWebApp(webApp);
  573   
  574                       outFile.write(shortWebApp.xmlText(opts));
  575                       outFile.flush();
  576                       outFile.close();
  577                   } catch (Exception e) {
  578                       throw new DeploymentException(e);
  579                   }
  580   //        }
  581               }
  582   
  583               if (!module.isStandAlone()) {
  584                   ConfigurationData moduleConfigurationData = moduleContext.getConfigurationData();
  585                   earContext.addChildConfiguration(module.getTargetPath(), moduleConfigurationData);
  586               }
  587           } catch (DeploymentException de) {
  588               throw de;
  589           } catch (Exception e) {
  590               throw new DeploymentException("Unable to initialize GBean for web app " + module.getName(), e);
  591           }
  592       }
  593   
  594       public String getSchemaNamespace() {
  595           return TOMCAT_NAMESPACE;
  596       }
  597   
  598       private static class TomcatAuthenticationWrapper implements AuthenticationWrapper {
  599           private final TomcatAuthenticationType authType;
  600   
  601           private TomcatAuthenticationWrapper(TomcatAuthenticationType authType) {
  602               this.authType = authType;
  603           }
  604   
  605           public JaspiConfigProviderType getConfigProvider() {
  606               return authType.getConfigProvider();
  607           }
  608   
  609           public boolean isSetConfigProvider() {
  610               return authType.isSetConfigProvider();
  611           }
  612   
  613           public JaspiServerAuthConfigType getServerAuthConfig() {
  614               return authType.getServerAuthConfig();
  615           }
  616   
  617           public boolean isSetServerAuthConfig() {
  618               return authType.isSetServerAuthConfig();
  619           }
  620   
  621           public JaspiServerAuthContextType getServerAuthContext() {
  622               return authType.getServerAuthContext();
  623           }
  624   
  625           public boolean isSetServerAuthContext() {
  626               return authType.isSetServerAuthContext();
  627           }
  628   
  629           public JaspiAuthModuleType getServerAuthModule() {
  630               return authType.getServerAuthModule();
  631           }
  632   
  633           public boolean isSetServerAuthModule() {
  634               return authType.isSetServerAuthModule();
  635           }
  636       }
  637   
  638   
  639   
  640       public static final GBeanInfo GBEAN_INFO;
  641       public static final String GBEAN_REF_CLUSTERING_BUILDERS = "ClusteringBuilders";
  642   
  643       static {
  644           GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(TomcatModuleBuilder.class, NameFactory.MODULE_BUILDER);
  645           infoBuilder.addAttribute("defaultEnvironment", Environment.class, true, true);
  646           infoBuilder.addAttribute("tomcatContainerName", AbstractNameQuery.class, true, true);
  647           infoBuilder.addReference("WebServiceBuilder", WebServiceBuilder.class, NameFactory.MODULE_BUILDER);
  648           infoBuilder.addReference("ServiceBuilders", NamespaceDrivenBuilder.class, NameFactory.MODULE_BUILDER);
  649           infoBuilder.addReference("NamingBuilders", NamingBuilder.class, NameFactory.MODULE_BUILDER);
  650           infoBuilder.addReference(GBEAN_REF_CLUSTERING_BUILDERS, NamespaceDrivenBuilder.class, NameFactory.MODULE_BUILDER);
  651           infoBuilder.addReference("ModuleBuilderExtensions", ModuleBuilderExtension.class, NameFactory.MODULE_BUILDER);
  652           infoBuilder.addReference("ResourceEnvironmentSetter", ResourceEnvironmentSetter.class, NameFactory.MODULE_BUILDER);
  653           infoBuilder.addAttribute("kernel", Kernel.class, false);
  654           infoBuilder.addInterface(ModuleBuilder.class);
  655   
  656           infoBuilder.setConstructor(new String[]{
  657                   "defaultEnvironment",
  658                   "tomcatContainerName",
  659                   "WebServiceBuilder",
  660                   "ServiceBuilders",
  661                   "NamingBuilders",
  662                   GBEAN_REF_CLUSTERING_BUILDERS,
  663                   "ModuleBuilderExtensions",
  664                   "ResourceEnvironmentSetter",
  665                   "kernel"});
  666           GBEAN_INFO = infoBuilder.getBeanInfo();
  667       }
  668   
  669       public static GBeanInfo getGBeanInfo() {
  670           return GBEAN_INFO;
  671       }
  672   
  673   }

Home » geronimo-2.2-source-release » org.apache.geronimo.tomcat.deployment » [javadoc | source]