Author: rmannibucau Date: Mon Feb 18 10:53:14 2013 New Revision: 1447187 URL: http://svn.apache.org/r1447187 Log: using a kind of facade to resolve app scoped resources
Added: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/naming/ContextualJndiReference.java Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/AutoConfig.java Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java?rev=1447187&r1=1447186&r2=1447187&view=diff ============================================================================== --- tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java (original) +++ tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java Mon Feb 18 10:53:14 2013 @@ -67,6 +67,7 @@ import org.apache.openejb.core.ParentCla import org.apache.openejb.core.SimpleTransactionSynchronizationRegistry; import org.apache.openejb.core.TransactionSynchronizationRegistryWrapper; import org.apache.openejb.core.WebContext; +import org.apache.openejb.core.ivm.naming.ContextualJndiReference; import org.apache.openejb.core.ivm.naming.IvmContext; import org.apache.openejb.core.ivm.naming.IvmJndiFactory; import org.apache.openejb.core.security.SecurityContextHandler; @@ -1046,7 +1047,7 @@ public class Assembler extends Assembler server.registerMBean(new DynamicMBeanWrapper(wc, instance), leaf); appMbeans.put(mbeanClass, leaf.getCanonicalName()); - if (Dependent.class.equals(bean.getScope())) { + if (creationalContext != null && (bean.getScope() == null || Dependent.class.equals(bean.getScope()))) { creationalContextForAppMbeans.put(leaf, creationalContext); } logger.info("Deployed MBean(" + leaf.getCanonicalName() + ")"); @@ -1974,12 +1975,15 @@ public class Assembler extends Assembler } bindResource(serviceInfo.id, service); - if (serviceInfo.originAppName != null) { - serviceInfo.aliases.add(serviceInfo.id.substring(serviceInfo.originAppName.length() + 1)); - } for (final String alias : serviceInfo.aliases) { bindResource(alias, service); } + if (serviceInfo.originAppName != null) { + final String baseJndiName = serviceInfo.id.substring(serviceInfo.originAppName.length() + 1); + serviceInfo.aliases.add(baseJndiName); + final ContextualJndiReference ref = new ContextualJndiReference(baseJndiName); + bindResource(baseJndiName, ref); + } // Update the config tree config.facilities.resources.add(serviceInfo); @@ -1991,8 +1995,34 @@ public class Assembler extends Assembler private void bindResource(final String id, final Object service) throws OpenEJBException { final String name = OPENEJB_RESOURCE_JNDI_PREFIX + id; + Object existing = null; try { - containerSystem.getJNDIContext().bind(name, service); + ContextualJndiReference.followReference.set(false); + existing = containerSystem.getJNDIContext().lookup(name); + } catch (final Exception ignored) { + // no-op + } + + boolean rebind = false; + if (existing != null) { + final boolean existingIsContextual = ContextualJndiReference.class.isInstance(existing); + final boolean serviceIsExisting = ContextualJndiReference.class.isInstance(service); + if (!existingIsContextual && serviceIsExisting) { + ContextualJndiReference.class.cast(service).setDefaultValue(existing); + rebind = true; + } else if (existingIsContextual && !serviceIsExisting) { + ContextualJndiReference.class.cast(existing).setDefaultValue(service); + } else if (existingIsContextual) { // && serviceIsExisting is always true here + return; + } + } + + try { + if (rebind) { + containerSystem.getJNDIContext().rebind(name, service); + } else { + containerSystem.getJNDIContext().bind(name, service); + } } catch (NameAlreadyBoundException nabe) { logger.warning("unbounding resource " + name + " can happen because of a redeployment or because of a duplicated id"); try { Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/AutoConfig.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/AutoConfig.java?rev=1447187&r1=1447186&r2=1447187&view=diff ============================================================================== --- tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/AutoConfig.java (original) +++ tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/AutoConfig.java Mon Feb 18 10:53:14 2013 @@ -888,6 +888,16 @@ public class AutoConfig implements Dynam resource.setJndi(value(resource.getJndi())); resource.getProperties().putAll(holds(resource.getProperties())); + final Collection<String> aliases = resource.getAliases(); + if (!aliases.isEmpty()) { + final Collection<String> newAliases = new ArrayList<String>(); + for (String s : aliases) { + newAliases.add(module.getModuleId() + "/" + s); + } + resource.getAliases().clear(); + resource.getAliases().addAll(newAliases); + } + Properties properties = resource.getProperties(); if (DataSource.class.getName().equals(resource.getType()) Added: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/naming/ContextualJndiReference.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/naming/ContextualJndiReference.java?rev=1447187&view=auto ============================================================================== --- tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/naming/ContextualJndiReference.java (added) +++ tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/ivm/naming/ContextualJndiReference.java Mon Feb 18 10:53:14 2013 @@ -0,0 +1,112 @@ +/* + * 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.core.ivm.naming; + +import org.apache.openejb.AppContext; +import org.apache.openejb.core.WebContext; +import org.apache.openejb.loader.SystemInstance; +import org.apache.openejb.spi.ContainerSystem; +import org.apache.openejb.util.Strings; + +import javax.naming.Context; +import javax.naming.NameNotFoundException; +import javax.naming.NamingException; + +public class ContextualJndiReference extends IntraVmJndiReference { + public static final ThreadLocal<Boolean> followReference = new ThreadLocal<Boolean>() { + @Override + public Boolean initialValue() { + return true; + } + }; + + private Object defaultValue; + + public ContextualJndiReference(final String jndiName) { + super(jndiName); + } + + public void setDefaultValue(final Object defaultValue) { + this.defaultValue = defaultValue; + } + + @Override + public Object getObject() throws NamingException { + final Boolean rawValue = !followReference.get(); + try { + if (rawValue) { + return this; + } + } finally { + followReference.remove(); + } + + final String prefix = findPrefix(); + final String jndiName = getJndiName(); + + if (prefix != null) { + try { + return lookup(prefix + '/' + jndiName); + } catch (final NamingException e) { + // no-op + } + } + + return defaultValue; + } + + private String findPrefix() { + final ClassLoader loader = Thread.currentThread().getContextClassLoader(); + final ContainerSystem containerSystem = SystemInstance.get().getComponent(ContainerSystem.class); + + for (final AppContext appContext : containerSystem.getAppContexts()) { + if (appContext.getClassLoader().equals(loader)) { + return appContext.getId(); + } + for (WebContext web : appContext.getWebContexts()) { + if (web.getClassLoader().equals(loader)) { + return appContext.getId(); + } + } + } + + return null; + } + + private Object lookup(final String s) throws NamingException { + final ContainerSystem containerSystem = SystemInstance.get().getComponent(ContainerSystem.class); + final Context jndiContext = containerSystem.getJNDIContext(); + try { + if (s.startsWith("java:") | s.startsWith("openejb:")) { + return jndiContext.lookup(s); + } else { + return jndiContext.lookup("openejb/Resource/" + s); + } + } catch (NameNotFoundException e) { + return jndiContext.lookup("java:module/" + Strings.lastPart(getClassName(), '.')); + } catch (NamingException e) { + throw (NamingException)new NamingException("could not look up " + s).initCause(e); + } + } + + @Override + public String toString() { + return "ContextualJndiReference{" + + "jndiName='" + getJndiName() + '\'' + + '}'; + } +}