CatalinaJWebContainerServiceImpl.java

00001 
00027 package org.objectweb.jonas.web.catalina50;
00028 
00029 import java.io.File;
00030 import java.io.FileInputStream;
00031 import java.io.FileNotFoundException;
00032 import java.io.InputStream;
00033 import java.lang.reflect.Method;
00034 import java.net.URL;
00035 import java.rmi.RemoteException;
00036 import java.util.ArrayList;
00037 import java.util.Enumeration;
00038 import java.util.Hashtable;
00039 import java.util.Iterator;
00040 import java.util.List;
00041 import java.util.StringTokenizer;
00042 import java.util.Vector;
00043 
00044 import javax.management.InstanceAlreadyExistsException;
00045 import javax.management.MBeanRegistrationException;
00046 import javax.management.MBeanServer;
00047 import javax.management.MalformedObjectNameException;
00048 import javax.management.NotCompliantMBeanException;
00049 import javax.management.ObjectName;
00050 import javax.naming.LinkRef;
00051 import javax.naming.NamingException;
00052 import javax.naming.Reference;
00053 import javax.naming.StringRefAddr;
00054 
00055 import org.apache.catalina.Connector;
00056 import org.apache.catalina.Container;
00057 import org.apache.catalina.Context;
00058 import org.apache.catalina.Engine;
00059 import org.apache.catalina.Host;
00060 import org.apache.catalina.Lifecycle;
00061 import org.apache.catalina.LifecycleException;
00062 import org.apache.catalina.Realm;
00063 import org.apache.catalina.Server;
00064 import org.apache.catalina.Service;
00065 import org.apache.catalina.core.StandardContext;
00066 import org.apache.catalina.core.StandardEngine;
00067 import org.apache.catalina.core.StandardServer;
00068 import org.apache.catalina.deploy.ContextResource;
00069 import org.apache.catalina.deploy.NamingResources;
00070 import org.apache.catalina.deploy.ResourceParams;
00071 import org.apache.catalina.startup.ContextConfig;
00072 import org.apache.commons.digester.Digester;
00073 import org.apache.commons.modeler.Registry;
00074 import org.objectweb.jonas.jmx.J2eeObjectName;
00075 import org.objectweb.jonas.jmx.JonasObjectName;
00076 import org.objectweb.jonas.security.realm.web.catalina50.JACC;
00077 import org.objectweb.jonas.server.J2EEServerMBean;
00078 import org.objectweb.jonas.server.LoaderManager;
00079 import org.objectweb.jonas.service.ServiceException;
00080 import org.objectweb.jonas.web.AbsJWebContainerServiceImpl;
00081 import org.objectweb.jonas.web.JWebContainerServiceException;
00082 import org.objectweb.jonas.web.lib.PermissionManager;
00083 import org.objectweb.jonas.web.wrapper.CatalinaJWebContainerService;
00084 import org.objectweb.jonas_lib.I18n;
00085 import org.objectweb.util.monolog.api.BasicLevel;
00086 import org.xml.sax.InputSource;
00087 
00088 
00095 public class CatalinaJWebContainerServiceImpl
00096     extends AbsJWebContainerServiceImpl
00097     implements CatalinaJWebContainerService {
00098 
00102     protected static final String CONFIG_FILE = "conf/server.xml";
00103 
00107     private static I18n i18n = null;
00108 
00112     private Server server = null;
00113 
00117     private ClassLoader parentClassLoader = null;
00118 
00122     private ClassLoader catalinaLoader = null;
00123 
00127     private static final int DEFAUT_DEBUG_LEVEL = 99;
00128 
00132     private boolean tomcatStarted = false;
00133 
00134 
00140     protected void doInit(javax.naming.Context ctx) throws ServiceException {
00141         super.doInit(ctx);
00142 
00143         // Set the environment
00144         initCatalinaEnvironment();
00145 
00146         // parent ClassLoader
00147         LoaderManager lm = LoaderManager.getInstance();
00148         try {
00149             parentClassLoader = lm.getAppsLoader();
00150             catalinaLoader = lm.getCatalinaLoader();
00151         } catch (Exception e1) {
00152             throw new ServiceException("Cannot get Application/Catalina ClassLoader", e1);
00153         }
00154 
00155         // Internationalization
00156         i18n = I18n.getInstance(CatalinaJWebContainerServiceImpl.class, catalinaLoader);
00157 
00158         // Add JOnAS-Tomcat mbean
00159         getLogger().log(BasicLevel.DEBUG, "Add mbeans descriptions to the JMX Registry");
00160         InputStream stream = this.getClass().getResourceAsStream("/org/objectweb/jonas/web/catalina50/mbeans-descriptors.xml");
00161         try {
00162             Registry.loadRegistry(stream);
00163             stream.close();
00164         } catch (Exception e) {
00165             getLogger().log(BasicLevel.ERROR, "Can't add the mbeans description into Tomcat" + e.getMessage());
00166         }
00167 
00168         // Add MBean for Catalina Connector creation
00169         CatalinaConnectorFactory cf = new CatalinaConnectorFactory();
00170         MBeanServer mbeanServer = getMbeanServer();
00171         cf.setMyServer(mbeanServer);
00172         if (mbeanServer != null) {
00173             ObjectName on = null;
00174             try {
00175                 on = JonasObjectName.catalinaConnectorFactory(getDomainName());
00176                 mbeanServer.registerMBean(cf, on);
00177             } catch (MalformedObjectNameException e1) {
00178                 getLogger().log(BasicLevel.WARN, "Can't create Objectname for CatalinaConnectorFactory MBean");
00179             } catch (InstanceAlreadyExistsException e2) {
00180                 getLogger().log(BasicLevel.WARN, "MBean named " + on.toString() + "already registered in the MBean server");
00181             } catch (MBeanRegistrationException e2) {
00182                 getLogger().log(BasicLevel.WARN, "Can't register MBean " + on.toString());
00183                 e2.printStackTrace();
00184             } catch (NotCompliantMBeanException e2) {
00185                 getLogger().log(BasicLevel.WARN, "Can't register MBean " + on.toString());
00186                 e2.printStackTrace();
00187             }
00188         }
00189 
00190         // Add MBean for WebModule Proxy creation
00191         WebModuleProxy px = new WebModuleProxy();
00192         px.setMyServer(mbeanServer);
00193         if (mbeanServer != null) {
00194             ObjectName on = null;
00195             try {
00196                 on = JonasObjectName.webModuleProxy(getDomainName());
00197                 mbeanServer.registerMBean(px, on);
00198             } catch (MalformedObjectNameException e1) {
00199                 getLogger().log(BasicLevel.WARN, "Can't create Objectname for WebModuleProxy MBean");
00200             } catch (InstanceAlreadyExistsException e2) {
00201                 getLogger().log(BasicLevel.WARN, "MBean named " + on.toString() + "already registered in the MBean server");
00202             } catch (MBeanRegistrationException e2) {
00203                 getLogger().log(BasicLevel.WARN, "Can't register MBean " + on.toString());
00204                 e2.printStackTrace();
00205             } catch (NotCompliantMBeanException e2) {
00206                 getLogger().log(BasicLevel.WARN, "Can't register MBean " + on.toString());
00207                 e2.printStackTrace();
00208             }
00209         }
00210     }
00211 
00212 
00218     protected void initCatalinaEnvironment() throws ServiceException {
00219 
00220         // if the user do not specify catalina.base,
00221         // set catalina.base to catalina.home.
00222         String catalinaHome = System.getProperty("catalina.home");
00223         if (catalinaHome != null) {
00224             if (System.getProperty("catalina.base") == null) {
00225                 System.setProperty("catalina.base", catalinaHome);
00226             }
00227         } else {
00228             throw new ServiceException("catalina.home property is not set");
00229         }
00230 
00231         // use the JOnAS naming instead of Tomcat naming
00232         System.setProperty("catalina.useNaming", "false");
00233     }
00234 
00235 
00240     public void doStart() throws ServiceException {
00241 
00242         // Create the digester for the parsing of the server.xml.
00243         Digester digester = createServerDigester();
00244 
00245         // Execute the digester for the parsing of the server.xml.
00246         // And configure the catalina server.
00247         File configFile = null;
00248 
00249         try {
00250             configFile = getConfigFile();
00251         } catch (FileNotFoundException e) {
00252             String err = i18n.getMessage("CatJWebServ.doStart.fileNotFound", configFile, e.getMessage());
00253             getLogger().log(BasicLevel.ERROR, err);
00254             throw new ServiceException(err, e);
00255         }
00256 
00257         try {
00258             InputSource is = new InputSource("file://" + configFile.getAbsolutePath());
00259             FileInputStream fis = new FileInputStream(configFile);
00260             is.setByteStream(fis);
00261             digester.push(this);
00262             digester.parse(is);
00263             fis.close();
00264         } catch (Exception e) {
00265             String err = i18n.getMessage("CatJWebServ.doStart.readfileError", configFile, e.getMessage());
00266             getLogger().log(BasicLevel.ERROR, err);
00267             throw new ServiceException(err, e);
00268         }
00269 
00270         javax.naming.Context ctxOld = setGlobalNamingResources();
00271 
00272         // Set the Domain and the name for each known Engine
00273         Iterator it = getEngines().iterator();
00274         while (it.hasNext()) {
00275             StandardEngine oSE = (StandardEngine) it.next();
00276             // WARNING : the order of th two next lines is very important.
00277             // The domain must be set in first and the name after.
00278             // In the others cases, Tomcat 5 doesn't set correctly these two properties
00279             // because there are somes controls that forbid to have a difference between
00280             // the name and the domain. Certainly a bug !
00281             oSE.setDomain(getDomainName());
00282             oSE.setName(getDomainName());
00283         }
00284 
00285         // Finaly start catalina ...
00286         if (server instanceof Lifecycle) {
00287             try {
00288                 server.initialize();
00289                 ((Lifecycle) server).start();
00290             } catch (Exception e) {
00291                 String err = i18n.getMessage("CatJWebServ.doStart.startCatalinaError");
00292                 getLogger().log(BasicLevel.ERROR, err);
00293                 throw new ServiceException(e.getMessage(), e);
00294             }
00295         }
00296         // Reset server context
00297         getNaming().setComponentContext(ctxOld);
00298 
00299         // Tomcat is started
00300         tomcatStarted = true;
00301 
00302         // ... and deploy wars of the jonas.properties
00303         super.doStart();
00304     }
00305 
00313     protected javax.naming.Context setGlobalNamingResources() throws ServiceException {
00314         // Set the global context of the server
00315         NamingResources namingResources = server.getGlobalNamingResources();
00316         javax.naming.Context globalCtx = null;
00317         javax.naming.Context ctxold = null;
00318         try {
00319             globalCtx = getNaming().createEnvironmentContext("catalina_global");
00320             ctxold = getNaming().setComponentContext(globalCtx);
00321 
00322             int i;
00323             // Resources
00324             ContextResource[] resources = namingResources.findResources();
00325             for (i = 0; i < resources.length; i++) {
00326                 addResource(globalCtx, namingResources, resources[i]);
00327             }
00328         } catch (NamingException e) {
00329             String err = i18n.getMessage("CatJWebServ.doStart.populateEnvError", e.getMessage());
00330             getLogger().log(BasicLevel.ERROR, err);
00331             throw new ServiceException(err, e);
00332         }
00333         // Set the global naming context of the server
00334         ((StandardServer) server).setGlobalNamingContext(globalCtx);
00335         return ctxold;
00336     }
00337 
00338 
00343     protected void doStop() throws ServiceException {
00344         // Undeploy the wars ...
00345         super.doStop();
00346 
00347         // ... and shut down embedded catalina
00348         if (server instanceof Lifecycle) {
00349             try {
00350                 ((Lifecycle) server).stop();
00351             } catch (Exception e) {
00352                 String err = i18n.getMessage("CatJWebServ.doStop.stopCatalinaError");
00353                 getLogger().log(BasicLevel.ERROR, err);
00354                 throw new ServiceException(e.getMessage(), e);
00355             }
00356         }
00357 
00358     }
00359 
00360 
00368     protected void doRegisterWar(javax.naming.Context ctx)
00369         throws JWebContainerServiceException {
00370         // Get the 7 parameters :
00371         //   - warURL is the URL of the war to register (required param).
00372         //   - contextRoot is the context root to which this application
00373         //     should be installed (must be unique) (required param).
00374         //   - hostName is the name of the host on which deploy the war
00375         //     (optional param taken into account only if no <context> element
00376         //      was declared in server.xml for this web application) .
00377         //   - Name of the Ear application of this war if any
00378         //   - java2DelegationModel the compliance to java2 delegation model
00379         //   - parentCL the war classloader of this war.
00380         //   - jonasDD JOnAS Deployment Desc content
00381         //   - permissionManager JACC permission manager
00382 
00383         URL warURL = null;
00384         URL earURL = null;
00385         URL unpackedWarURL = null;
00386         String contextRoot = null;
00387         boolean java2DelegationModel = true;
00388         PermissionManager permissionManager = null;
00389         boolean inEarCase = true;
00390         String earAppName = null;
00391         String jonasDD = null;
00392         try {
00393             warURL = (URL) ctx.lookup("warURL");
00394             unpackedWarURL = (URL) ctx.lookup("unpackedWarURL");
00395             contextRoot = (String) ctx.lookup("contextRoot");
00396             Boolean bool = (Boolean) ctx.lookup("java2DelegationModel");
00397             java2DelegationModel = bool.booleanValue();
00398             jonasDD = (String) ctx.lookup("jonasDD");
00399             permissionManager = (PermissionManager) ctx.lookup("permissionManager");
00400         } catch (NamingException e) {
00401             String err = i18n.getMessage("CatJWebServ.doRegisterWar.gettingParamError");
00402             getLogger().log(BasicLevel.ERROR, err + e.getMessage());
00403             throw new JWebContainerServiceException(err, e);
00404         }
00405 
00406         try {
00407             earAppName = (String) ctx.lookup("earAppName");
00408             earURL = (URL) ctx.lookup("earURL");
00409         } catch (NamingException e) {
00410             // no ear case, so no ear application name
00411             inEarCase = false;
00412             // set earURL to something only to avoid null value
00413             earURL = warURL;
00414         }
00415 
00416         ClassLoader webClassLoader = null;
00417 
00418         try {
00419             webClassLoader = (ClassLoader) ctx.lookup("parentCL");
00420         } catch (NamingException e) {
00421             String err = i18n.getMessage("CatJWebServ.doRegisterWar.gettingParamError");
00422             getLogger().log(BasicLevel.ERROR, err + e.getMessage());
00423             throw new JWebContainerServiceException(err, e);
00424         }
00425 
00426         String hostName = null;
00427         try {
00428             hostName = (String) ctx.lookup("hostName");
00429         } catch (NamingException e) {
00430             hostName = "";
00431         }
00432 
00433         // Install a new web application, whose web application archive is
00434         // at the specified URL, into this container with the specified
00435         // context root.
00436         // A context root of "" (the empty string) should be used for the root
00437         // application for this container.  Otherwise, the context root must
00438         // start with a slash.
00439 
00440         if (contextRoot.equals("/")) {
00441             contextRoot = "";
00442         } else {
00443             contextRoot = "/" + contextRoot;
00444         }
00445 
00446         // Install the war.
00447         File fWar = new File(warURL.getFile());
00448         //File fpackedWar = new File(packedWarURL.getFile());
00449 
00450         // Unpacked path of the war
00451         String destDir = null;
00452         if (fWar.isDirectory()) {
00453             destDir = warURL.getPath();
00454         } else {
00455             destDir = unpackedWarURL.getPath();
00456         }
00457 
00458         // Check if some contexts were configured in server.xml
00459         List jonasContexts = getConfiguredMatchingJonasContexts(contextRoot, fWar, destDir);
00460 
00461         Host deployer = null;
00462         // The context was not found in server.xml, a new context will be created.
00463         if (jonasContexts.isEmpty()) {
00464             // Find host on which deploy the context
00465             deployer = findHost(hostName);
00466 
00467             // Create context (false because not in server.xml)
00468             JOnASStandardContext context = new JOnASStandardContext(false, java2DelegationModel, inEarCase);
00469             if (getLogger().isLoggable(BasicLevel.DEBUG)) {
00470                 context.setDebug(DEFAUT_DEBUG_LEVEL);
00471             }
00472             context.setDocBase(destDir);
00473             context.setPath(contextRoot);
00474             ContextConfig config = new ContextConfig();
00475 
00476             // add the config
00477             ((Lifecycle) context).addLifecycleListener(config);
00478             jonasContexts.add(context);
00479         }
00480 
00481         // Configure these contexts and start them
00482         Iterator it = jonasContexts.iterator();
00483         while (it.hasNext()) {
00484             JOnASStandardContext jStdCtx = (JOnASStandardContext) it.next();
00485 
00486             // Set the parent class loader
00487             jStdCtx.setParentClassLoader(webClassLoader);
00488 
00489             // Delegation model
00490             jStdCtx.setDelegate(java2DelegationModel);
00491             if (getLogger().isLoggable(BasicLevel.DEBUG)) {
00492                 getLogger().log(BasicLevel.DEBUG, "Webapp class loader java 2 delegation model set to " + java2DelegationModel);
00493             }
00494 
00495             // JSR 77
00496             jStdCtx.setJ2EEServer(getJonasServerName());
00497             jStdCtx.setServer(J2eeObjectName.J2EEServer(getDomainName(), getJonasServerName()).toString());
00498             if (getMbeanServer() != null) {
00499                 try {
00500                     String[] as = (String[]) getMbeanServer().getAttribute(J2eeObjectName.J2EEServer(getDomainName()
00501                         , getJonasServerName()), "javaVMs");
00502                     jStdCtx.setJavaVMs(as);
00503                 } catch (Exception e) {
00504                     //String err = i18n.getMessage("CatJWebServ.doRegisterWar.startContextError", jStdCtx);
00505                     //getLogger().log(BasicLevel.WARN, err + e.getMessage());
00506                     getLogger().log(BasicLevel.WARN, "Set MBean JVM error : " + e.getClass().getName() + " " + e.getMessage());
00507                 }
00508             }
00509             if (earAppName != null) {
00510                 jStdCtx.setJ2EEApplication(earAppName);
00511             }
00512             jStdCtx.setJonasDeploymentDescriptor(jonasDD);
00513 
00514             // Set the realm
00515             Realm ctxRealm = jStdCtx.getRealm();
00516 
00517             // Take realm of parent
00518             if (ctxRealm == null) {
00519                 ctxRealm = deployer.getRealm();
00520             }
00521 
00522             if (ctxRealm != null && ctxRealm instanceof JACC) {
00523                 JACC jaccRealm = null;
00524                 try {
00525                     jaccRealm = (JACC) ((JACC) ctxRealm).clone();
00526                 } catch (CloneNotSupportedException cnse) {
00527                     String err = "Cannot clone the realm used by the existing context or its parent realm";
00528                     getLogger().log(BasicLevel.ERROR, err + cnse.getMessage());
00529                     throw new JWebContainerServiceException(err, cnse);
00530                 }
00531                 if (getLogger().isLoggable(BasicLevel.DEBUG)) {
00532                     getLogger().log(BasicLevel.DEBUG, "Setting permission manager to " + permissionManager);
00533                 }
00534                 jaccRealm.setPermissionManager(permissionManager);
00535                 jaccRealm.setContext(jStdCtx);
00536                 // Set the new realm
00537                 jStdCtx.setRealm(jaccRealm);
00538             }
00539 
00540 
00541             // Set the attributes transfered from the JOnAS War MBean.
00542             // Note that 'java2DelegationModel' and 'inEarCase' attributes
00543             // are passed asarguments to the JOnASStandardContext's constructor
00544             jStdCtx.setWarURL(warURL);
00545             if (inEarCase) {
00546                 jStdCtx.setEarURL(earURL);
00547             }
00548 
00549             // ... and start it or add it
00550             if (jStdCtx.isInServerXml()) {
00551                 try {
00552                     jStdCtx.setLoader(null);
00553                     jStdCtx.start();
00554                 } catch (LifecycleException lce) {
00555                     String err = i18n.getMessage("CatJWebServ.doRegisterWar.startContextError", jStdCtx);
00556                     getLogger().log(BasicLevel.ERROR, err + lce.getMessage());
00557                     throw new JWebContainerServiceException(err, lce);
00558 
00559                 }
00560             } else {
00561                 // add it
00562                 if (deployer == null) {
00563                     String err = i18n.getMessage("CatJWebServ.doRegisterWar.deployerIsNull", jStdCtx);
00564                     getLogger().log(BasicLevel.ERROR, err);
00565                     throw new JWebContainerServiceException(err);
00566                 }
00567                 deployer.addChild(jStdCtx);
00568             }
00569 
00570             // ...and check if it is now configured
00571             checkStartedContext(jStdCtx);
00572         }
00573     }
00574 
00575 
00584     protected List getConfiguredMatchingJonasContexts(String contextRoot, File fpackedWar, String destDir) {
00585         ArrayList jonasContexts = new ArrayList();
00586         // Check contexts of all services to see if there is a configured context.
00587         // that we must use instead of creating a new one.
00588         // If a context is matching, we set its docbase and start it.
00589         Iterator it = getContexts().iterator();
00590         while (it.hasNext()) {
00591             Context ctx = (Context) it.next();
00592             // Continue if it is not a JOnAS context
00593             if (!(ctx instanceof JOnASStandardContext)) {
00594                 continue;
00595             }
00596             JOnASStandardContext jStdCtx = (JOnASStandardContext) ctx;
00597             if (jStdCtx != null) {
00598                 // Not created in server.xml file
00599                 if (!jStdCtx.isInServerXml()) {
00600                     continue;
00601                 }
00602 
00603                 // The context was configured ?
00604                 String serverCtxRoot = jStdCtx.getPath();
00605                 if (!serverCtxRoot.equals(contextRoot)) {
00606                     continue;
00607                 }
00608                 if (jStdCtx.getPrivileged()) {
00609                     // Can deploy a privileged context only if it's a .war file
00610                     if (fpackedWar.isDirectory()) {
00611                         String err = i18n.getMessage("CatJWebServ.getConfiguredMatchingJonasContexts.privilegedContextError");
00612                         getLogger().log(BasicLevel.ERROR, err);
00613                     }
00614                     jStdCtx.setDocBase(fpackedWar.getPath());
00615                 } else {
00616                     jStdCtx.setDocBase(destDir);
00617                 }
00618                 jonasContexts.add(jStdCtx);
00619             }
00620         }
00621         return jonasContexts;
00622     }
00623 
00624 
00630     protected void checkStartedContext(Context context) throws JWebContainerServiceException {
00631         // Check if the context was configured
00632         if (!context.getConfigured()) {
00633             String err = i18n.getMessage("CatJWebServ.checkStartedContext.configuredFail", context.getName());
00634             getLogger().log(BasicLevel.ERROR, err);
00635             throw new JWebContainerServiceException(err);
00636         } else {
00637             ((JOnASStandardContext) context).unsetAuthenticationCaching();
00638             if (getLogger().isLoggable(BasicLevel.DEBUG)) {
00639                 getLogger().log(BasicLevel.DEBUG, "context " + context + " started");
00640             }
00641         }
00642     }
00643 
00649     protected synchronized List getEngines() throws JWebContainerServiceException {
00650         List engines = new ArrayList();
00651         Service[] services = server.findServices();
00652 
00653         // Get contexts of each engine of each service
00654         for (int s = 0; s < services.length; s++) {
00655             Container cont = services[s].getContainer();
00656             if (!(cont instanceof Engine)) {
00657                 String err = "The container of the service must be an engine (server.xml)";
00658                 throw new JWebContainerServiceException(err);
00659             }
00660             engines.add(cont);
00661         }
00662         return engines;
00663     }
00664 
00670     protected synchronized List getContexts() throws JWebContainerServiceException {
00671         List contexts = new ArrayList();
00672 
00673         Iterator itEngines = getEngines().iterator();
00674         while (itEngines.hasNext()) {
00675             Engine engine = (Engine) itEngines.next();
00676             Container[] hosts = engine.findChildren();
00677 
00678             for (int j = 0; j < hosts.length; j++) {
00679                 Container[] containers = hosts[j].findChildren();
00680                 for (int k = 0; k < containers.length; k++) {
00681                     Container container = containers[k];
00682                     if (container instanceof Context) {
00683                         contexts.add(container);
00684                     }
00685                 }
00686             }
00687         }
00688         return contexts;
00689     }
00690 
00691 
00698     protected void doUnRegisterWar(javax.naming.Context ctx)
00699         throws JWebContainerServiceException {
00700 
00701         // Get the 2 parameters :
00702         //   - contextRoot is the context root to be removed (required param).
00703         //   - hostName is the name of the host to remove the war (optional).
00704         String contextRoot = null;
00705         try {
00706             contextRoot = (String) ctx.lookup("contextRoot");
00707         } catch (NamingException e) {
00708             String err = i18n.getMessage("CatJWebServ.doUnRegisterWar.gettingParamError");
00709             getLogger().log(BasicLevel.ERROR, err + e.getMessage());
00710             throw new JWebContainerServiceException(err, e);
00711         }
00712 
00713         if (contextRoot.equals("/")) {
00714             contextRoot = "";
00715         } else {
00716             contextRoot = "/" + contextRoot;
00717         }
00718 
00719         String hostName = null;
00720         try {
00721             hostName = (String) ctx.lookup("hostName");
00722         } catch (NamingException e) {
00723             getLogger().log(BasicLevel.DEBUG, "No define hostname for this context");
00724         }
00725 
00726         // Undeploy all matching context if there is no hostname provided
00727         if (hostName == null) {
00728             boolean found = false;
00729             Iterator it = getContexts().iterator();
00730             while (it.hasNext()) {
00731                 Context context = (Context) it.next();
00732                 String serverCtxRoot = context.getPath();
00733                 if (serverCtxRoot.equals(contextRoot)) {
00734                     removeContext(context);
00735                     found = true;
00736                 }
00737             }
00738             if (!found) {
00739                 String err = i18n.getMessage("CatJWebServ.doUnRegisterWar.undeployError", contextRoot);
00740                 getLogger().log(BasicLevel.ERROR, err);
00741                 throw new JWebContainerServiceException(err);
00742             }
00743         } else {
00744             // Remove the specified Context from the set of defined Contexts
00745             // for its associated Host.
00746             Host host = findHost(hostName);
00747             org.apache.catalina.Context context = host.map(contextRoot);
00748             if (context != null) {
00749                 removeContext(context);
00750             } else {
00751                 String err = i18n.getMessage("CatJWebServ.doUnRegisterWar.undeployError", contextRoot);
00752                 getLogger().log(BasicLevel.ERROR, err);
00753                 throw new JWebContainerServiceException(err);
00754             }
00755         }
00756     }
00757 
00758 
00767     public synchronized void removeContext(Context context) throws JWebContainerServiceException {
00768 
00769         // Is this Context actually among those that are deployed ?
00770         boolean found = false;
00771         Iterator it = getContexts().iterator();
00772         while (it.hasNext() && !found) {
00773             if (context == (Context) it.next()) {
00774                 found = true;
00775             }
00776         }
00777 
00778         if (!found) {
00779             return;
00780         }
00781         // Remove this Context from the associated Host
00782         // Or stop it if it is a JOnAS standard context (to keep the configuration)
00783         if (context instanceof JOnASStandardContext) {
00784             JOnASStandardContext jctx = (JOnASStandardContext) context;
00785             if (jctx.isInServerXml()) {
00786                 try {
00787                     ((JOnASStandardContext) context).stop();
00788                 } catch (LifecycleException le) {
00789                     throw new JWebContainerServiceException("Cannot stop context (" + le.getMessage() + ")");
00790                 }
00791             } else {
00792                 // must not persist
00793                 context.getParent().removeChild(context);
00794                 // Bug Tomcat 5 doesn't remove MBean WebModule
00795                 // Delete the next line when will be fixed
00796                 // Bug Tomcat 5 : begin
00797                 if (getMbeanServer() != null) {
00798                     try {
00799                         // unregister WebModule MBean
00800                         getMbeanServer().unregisterMBean(jctx.getJmxName());
00801                     } catch (Exception e) {
00802                         getLogger().log(BasicLevel.ERROR, "Cannot remove the MBean for the WebModule " + jctx.getObjectName() + " : " + e.getMessage());
00803                     }
00804                 }
00805             }
00806         } else {
00807             context.getParent().removeChild(context);
00808             // Bug Tomcat 5 doesn't remove MBean WebModule
00809             // Delete the next line when will be fixed
00810             // Bug Tomcat 5 : begin
00811             if (context instanceof StandardContext) {
00812                 StandardContext ctx = (JOnASStandardContext) context;
00813                 if (getMbeanServer() != null) {
00814                     try {
00815                         // unregister WebModule MBean
00816                         getMbeanServer().unregisterMBean(ctx.getJmxName());
00817                     } catch (Exception e) {
00818                         getLogger().log(BasicLevel.ERROR
00819                             , "Cannot remove the MBean for the WebModule " + ctx.getObjectName()
00820                             + " : " + e.getMessage());
00821                     }
00822                 }
00823             }
00824         }
00825 
00826     }
00827 
00828 
00833     public boolean isTomcatStarted() {
00834         return tomcatStarted;
00835     }
00836 
00837 
00843     public void setServer(Server server) {
00844         this.server = server;
00845     }
00846 
00847 
00853     protected File getConfigFile() throws FileNotFoundException {
00854         String fileName = System.getProperty("catalina.base");
00855         fileName = fileName + File.separator + CONFIG_FILE;
00856         File file = new File(fileName);
00857         if (!file.exists()) {
00858             String err = i18n.getMessage("CatJWebServ.getConfigFile.findfileError", fileName);
00859             throw new FileNotFoundException(err);
00860         }
00861         return (file);
00862     }
00863 
00864 
00872     public Host findHost(String hostName)
00873         throws JWebContainerServiceException {
00874 
00875         Service[] services = server.findServices();
00876         // Check number of services
00877         if (services.length < 1) {
00878             String err = "At least one service must be define in the server.xml of Tomcat";
00879             throw new JWebContainerServiceException(err);
00880         }
00881 
00882         // Two cases :
00883         //   1/ No host specified
00884         //      -> defaulthost of the engine of the first service.
00885         //   2) A host is specified in the jonas-web.xml
00886         //      -> find the host and deploy on this host
00887 
00888 
00889         if (hostName == null || hostName.equals("")) {
00890             // First case
00891 
00892             //Take first service
00893             Service service = services[0];
00894 
00895             Container cont = service.getContainer();
00896             if (!(cont instanceof Engine)) {
00897                 String err = "The container of the service must be an engine";
00898                 throw new JWebContainerServiceException(err);
00899             }
00900 
00901             Engine engine = (Engine) cont;
00902             String defaultHost = engine.getDefaultHost();
00903             if (defaultHost == null) {
00904                 String err = "Default host must be specified in server.xml or host must be specified in jonas-web.xml";
00905                 throw new JWebContainerServiceException(err);
00906             }
00907             Container child = engine.findChild(defaultHost);
00908             if (child instanceof Host) {
00909                 return (Host) child;
00910             } else {
00911                 String err = "Default host " + defaultHost + " not found";
00912                 throw new JWebContainerServiceException(err);
00913             }
00914         } else {
00915             // Second case.
00916             // Get all hosts.
00917             Vector hosts = new Vector();
00918 
00919             for (int s = 0; s < services.length; s++) {
00920                 Container cont = services[s].getContainer();
00921                 if (!(cont instanceof Engine)) {
00922                     String err = "The container of a service must be an engine";
00923                     throw new JWebContainerServiceException(err);
00924                 }
00925                 Engine engine = (Engine) cont;
00926                 Container child = engine.findChild(hostName);
00927                 if (child instanceof Host) {
00928                     hosts.addElement(child);
00929                 }
00930             }
00931 
00932             if (hosts.size() == 0) {
00933                 // No host found.
00934                 String err = "Host " + hostName + " not found in all services/Engine of server.xml";
00935                 throw new JWebContainerServiceException(err);
00936             } else {
00937                 return (Host) hosts.elementAt(0);
00938             }
00939         }
00940     }
00941 
00942 
00950     private void addResource(javax.naming.Context ctx, NamingResources resources, ContextResource resource) throws JWebContainerServiceException {
00951 
00952         String name = resource.getName();
00953         String type = resource.getType();
00954         String registryName = name;
00955 
00956         // Add only UserDatabase resources
00957         if (!type.equals("org.apache.catalina.UserDatabase")) {
00958             return;
00959         }
00960 
00961         // Create a reference to the resource.
00962         Reference ref = new Reference("org.apache.catalina.UserDatabase", "org.apache.catalina.users.MemoryUserDatabaseFactory", null);
00963 
00964         // Add extra parameters
00965         ResourceParams resourceParameters = resources.findResourceParams(name);
00966         if (resourceParameters != null) {
00967             Hashtable params = resourceParameters.getParameters();
00968             Enumeration keys = params.keys();
00969             while (keys.hasMoreElements()) {
00970                 String paramName = (String) keys.nextElement();
00971                 String paramValue = (String) params.get(paramName);
00972                 StringRefAddr refAddr = new StringRefAddr(paramName, paramValue);
00973                 ref.add(refAddr);
00974             }
00975         }
00976         try {
00977             javax.naming.Context ictx = getNaming().getInitialContext();
00978 
00979             // Bind into registry
00980             ictx.bind(registryName, ref);
00981 
00982             // Bind LinkRef
00983             LinkRef lref = new LinkRef(registryName);
00984             ctx.bind(name, lref);
00985 
00986         } catch (Exception e) {
00987             e.printStackTrace();
00988             String err = "Can't add the resource " + name;
00989             throw new JWebContainerServiceException(err, e);
00990         }
00991     }
00992 
00993 
01000     protected Digester createServerDigester() {
01001 
01002         // Initialize the digester
01003         Digester digester = new Digester();
01004         digester.setValidating(false);
01005         digester.addRuleSet(new JCatalinaRuleSet(parentClassLoader));
01006 
01007         // Use context class loader.
01008         // Could avoid problem for users putting digester in JONAS_ROOT/lib/ext folder
01009         digester.setUseContextClassLoader(true);
01010         return (digester);
01011 
01012     }
01013 
01014 
01018     protected void updateServerInfos() {
01019         String infos = org.apache.catalina.util.ServerInfo.getServerInfo();
01020         StringTokenizer st = new StringTokenizer(infos, "/");
01021         if (st.countTokens() != 2) {
01022             setServerName(infos);
01023             setServerVersion("");
01024         } else {
01025             setServerName(st.nextToken());
01026             setServerVersion(st.nextToken());
01027         }
01028     }
01029 
01036     public String getDefaultHost() throws JWebContainerServiceException {
01037         Service[] svc = server.findServices();
01038         if (svc.length != 1) {
01039             String err = "Cannot find defaultHost! Cause of multiple Services";
01040             throw new JWebContainerServiceException(err);
01041         }
01042 
01043         Engine engine = (Engine) svc[0].getContainer();
01044         return engine.getDefaultHost();
01045     }
01046 
01047 
01055     public String getDefaultHttpPort() throws JWebContainerServiceException {
01056         Service[] svc = server.findServices();
01057         if (svc.length != 1) {
01058             String err = "Cannot find Default Http Port! Cause of multiple Services";
01059             throw new JWebContainerServiceException(err);
01060         }
01061 
01062         Connector[] conn = svc[0].findConnectors();
01063         Vector httpConn = new Vector();
01064         for (int i = 0; i < conn.length; i++) {
01065             if (conn[i].getScheme().equalsIgnoreCase("http")) {
01066                 httpConn.add(conn[i]);
01067             }
01068         }
01069         if (httpConn.size() != 1) {
01070             String err = "Cannot find Default Http Port! Cause of multiple Http Connector";
01071             throw new JWebContainerServiceException(err);
01072         }
01073 
01074         Class connectorClass = httpConn.get(0).getClass();
01075         String port = null;
01076         try {
01077             Method getPortMethod = connectorClass.getMethod("getPort", new Class[] {});
01078             port = ((Integer) getPortMethod.invoke(httpConn.get(0), new Object[] {})).toString();
01079         } catch (Exception e) {
01080             String err = "Connector does not have a getPort method.";
01081             throw new JWebContainerServiceException(err, e);
01082         }
01083 
01084         return port;
01085     }
01086 
01087 
01095     public String getDefaultHttpsPort() throws JWebContainerServiceException {
01096         Service[] svc = server.findServices();
01097         if (svc.length != 1) {
01098             String err = "Cannot find Default Http Port! Cause of multiple Services";
01099             throw new JWebContainerServiceException(err);
01100         }
01101 
01102         Connector[] conn = svc[0].findConnectors();
01103         Vector httpsConn = new Vector();
01104         for (int i = 0; i < conn.length; i++) {
01105             if (conn[i].getScheme().equalsIgnoreCase("https")) {
01106                 httpsConn.add(conn[i]);
01107             }
01108         }
01109         if (httpsConn.size() != 1) {
01110             String err = "Cannot find Default Https Port! Cause of multiple Https Connector";
01111             throw new JWebContainerServiceException(err);
01112         }
01113 
01114         Class connectorClass = httpsConn.get(0).getClass();
01115         String port = null;
01116         try {
01117             Method getPortMethod = connectorClass.getMethod("getPort", new Class[] {});
01118             port = ((Integer) getPortMethod.invoke(httpsConn.get(0), new Object[] {})).toString();
01119         } catch (Exception e) {
01120             String err = "Connector does not have a getPort method.";
01121             throw new JWebContainerServiceException(err, e);
01122         }
01123 
01124         return port;
01125     }
01126 
01134     public void registerWarMBean(String fileName) throws RemoteException, JWebContainerServiceException {
01135         ClassLoader old = null;
01136         try {
01137             old = Thread.currentThread().getContextClassLoader();
01138             Thread.currentThread().setContextClassLoader(catalinaLoader);
01139             super.registerWarMBean(fileName);
01140         } catch (Exception e) {
01141             throw new ServiceException("Exception during registering war", e);
01142         } finally {
01143             if (old != null) {
01144                 Thread.currentThread().setContextClassLoader(old);
01145             }
01146         }
01147     }
01148 
01156     public void unRegisterWarMBean(String fileName) throws RemoteException, JWebContainerServiceException {
01157         ClassLoader old = null;
01158         try {
01159             old = Thread.currentThread().getContextClassLoader();
01160             Thread.currentThread().setContextClassLoader(catalinaLoader);
01161             super.unRegisterWarMBean(fileName);
01162         } catch (Exception e) {
01163             throw new ServiceException("Exception during unregistering war", e);
01164         } finally {
01165             if (old != null) {
01166                 Thread.currentThread().setContextClassLoader(old);
01167             }
01168         }
01169     }
01170 }

Generated on Tue Feb 15 15:05:25 2005 for JOnAS by  doxygen 1.3.9.1