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;
+ }
+ }
+}