[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