[exo-jcr-commits] exo-jcr SVN: r4616 - in kernel/trunk/exo.kernel.component.common/src: test/java/org/exoplatform/services/naming and 1 other directories.
do-not-reply at jboss.org
do-not-reply at jboss.org
Tue Jul 12 10:45:11 EDT 2011
Author: tolusha
Date: 2011-07-12 10:45:11 -0400 (Tue, 12 Jul 2011)
New Revision: 4616
Added:
kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/naming/ExoContainerContextFactory.java
Modified:
kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/naming/InitialContextBinder.java
kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/naming/InitialContextInitializer.java
kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/naming/SimpleContext.java
kernel/trunk/exo.kernel.component.common/src/test/java/org/exoplatform/services/naming/InitialContextTest.java
kernel/trunk/exo.kernel.component.common/src/test/resources/conf/portal/test-configuration.xml
Log:
EXOJCR-1416: Get rid of any call to InitialContextInitializer.recall()
Added: kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/naming/ExoContainerContextFactory.java
===================================================================
--- kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/naming/ExoContainerContextFactory.java (rev 0)
+++ kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/naming/ExoContainerContextFactory.java 2011-07-12 14:45:11 UTC (rev 4616)
@@ -0,0 +1,529 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.naming;
+
+import org.exoplatform.container.ExoContainer;
+import org.exoplatform.container.ExoContainerContext;
+
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.naming.Binding;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.Name;
+import javax.naming.NameClassPair;
+import javax.naming.NameParser;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.spi.InitialContextFactory;
+
+/**
+ * This implementation of {@link InitialContextFactory} is used to be able to share
+ * all the objects that have been binded thanks to the {@link InitialContextInitializer}
+ * which is required for example to be able to create and bind data sources dynamically
+ *
+ * @author <a href="mailto:nfilotto at exoplatform.com">Nicolas Filotto</a>
+ * @version $Id$
+ *
+ */
+public class ExoContainerContextFactory implements InitialContextFactory
+{
+
+ /**
+ * {@inheritDoc}
+ */
+ public Context getInitialContext(Hashtable<?, ?> environment) throws NamingException
+ {
+ return new ExoContainerCtx(environment);
+ }
+
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ private static class ExoContainerCtx extends SimpleContext
+ {
+
+ /**
+ * The map containing all the bindings for all the containers defined
+ */
+ private static volatile Map<ExoContainer, AtomicReference<Map<String, Object>>> ALL_BINDINGS =
+ new HashMap<ExoContainer, AtomicReference<Map<String, Object>>>();
+
+ /**
+ * The environment to use in case we cannot find the object
+ */
+ private final Hashtable env;
+
+ /**
+ * The current eXo container
+ */
+ private final ExoContainer container;
+
+ /**
+ * The nested context
+ */
+ private InitialContext ctx;
+
+ /**
+ * The reference to the bindings corresponding to this context;
+ */
+ private AtomicReference<Map<String, Object>> bindingsRef;
+
+ public ExoContainerCtx(Hashtable<?, ?> env)
+ {
+ this.env = env == null ? null : (Hashtable)env.clone();
+ this.container = ExoContainerContext.getCurrentContainerIfPresent();
+ if (container != null)
+ {
+ AtomicReference<Map<String, Object>> ref = ALL_BINDINGS.get(container);
+ if (ref == null)
+ {
+ synchronized (ExoContainerCtx.class)
+ {
+ if (ref == null)
+ {
+ Map<ExoContainer, AtomicReference<Map<String, Object>>> tempAllBindings =
+ new HashMap<ExoContainer, AtomicReference<Map<String, Object>>>(ALL_BINDINGS);
+ tempAllBindings.put(container, ref =
+ new AtomicReference<Map<String, Object>>(new HashMap<String, Object>()));
+ ALL_BINDINGS = tempAllBindings;
+ }
+ }
+ }
+ this.bindingsRef = ref;
+ }
+ }
+
+ protected Map<String, Object> getBindings()
+ {
+ return bindingsRef.get();
+ }
+
+ protected void setBindings(Map<String, Object> bindings)
+ {
+ bindingsRef.set(bindings);
+ }
+
+ private InitialContext getContext() throws NamingException
+ {
+ if (ctx == null)
+ {
+ Hashtable env;
+ if (this.env == null)
+ {
+ env = new Hashtable();
+ }
+ else
+ {
+ env = new Hashtable(this.env);
+ }
+ env.put(Context.INITIAL_CONTEXT_FACTORY, InitialContextInitializer.DEFAULT_INITIAL_CONTEXT_FACTORY);
+ env.remove(InitialContextInitializer.class.getName());
+ ctx = new InitialContext(env);
+ }
+ return ctx;
+ }
+
+ private boolean isInitialContextInitializerCall()
+ {
+ return container != null && env != null && env.containsKey(InitialContextInitializer.class.getName());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object lookup(String name) throws NamingException
+ {
+ if (getBindings().containsKey(name) || isInitialContextInitializerCall())
+ {
+ return super.lookup(name);
+ }
+ return getContext().lookup(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object lookup(Name name) throws NamingException
+ {
+ if (getBindings().containsKey(name) || isInitialContextInitializerCall())
+ {
+ return super.lookup(nameToString(name));
+ }
+ return getContext().lookup(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void bind(String name, Object value) throws NamingException
+ {
+ if (isInitialContextInitializerCall())
+ {
+ super.bind(name, value);
+ return;
+ }
+ getContext().bind(name, value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void bind(Name name, Object value) throws NamingException
+ {
+ if (isInitialContextInitializerCall())
+ {
+ super.bind(nameToString(name), value);
+ return;
+ }
+ getContext().bind(name, value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void rebind(String name, Object value) throws NamingException
+ {
+ if (isInitialContextInitializerCall())
+ {
+ super.rebind(name, value);
+ return;
+ }
+ getContext().rebind(name, value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void rebind(Name name, Object value) throws NamingException
+ {
+ if (isInitialContextInitializerCall())
+ {
+ super.rebind(nameToString(name), value);
+ return;
+ }
+ getContext().rebind(name, value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void unbind(String name) throws NamingException
+ {
+ if (isInitialContextInitializerCall())
+ {
+ super.unbind(name);
+ return;
+ }
+ getContext().unbind(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void unbind(Name name) throws NamingException
+ {
+ if (isInitialContextInitializerCall())
+ {
+ super.unbind(nameToString(name));
+ return;
+ }
+ getContext().unbind(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void rename(String name1, String name2) throws NamingException
+ {
+ if (isInitialContextInitializerCall())
+ {
+ super.rename(name1, name2);
+ return;
+ }
+ getContext().rename(name1, name2);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void rename(Name name1, Name name2) throws NamingException
+ {
+ if (isInitialContextInitializerCall())
+ {
+ super.rename(nameToString(name1), nameToString(name2));
+ return;
+ }
+ getContext().rename(name1, name2);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public NamingEnumeration<NameClassPair> list(Name name) throws NamingException
+ {
+ if (isInitialContextInitializerCall())
+ {
+ return super.list(name);
+ }
+ return getContext().list(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public NamingEnumeration<NameClassPair> list(String name) throws NamingException
+ {
+ if (isInitialContextInitializerCall())
+ {
+ return super.list(name);
+ }
+ return getContext().list(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public NamingEnumeration<Binding> listBindings(Name name) throws NamingException
+ {
+ if (isInitialContextInitializerCall())
+ {
+ return super.listBindings(name);
+ }
+ return getContext().listBindings(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public NamingEnumeration<Binding> listBindings(String name) throws NamingException
+ {
+ if (isInitialContextInitializerCall())
+ {
+ return super.listBindings(name);
+ }
+ return getContext().listBindings(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void destroySubcontext(Name name) throws NamingException
+ {
+ if (isInitialContextInitializerCall())
+ {
+ super.destroySubcontext(name);
+ return;
+ }
+ getContext().destroySubcontext(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void destroySubcontext(String name) throws NamingException
+ {
+ if (isInitialContextInitializerCall())
+ {
+ super.destroySubcontext(name);
+ return;
+ }
+ getContext().destroySubcontext(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Context createSubcontext(Name name) throws NamingException
+ {
+ if (isInitialContextInitializerCall())
+ {
+ return super.createSubcontext(name);
+ }
+ return getContext().createSubcontext(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Context createSubcontext(String name) throws NamingException
+ {
+ if (isInitialContextInitializerCall())
+ {
+ return super.createSubcontext(name);
+ }
+ return getContext().createSubcontext(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object lookupLink(Name name) throws NamingException
+ {
+ if (isInitialContextInitializerCall())
+ {
+ return super.lookupLink(name);
+ }
+ return getContext().lookupLink(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object lookupLink(String name) throws NamingException
+ {
+ if (isInitialContextInitializerCall())
+ {
+ return super.lookupLink(name);
+ }
+ return getContext().lookupLink(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public NameParser getNameParser(Name name) throws NamingException
+ {
+ if (isInitialContextInitializerCall())
+ {
+ return super.getNameParser(name);
+ }
+ return getContext().getNameParser(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public NameParser getNameParser(String name) throws NamingException
+ {
+ if (isInitialContextInitializerCall())
+ {
+ return super.getNameParser(name);
+ }
+ return getContext().getNameParser(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Name composeName(Name name, Name prefix) throws NamingException
+ {
+ if (isInitialContextInitializerCall())
+ {
+ return super.composeName(name, prefix);
+ }
+ return getContext().composeName(name, prefix);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String composeName(String name, String prefix) throws NamingException
+ {
+ if (isInitialContextInitializerCall())
+ {
+ return super.composeName(name, prefix);
+ }
+ return getContext().composeName(name, prefix);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object addToEnvironment(String propName, Object propVal) throws NamingException
+ {
+ if (isInitialContextInitializerCall())
+ {
+ return super.addToEnvironment(propName, propVal);
+ }
+ return getContext().addToEnvironment(propName, propVal);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object removeFromEnvironment(String propName) throws NamingException
+ {
+ if (isInitialContextInitializerCall())
+ {
+ return super.removeFromEnvironment(propName);
+ }
+ return getContext().removeFromEnvironment(propName);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Hashtable<?, ?> getEnvironment() throws NamingException
+ {
+ if (isInitialContextInitializerCall())
+ {
+ if (env == null)
+ {
+ // Must return non-null
+ return new Hashtable(3, 0.75f);
+ }
+ else
+ {
+ return (Hashtable)env.clone();
+ }
+ }
+ return getContext().getEnvironment();
+ }
+
+ protected Hashtable<?, ?> getInternalEnv()
+ {
+ return env;
+ }
+
+ protected Object getMutex()
+ {
+ return bindingsRef;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void close() throws NamingException
+ {
+ bindingsRef = null;
+ if (env != null)
+ {
+ env.clear();
+ }
+ if (ctx != null)
+ {
+ ctx.close();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getNameInNamespace() throws NamingException
+ {
+ if (isInitialContextInitializerCall())
+ {
+ return super.getNameInNamespace();
+ }
+ return getContext().getNameInNamespace();
+ }
+ }
+}
Modified: kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/naming/InitialContextBinder.java
===================================================================
--- kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/naming/InitialContextBinder.java 2011-07-08 11:31:30 UTC (rev 4615)
+++ kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/naming/InitialContextBinder.java 2011-07-12 14:45:11 UTC (rev 4616)
@@ -354,7 +354,7 @@
/**
* Class implements Map.Entry interface and used to push/pop entity in stack.
*/
- class RefEntity implements Map.Entry
+ class RefEntity implements Map.Entry<String, Reference>
{
/**
@@ -384,7 +384,6 @@
/**
* {@inheritDoc}
*/
- @Override
public String getKey()
{
return key;
@@ -393,7 +392,6 @@
/**
* {@inheritDoc}
*/
- @Override
public Reference getValue()
{
return value;
@@ -402,11 +400,10 @@
/**
* {@inheritDoc}
*/
- @Override
- public Reference setValue(Object value)
+ public Reference setValue(Reference value)
{
Reference oldValue = this.value;
- this.value = (Reference)value;
+ this.value = value;
return oldValue;
}
Modified: kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/naming/InitialContextInitializer.java
===================================================================
--- kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/naming/InitialContextInitializer.java 2011-07-08 11:31:30 UTC (rev 4615)
+++ kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/naming/InitialContextInitializer.java 2011-07-12 14:45:11 UTC (rev 4616)
@@ -32,6 +32,7 @@
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
@@ -52,23 +53,26 @@
public class InitialContextInitializer
{
- final public static String PROPERTIES_DEFAULT = "default-properties";
+ static String DEFAULT_INITIAL_CONTEXT_FACTORY = PrivilegedSystemHelper.getProperty(Context.INITIAL_CONTEXT_FACTORY);
+
+ public static final String PROPERTIES_DEFAULT = "default-properties";
- final public static String PROPERTIES_MANDATORY = "mandatory-properties";
+ public static final String PROPERTIES_MANDATORY = "mandatory-properties";
- final public static String BINDINGS_STORE_PATH = "bindings-store-path";
+ /**
+ * This parameter is used to overload the default initial context factory in order to ensure that binded objects are shared
+ */
+ public static final String OVERLOAD_CONTEXT_FACTORY = "overload-context-factory";
- final public static String DEFAULT_BINDING_STORE_PATH = PrivilegedSystemHelper.getProperty("java.io.tmpdir")
+ public static final String BINDINGS_STORE_PATH = "bindings-store-path";
+
+ public static final String DEFAULT_BINDING_STORE_PATH = PrivilegedSystemHelper.getProperty("java.io.tmpdir")
+ File.separator + "bind-references.xml";
private static Log LOG = ExoLogger.getLogger("exo.kernel.component.common.InitialContextInitializer");
private List<BindReferencePlugin> bindReferencesPlugins;
- private String defaultContextFactory;
-
- private final InitialContext initialContext;
-
private final InitialContextBinder binder;
/**
@@ -110,7 +114,6 @@
}
}
}
- initialContext = new InitialContext();
bindReferencesPlugins = new ArrayList<BindReferencePlugin>();
ValueParam bindingStorePathParam = params.getValueParam(BINDINGS_STORE_PATH);
@@ -124,7 +127,19 @@
{
binder = new InitialContextBinder(this, bindingStorePathParam.getValue());
}
+
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("The default initial context factory is " + DEFAULT_INITIAL_CONTEXT_FACTORY);
+ }
+ ValueParam overloadContextFactoryParam = params.getValueParam(OVERLOAD_CONTEXT_FACTORY);
+ if (overloadContextFactoryParam != null && overloadContextFactoryParam.getValue() != null
+ && Boolean.valueOf(overloadContextFactoryParam.getValue()))
+ {
+ PrivilegedSystemHelper
+ .setProperty(Context.INITIAL_CONTEXT_FACTORY, ExoContainerContextFactory.class.getName());
+ }
}
private void setSystemProperty(String propName, String propValue, String propParamName)
@@ -132,7 +147,7 @@
PrivilegedSystemHelper.setProperty(propName, propValue);
if (propName.equals(Context.INITIAL_CONTEXT_FACTORY))
{
- defaultContextFactory = propValue;
+ DEFAULT_INITIAL_CONTEXT_FACTORY = PrivilegedSystemHelper.getProperty(Context.INITIAL_CONTEXT_FACTORY);
}
LOG.info("Using mandatory system property: " + propName + " = " + PrivilegedSystemHelper.getProperty(propName));
}
@@ -141,11 +156,8 @@
private InitialContextInitializer(String name, Reference reference) throws NamingException, FileNotFoundException,
XMLStreamException
{
- if (PrivilegedSystemHelper.getProperty(Context.INITIAL_CONTEXT_FACTORY) == null)
- {
- PrivilegedSystemHelper.setProperty(Context.INITIAL_CONTEXT_FACTORY, defaultContextFactory);
- }
- initialContext = new InitialContext();
+ PrivilegedSystemHelper.setProperty(Context.INITIAL_CONTEXT_FACTORY, DEFAULT_INITIAL_CONTEXT_FACTORY);
+ InitialContext initialContext = getInitialContext();
initialContext.rebind(name, reference);
// binder
@@ -157,13 +169,14 @@
* of app using different copy of Context, for example per web app
* InitialContext in Tomcat
*/
+ @deprecated
public void recall()
{
for (BindReferencePlugin plugin : bindReferencesPlugins)
{
try
{
- InitialContext ic = new InitialContext();
+ InitialContext ic = getInitialContext();
ic.bind(plugin.getBindName(), plugin.getReference());
LOG.info("Reference bound (by recall()): " + plugin.getBindName());
}
@@ -185,8 +198,8 @@
BindReferencePlugin brplugin = (BindReferencePlugin)plugin;
try
{
- // initialContext = new InitialContext();
- initialContext.rebind(brplugin.getBindName(), brplugin.getReference());
+ InitialContext ic = getInitialContext();
+ ic.rebind(brplugin.getBindName(), brplugin.getReference());
LOG.info("Reference bound: " + brplugin.getBindName());
bindReferencesPlugins.add((BindReferencePlugin)plugin);
}
@@ -212,15 +225,24 @@
*/
public String getDefaultContextFactory()
{
- return defaultContextFactory;
+ return DEFAULT_INITIAL_CONTEXT_FACTORY;
}
/**
* @return stored InitialContext
*/
- public synchronized InitialContext getInitialContext()
+ public InitialContext getInitialContext()
{
- return initialContext;
+ try
+ {
+ Hashtable<String, Object> env = new Hashtable<String, Object>();
+ env.put(InitialContextInitializer.class.getName(), "true");
+ return new InitialContext(env);
+ }
+ catch (NamingException e)
+ {
+ throw new RuntimeException("Cannot create the intial context", e);
+ }
}
// for out-of-container testing
Modified: kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/naming/SimpleContext.java
===================================================================
--- kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/naming/SimpleContext.java 2011-07-08 11:31:30 UTC (rev 4615)
+++ kernel/trunk/exo.kernel.component.common/src/main/java/org/exoplatform/services/naming/SimpleContext.java 2011-07-12 14:45:11 UTC (rev 4616)
@@ -18,22 +18,29 @@
*/
package org.exoplatform.services.naming;
-import org.exoplatform.commons.utils.SecurityHelper;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
-import java.security.PrivilegedExceptionAction;
+import java.util.HashMap;
import java.util.Hashtable;
+import java.util.Map;
import javax.naming.Binding;
+import javax.naming.CompositeName;
import javax.naming.Context;
+import javax.naming.InvalidNameException;
+import javax.naming.LinkRef;
import javax.naming.Name;
+import javax.naming.NameAlreadyBoundException;
import javax.naming.NameClassPair;
+import javax.naming.NameNotFoundException;
import javax.naming.NameParser;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
+import javax.naming.OperationNotSupportedException;
import javax.naming.Reference;
-import javax.naming.spi.ObjectFactory;
+import javax.naming.Referenceable;
+import javax.naming.spi.NamingManager;
/**
* Created by The eXo Platform SAS.
@@ -45,186 +52,383 @@
public class SimpleContext implements Context
{
-
+
/**
* The logger
*/
private static final Log LOG = ExoLogger.getLogger("org.exoplatform.services.naming.SimpleContext");
- private static Hashtable objects = new Hashtable();
+ private static final NameParser NAME_PARSER = new SimpleNameParser();
+
+ private static volatile Map<String, Object> BINDINGS = new HashMap<String, Object>();
public SimpleContext()
{
}
+ protected Map<String, Object> getBindings()
+ {
+ return BINDINGS;
+ }
+
+ protected void setBindings(Map<String, Object> bindings)
+ {
+ BINDINGS = bindings;
+ }
+
+ /**
+ * Converts a Name to a flat String.
+ */
+ protected String nameToString(Name name) throws NamingException
+ {
+ return name.toString();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public Object lookup(Name name) throws NamingException
{
- throw new NamingException("Not supported");
+ return lookup(nameToString(name));
}
+ /**
+ * {@inheritDoc}
+ */
public Object lookup(String name) throws NamingException
{
- Object obj = objects.get(name);
+ if (name.isEmpty())
+ {
+ throw new InvalidNameException("Cannot bind empty name");
+ }
+ Object obj = getBindings().get(name);
if (obj instanceof Reference)
{
- final Reference ref = (Reference)obj;
- String factoryCN = ref.getFactoryClassName();
- try
+ synchronized (obj)
{
- final ObjectFactory factory = (ObjectFactory)Class.forName(factoryCN).newInstance();
- obj = SecurityHelper.doPrivilegedExceptionAction(new PrivilegedExceptionAction<Object>()
+ obj = getBindings().get(name);
+ if (obj instanceof Reference)
{
- public Object run() throws Exception
+ try
{
- return factory.getObjectInstance(ref, null, null, null);
+ obj = NamingManager.getObjectInstance(obj, NAME_PARSER.parse(name), this, getInternalEnv());
+ // Re-bind with the object with its new value to be able to return the same ins
+ bind(name, obj, false);
}
- });
+ catch (Exception e)
+ {
+ LOG.error(e.getLocalizedMessage(), e);
+ NamingException ne = new NamingException("getObjectInstance failed");
+ ne.setRootCause(e);
+ throw ne;
+ }
+ }
}
- catch (Exception e)
- {
- LOG.error(e.getLocalizedMessage(), e);
- throw new NamingException("Exception: " + e);
- }
}
+ else if (obj == null)
+ {
+ throw new NameNotFoundException("No object has been binded with the name '" + name + "'");
+ }
return obj;
}
+ /**
+ * {@inheritDoc}
+ */
public void bind(Name name, Object value) throws NamingException
{
- throw new NamingException("Not supported");
+ bind(nameToString(name), value);
}
+ /**
+ * {@inheritDoc}
+ */
public void bind(String name, Object value) throws NamingException
{
- // System.out.println("Bind: "+name+" "+value+" "+objects);
- objects.put(name, value);
+ bind(name, value, true);
}
+ private void bind(String name, Object value, boolean checkIfExists) throws NamingException
+ {
+ if (name.isEmpty())
+ {
+ throw new InvalidNameException("Cannot bind empty name");
+ }
+ // Call getStateToBind for using any state factories
+ value = NamingManager.getStateToBind(value, NAME_PARSER.parse(name), this, getInternalEnv());
+
+ if (value instanceof Context)
+ {
+ throw new OperationNotSupportedException("Context not supported");
+ }
+ else if (value instanceof LinkRef)
+ {
+ throw new OperationNotSupportedException("LinkRef not supported");
+ }
+ else if (value instanceof Referenceable)
+ {
+ value = ((Referenceable)value).getReference();
+ }
+ synchronized (getMutex())
+ {
+ Map<String, Object> tmpObjects = new HashMap<String, Object>(getBindings());
+ if (checkIfExists && tmpObjects.containsKey(name))
+ {
+ throw new NameAlreadyBoundException("An object has already been binded with the name '" + name + "'");
+ }
+ tmpObjects.put(name, value);
+ setBindings(tmpObjects);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public void rebind(Name name, Object value) throws NamingException
{
- throw new NamingException("Not supported");
+ rebind(nameToString(name), value);
}
+ /**
+ * {@inheritDoc}
+ */
public void rebind(String name, Object value) throws NamingException
{
- objects.put(name, value);
+ bind(name, value, false);
}
+ /**
+ * {@inheritDoc}
+ */
public void unbind(Name name) throws NamingException
{
- throw new NamingException("Not supported");
+ unbind(nameToString(name));
}
+ /**
+ * {@inheritDoc}
+ */
public void unbind(String name) throws NamingException
{
- objects.remove(name);
+ if (name.isEmpty())
+ {
+ throw new InvalidNameException("Cannot bind empty name");
+ }
+ synchronized (getMutex())
+ {
+ Map<String, Object> tmpObjects = new HashMap<String, Object>(getBindings());
+ if (tmpObjects.remove(name) == null)
+ {
+ throw new NameNotFoundException("No object has been binded with the name '" + name + "'");
+ }
+ setBindings(tmpObjects);
+ }
}
+ /**
+ * {@inheritDoc}
+ */
public void rename(Name name1, Name name2) throws NamingException
{
- throw new NamingException("Not supported");
+ rename(nameToString(name1), nameToString(name2));
}
+ /**
+ * {@inheritDoc}
+ */
public void rename(String name1, String name2) throws NamingException
{
- Object val = objects.get(name1);
- objects.remove(name1);
- objects.put(name2, val);
+ if (name1.isEmpty() || name2.isEmpty())
+ {
+ throw new InvalidNameException("Cannot bind empty name");
+ }
+ Object value;
+ synchronized (getMutex())
+ {
+ Map<String, Object> tmpObjects = new HashMap<String, Object>(getBindings());
+ if (tmpObjects.containsKey(name2))
+ {
+ throw new NameAlreadyBoundException("An object has already been binded with the name '" + name2 + "'");
+ }
+ else if ((value = tmpObjects.remove(name1)) == null)
+ {
+ throw new NameNotFoundException("No object has been binded with the name '" + name1 + "'");
+ }
+ tmpObjects.put(name2, value);
+ setBindings(tmpObjects);
+ }
}
- public NamingEnumeration<NameClassPair> list(Name arg0) throws NamingException
+ /**
+ * {@inheritDoc}
+ */
+ public NamingEnumeration<NameClassPair> list(Name name) throws NamingException
{
- throw new NamingException("Not supported");
+ throw new OperationNotSupportedException("Not supported");
}
- public NamingEnumeration<NameClassPair> list(String arg0) throws NamingException
+ /**
+ * {@inheritDoc}
+ */
+ public NamingEnumeration<NameClassPair> list(String name) throws NamingException
{
- throw new NamingException("Not supported");
+ throw new OperationNotSupportedException("Not supported");
}
- public NamingEnumeration<Binding> listBindings(Name arg0) throws NamingException
+ /**
+ * {@inheritDoc}
+ */
+ public NamingEnumeration<Binding> listBindings(Name name) throws NamingException
{
- throw new NamingException("Not supported");
+ throw new OperationNotSupportedException("Not supported");
}
- public NamingEnumeration<Binding> listBindings(String arg0) throws NamingException
+ /**
+ * {@inheritDoc}
+ */
+ public NamingEnumeration<Binding> listBindings(String name) throws NamingException
{
- throw new NamingException("Not supported");
+ throw new OperationNotSupportedException("Not supported");
}
- public void destroySubcontext(Name arg0) throws NamingException
+ /**
+ * {@inheritDoc}
+ */
+ public void destroySubcontext(Name name) throws NamingException
{
- throw new NamingException("Not supported");
+ throw new OperationNotSupportedException("Not supported");
}
- public void destroySubcontext(String arg0) throws NamingException
+ /**
+ * {@inheritDoc}
+ */
+ public void destroySubcontext(String name) throws NamingException
{
- throw new NamingException("Not supported");
+ throw new OperationNotSupportedException("Not supported");
}
- public Context createSubcontext(Name arg0) throws NamingException
+ /**
+ * {@inheritDoc}
+ */
+ public Context createSubcontext(Name name) throws NamingException
{
- throw new NamingException("Not supported");
+ throw new OperationNotSupportedException("Not supported");
}
- public Context createSubcontext(String arg0) throws NamingException
+ /**
+ * {@inheritDoc}
+ */
+ public Context createSubcontext(String name) throws NamingException
{
- throw new NamingException("Not supported");
+ throw new OperationNotSupportedException("Not supported");
}
- public Object lookupLink(Name arg0) throws NamingException
+ /**
+ * {@inheritDoc}
+ */
+ public Object lookupLink(Name name) throws NamingException
{
- throw new NamingException("Not supported");
+ throw new OperationNotSupportedException("Not supported");
}
- public Object lookupLink(String arg0) throws NamingException
+ /**
+ * {@inheritDoc}
+ */
+ public Object lookupLink(String name) throws NamingException
{
- throw new NamingException("Not supported");
+ throw new OperationNotSupportedException("Not supported");
}
- public NameParser getNameParser(Name arg0) throws NamingException
+ /**
+ * {@inheritDoc}
+ */
+ public NameParser getNameParser(Name name) throws NamingException
{
- throw new NamingException("Not supported");
+ return getNameParser(nameToString(name));
}
- public NameParser getNameParser(String arg0) throws NamingException
+ /**
+ * {@inheritDoc}
+ */
+ public NameParser getNameParser(String name) throws NamingException
{
- throw new NamingException("Not supported");
+ return NAME_PARSER;
}
- public Name composeName(Name arg0, Name arg1) throws NamingException
+ /**
+ * {@inheritDoc}
+ */
+ public Name composeName(Name nam1, Name name2) throws NamingException
{
- throw new NamingException("Not supported");
+ throw new OperationNotSupportedException("Not supported");
}
- public String composeName(String arg0, String arg1) throws NamingException
+ /**
+ * {@inheritDoc}
+ */
+ public String composeName(String name1, String name2) throws NamingException
{
- throw new NamingException("Not supported");
+ throw new OperationNotSupportedException("Not supported");
}
- public Object addToEnvironment(String arg0, Object arg1) throws NamingException
+ /**
+ * {@inheritDoc}
+ */
+ public Object addToEnvironment(String name1, Object name2) throws NamingException
{
- throw new NamingException("Not supported");
+ throw new OperationNotSupportedException("Not supported");
}
- public Object removeFromEnvironment(String arg0) throws NamingException
+ /**
+ * {@inheritDoc}
+ */
+ public Object removeFromEnvironment(String name) throws NamingException
{
- throw new NamingException("Not supported");
+ throw new OperationNotSupportedException("Not supported");
}
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("rawtypes")
public Hashtable<?, ?> getEnvironment() throws NamingException
{
- throw new NamingException("Not supported");
+ return new Hashtable(3, 0.75f);
}
+ protected Hashtable<?, ?> getInternalEnv()
+ {
+ return null;
+ }
+
+ protected Object getMutex()
+ {
+ return SimpleContext.class;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public void close() throws NamingException
{
- objects.clear();
}
+ /**
+ * {@inheritDoc}
+ */
public String getNameInNamespace() throws NamingException
{
- throw new NamingException("Not supported");
+ throw new OperationNotSupportedException("Not supported");
}
-}
+ private static class SimpleNameParser implements NameParser
+ {
+ /**
+ * {@inheritDoc}
+ */
+ public Name parse(String name) throws NamingException
+ {
+ return new CompositeName(name);
+ }
+ }
+}
\ No newline at end of file
Modified: kernel/trunk/exo.kernel.component.common/src/test/java/org/exoplatform/services/naming/InitialContextTest.java
===================================================================
--- kernel/trunk/exo.kernel.component.common/src/test/java/org/exoplatform/services/naming/InitialContextTest.java 2011-07-08 11:31:30 UTC (rev 4615)
+++ kernel/trunk/exo.kernel.component.common/src/test/java/org/exoplatform/services/naming/InitialContextTest.java 2011-07-12 14:45:11 UTC (rev 4616)
@@ -33,6 +33,8 @@
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.Name;
+import javax.naming.NameAlreadyBoundException;
+import javax.naming.NameNotFoundException;
import javax.naming.NamingException;
import javax.xml.stream.XMLStreamException;
@@ -90,6 +92,101 @@
assertNotNull(ctx);
ctx.bind("test", "test");
assertEquals("test", ctx.lookup("test"));
+ try
+ {
+ ctx.bind("test", "test2");
+ fail("A NameAlreadyBoundException is expected here");
+ }
+ catch (NameAlreadyBoundException e)
+ {
+ // expected exception
+ }
+ assertEquals("test", ctx.lookup("test"));
+ ctx.rebind("test", "test2");
+ assertEquals("test2", ctx.lookup("test"));
+
+ InitialContextInitializer initializer =
+ (InitialContextInitializer)container.getComponentInstanceOfType(InitialContextInitializer.class);
+
+ assertNotNull(initializer);
+ initializer.getInitialContext().bind("test", "test3");
+ assertEquals("test3", ctx.lookup("test"));
+ ctx.rebind("test", "test4");
+ assertEquals("test3", ctx.lookup("test"));
+ initializer.getInitialContext().rebind("test", "test5");
+ assertEquals("test5", ctx.lookup("test"));
+ initializer.getInitialContext().unbind("test");
+ try
+ {
+ initializer.getInitialContext().lookup("test");
+ fail("A NameNotFoundException is expected here");
+ }
+ catch (NameNotFoundException e)
+ {
+ // expected exception
+ }
+ assertEquals("test4", ctx.lookup("test"));
+ ctx.unbind("test");
+ try
+ {
+ ctx.lookup("test");
+ fail("A NameNotFoundException is expected here");
+ }
+ catch (NameNotFoundException e)
+ {
+ // expected exception
+ }
+ try
+ {
+ initializer.getInitialContext().unbind("test2");
+ fail("A NameNotFoundException is expected here");
+ }
+ catch (NameNotFoundException e)
+ {
+ // expected exception
+ }
+ initializer.getInitialContext().bind("foo", "foo");
+ assertEquals("foo", ctx.lookup("foo"));
+ initializer.getInitialContext().bind("foo2", "foo2");
+ assertEquals("foo2", ctx.lookup("foo2"));
+ try
+ {
+ initializer.getInitialContext().rename("foo", "foo2");
+ fail("A NameAlreadyBoundException is expected here");
+ }
+ catch (NameAlreadyBoundException e)
+ {
+ // expected exception
+ }
+ assertEquals("foo", ctx.lookup("foo"));
+ assertEquals("foo2", ctx.lookup("foo2"));
+ try
+ {
+ initializer.getInitialContext().rename("foo3", "foo4");
+ fail("A NameNotFoundException is expected here");
+ }
+ catch (NameNotFoundException e)
+ {
+ // expected exception
+ }
+ initializer.getInitialContext().rename("foo", "foo3");
+ assertEquals("foo", ctx.lookup("foo3"));
+ assertEquals("foo2", ctx.lookup("foo2"));
+ try
+ {
+ initializer.getInitialContext().lookup("foo");
+ fail("A NameNotFoundException is expected here");
+ }
+ catch (NameNotFoundException e)
+ {
+ // expected exception
+ }
+
+ // check same instance
+ initializer.getInitialContext().bind("bla", "bla");
+ Object obj1 = initializer.getInitialContext().lookup("bla");
+ Object obj2 = initializer.getInitialContext().lookup("bla");
+ assertTrue(obj1 == obj2);
}
public void testCompositeNameUsing() throws Exception
@@ -102,6 +199,30 @@
{
System.out.println("---- " + en.nextElement());
}
+ InitialContext ctx = new InitialContext();
+ ctx.bind(name, "foo");
+ assertEquals("foo", ctx.lookup(name));
+ try
+ {
+ ctx.bind(name, "foo2");
+ fail("A NameAlreadyBoundException is expected here");
+ }
+ catch (NameAlreadyBoundException e)
+ {
+ // expected exception
+ }
+ assertEquals("foo", ctx.lookup(name));
+ assertEquals("foo", ctx.lookup("java:comp/env/jdbc/jcr"));
+ ctx.unbind(name);
+ try
+ {
+ ctx.lookup(name);
+ fail("A NameNotFoundException is expected here");
+ }
+ catch (NameNotFoundException e)
+ {
+ // expected exception
+ }
}
/*
Modified: kernel/trunk/exo.kernel.component.common/src/test/resources/conf/portal/test-configuration.xml
===================================================================
--- kernel/trunk/exo.kernel.component.common/src/test/resources/conf/portal/test-configuration.xml 2011-07-08 11:31:30 UTC (rev 4615)
+++ kernel/trunk/exo.kernel.component.common/src/test/resources/conf/portal/test-configuration.xml 2011-07-12 14:45:11 UTC (rev 4616)
@@ -134,7 +134,13 @@
<value-param>
<name>bindings-store-path</name>
<value>target/store-path.xml</value>
- </value-param>
+ </value-param>
+ <!-- This parameter is required in case your AS don't share the objects
+ by default and you need to be able to remove repositories dynamically -->
+ <value-param>
+ <name>overload-context-factory</name>
+ <value>true</value>
+ </value-param>
<properties-param>
<name>default-properties</name>
<description>Default initial context properties</description>
More information about the exo-jcr-commits
mailing list