Package org.apache.geronimo.jetty

Source Code of org.apache.geronimo.jetty.JettyWebAppContext

/**
*
* Copyright 2003-2004 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.jetty;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.Set;
import javax.resource.ResourceException;
import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;

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.gbean.WaitingException;
import org.apache.geronimo.naming.java.ReadOnlyContext;
import org.apache.geronimo.naming.java.RootContext;
import org.apache.geronimo.transaction.DefaultInstanceContext;
import org.apache.geronimo.transaction.InstanceContext;
import org.apache.geronimo.transaction.OnlineUserTransaction;
import org.apache.geronimo.transaction.TrackedConnectionAssociator;
import org.apache.geronimo.transaction.context.InheritableTransactionContext;
import org.apache.geronimo.transaction.context.TransactionContext;
import org.apache.geronimo.transaction.context.TransactionContextManager;
import org.mortbay.http.HttpException;
import org.mortbay.http.HttpRequest;
import org.mortbay.http.HttpResponse;
import org.mortbay.jetty.servlet.WebApplicationContext;

/**
* Wrapper for a WebApplicationContext that sets up its J2EE environment.
*
* @version $Rev: 56022 $ $Date: 2004-10-30 00:16:18 -0500 (Sat, 30 Oct 2004) $
*/
public class JettyWebAppContext extends WebApplicationContext implements GBeanLifecycle {
    private static Log log = LogFactory.getLog(JettyWebAppContext.class);

    private final ReadOnlyContext componentContext;
    private final OnlineUserTransaction userTransaction;
    private final ClassLoader classLoader;
    private final Set unshareableResources;
    private final Set applicationManagedSecurityResources;
    private final TransactionContextManager transactionContextManager;
    private final TrackedConnectionAssociator trackedConnectionAssociator;
    private final JettyContainer jettyContainer;

    private final URI webAppRoot;

    /**
     * @deprecated never use this... this is only here because Jetty WebApplicationContext is externalizable
     */
    public JettyWebAppContext() {
        componentContext = null;
        userTransaction = null;
        classLoader = null;
        unshareableResources = null;
        applicationManagedSecurityResources = null;
        transactionContextManager = null;
        trackedConnectionAssociator = null;
        jettyContainer = null;
        webAppRoot = null;
    }

    public JettyWebAppContext(URI uri,
                              ReadOnlyContext componentContext,
                              OnlineUserTransaction userTransaction,
                              ClassLoader classLoader,
                              URI[] webClassPath,
                              boolean contextPriorityClassLoader,
                              URL configurationBaseUrl,
                              Set unshareableResources,
                              Set applicationManagedSecurityResources,
                              TransactionContextManager transactionContextManager,
                              TrackedConnectionAssociator trackedConnectionAssociator,
                              JettyContainer jettyContainer) throws MalformedURLException {

        assert uri != null;
        assert componentContext != null;
        assert userTransaction != null;
        assert classLoader != null;
        assert webClassPath != null;
        assert configurationBaseUrl != null;
        assert transactionContextManager != null;
        assert trackedConnectionAssociator != null;
        assert jettyContainer != null;

        this.componentContext = componentContext;
        this.userTransaction = userTransaction;
        this.unshareableResources = unshareableResources;
        this.applicationManagedSecurityResources = applicationManagedSecurityResources;
        this.transactionContextManager = transactionContextManager;
        this.trackedConnectionAssociator = trackedConnectionAssociator;
        this.jettyContainer = jettyContainer;

        setDefaultsDescriptor("META-INF/default-web.xml");
        setConfigurationClassNames(new String[]{"org.apache.geronimo.jetty.JettyXMLConfiguration"});

        URI root = URI.create(configurationBaseUrl.toString());
        webAppRoot = root.resolve(uri);

        URL[] urls = new URL[webClassPath.length];
        for (int i = 0; i < webClassPath.length; i++) {
            URI classPathEntry = webClassPath[i];
            classPathEntry = webAppRoot.resolve(classPathEntry);
            urls[i] = classPathEntry.toURL();
        }
        this.classLoader = new JettyClassLoader(urls, classLoader, contextPriorityClassLoader);
        setClassLoader(this.classLoader);
    }

    //TODO tx logic may not be complete.  exceptions are certainly wrong!
    public void handle(String pathInContext,
                       String pathParams,
                       HttpRequest httpRequest,
                       HttpResponse httpResponse)
            throws HttpException, IOException {

        // save previous state
        ReadOnlyContext oldComponentContext = RootContext.getComponentContext();

        InstanceContext oldInstanceContext = null;

        try {
            // set up java:comp JNDI Context
            RootContext.setComponentContext(componentContext);


            TransactionContext oldTransactionContext = transactionContextManager.getContext();
            TransactionContext newTransactionContext = null;
            if (oldTransactionContext == null || !(oldTransactionContext instanceof InheritableTransactionContext)) {
                newTransactionContext = transactionContextManager.newUnspecifiedTransactionContext();
            }

            try {
                try {
                    oldInstanceContext = trackedConnectionAssociator.enter(new DefaultInstanceContext(unshareableResources, applicationManagedSecurityResources));
                } catch (ResourceException e) {
                    throw new RuntimeException(e);
                }

                super.handle(pathInContext, pathParams, httpRequest, httpResponse);
            } finally {
                try {
                    if (newTransactionContext != null) {
                        if (newTransactionContext != transactionContextManager.getContext()) {
                            transactionContextManager.getContext().rollback();
                            newTransactionContext.rollback();
                            throw new HttpException(500, "WRONG EXCEPTION! returned from servlet call with wrong tx context");
                        }
                        newTransactionContext.commit();

                    } else {
                        if (oldTransactionContext != transactionContextManager.getContext()) {
                            if (transactionContextManager.getContext() != null) {
                                transactionContextManager.getContext().rollback();
                            }
                            throw new HttpException(500, "WRONG EXCEPTION! returned from servlet call with wrong tx context");
                        }
                    }
                } catch (SystemException e) {
                    throw (HttpException) new HttpException(500, "WRONG EXCEPTION!").initCause(e);
                } catch (HeuristicMixedException e) {
                    throw (HttpException) new HttpException(500, "WRONG EXCEPTION!").initCause(e);
                } catch (HeuristicRollbackException e) {
                    throw (HttpException) new HttpException(500, "WRONG EXCEPTION!").initCause(e);
                } catch (RollbackException e) {
                    throw (HttpException) new HttpException(500, "WRONG EXCEPTION!").initCause(e);
                } finally {
                    //this is redundant when we enter with an inheritable context and nothing goes wrong.
                    transactionContextManager.setContext(oldTransactionContext);
                }
            }
        } finally {
            try {
                trackedConnectionAssociator.exit(oldInstanceContext);
            } catch (ResourceException e) {
                throw new RuntimeException(e);
            } finally {
                RootContext.setComponentContext(oldComponentContext);
            }
        }
    }

    public void doStart() throws WaitingException, Exception {
        // reset the classsloader... jetty likes to set it to null when stopping
        setClassLoader(classLoader);

        // merge Geronimo and Jetty Lifecycles
        if (!isStarting()) {
            super.start();
            return;
        }

        setWAR(webAppRoot.toString());

        userTransaction.setUp(transactionContextManager, trackedConnectionAssociator);

        jettyContainer.addContext(this);

        ClassLoader oldCL = Thread.currentThread().getContextClassLoader();
        try {
            Thread.currentThread().setContextClassLoader(classLoader);
            ReadOnlyContext oldComponentContext = RootContext.getComponentContext();
            InstanceContext oldInstanceContext = null;
            try {
                RootContext.setComponentContext(componentContext);
//TODO FIXME!!!
                TransactionContext transactionContext = transactionContextManager.getContext();
                if (transactionContext == null) {
                    transactionContext = transactionContextManager.newUnspecifiedTransactionContext();
                } else {
                    transactionContext = null;
                }

                try {

                    try {
                        oldInstanceContext = trackedConnectionAssociator.enter(new DefaultInstanceContext(unshareableResources, applicationManagedSecurityResources));
                    } catch (ResourceException e) {
                        throw new RuntimeException(e);
                    }

                    super.doStart();
                } finally {
                    if (transactionContext != null) {
                        transactionContextManager.setContext(null);
                        try {
                            transactionContext.commit();
                        } catch (Exception e) {
                            //TODO this is undoubtedly the wrong error code!
                            throw (HttpException) new HttpException(500, "Problem committing unspecified transaction context").initCause(e);
                        }
                    }
                }
            } finally {
                try {
                    trackedConnectionAssociator.exit(oldInstanceContext);
                } catch (ResourceException e) {
                    throw new RuntimeException(e);
                } finally {
                    RootContext.setComponentContext(oldComponentContext);
                }
                //TODO should we reset the transactioncontext to null if we set it?
            }
        } finally {
            Thread.currentThread().setContextClassLoader(oldCL);
        }

        log.info("JettyWebAppContext started");
    }

    public void doStop() throws Exception {
        // merge Geronimo and Jetty Lifecycles
        if (!isStopping()) {
            super.stop();
            return;
        }

        ClassLoader oldCL = Thread.currentThread().getContextClassLoader();
        try {
            Thread.currentThread().setContextClassLoader(classLoader);
            ReadOnlyContext oldComponentContext = RootContext.getComponentContext();
            InstanceContext oldInstanceContext = null;
            try {
                RootContext.setComponentContext(componentContext);

                TransactionContext transactionContext = transactionContextManager.getContext();
                if (transactionContext == null) {
                    transactionContext = transactionContextManager.newUnspecifiedTransactionContext();
                } else {
                    transactionContext = null;
                }
                try {

                    try {
                        oldInstanceContext = trackedConnectionAssociator.enter(new DefaultInstanceContext(unshareableResources, applicationManagedSecurityResources));
                    } catch (ResourceException e) {
                        throw new RuntimeException(e);
                    }

                    while (true) {
                        try {
                            super.doStop();
                            break;
                        } catch (InterruptedException e) {
                            continue;
                        }
                    }
                } finally {
                    if (transactionContext != null) {
                        transactionContextManager.setContext(null);
                        try {
                            transactionContext.commit();
                        } catch (Exception e) {
                            //TODO this is undoubtedly the wrong error code!
                            throw (HttpException) new HttpException(500, "Problem committing unspecified transaction context").initCause(e);
                        }
                    }
                }
            } finally {
                try {
                    trackedConnectionAssociator.exit(oldInstanceContext);
                } catch (ResourceException e) {
                    throw new RuntimeException(e);
                } finally {
                    RootContext.setComponentContext(oldComponentContext);
                }
                //TODO should we reset the transactioncontext to null if we set it?
            }
            jettyContainer.removeContext(this);
        } finally {
            Thread.currentThread().setContextClassLoader(oldCL);
        }

        log.info("JettyWebAppContext stopped");
    }

    public void doFail() {
        try {
            super.stop();
        } catch (InterruptedException e) {
        }

        jettyContainer.removeContext(this);
        log.info("JettyWebAppContext failed");
    }

    public static final GBeanInfo GBEAN_INFO;

    static {
        GBeanInfoBuilder infoFactory = new GBeanInfoBuilder("Jetty WebApplication Context", JettyWebAppContext.class);

        infoFactory.addAttribute("uri", URI.class, true);
        infoFactory.addAttribute("componentContext", ReadOnlyContext.class, true);
        infoFactory.addAttribute("userTransaction", OnlineUserTransaction.class, true);
        infoFactory.addAttribute("classLoader", ClassLoader.class, false);
        infoFactory.addAttribute("webClassPath", URI[].class, true);
        infoFactory.addAttribute("contextPriorityClassLoader", boolean.class, true);
        infoFactory.addAttribute("configurationBaseUrl", URL.class, true);
        infoFactory.addAttribute("unshareableResources", Set.class, true);
        infoFactory.addAttribute("applicationManagedSecurityResources", Set.class, true);

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

        infoFactory.addReference("TransactionContextManager", TransactionContextManager.class);
        infoFactory.addReference("TrackedConnectionAssociator", TrackedConnectionAssociator.class);
        infoFactory.addReference("JettyContainer", JettyContainer.class);

        infoFactory.setConstructor(new String[]{
            "uri",
            "componentContext",
            "userTransaction",
            "classLoader",
            "webClassPath",
            "contextPriorityClassLoader",
            "configurationBaseUrl",
            "unshareableResources",
            "applicationManagedSecurityResources",
            "TransactionContextManager",
            "TrackedConnectionAssociator",
            "JettyContainer",
        });

        GBEAN_INFO = infoFactory.getBeanInfo();
    }

    public static GBeanInfo getGBeanInfo() {
        return GBEAN_INFO;
    }
}
TOP

Related Classes of org.apache.geronimo.jetty.JettyWebAppContext

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.