You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by da...@apache.org on 2008/03/03 21:39:21 UTC

svn commit: r633268 [2/4] - in /openejb/trunk/openejb3: assembly/openejb-tomcat/ assembly/openejb-tomcat/openejb-tomcat-catalina/ assembly/openejb-tomcat/openejb-tomcat-catalina/src/ assembly/openejb-tomcat/openejb-tomcat-catalina/src/main/ assembly/op...

Added: openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-catalina/src/main/java/org/apache/openejb/tomcat/catalina/TomcatJndiBuilder.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-catalina/src/main/java/org/apache/openejb/tomcat/catalina/TomcatJndiBuilder.java?rev=633268&view=auto
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-catalina/src/main/java/org/apache/openejb/tomcat/catalina/TomcatJndiBuilder.java (added)
+++ openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-catalina/src/main/java/org/apache/openejb/tomcat/catalina/TomcatJndiBuilder.java Mon Mar  3 12:39:06 2008
@@ -0,0 +1,564 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.openejb.tomcat.catalina;
+
+import org.apache.catalina.core.NamingContextListener;
+import org.apache.catalina.core.StandardContext;
+import org.apache.catalina.deploy.ContextEjb;
+import org.apache.catalina.deploy.ContextEnvironment;
+import org.apache.catalina.deploy.ContextResource;
+import org.apache.catalina.deploy.ContextResourceEnvRef;
+import org.apache.catalina.deploy.ContextTransaction;
+import org.apache.catalina.deploy.NamingResources;
+import org.apache.naming.ContextAccessController;
+import org.apache.naming.factory.Constants;
+import org.apache.openejb.Injection;
+import org.apache.openejb.OpenEJBException;
+import org.apache.openejb.spi.ContainerSystem;
+import org.apache.openejb.assembler.classic.EjbLocalReferenceInfo;
+import org.apache.openejb.assembler.classic.EjbReferenceInfo;
+import org.apache.openejb.assembler.classic.EnvEntryInfo;
+import org.apache.openejb.assembler.classic.PersistenceContextReferenceInfo;
+import org.apache.openejb.assembler.classic.PersistenceUnitReferenceInfo;
+import org.apache.openejb.assembler.classic.PortRefInfo;
+import org.apache.openejb.assembler.classic.ResourceEnvReferenceInfo;
+import org.apache.openejb.assembler.classic.ResourceReferenceInfo;
+import org.apache.openejb.assembler.classic.ServiceReferenceInfo;
+import org.apache.openejb.assembler.classic.WebAppInfo;
+import org.apache.openejb.assembler.classic.WsBuilder;
+import org.apache.openejb.core.webservices.HandlerChainData;
+import org.apache.openejb.core.webservices.PortRefData;
+import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.persistence.JtaEntityManager;
+import org.apache.openejb.persistence.JtaEntityManagerRegistry;
+import static org.apache.openejb.tomcat.common.NamingUtil.DEPLOYMENT_ID;
+import static org.apache.openejb.tomcat.common.NamingUtil.EXTENDED;
+import static org.apache.openejb.tomcat.common.NamingUtil.EXTERNAL;
+import static org.apache.openejb.tomcat.common.NamingUtil.JNDI_NAME;
+import static org.apache.openejb.tomcat.common.NamingUtil.JNDI_PROVIDER_ID;
+import static org.apache.openejb.tomcat.common.NamingUtil.LOCAL;
+import static org.apache.openejb.tomcat.common.NamingUtil.NAME;
+import static org.apache.openejb.tomcat.common.NamingUtil.RESOURCE_ID;
+import static org.apache.openejb.tomcat.common.NamingUtil.UNIT;
+import static org.apache.openejb.tomcat.common.NamingUtil.WSDL_URL;
+import static org.apache.openejb.tomcat.common.NamingUtil.WS_CLASS;
+import static org.apache.openejb.tomcat.common.NamingUtil.WS_ID;
+import static org.apache.openejb.tomcat.common.NamingUtil.WS_PORT_QNAME;
+import static org.apache.openejb.tomcat.common.NamingUtil.WS_QNAME;
+import static org.apache.openejb.tomcat.common.NamingUtil.setStaticValue;
+import org.apache.openejb.tomcat.common.EjbFactory;
+import org.apache.openejb.tomcat.common.WsFactory;
+import org.apache.openejb.tomcat.common.ResourceFactory;
+import org.apache.openejb.tomcat.common.PersistenceUnitFactory;
+import org.apache.openejb.tomcat.common.PersistenceContextFactory;
+import org.apache.openejb.tomcat.common.UserTransactionFactory;
+import org.apache.openejb.tomcat.common.NamingUtil;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.transaction.UserTransaction;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+public class TomcatJndiBuilder {
+    private final StandardContext standardContext;
+    private final WebAppInfo webAppInfo;
+    private final List<Injection> injections;
+    private final boolean replaceEntry;
+    private boolean useCrossClassLoaderRef = true;
+    private NamingContextListener namingContextListener;
+
+    public TomcatJndiBuilder(StandardContext standardContext, WebAppInfo webAppInfo, List<Injection> injections) {
+        this.injections = injections;
+        this.standardContext = standardContext;
+        this.namingContextListener = BackportUtil.getNamingContextListener(standardContext);
+        this.webAppInfo = webAppInfo;
+
+        String parameter = standardContext.findParameter("openejb.start.late");
+        replaceEntry = Boolean.parseBoolean(parameter);
+    }
+
+    public boolean isUseCrossClassLoaderRef() {
+        return useCrossClassLoaderRef;
+    }
+
+    public void setUseCrossClassLoaderRef(boolean useCrossClassLoaderRef) {
+        this.useCrossClassLoaderRef = useCrossClassLoaderRef;
+    }
+
+    public void mergeJndi() throws OpenEJBException {
+
+        NamingResources naming = standardContext.getNamingResources();
+
+        URI moduleUri;
+        try {
+            moduleUri = new URI(webAppInfo.moduleId);
+        } catch (URISyntaxException e) {
+            throw new OpenEJBException(e);
+        }
+
+        for (EnvEntryInfo ref : webAppInfo.jndiEnc.envEntries) {
+            mergeRef(naming, ref);
+        }
+        for (EjbReferenceInfo ref : webAppInfo.jndiEnc.ejbReferences) {
+            mergeRef(naming, ref);
+        }
+        for (EjbLocalReferenceInfo ref : webAppInfo.jndiEnc.ejbLocalReferences) {
+            mergeRef(naming, ref);
+        }
+        for (PersistenceContextReferenceInfo ref : webAppInfo.jndiEnc.persistenceContextRefs) {
+            mergeRef(naming, ref, moduleUri);
+        }
+        for (PersistenceUnitReferenceInfo ref : webAppInfo.jndiEnc.persistenceUnitRefs) {
+            mergeRef(naming, ref, moduleUri);
+        }
+        for (ResourceReferenceInfo ref : webAppInfo.jndiEnc.resourceRefs) {
+            mergeRef(naming, ref);
+        }
+        for (ResourceEnvReferenceInfo ref : webAppInfo.jndiEnc.resourceEnvRefs) {
+            mergeRef(naming, ref);
+        }
+        for (ServiceReferenceInfo ref : webAppInfo.jndiEnc.serviceRefs) {
+            mergeRef(naming, ref);
+        }
+        ContextTransaction contextTransaction = new ContextTransaction();
+        contextTransaction.setProperty(Constants.FACTORY, UserTransactionFactory.class.getName());
+        naming.setTransaction(contextTransaction);
+    }
+
+    public void mergeRef(NamingResources naming, EnvEntryInfo ref) {
+        ContextEnvironment environment = naming.findEnvironment(ref.name);
+        boolean addEntry = false;
+        if (environment == null) {
+            environment = new ContextEnvironment();
+            environment.setName(ref.name);
+            addEntry = true;
+        }
+
+        environment.setType(ref.type);
+        environment.setValue(ref.value);
+
+        if (addEntry) {
+            naming.addEnvironment(environment);
+        }
+
+        if (replaceEntry) {
+            ContextAccessController.setWritable(namingContextListener.getName(), standardContext);
+            if (!addEntry) namingContextListener.removeEnvironment(environment.getName());
+            namingContextListener.addEnvironment(environment);
+            ContextAccessController.setReadOnly(namingContextListener.getName());
+        }
+    }
+
+    public void mergeRef(NamingResources naming, EjbReferenceInfo ref) {
+        ContextEjb ejb = naming.findEjb(ref.referenceName);
+        boolean addEntry = false;
+        if (ejb == null) {
+            ejb = new ContextEjb();
+            ejb.setName(ref.referenceName);
+            addEntry = true;
+        }
+
+        ejb.setProperty(Constants.FACTORY, EjbFactory.class.getName());
+        ejb.setProperty(NAME, ref.referenceName);
+        ejb.setHome(ref.homeType);
+        ejb.setRemote(ref.interfaceType);
+        ejb.setLink(null);
+        ejb.setType(ref.interfaceType);
+        if (useCrossClassLoaderRef) {
+            ejb.setProperty(EXTERNAL, "" + ref.externalReference);
+        }
+
+        if (ref.ejbDeploymentId != null) {
+            ejb.setProperty(DEPLOYMENT_ID, ref.ejbDeploymentId);
+        }
+
+        if (ref.location != null) {
+            ejb.setProperty(JNDI_NAME, ref.location.jndiName);
+            ejb.setProperty(JNDI_PROVIDER_ID, ref.location.jndiProviderId);
+        }
+
+        if (addEntry) {
+            naming.addEjb(ejb);
+        }
+
+        if (replaceEntry) {
+            ContextAccessController.setWritable(namingContextListener.getName(), standardContext);
+            if (!addEntry) namingContextListener.removeEjb(ejb.getName());
+            namingContextListener.addEjb(ejb);
+            ContextAccessController.setReadOnly(namingContextListener.getName());
+        }
+    }
+
+    public void mergeRef(NamingResources naming, EjbLocalReferenceInfo ref) {
+        // NamingContextListener.addLocalEjb is empty so we'll just use an ejb ref
+        ContextEjb ejb = naming.findEjb(ref.referenceName);
+        boolean addEntry = false;
+        if (ejb == null) {
+            ejb = new ContextEjb();
+            ejb.setName(ref.referenceName);
+            addEntry = true;
+        }
+
+        ejb.setProperty(Constants.FACTORY, EjbFactory.class.getName());
+        ejb.setProperty(NAME, ref.referenceName);
+        ejb.setHome(ref.homeType);
+        ejb.setRemote(null);
+        ejb.setProperty(LOCAL, ref.interfaceType);
+        ejb.setLink(null);
+        ejb.setType(ref.interfaceType);
+
+        if (ref.ejbDeploymentId != null) {
+            ejb.setProperty(DEPLOYMENT_ID, ref.ejbDeploymentId);
+        }
+
+        if (ref.location != null) {
+            ejb.setProperty(JNDI_NAME, ref.location.jndiName);
+            ejb.setProperty(JNDI_PROVIDER_ID, ref.location.jndiProviderId);
+        }
+
+        if (addEntry) {
+            naming.addEjb(ejb);
+        }
+
+        if (replaceEntry) {
+            ContextAccessController.setWritable(namingContextListener.getName(), standardContext);
+            if (!addEntry) namingContextListener.removeEjb(ejb.getName());
+            namingContextListener.addEjb(ejb);
+            ContextAccessController.setReadOnly(namingContextListener.getName());
+        }
+    }
+
+    @SuppressWarnings({"UnusedDeclaration"})
+    public void mergeRef(NamingResources naming, PersistenceContextReferenceInfo ref, URI moduleUri) {
+        ContextResource resource = naming.findResource(ref.referenceName);
+        boolean addEntry = false;
+        if (resource == null) {
+            resource = new ContextResource();
+            resource.setName(ref.referenceName);
+            addEntry = true;
+        }
+
+        resource.setProperty(Constants.FACTORY, PersistenceContextFactory.class.getName());
+        resource.setProperty(NAME, ref.referenceName);
+        resource.setType(EntityManager.class.getName());
+
+        if (ref.persistenceUnitName != null) {
+            resource.setProperty(UNIT, ref.persistenceUnitName);
+        }
+        resource.setProperty(EXTENDED, "" + ref.extended);
+        if (ref.properties != null) {
+            // resource.setProperty(NamingConstants.PROPERTIES, ref.properties);
+        }
+
+        if (ref.location != null) {
+            resource.setProperty(JNDI_NAME, ref.location.jndiName);
+            resource.setProperty(JNDI_PROVIDER_ID, ref.location.jndiProviderId);
+        } else {
+            Context context = SystemInstance.get().getComponent(ContainerSystem.class).getJNDIContext();
+            EntityManagerFactory factory;
+            try {
+                factory = (EntityManagerFactory) context.lookup("openejb/PersistenceUnit/" + ref.unitId);
+            } catch (NamingException e) {
+                throw new IllegalStateException("PersistenceUnit '" + ref.unitId + "' not found for EXTENDED ref '" + ref.referenceName + "'");
+            }
+
+            JtaEntityManagerRegistry jtaEntityManagerRegistry = SystemInstance.get().getComponent(JtaEntityManagerRegistry.class);
+            JtaEntityManager jtaEntityManager = new JtaEntityManager(jtaEntityManagerRegistry, factory, ref.properties, ref.extended);
+            Object object = jtaEntityManager;
+            setResource(resource, object);
+        }
+
+        if (addEntry) {
+            naming.addResource(resource);
+        }
+
+        if (replaceEntry) {
+            ContextAccessController.setWritable(namingContextListener.getName(), standardContext);
+            if (!addEntry) namingContextListener.removeResource(resource.getName());
+            namingContextListener.addResource(resource);
+            ContextAccessController.setReadOnly(namingContextListener.getName());
+        }
+    }
+
+    @SuppressWarnings({"UnusedDeclaration"})
+    public void mergeRef(NamingResources naming, PersistenceUnitReferenceInfo ref, URI moduleUri) {
+        ContextResource resource = naming.findResource(ref.referenceName);
+        boolean addEntry = false;
+        if (resource == null) {
+            resource = new ContextResource();
+            resource.setName(ref.referenceName);
+            addEntry = true;
+        }
+
+        resource.setProperty(Constants.FACTORY, PersistenceUnitFactory.class.getName());
+        resource.setProperty(NAME, ref.referenceName);
+        resource.setType(EntityManagerFactory.class.getName());
+
+        if (ref.persistenceUnitName != null) {
+            resource.setProperty(UNIT, ref.persistenceUnitName);
+        }
+
+        if (ref.location != null) {
+            resource.setProperty(JNDI_NAME, ref.location.jndiName);
+            resource.setProperty(JNDI_PROVIDER_ID, ref.location.jndiProviderId);
+        } else {
+            // TODO: This will not work if webapps don't use AutoConfi
+            Context context = SystemInstance.get().getComponent(ContainerSystem.class).getJNDIContext();
+            EntityManagerFactory factory;
+            try {
+                factory = (EntityManagerFactory) context.lookup("openejb/PersistenceUnit/" + ref.unitId);
+            } catch (NamingException e) {
+                throw new IllegalStateException("PersistenceUnit '" + ref.unitId + "' not found for EXTENDED ref '" + ref.referenceName + "'");
+            }
+            setResource(resource, factory);
+        }
+
+        if (addEntry) {
+            naming.addResource(resource);
+        }
+
+        if (replaceEntry) {
+            ContextAccessController.setWritable(namingContextListener.getName(), standardContext);
+            if (!addEntry) namingContextListener.removeResource(resource.getName());
+            namingContextListener.addResource(resource);
+            ContextAccessController.setReadOnly(namingContextListener.getName());
+        }
+    }
+
+    public void mergeRef(NamingResources naming, ResourceReferenceInfo ref) {
+        ContextResource resource = naming.findResource(ref.referenceName);
+        boolean addEntry = false;
+        if (resource == null) {
+            resource = new ContextResource();
+            resource.setName(ref.referenceName);
+            addEntry = true;
+        }
+
+        resource.setProperty(Constants.FACTORY, ResourceFactory.class.getName());
+        resource.setProperty(NAME, ref.referenceName);
+        resource.setType(ref.referenceType);
+        resource.setAuth(ref.referenceAuth);
+
+        if (ref.resourceID != null) {
+            resource.setProperty(RESOURCE_ID, ref.resourceID);
+        }
+
+        if (ref.properties != null) {
+            // resource.setProperty(NamingConstants.PROPERTIES, ref.properties);
+        }
+
+        if (ref.location != null) {
+            resource.setProperty(JNDI_NAME, ref.location.jndiName);
+            resource.setProperty(JNDI_PROVIDER_ID, ref.location.jndiProviderId);
+        }
+
+        if (addEntry) {
+            naming.addResource(resource);
+        }
+
+        if (replaceEntry) {
+            ContextAccessController.setWritable(namingContextListener.getName(), standardContext);
+            if (!addEntry) namingContextListener.removeResource(resource.getName());
+            namingContextListener.addResource(resource);
+            ContextAccessController.setReadOnly(namingContextListener.getName());
+        }
+    }
+
+    public void mergeRef(NamingResources naming, ResourceEnvReferenceInfo ref) {
+        ContextResourceEnvRef resourceEnv = naming.findResourceEnvRef(ref.resourceEnvRefName);
+        boolean addEntry = false;
+        if (resourceEnv == null) {
+            resourceEnv = new ContextResourceEnvRef();
+            resourceEnv.setName(ref.resourceEnvRefName);
+            addEntry = true;
+        }
+
+        if (UserTransaction.class.getName().equals(ref.resourceEnvRefType)) {
+            resourceEnv.setProperty(Constants.FACTORY, UserTransactionFactory.class.getName());
+        } else {
+            resourceEnv.setProperty(Constants.FACTORY, ResourceFactory.class.getName());
+            resourceEnv.setProperty(NAME, ref.resourceEnvRefName);
+            resourceEnv.setType(ref.resourceEnvRefType);
+
+            if (ref.resourceID != null) {
+                resourceEnv.setProperty(RESOURCE_ID, ref.resourceID);
+            }
+
+            if (ref.location != null) {
+                resourceEnv.setProperty(JNDI_NAME, ref.location.jndiName);
+                resourceEnv.setProperty(JNDI_PROVIDER_ID, ref.location.jndiProviderId);
+            }
+        }
+
+        if (addEntry) {
+            naming.addResourceEnvRef(resourceEnv);
+        }
+
+        if (replaceEntry) {
+            ContextAccessController.setWritable(namingContextListener.getName(), standardContext);
+            if (!addEntry) namingContextListener.removeResourceEnvRef(resourceEnv.getName());
+            namingContextListener.addResourceEnvRef(resourceEnv);
+            ContextAccessController.setReadOnly(namingContextListener.getName());
+        }
+    }
+
+    public void mergeRef(NamingResources naming, ServiceReferenceInfo ref) {
+        ContextResource resource = naming.findResource(ref.referenceName);
+        boolean addEntry = false;
+        if (resource == null) {
+            resource = new ContextResource();
+            resource.setName(ref.referenceName);
+            addEntry = true;
+        }
+
+        resource.setProperty(Constants.FACTORY, WsFactory.class.getName());
+        resource.setProperty(NAME, ref.referenceName);
+        if (ref.referenceType != null) {
+            resource.setType(ref.referenceType);
+        } else {
+            resource.setType(ref.serviceType);
+        }
+
+        if (ref.location != null) {
+            resource.setProperty(JNDI_NAME, ref.location.jndiName);
+            resource.setProperty(JNDI_PROVIDER_ID, ref.location.jndiProviderId);
+        } else {
+            // ID
+            if (ref.id != null) {
+                resource.setProperty(WS_ID, ref.id);
+            }
+            // Service QName
+            if (ref.serviceQName != null) {
+                resource.setProperty(WS_QNAME, ref.serviceQName.toString());
+            }
+            // Service Class
+            resource.setProperty(WS_CLASS, ref.serviceType);
+
+            // Port QName
+            if (ref.portQName != null) {
+                resource.setProperty(WS_PORT_QNAME, ref.portQName.toString());
+            }
+
+            // add the wsdl url
+            URL wsdlURL = getWsdlUrl(ref);
+            if (wsdlURL != null) {
+                resource.setProperty(WSDL_URL, wsdlURL.toString());
+            }
+
+            // add port refs
+            if (!ref.portRefs.isEmpty()) {
+                List<PortRefData> portRefs = new ArrayList<PortRefData>(ref.portRefs.size());
+                for (PortRefInfo portRefInfo : ref.portRefs) {
+                    PortRefData portRef = new PortRefData();
+                    portRef.setQName(portRefInfo.qname);
+                    portRef.setServiceEndpointInterface(portRefInfo.serviceEndpointInterface);
+                    portRef.setEnableMtom(portRefInfo.enableMtom);
+                    portRef.getProperties().putAll(portRefInfo.properties);
+                    portRefs.add(portRef);
+                }
+                setResource(resource, "port-refs", portRefs);
+            }
+
+            // add the handle chains
+            if (!ref.handlerChains.isEmpty()) {
+                try {
+                    List<HandlerChainData> handlerChains = WsBuilder.toHandlerChainData(ref.handlerChains, standardContext.getLoader().getClassLoader());
+                    setResource(resource, "handler-chains", handlerChains);
+                    setResource(resource, "injections", injections);
+                } catch (OpenEJBException e) {
+                    throw new IllegalArgumentException("Error creating handler chain for web service-ref " + ref.referenceName);
+                }
+            }
+        }
+
+        // if there was a service entry, remove it
+        String serviceName = BackportUtil.findServiceName(naming, ref.referenceName);
+        if (serviceName != null) {
+            ContextAccessController.setWritable(namingContextListener.getName(), standardContext);
+            if (!addEntry) BackportUtil.removeService(namingContextListener, serviceName);
+            ContextAccessController.setReadOnly(namingContextListener.getName());
+        }
+
+        // add the new resource entry
+        if (addEntry) {
+            naming.addResource(resource);
+        }
+
+        // or replace the exisitng resource entry
+        if (replaceEntry) {
+            ContextAccessController.setWritable(namingContextListener.getName(), standardContext);
+            if (!addEntry) namingContextListener.removeResource(resource.getName());
+            namingContextListener.addResource(resource);
+            ContextAccessController.setReadOnly(namingContextListener.getName());
+        }
+    }
+
+    private URL getWsdlUrl(ServiceReferenceInfo ref) {
+        if (ref.wsdlFile == null) return null;
+
+        URL wsdlUrl = null;
+        try {
+            wsdlUrl = new URL(ref.wsdlFile);
+        } catch (MalformedURLException e) {
+        }
+
+        if (wsdlUrl == null) {
+            wsdlUrl = standardContext.getLoader().getClassLoader().getResource(ref.wsdlFile);
+        }
+
+        if (wsdlUrl == null) {
+            try {
+                wsdlUrl = standardContext.getServletContext().getResource("/" + ref.wsdlFile);
+            } catch (MalformedURLException e) {
+            }
+        }
+
+        if (wsdlUrl == null ) {
+            throw new IllegalArgumentException("WSDL file " + ref.wsdlFile + " for web service-ref " + ref.referenceName + " not found");
+        }
+
+        return wsdlUrl;
+    }
+
+    private void setResource(ContextResource resource, String name, Object object) {
+        setStaticValue(new Resource(resource), name, object);
+    }
+
+    private void setResource(ContextResource resource, Object object) {
+        setStaticValue(new Resource(resource), object);
+    }
+
+    private static class Resource implements NamingUtil.Resource {
+        private final ContextResource contextResource;
+
+        public Resource(ContextResource contextResource) {
+            this.contextResource = contextResource;
+        }
+
+        public void setProperty(String name, Object value) {
+            contextResource.setProperty(name, value);
+        }
+    }
+}

Added: openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-catalina/src/main/java/org/apache/openejb/tomcat/catalina/TomcatJndiSupport.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-catalina/src/main/java/org/apache/openejb/tomcat/catalina/TomcatJndiSupport.java?rev=633268&view=auto
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-catalina/src/main/java/org/apache/openejb/tomcat/catalina/TomcatJndiSupport.java (added)
+++ openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-catalina/src/main/java/org/apache/openejb/tomcat/catalina/TomcatJndiSupport.java Mon Mar  3 12:39:06 2008
@@ -0,0 +1,123 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.openejb.tomcat.catalina;
+
+import org.apache.openejb.OpenEJBException;
+import org.apache.openejb.RpcContainer;
+import org.apache.openejb.DeploymentInfo;
+import org.apache.openejb.core.RpcContainerWrapper;
+import org.apache.openejb.core.CoreDeploymentInfo;
+
+import javax.naming.Context;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+public class TomcatJndiSupport extends RpcContainerWrapper {
+    private final Method bindContext;
+    private final Method bindThread;
+    private final Method unbindThread;
+
+    public TomcatJndiSupport(RpcContainer container) throws OpenEJBException {
+        super(container);
+        try {
+            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+            Class contextBindings = classLoader.loadClass("org.apache.naming.ContextBindings");
+            bindContext = contextBindings.getMethod("bindContext", Object.class, Context.class, Object.class);
+            bindThread = contextBindings.getMethod("bindThread", Object.class, Object.class);
+            unbindThread = contextBindings.getMethod("unbindThread", Object.class, Object.class);
+        } catch (ClassNotFoundException e) {
+            throw new OpenEJBException("Unable to setup Tomcat JNDI support.  Support requires the org.apache.naming.ContextBindings class to be available.");
+        } catch (NoSuchMethodException e) {
+            throw new OpenEJBException("Unable to setup Tomcat JNDI support.  Method of org.apache.naming.ContextBindings was not found:" + e.getMessage());
+        }
+        DeploymentInfo[] deploymentInfos = container.deployments();
+        for (DeploymentInfo deploymentInfo : deploymentInfos) {
+            CoreDeploymentInfo deployment = (CoreDeploymentInfo) deploymentInfo;
+            setupDeployment(deployment);
+        }
+    }
+
+    @SuppressWarnings({"UnusedDeclaration"})
+    public void init(Object containerId, HashMap deployments, Properties properties) throws OpenEJBException {
+    }
+
+    public void deploy(DeploymentInfo info) throws OpenEJBException {
+        super.deploy(info);
+        setupDeployment((org.apache.openejb.core.CoreDeploymentInfo) info);
+    }
+
+    public static Map<Object,Context> contexts = new HashMap<Object,Context>();
+
+    private void setupDeployment(org.apache.openejb.core.CoreDeploymentInfo deployment) {
+
+        deployment.setContainer(this);
+
+        Object deploymentID = deployment.getDeploymentID();
+        Context jndiEnc = deployment.getJndiEnc();
+        bindContext(deploymentID, jndiEnc);
+        contexts.put(deploymentID, jndiEnc);
+    }
+
+    public Object invoke(Object deployID, Method callMethod, Object[] args, Object primKey, Object securityIdentity) throws OpenEJBException {
+        try {
+
+            bindThread(deployID);
+            return super.invoke(deployID, callMethod, args, primKey, securityIdentity);
+        } finally {
+            unbindThread(deployID);
+        }
+    }
+
+    public void bindContext(Object name, Context context) {
+        try {
+            bindContext.invoke(null, name, context, name);
+        } catch (Throwable e) {
+            throw convertToRuntimeException(e, "bindContext");
+        }
+    }
+
+    public void bindThread(Object name) {
+        try {
+            bindThread.invoke(null, name, name);
+        } catch (Throwable e) {
+            throw convertToRuntimeException(e, "bindThread");
+        }
+    }
+
+    public void unbindThread(Object name) {
+        try {
+            unbindThread.invoke(null, name, name);
+        } catch (Throwable e) {
+            throw convertToRuntimeException(e, "unbindThread");
+        }
+    }
+
+    private RuntimeException convertToRuntimeException(Throwable e, String methodName) {
+        if (e instanceof InvocationTargetException) {
+            Throwable cause = e.getCause();
+            if (cause instanceof RuntimeException) {
+                return (RuntimeException) cause;
+            } else {
+                e = cause;
+            }
+        }
+        return new RuntimeException("ContextBindings." + methodName, e);
+    }
+}

Added: openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-catalina/src/main/java/org/apache/openejb/tomcat/catalina/TomcatLoader.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-catalina/src/main/java/org/apache/openejb/tomcat/catalina/TomcatLoader.java?rev=633268&view=auto
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-catalina/src/main/java/org/apache/openejb/tomcat/catalina/TomcatLoader.java (added)
+++ openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-catalina/src/main/java/org/apache/openejb/tomcat/catalina/TomcatLoader.java Mon Mar  3 12:39:06 2008
@@ -0,0 +1,230 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.openejb.tomcat.catalina;
+
+import org.apache.catalina.Container;
+import org.apache.catalina.Engine;
+import org.apache.catalina.Host;
+import org.apache.catalina.Lifecycle;
+import org.apache.catalina.LifecycleEvent;
+import org.apache.catalina.LifecycleListener;
+import org.apache.catalina.ServerFactory;
+import org.apache.catalina.Service;
+import org.apache.catalina.core.StandardContext;
+import org.apache.catalina.core.StandardServer;
+import org.apache.openejb.OpenEJB;
+import org.apache.openejb.tomcat.installer.Installer;
+import org.apache.openejb.tomcat.installer.Paths;
+import org.apache.openejb.assembler.classic.WebAppBuilder;
+import org.apache.openejb.core.ServerFederation;
+import org.apache.openejb.core.ThreadContext;
+import org.apache.openejb.loader.Loader;
+import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.server.ServerService;
+import org.apache.openejb.server.ServiceException;
+import org.apache.openejb.server.ServiceManager;
+import org.apache.openejb.server.ejbd.EjbServer;
+import org.apache.openejb.server.webservices.WsRegistry;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+/**
+ * @version $Revision: 617255 $ $Date: 2008-01-31 13:58:36 -0800 (Thu, 31 Jan 2008) $
+ */
+public class TomcatLoader implements Loader {
+    private EjbServer ejbServer;
+    protected ServiceManager manager;
+
+    public void init(Properties properties) throws Exception {
+        // Loader maybe the first thing executed in a new classloader
+        // so we must attempt to initialize the system instance.
+        SystemInstance.init(properties);
+
+        installConfigFiles(properties);
+
+        // Not thread safe
+        if (OpenEJB.isInitialized()) {
+            ejbServer = SystemInstance.get().getComponent(EjbServer.class);
+            return;
+        }
+
+        // Read in and apply the conf/system.properties
+        try {
+            File conf = SystemInstance.get().getBase().getDirectory("conf");
+            File file = new File(conf, "system.properties");
+            if (file.exists()){
+                Properties systemProperties = new Properties();
+                FileInputStream fin = new FileInputStream(file);
+                InputStream in = new BufferedInputStream(fin);
+                systemProperties.load(in);
+                System.getProperties().putAll(systemProperties);
+            }
+        } catch (IOException e) {
+            System.out.println("Processing conf/system.properties failed: "+e.getMessage());
+        }
+
+
+        // initialize system instance before doing anything
+        System.setProperty("openejb.deployments.classpath", "true");
+        System.setProperty("openejb.deployments.classpath.filter.systemapps", "false");
+        System.setProperty("openejb.provider.default", "org.apache.openejb.tomcat");
+        SystemInstance.init(properties);
+
+        System.setProperty("openejb.home", SystemInstance.get().getHome().getDirectory().getAbsolutePath());
+        System.setProperty("openejb.base", SystemInstance.get().getBase().getDirectory().getAbsolutePath());
+
+        // Install tomcat thread context listener
+        ThreadContext.addThreadContextListener(new TomcatThreadContextListener());
+
+        // Install tomcat war builder
+        TomcatWebAppBuilder tomcatWebAppBuilder = (TomcatWebAppBuilder) SystemInstance.get().getComponent(WebAppBuilder.class);
+        if (tomcatWebAppBuilder == null) {
+            tomcatWebAppBuilder = new TomcatWebAppBuilder();
+            tomcatWebAppBuilder.start();
+            SystemInstance.get().setComponent(WebAppBuilder.class, tomcatWebAppBuilder);
+        }
+
+        // Install the Tomcat webservice registry
+        TomcatWsRegistry tomcatSoapHandler = (TomcatWsRegistry) SystemInstance.get().getComponent(WsRegistry.class);
+        if (tomcatSoapHandler == null) {
+            tomcatSoapHandler = new TomcatWsRegistry();
+            SystemInstance.get().setComponent(WsRegistry.class, tomcatSoapHandler);
+        }
+
+        // Start OpenEJB
+        ejbServer = new EjbServer();
+        SystemInstance.get().setComponent(EjbServer.class, ejbServer);
+        OpenEJB.init(properties, new ServerFederation());
+        
+        Properties ejbServerProps = new Properties();
+        ejbServerProps.putAll(properties);
+        ejbServerProps.setProperty("openejb.ejbd.uri", "http://127.0.0.1:8080/openejb/ejb");
+        ejbServer.init(ejbServerProps);
+
+        // Add our naming context listener to the server which registers all Tomcat resources with OpenEJB
+        StandardServer standardServer = (StandardServer) ServerFactory.getServer();
+        OpenEJBNamingContextListener namingContextListener = new OpenEJBNamingContextListener(standardServer);
+        // Standard server has no state property, so we check global naming context to determine if server is started yet
+        if (standardServer.getGlobalNamingContext() != null) {
+            namingContextListener.start();
+        }
+        standardServer.addLifecycleListener(namingContextListener);
+
+        // Process all applications already started.  This deploys EJBs, PersistenceUnits
+        // and modifies JNDI ENC references to OpenEJB managed objects such as EJBs.
+        processRunningApplications(tomcatWebAppBuilder, standardServer);
+
+        if (Boolean.getBoolean("openejb.servicemanager.enabled")) {
+            manager = ServiceManager.getManager();
+            manager.init();
+            manager.start(false);
+        } else {
+            try {
+                ServerService serverService = (ServerService) Class.forName("org.apache.openejb.server.cxf.CxfService").newInstance();
+                serverService.start();
+            } catch (Exception ignored) {
+            }
+        }
+
+        standardServer.addLifecycleListener(new LifecycleListener() {
+            public void lifecycleEvent(LifecycleEvent event) {
+                String type = event.getType();
+                if (Lifecycle.AFTER_STOP_EVENT.equals(type)) {
+                    TomcatLoader.this.destroy();
+                }
+            }
+        });
+
+        Runtime.getRuntime().addShutdownHook(new Thread() {
+            public void run() {
+                TomcatLoader.this.destroy();
+            }
+        });
+    }
+
+    public void destroy() {
+        if (manager != null) {
+            try {
+                manager.stop();
+            } catch (ServiceException e) {
+            }
+            manager = null;
+        }
+        if (ejbServer != null) {
+            try {
+                ejbServer.stop();
+            } catch (ServiceException e) {
+            }
+            ejbServer = null;
+        }
+        OpenEJB.destroy();
+    }
+
+    private void installConfigFiles(Properties properties) {
+        String openejbWarDir = properties.getProperty("openejb.war");
+        if (openejbWarDir == null) return;
+
+        Paths paths = new Paths(new File(openejbWarDir));
+        if (paths.verify()) {
+            Installer installer = new Installer(paths);
+            installer.installConfigFiles();
+        }
+    }
+
+    private void processRunningApplications(TomcatWebAppBuilder tomcatWebAppBuilder, StandardServer standardServer) {
+        for (Service service : standardServer.findServices()) {
+            if (service.getContainer() instanceof Engine) {
+                Engine engine = (Engine) service.getContainer();
+                for (Container engineChild : engine.findChildren()) {
+                    if (engineChild instanceof Host) {
+                        Host host = (Host) engineChild;
+                        for (Container hostChild : host.findChildren()) {
+                            if (hostChild instanceof StandardContext) {
+                                StandardContext standardContext = (StandardContext) hostChild;
+                                int state = standardContext.getState();
+                                if (state == 0) {
+                                    // context only initialized
+                                    tomcatWebAppBuilder.init(standardContext);
+                                } else if (state == 1) {
+                                    // context already started
+                                    standardContext.addParameter("openejb.start.late", "true");
+                                    ClassLoader oldCL = Thread.currentThread().getContextClassLoader();
+                                    Thread.currentThread().setContextClassLoader(standardContext.getLoader().getClassLoader());
+                                    try {
+                                        tomcatWebAppBuilder.init(standardContext);
+                                        tomcatWebAppBuilder.beforeStart(standardContext);
+                                        tomcatWebAppBuilder.start(standardContext);
+                                        tomcatWebAppBuilder.afterStart(standardContext);
+                                    } finally {
+                                        Thread.currentThread().setContextClassLoader(oldCL);
+                                    }
+                                    standardContext.removeParameter("openejb.start.late");
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}

Added: openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-catalina/src/main/java/org/apache/openejb/tomcat/catalina/TomcatSecurityService.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-catalina/src/main/java/org/apache/openejb/tomcat/catalina/TomcatSecurityService.java?rev=633268&view=auto
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-catalina/src/main/java/org/apache/openejb/tomcat/catalina/TomcatSecurityService.java (added)
+++ openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-catalina/src/main/java/org/apache/openejb/tomcat/catalina/TomcatSecurityService.java Mon Mar  3 12:39:06 2008
@@ -0,0 +1,239 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.openejb.tomcat.catalina;
+
+import org.apache.catalina.Realm;
+import org.apache.catalina.Service;
+import org.apache.catalina.Engine;
+import org.apache.catalina.ServerFactory;
+import org.apache.catalina.Server;
+import org.apache.openejb.core.security.AbstractSecurityService;
+import org.apache.openejb.core.CoreDeploymentInfo;
+
+import javax.security.auth.Subject;
+import javax.security.auth.login.LoginException;
+import java.security.Principal;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.LinkedList;
+import java.util.UUID;
+
+public class TomcatSecurityService  extends AbstractSecurityService {
+    static protected final ThreadLocal<LinkedList<Subject>> runAsStack = new ThreadLocal<LinkedList<Subject>>() {
+        protected LinkedList<Subject> initialValue() {
+            return new LinkedList<Subject>();
+        }
+    };
+
+    private Realm defaultRealm;
+
+    public TomcatSecurityService() {
+        Server server = ServerFactory.getServer();
+        for (Service service : server.findServices()) {
+            if (service.getContainer() instanceof Engine) {
+                Engine engine = (Engine) service.getContainer();
+                if (engine.getRealm() != null) {
+                    defaultRealm = engine.getRealm();
+                    break;
+                }
+            }
+        }
+    }
+
+    public UUID login(String realmName, String username, String password) throws LoginException {
+        if (defaultRealm == null) {
+            throw new LoginException("No Tomcat realm available");
+        }
+
+        Principal principal = defaultRealm.authenticate(username, password);
+        Subject subject = createSubject(defaultRealm, principal);
+        UUID token = registerSubject(subject);
+        return token;
+    }
+
+    private Subject createSubject(Realm realm, Principal principal) {
+        TomcatUser tomcatUser = new TomcatUser(realm, principal);
+
+        HashSet<Principal> principals = new HashSet<Principal>();
+        principals.add(tomcatUser);
+
+        Subject subject = new Subject(true, principals, new HashSet(), new HashSet());
+        return subject;
+    }
+
+    public Set<String> getLogicalRoles(Principal[] principals, Set<String> logicalRoles) {
+        LinkedHashSet<String> roles = new LinkedHashSet<String>(logicalRoles.size());
+        for (String logicalRole : logicalRoles) {
+            for (Principal principal : principals) {
+                if (principal instanceof TomcatUser) {
+                    TomcatUser user = (TomcatUser) principal;
+                    if (user.getRealm().hasRole(user.getTomcatPrincipal(), logicalRole)) {
+                        roles.add(logicalRole);
+                        break;
+                    }
+                } else if (principal instanceof RunAsRole) {
+                    RunAsRole runAsRole = (RunAsRole) principal;
+                    String name = runAsRole.getName();
+                    if (logicalRole.equals(name)) {
+                        roles.add(logicalRole);
+                    }
+                }
+            }
+        }
+        return roles;
+    }
+
+    public Object enterWebApp(Realm realm, Principal principal, String runAs) {
+        Identity newIdentity = null;
+        if (principal != null) {
+            Subject newSubject = createSubject(realm, principal);
+            newIdentity = new Identity(newSubject, null);
+        }
+
+        Identity oldIdentity = clientIdentity.get();
+        WebAppState webAppState = new WebAppState(oldIdentity, runAs != null);
+        clientIdentity.set(newIdentity);
+
+        if (runAs != null) {
+            Subject runAsSubject = createRunAsSubject(runAs);
+            runAsStack.get().addFirst(runAsSubject);
+        }
+
+        return webAppState;
+    }
+
+    public void exitWebApp(Object state) {
+        if (state instanceof WebAppState) {
+            WebAppState webAppState = (WebAppState) state;
+            clientIdentity.set(webAppState.oldIdentity);
+            if (webAppState.hadRunAs) {
+                runAsStack.get().removeFirst();
+            }
+        }
+    }
+
+    protected Subject getRunAsSubject(CoreDeploymentInfo callingDeploymentInfo) {
+        Subject runAsSubject = super.getRunAsSubject(callingDeploymentInfo);
+        if (runAsSubject != null) return runAsSubject;
+
+        LinkedList<Subject> stack = runAsStack.get();
+        if (stack.isEmpty()) {
+            return null;
+        }
+        return stack.getFirst();
+    }
+
+
+    protected Subject createRunAsSubject(String role) {
+        if (role == null) return null;
+
+        RunAsRole runAsRole = new RunAsRole(role);
+
+        HashSet<Principal> principals = new HashSet<Principal>();
+        principals.add(runAsRole);
+
+        return new Subject(true, principals, new HashSet(), new HashSet());
+    }
+
+    protected static class TomcatUser implements Principal {
+        private final Realm realm;
+        private final Principal tomcatPrincipal;
+
+
+        public TomcatUser(Realm realm, Principal tomcatPrincipal) {
+            if (realm == null) throw new NullPointerException("realm is null");
+            if (tomcatPrincipal == null) throw new NullPointerException("tomcatPrincipal is null");
+            this.realm = realm;
+            this.tomcatPrincipal = tomcatPrincipal;
+        }
+
+        public Realm getRealm() {
+            return realm;
+        }
+
+        public Principal getTomcatPrincipal() {
+            return tomcatPrincipal;
+        }
+
+        public String getName() {
+            return tomcatPrincipal.getName();
+        }
+
+        public String toString() {
+            return "[TomcatUser: " + tomcatPrincipal + "]";
+        }
+
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            TomcatUser that = (TomcatUser) o;
+
+            return realm.equals(that.realm) && tomcatPrincipal.equals(that.tomcatPrincipal);
+        }
+
+        public int hashCode() {
+            int result;
+            result = realm.hashCode();
+            result = 31 * result + tomcatPrincipal.hashCode();
+            return result;
+        }
+    }
+
+    protected static class RunAsRole implements Principal {
+        private final String name;
+
+        public RunAsRole(String name) {
+            if (name == null) throw new NullPointerException("name is null");
+            this.name = name;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public String toString() {
+            return "[RunAsRole: " + name + "]";
+        }
+
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            RunAsRole runAsRole = (RunAsRole) o;
+
+            return name.equals(runAsRole.name);
+        }
+
+        public int hashCode() {
+            return name.hashCode();
+        }
+    }
+
+    private static class WebAppState {
+        private final Identity oldIdentity;
+        private final boolean hadRunAs;
+
+
+        public WebAppState(Identity oldIdentity, boolean hadRunAs) {
+            this.oldIdentity = oldIdentity;
+            this.hadRunAs = hadRunAs;
+        }
+    }
+}

Added: openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-catalina/src/main/java/org/apache/openejb/tomcat/catalina/TomcatThreadContextListener.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-catalina/src/main/java/org/apache/openejb/tomcat/catalina/TomcatThreadContextListener.java?rev=633268&view=auto
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-catalina/src/main/java/org/apache/openejb/tomcat/catalina/TomcatThreadContextListener.java (added)
+++ openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-catalina/src/main/java/org/apache/openejb/tomcat/catalina/TomcatThreadContextListener.java Mon Mar  3 12:39:06 2008
@@ -0,0 +1,94 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.openejb.tomcat.catalina;
+
+import org.apache.naming.ContextBindings;
+import org.apache.openejb.core.ThreadContext;
+import org.apache.openejb.core.ThreadContextListener;
+import org.apache.openejb.util.Logger;
+import org.apache.openejb.util.LogCategory;
+
+import javax.naming.NamingException;
+import java.lang.reflect.Method;
+
+public class TomcatThreadContextListener implements ThreadContextListener {
+    private static final Logger logger = Logger.getInstance(LogCategory.OPENEJB.createChild("tomcat"), "org.apache.openejb.util.resources");
+    private static final String OPENEJB_CONTEXT = "OpenEJBContext";
+    protected Method method;
+
+    public TomcatThreadContextListener() {
+        ContextBindings.bindContext(OPENEJB_CONTEXT, new OpenEJBContext());
+        try {
+            // someone decided to make the getThreadName package protected so we have to use reflection
+            method = ContextBindings.class.getDeclaredMethod("getThreadName");
+            method.setAccessible(true);
+        } catch (NoSuchMethodException e) {
+            logger.error("Expected ContextBinding to have the method getThreadName()");
+        }
+    }
+
+    public void contextEntered(ThreadContext oldContext, ThreadContext newContext) {
+        // save off the old context if possible
+        try {
+            Data data = new Data(getThreadName());
+            newContext.set(Data.class, data);
+        } catch (NamingException ignored) {
+        }
+
+        // set the new context
+        try {
+            ContextBindings.bindThread(OPENEJB_CONTEXT);
+        } catch (NamingException e) {
+            ContextBindings.unbindContext(OPENEJB_CONTEXT);
+            throw new IllegalArgumentException("Unable to bind OpenEJB enc");
+        }
+    }
+
+
+    public void contextExited(ThreadContext exitedContext, ThreadContext reenteredContext) {
+        // unbind the new context
+        ContextBindings.unbindThread(OPENEJB_CONTEXT);
+
+        // attempt to restore the old context
+        Data data = exitedContext.get(Data.class);
+        if (data != null && data.oldContextName != null) {
+            try {
+                ContextBindings.bindThread(data.oldContextName);
+            } catch (NamingException e) {
+            }
+        }
+    }
+
+    private Object getThreadName() throws NamingException {
+        // someone decided to make the getThreadName package protected so we have to use reflection
+        try {
+            Object threadName = method.invoke(null);
+            return threadName;
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    private static class Data {
+        private Object oldContextName;
+
+        public Data(Object oldContext) {
+            this.oldContextName = oldContext;
+        }
+    }
+}