Author: dain
Date: Tue Sep 18 14:36:30 2007
New Revision: 577073

URL: http://svn.apache.org/viewvc?rev=577073&view=rev
Log:
Fix Tomcat jndi enc lookups

Added:
    
openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/OpenEJBNamingContextListener.java
Modified:
    
openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/TomcatWebAppBuilder.java
    
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AutoConfig.java

Added: 
openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/OpenEJBNamingContextListener.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/OpenEJBNamingContextListener.java?rev=577073&view=auto
==============================================================================
--- 
openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/OpenEJBNamingContextListener.java
 (added)
+++ 
openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/OpenEJBNamingContextListener.java
 Tue Sep 18 14:36:30 2007
@@ -0,0 +1,295 @@
+/**
+ *
+ * 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;
+
+import org.apache.catalina.Lifecycle;
+import org.apache.catalina.LifecycleEvent;
+import org.apache.catalina.LifecycleListener;
+import org.apache.catalina.core.StandardServer;
+import org.apache.catalina.deploy.ContextEjb;
+import org.apache.catalina.deploy.ContextEnvironment;
+import org.apache.catalina.deploy.ContextLocalEjb;
+import org.apache.catalina.deploy.ContextResource;
+import org.apache.catalina.deploy.ContextResourceEnvRef;
+import org.apache.catalina.deploy.ContextResourceLink;
+import org.apache.catalina.deploy.NamingResources;
+import org.apache.openejb.OpenEJBException;
+import org.apache.openejb.assembler.classic.Assembler;
+import org.apache.openejb.assembler.classic.ResourceInfo;
+import org.apache.openejb.assembler.dynamic.PassthroughFactory;
+import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.util.LogCategory;
+import org.apache.openejb.util.Logger;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+
+public class OpenEJBNamingContextListener implements LifecycleListener, 
PropertyChangeListener {
+    private static final Logger logger = 
Logger.getInstance(LogCategory.OPENEJB.createChild("tomcat"), 
"org.apache.openejb.util.resources");
+
+    /**
+     * Associated standardServer.
+     */
+    private final StandardServer standardServer;
+
+    /**
+     * Initialized flag.
+     */
+    private boolean initialized = false;
+
+    /**
+     * Associated naming resources.
+     */
+    private final NamingResources namingResources;
+
+    public OpenEJBNamingContextListener(StandardServer standardServer) {
+        this.standardServer = standardServer;
+        namingResources = standardServer.getGlobalNamingResources();
+    }
+
+    public void lifecycleEvent(LifecycleEvent event) {
+        if (event.getLifecycle() != standardServer) {
+            return;
+        }
+
+        if (event.getType() == Lifecycle.START_EVENT) {
+            if (initialized) return;
+
+            namingResources.addPropertyChangeListener(this);
+            processInitialNamingResources();
+
+
+            initialized = true;
+
+        } else if (event.getType() == Lifecycle.STOP_EVENT) {
+
+            if (!initialized) return;
+
+            namingResources.removePropertyChangeListener(this);
+
+            initialized = false;
+        }
+    }
+
+    public void propertyChange(PropertyChangeEvent event) {
+        if (!initialized) return;
+
+        Object source = event.getSource();
+        if (source == namingResources) {
+            processGlobalResourcesChange(event.getPropertyName(), 
event.getOldValue(), event.getNewValue());
+        }
+    }
+
+    /**
+     * Process a property change on the global naming resources, by making the
+     * corresponding addition or removal to OpenEJB.
+     *
+     * @param name     Property name of the change to be processed
+     * @param oldValue The old value (or <code>null</code> if adding)
+     * @param newValue The new value (or <code>null</code> if removing)
+     */
+    private void processGlobalResourcesChange(String name, Object oldValue, 
Object newValue) {
+
+        // NOTE - It seems that the Context for global JNDI resources
+        // is left in read-write mode, so we do not have to change it here
+
+        if (name.equals("ejb")) {
+            if (oldValue != null) {
+                ContextEjb ejb = (ContextEjb) oldValue;
+                if (ejb.getName() != null) {
+                    removeEjb(ejb.getName());
+                }
+            }
+            if (newValue != null) {
+                ContextEjb ejb = (ContextEjb) newValue;
+                if (ejb.getName() != null) {
+                    addEjb(ejb);
+                }
+            }
+        } else if (name.equals("environment")) {
+            if (oldValue != null) {
+                ContextEnvironment env = (ContextEnvironment) oldValue;
+                if (env.getName() != null) {
+                    removeEnvironment(env.getName());
+                }
+            }
+            if (newValue != null) {
+                ContextEnvironment env = (ContextEnvironment) newValue;
+                if (env.getName() != null) {
+                    addEnvironment(env);
+                }
+            }
+        } else if (name.equals("localEjb")) {
+            if (oldValue != null) {
+                ContextLocalEjb ejb = (ContextLocalEjb) oldValue;
+                if (ejb.getName() != null) {
+                    removeLocalEjb(ejb.getName());
+                }
+            }
+            if (newValue != null) {
+                ContextLocalEjb ejb = (ContextLocalEjb) newValue;
+                if (ejb.getName() != null) {
+                    addLocalEjb(ejb);
+                }
+            }
+        } else if (name.equals("resource")) {
+            if (oldValue != null) {
+                ContextResource resource = (ContextResource) oldValue;
+                if (resource.getName() != null) {
+                    removeResource(resource.getName());
+                }
+            }
+            if (newValue != null) {
+                ContextResource resource = (ContextResource) newValue;
+                if (resource.getName() != null) {
+                    addResource(resource);
+                }
+            }
+        } else if (name.equals("resourceEnvRef")) {
+            if (oldValue != null) {
+                ContextResourceEnvRef resourceEnvRef = (ContextResourceEnvRef) 
oldValue;
+                if (resourceEnvRef.getName() != null) {
+                    removeResourceEnvRef(resourceEnvRef.getName());
+                }
+            }
+            if (newValue != null) {
+                ContextResourceEnvRef resourceEnvRef = (ContextResourceEnvRef) 
newValue;
+                if (resourceEnvRef.getName() != null) {
+                    addResourceEnvRef(resourceEnvRef);
+                }
+            }
+        } else if (name.equals("resourceLink")) {
+            if (oldValue != null) {
+                ContextResourceLink rl = (ContextResourceLink) oldValue;
+                if (rl.getName() != null) {
+                    removeResourceLink(rl.getName());
+                }
+            }
+            if (newValue != null) {
+                ContextResourceLink rl = (ContextResourceLink) newValue;
+                if (rl.getName() != null) {
+                    addResourceLink(rl);
+                }
+            }
+        }
+    }
+
+
+    private void processInitialNamingResources() {
+        // Resource links
+        ContextResourceLink[] resourceLinks = 
namingResources.findResourceLinks();
+        for (ContextResourceLink resourceLink : resourceLinks) {
+            addResourceLink(resourceLink);
+        }
+
+        // Resources
+        ContextResource[] resources = namingResources.findResources();
+        for (ContextResource resource : resources) {
+            addResource(resource);
+        }
+
+        // Resources Env
+        ContextResourceEnvRef[] resourceEnvRefs = 
namingResources.findResourceEnvRefs();
+        for (ContextResourceEnvRef resourceEnvRef : resourceEnvRefs) {
+            addResourceEnvRef(resourceEnvRef);
+        }
+
+        // Environment entries
+        ContextEnvironment[] contextEnvironments = 
namingResources.findEnvironments();
+        for (ContextEnvironment contextEnvironment : contextEnvironments) {
+            addEnvironment(contextEnvironment);
+        }
+
+        // EJB references
+        ContextEjb[] ejbs = namingResources.findEjbs();
+        for (ContextEjb ejb : ejbs) {
+            addEjb(ejb);
+        }
+    }
+
+    public void addEjb(ContextEjb ejb) {
+    }
+
+    public void addEnvironment(ContextEnvironment env) {
+    }
+
+    public void addLocalEjb(ContextLocalEjb localEjb) {
+    }
+
+    public void addResource(ContextResource resource) {
+        try {
+            Context globalNamingContext = 
standardServer.getGlobalNamingContext();
+            Object value = globalNamingContext.lookup(resource.getName());
+            String type = resource.getType();
+            bindResource(resource.getName(), value, type);
+        } catch (NamingException e) {
+            logger.error("Unable to lookup Global Tomcat resource " + 
resource.getName(), e);
+        }
+    }
+
+    public void addResourceEnvRef(ContextResourceEnvRef resourceEnvRef) {
+        try {
+            Context globalNamingContext = 
standardServer.getGlobalNamingContext();
+            Object value = 
globalNamingContext.lookup(resourceEnvRef.getName());
+            String type = resourceEnvRef.getType();
+            bindResource(resourceEnvRef.getName(), value, type);
+        } catch (NamingException e) {
+            logger.error("Unable to lookup Global Tomcat resource " + 
resourceEnvRef.getName(), e);
+        }
+    }
+
+    private void bindResource(String name, Object value, String type) {
+        ResourceInfo resourceInfo = new ResourceInfo();
+        resourceInfo.id = name;
+        resourceInfo.service = "Resource";
+        resourceInfo.types.add(type);
+        PassthroughFactory.add(resourceInfo, value);
+        Assembler assembler = (Assembler) 
SystemInstance.get().getComponent(org.apache.openejb.spi.Assembler.class);
+
+        try {
+            assembler.createResource(resourceInfo);
+        } catch (OpenEJBException e) {
+            logger.error("Unable to bind Global Tomcat resource " + name + " 
into OpenEJB", e);
+        }
+    }
+
+    public void addResourceLink(ContextResourceLink resourceLink) {
+    }
+
+    public void removeEjb(String name) {
+    }
+
+    public void removeEnvironment(String name) {
+    }
+
+    public void removeLocalEjb(String name) {
+    }
+
+    public void removeResource(String name) {
+        // there isn't any way to remove a resource yet
+    }
+
+    public void removeResourceEnvRef(String name) {
+        // there isn't any way to remove a resource yet
+    }
+
+    public void removeResourceLink(String name) {
+    }
+}

Modified: 
openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/TomcatWebAppBuilder.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/TomcatWebAppBuilder.java?rev=577073&r1=577072&r2=577073&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/TomcatWebAppBuilder.java
 (original)
+++ 
openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/TomcatWebAppBuilder.java
 Tue Sep 18 14:36:30 2007
@@ -18,11 +18,13 @@
 package org.apache.openejb.tomcat;
 
 import org.apache.catalina.ServerFactory;
+import org.apache.catalina.Container;
 import org.apache.catalina.util.DefaultAnnotationProcessor;
 import org.apache.catalina.core.StandardContext;
 import org.apache.catalina.core.StandardServer;
 import org.apache.naming.ContextAccessController;
 import org.apache.naming.ContextBindings;
+import org.apache.naming.NamingContext;
 import org.apache.openejb.assembler.classic.AppInfo;
 import org.apache.openejb.assembler.classic.Assembler;
 import org.apache.openejb.assembler.classic.JndiEncBuilder;
@@ -52,6 +54,8 @@
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Hashtable;
+import java.util.Stack;
 
 public class TomcatWebAppBuilder implements WebAppBuilder, ContextListener {
     private static final Logger logger = 
Logger.getInstance(LogCategory.OPENEJB.createChild("tomcat"), 
"org.apache.openejb.util.resources");
@@ -64,6 +68,7 @@
 
     public TomcatWebAppBuilder() {
         StandardServer standardServer = (StandardServer) 
ServerFactory.getServer();
+        standardServer.addLifecycleListener(new 
OpenEJBNamingContextListener(standardServer));
 
         globalListenerSupport = new GlobalListenerSupport(standardServer, 
this);
 
@@ -114,6 +119,8 @@
     //
 
     public void init(StandardContext standardContext) {
+        // turn off Tomcat's naming system
+        standardContext.setUseNaming(false);
     }
 
     public void beforeStart(StandardContext standardContext) {
@@ -247,12 +254,18 @@
     //
 
     private void bindEnc(StandardContext standardContext, Context enc) {
-        // turn off Tomcat's naming system
-        standardContext.setUseNaming(false);
+        Context rootContext = null;
+        try {
+            rootContext = new NamingContext(new Hashtable(), 
getNamingContextName(standardContext));
+            Context compCtx = rootContext.createSubcontext("comp");
+            compCtx.bind("env", enc);
+        } catch (NamingException e) {
+            // Never happens
+        }
 
         // Add enc to global map of named contexts
         ContextAccessController.setSecurityToken(standardContext.getName(), 
standardContext);
-        ContextBindings.bindContext(standardContext, enc, standardContext);
+        ContextBindings.bindContext(standardContext, rootContext, 
standardContext);
         if( logger.isDebugEnabled() ) {
             logger.debug("Bound enc for " + standardContext);
         }
@@ -270,9 +283,6 @@
     private void unbindEnc(StandardContext standardContext) {
         encs.remove(standardContext.getPath());
 
-        // turn Tomcat's naming system back on
-        standardContext.setUseNaming(true);
-
         ContextBindings.unbindContext(standardContext, standardContext);
 
         ContextBindings.unbindClassLoader(standardContext, standardContext, 
standardContext.getLoader().getClassLoader());
@@ -285,5 +295,24 @@
             assembler = (Assembler) 
SystemInstance.get().getComponent(org.apache.openejb.spi.Assembler.class);
         }
         return assembler;
+    }
+
+    private String getNamingContextName(StandardContext standardContext) {
+        Container parent = standardContext.getParent();
+        if (parent == null) {
+            return standardContext.getName();
+        } else {
+            Stack<String> stk = new Stack<String>();
+            StringBuffer buff = new StringBuffer();
+            while (parent != null) {
+                stk.push(parent.getName());
+                parent = parent.getParent();
+            }
+            while (!stk.empty()) {
+                buff.append("/").append(stk.pop());
+            }
+            buff.append(standardContext.getName());
+            return buff.toString();
+        }
     }
 }

Modified: 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AutoConfig.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AutoConfig.java?rev=577073&r1=577072&r2=577073&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AutoConfig.java
 (original)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AutoConfig.java
 Tue Sep 18 14:36:30 2007
@@ -765,7 +765,11 @@
         // Auto create a resource using the first provider that can supply a 
resource of the desired type
         String providerId = ServiceUtils.getServiceProviderId(type);
         if (providerId == null) {
-                throw new OpenEJBException("No provider available for resource 
reference '" + resourceId + "' of type '" + type + "' for '" + beanName + "'.");
+            // if there are any existing resources of the desired type, use 
the first one
+            if (resourceIds.size() > 0) {
+                return resourceIds.get(0);
+            }
+            throw new OpenEJBException("No provider available for resource 
reference '" + resourceId + "' of type '" + type + "' for '" + beanName + "'.");
         }
 
         Resource resource = new Resource(resourceId, providerId, null);


Reply via email to