Package org.apache.geronimo.tomcat

Source Code of org.apache.geronimo.tomcat.TomcatContainer

/**
*
* Copyright 2003-2005 The Apache Software Foundation
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package org.apache.geronimo.tomcat;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.net.URLStreamHandlerFactory;
import java.net.URL;

import org.apache.catalina.Container;
import org.apache.catalina.Context;
import org.apache.catalina.Engine;
import org.apache.catalina.Realm;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.realm.JAASRealm;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.geronimo.gbean.GBeanInfo;
import org.apache.geronimo.gbean.GBeanInfoBuilder;
import org.apache.geronimo.gbean.GBeanLifecycle;
import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
import org.apache.geronimo.management.geronimo.NetworkConnector;
import org.apache.geronimo.management.geronimo.WebManager;
import org.apache.geronimo.system.serverinfo.ServerInfo;
import org.apache.geronimo.tomcat.realm.TomcatGeronimoRealm;
import org.apache.geronimo.tomcat.realm.TomcatJAASRealm;
import org.apache.geronimo.tomcat.util.SecurityHolder;
import org.apache.geronimo.webservices.SoapHandler;
import org.apache.geronimo.webservices.WebServiceContainer;
import org.apache.naming.resources.DirContextURLStreamHandlerFactory;


/**
* Apache Tomcat GBean
* http://wiki.apache.org/geronimo/Tomcat
* http://nagoya.apache.org/jira/browse/GERONIMO-215
*
* @version $Rev: 406493 $ $Date: 2006-05-14 21:14:11 -0400 (Sun, 14 May 2006) $
*/
public class TomcatContainer implements SoapHandler, GBeanLifecycle, TomcatWebContainer {

    private static final Log log = LogFactory.getLog(TomcatContainer.class);

    /**
     * The default value of CATALINA_HOME variable
     */
    private static final String DEFAULT_CATALINA_HOME = "var/catalina";

    /**
     * Reference to the org.apache.catalina.Embedded embedded.
     */
    private TomcatGeronimoEmbedded embedded;

    /**
     * Tomcat Engine that will contain the host
     */
    private Engine engine;

    /**
     * Geronimo class loader
     */
    private ClassLoader classLoader;

    private final Map webServices = new HashMap();
    private final String objectName;
    private final WebManager manager;
    private static boolean first = true;

    // Required as it's referenced by deployed webapps
    public TomcatContainer() {
        this.objectName = null; // is this OK??
        setCatalinaHome(DEFAULT_CATALINA_HOME);
        manager = null;
    }

    /**
     * GBean constructor (invoked dynamically when the gbean is declared in a plan)
     */
    public TomcatContainer(ClassLoader classLoader, String catalinaHome, ObjectRetriever engineGBean, ServerInfo serverInfo, String objectName, WebManager manager) {
        // Register a stream handler factory for the JNDI protocol
        URLStreamHandlerFactory streamHandlerFactory =
            new DirContextURLStreamHandlerFactory();
        if (first) {
            first = false;
            try {
                URL.setURLStreamHandlerFactory(streamHandlerFactory);
            } catch (Exception e) {
                // Log and continue anyway, this is not critical
                log.error("Error registering jndi stream handler", e);
            } catch (Throwable t) {
                // This is likely a dual registration
                log.info("Dual registration of jndi stream handler: "
                         + t.getMessage());
            }
        }


        if (catalinaHome == null)
            catalinaHome = DEFAULT_CATALINA_HOME;

        setCatalinaHome(serverInfo.resolveServerPath(catalinaHome));

        if (classLoader == null) {
            throw new IllegalArgumentException("classLoader cannot be null.");
        }

        if (engineGBean == null) {
            throw new IllegalArgumentException("engineGBean cannot be null.");
        }

        this.classLoader = classLoader;

        this.engine = (Engine) engineGBean.getInternalObject();

        this.objectName = objectName;
        this.manager = manager;
    }

    public String getObjectName() {
        return objectName;
    }

    public boolean isStateManageable() {
        return true;
    }

    public boolean isStatisticsProvider() {
        return false; // todo: return true once stats are integrated
    }

    public boolean isEventProvider() {
        return true;
    }

    public NetworkConnector[] getConnectors() {
        return manager.getConnectorsForContainer(this);
    }

    public NetworkConnector[] getConnectors(String protocol) {
        return manager.getConnectorsForContainer(this, protocol);
    }

    public void doFail() {
        try {
            doStop();
        } catch (Exception ignored) {
        }
    }

    /**
     * Instantiate and start up Tomcat's Embedded class
     * <p/>
     * See org.apache.catalina.startup.Embedded for details (TODO: provide the link to the javadoc)
     */
    public void doStart() throws Exception {
        log.debug("doStart()");

        log.debug("Endorsed Dirs set to:" + System.getProperty("java.endorsed.dirs"));

        // The comments are from the javadoc of the Embedded class

        // 1. Instantiate a new instance of this class.
        if (embedded == null) {
            embedded = new TomcatGeronimoEmbedded();
        }

        // Assemble FileLogger as a gbean
        /*
         * FileLogger fileLog = new FileLogger(); fileLog.setDirectory("."); fileLog.setPrefix("vsjMbedTC5");
         * fileLog.setSuffix(".log"); fileLog.setTimestamp(true);
         */

        // 2. Set the relevant properties of this object itself. In particular,
        // you will want to establish the default Logger to be used, as well as
        // the default Realm if you are using container-managed security.
        embedded.setUseNaming(false);

        //Add default contexts
        File rootContext = new File(System.getProperty("catalina.home") + "/ROOT");

        String docBase = "";
        if (rootContext.exists()) {
            docBase = "ROOT";
        }

        Container[] hosts = engine.findChildren();
        Context defaultContext;
        for (int i = 0; i < hosts.length; i++) {
            defaultContext = embedded.createContext("", docBase, classLoader);
            hosts[i].addChild(defaultContext);
        }

        // 6. Call addEngine() to attach this Engine to the set of defined
        // Engines for this object.
        embedded.addEngine(engine);

        // 9. Call start() to initiate normal operations of all the attached
        // components.
        embedded.start();
    }

    public void doStop() throws Exception {
        if (embedded != null) {
            embedded.stop();
            embedded = null;
        }

    }

    /**
     * Creates and adds the context to the running host
     * <p/>
     * It simply delegates the call to Tomcat's Embedded and Host classes
     *
     * @param ctx the context to be added
     * @see org.apache.catalina.startup.Embedded
     * @see org.apache.catalina.Host
     */
    public void addContext(TomcatContext ctx) throws Exception {
        Context anotherCtxObj = embedded.createContext(ctx.getContextPath(), ctx.getDocBase(), ctx.getClassLoader());

        // Set the context for the Tomcat implementation
        ctx.setContext(anotherCtxObj);

        // Have the context to set its properties if its a GeronimoStandardContext
        if (anotherCtxObj instanceof GeronimoStandardContext) {
            ((GeronimoStandardContext) anotherCtxObj).setContextProperties(ctx);
        }
        //Was a virtual server defined?
        String virtualServer = ctx.getVirtualServer();
        if (virtualServer == null) {
            virtualServer = engine.getDefaultHost();
        }
        Container host = engine.findChild(virtualServer);
        if (host == null) {
            throw new IllegalArgumentException("Invalid virtual host '" + virtualServer + "'.  Do you have a matching Host entry in the plan?");
        }

        //Get the security-realm-name if there is one
        String securityRealmName = null;
        SecurityHolder secHolder = ctx.getSecurityHolder();
        if (secHolder != null)
            securityRealmName = secHolder.getSecurityRealm();

        //Did we declare a GBean at the context level?
        if (ctx.getRealm() != null) {
            Realm realm = ctx.getRealm();

            //Allow for the <security-realm-name> override from the
            //geronimo-web.xml file to be used if our Realm is a JAAS type
            if (securityRealmName != null) {
                if (realm instanceof JAASRealm) {
                    ((JAASRealm) realm).setAppName(securityRealmName);
                }
            }
            anotherCtxObj.setRealm(realm);
        } else {
            Realm realm = host.getRealm();
            //Check and see if we have a declared realm name and no match to a parent name
            if (securityRealmName != null) {
                String parentRealmName = null;
                if (realm instanceof JAASRealm) {
                    parentRealmName = ((JAASRealm) realm).getAppName();
                }

                //Do we have a match to a parent?
                if (!securityRealmName.equals(parentRealmName)) {
                    //No...we need to create a default adapter

                    //Is the context requiring JACC?
                    if (secHolder.isSecurity()) {
                        //JACC
                        realm = new TomcatGeronimoRealm();
                    } else {
                        //JAAS
                        realm = new TomcatJAASRealm();
                    }

                    log.debug("The security-realm-name '" + securityRealmName +
                            "' was specified and a parent (Engine/Host) is not named the same or no RealmGBean was configured for this context. " +
                            "Creating a default " + realm.getClass().getName() +
                            " adapter for this context.");

                    ((JAASRealm) realm).setUserClassNames("org.apache.geronimo.security.realm.providers.GeronimoUserPrincipal");
                    ((JAASRealm) realm).setRoleClassNames("org.apache.geronimo.security.realm.providers.GeronimoGroupPrincipal");
                    ((JAASRealm) realm).setAppName(securityRealmName);

                    anotherCtxObj.setRealm(realm);
                } else {
                    //Use the parent since a name matches
                    anotherCtxObj.setRealm(realm);
                }
            } else {
                anotherCtxObj.setRealm(realm);
            }
        }

        host.addChild(anotherCtxObj);
    }

    public void removeContext(TomcatContext ctx) {
        Context context = ctx.getContext();

        if (context != null) {
            if (context instanceof GeronimoStandardContext) {
                GeronimoStandardContext stdctx = (GeronimoStandardContext) context;

                try {
                    stdctx.stop();
                    stdctx.destroy();
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }

            }
            context.getParent().removeChild(context);
        }

    }

    public void setCatalinaHome(String catalinaHome) {
        System.setProperty("catalina.home", catalinaHome);
    }

    public void addConnector(Connector connector) {
        embedded.addConnector(connector);
    }

    public void removeConnector(Connector connector) {
        embedded.removeConnector(connector);
    }

    public void addWebService(String contextPath, String[] virtualHosts, WebServiceContainer webServiceContainer, String securityRealmName, String realmName, String transportGuarantee, String authMethod, ClassLoader classLoader) throws Exception {
        Context webServiceContext = embedded.createEJBWebServiceContext(contextPath, webServiceContainer, securityRealmName, realmName, transportGuarantee, authMethod, classLoader);

        String virtualServer;
        if (virtualHosts != null && virtualHosts.length > 0) {
            virtualServer = virtualHosts[0];
        } else {
            virtualServer = engine.getDefaultHost();
        }

        Container host = engine.findChild(virtualServer);
        if (host == null) {
            throw new IllegalArgumentException("Invalid virtual host '" + virtualServer + "'.  Do you have a matchiing Host entry in the plan?");
        }

        host.addChild(webServiceContext);
        webServices.put(contextPath, webServiceContext);
    }

    public void removeWebService(String contextPath) {
        TomcatEJBWebServiceContext context = (TomcatEJBWebServiceContext) webServices.get(contextPath);
        try {
            context.stop();
            context.destroy();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        context.getParent().removeChild(context);
        webServices.remove(contextPath);
    }

    public static final GBeanInfo GBEAN_INFO;

    static {
        GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic("Tomcat Web Container", TomcatContainer.class);

        infoFactory.setConstructor(new String[]{"classLoader", "catalinaHome", "EngineGBean", "ServerInfo", "objectName", "WebManager"});

        infoFactory.addAttribute("classLoader", ClassLoader.class, false);

        infoFactory.addAttribute("catalinaHome", String.class, true);

        infoFactory.addAttribute("objectName", String.class, false);

        infoFactory.addReference("EngineGBean", ObjectRetriever.class, NameFactory.GERONIMO_SERVICE);

        infoFactory.addReference("ServerInfo", ServerInfo.class, "GBean");
        infoFactory.addReference("WebManager", WebManager.class);

        infoFactory.addOperation("addContext", new Class[]{TomcatContext.class});
        infoFactory.addOperation("removeContext", new Class[]{TomcatContext.class});

        infoFactory.addOperation("addConnector", new Class[]{Connector.class});
        infoFactory.addOperation("removeConnector", new Class[]{Connector.class});

        infoFactory.addInterface(SoapHandler.class);
        infoFactory.addInterface(TomcatWebContainer.class);

        GBEAN_INFO = infoFactory.getBeanInfo();
    }

    public static GBeanInfo getGBeanInfo() {
        return GBEAN_INFO;
    }

}
TOP

Related Classes of org.apache.geronimo.tomcat.TomcatContainer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.