geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From d...@apache.org
Subject svn commit: r433410 - in /geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context: AbstractUnmodifiableContext.java ImmutableContext.java UnmodifiableContext.java WritableContext.java
Date Mon, 21 Aug 2006 22:58:29 GMT
Author: dain
Date: Mon Aug 21 15:58:28 2006
New Revision: 433410

URL: http://svn.apache.org/viewvc?rev=433410&view=rev
Log:
Moved base data structrue from AbstractUnmodifiableContext to WritableContext.
Changed UnmodifiableContext to be a subclass of WritableContext.
Changed ImmutableContext to be a direct subclass of Abstractcontext.
Deleted UnmodifiableContext since is it no longer used.

Removed:
    geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/AbstractUnmodifiableContext.java
Modified:
    geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/ImmutableContext.java
    geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/UnmodifiableContext.java
    geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/WritableContext.java

Modified: geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/ImmutableContext.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/ImmutableContext.java?rev=433410&r1=433409&r2=433410&view=diff
==============================================================================
--- geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/ImmutableContext.java
(original)
+++ geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/ImmutableContext.java
Mon Aug 21 15:58:28 2006
@@ -31,7 +31,7 @@
  *
  * @version $Rev: 417891 $ $Date: 2006-06-28 15:45:07 -0700 (Wed, 28 Jun 2006) $
  */
-public class ImmutableContext extends AbstractUnmodifiableContext {
+public class ImmutableContext extends AbstractContext {
     private final Map localBindings;
     private final Map absoluteIndex;
 
@@ -85,19 +85,19 @@
         return localBindings;
     }
 
-    protected void addDeepBinding(String name, Object value, boolean createIntermediateContexts)
throws NamingException {
+    protected final void addDeepBinding(String name, Object value, boolean createIntermediateContexts)
throws NamingException {
         throw new OperationNotSupportedException("Context is immutable");
     }
 
-    protected void addBinding(String name, Object value, boolean rebind) throws NamingException
{
+    protected final void addBinding(String name, Object value, boolean rebind) throws NamingException
{
         throw new OperationNotSupportedException("Context is immutable");
     }
 
-    protected void removeDeepBinding(Name name, boolean pruneEmptyContexts) throws NamingException
{
+    protected final void removeDeepBinding(Name name, boolean pruneEmptyContexts) throws
NamingException {
         throw new OperationNotSupportedException("Context is immutable");
     }
 
-    protected void removeBinding(String name) throws NamingException {
+    protected final void removeBinding(String name) throws NamingException {
         throw new OperationNotSupportedException("Context is immutable");
     }
 
@@ -113,10 +113,62 @@
         return new NestedImmutableContext(path, bindings);
     }
 
+    public final void bind(Name name, Object obj) throws NamingException {
+        throw new OperationNotSupportedException("Context is read only");
+    }
+
+    public final void bind(String name, Object obj) throws NamingException {
+        throw new OperationNotSupportedException("Context is read only");
+    }
+
+    public final void close() throws NamingException {
+        throw new OperationNotSupportedException("Context is read only");
+    }
+
+    public final Context createSubcontext(Name name) throws NamingException {
+        throw new OperationNotSupportedException("Context is read only");
+    }
+
+    public final Context createSubcontext(String name) throws NamingException {
+        throw new OperationNotSupportedException("Context is read only");
+    }
+
+    public final void destroySubcontext(Name name) throws NamingException {
+        throw new OperationNotSupportedException("Context is read only");
+    }
+
+    public final void destroySubcontext(String name) throws NamingException {
+        throw new OperationNotSupportedException("Context is read only");
+    }
+
+    public final void rebind(Name name, Object obj) throws NamingException {
+        throw new OperationNotSupportedException("Context is read only");
+    }
+
+    public final void rebind(String name, Object obj) throws NamingException {
+        throw new OperationNotSupportedException("Context is read only");
+    }
+
+    public final void rename(Name oldName, Name newName) throws NamingException {
+        throw new OperationNotSupportedException("Context is read only");
+    }
+
+    public final void rename(String oldName, String newName) throws NamingException {
+        throw new OperationNotSupportedException("Context is read only");
+    }
+
+    public final void unbind(Name name) throws NamingException {
+        throw new OperationNotSupportedException("Context is read only");
+    }
+
+    public final void unbind(String name) throws NamingException {
+        throw new OperationNotSupportedException("Context is read only");
+    }
+
     /**
      * Nested context which shares the absolute index map in MapContext.
      */
-    public final class NestedImmutableContext extends AbstractUnmodifiableContext {
+    public final class NestedImmutableContext extends AbstractContext {
         private final Map localBindings;
         private final String pathWithSlash;
 
@@ -138,19 +190,19 @@
             return localBindings;
         }
 
-        protected void addDeepBinding(String name, Object value, boolean createIntermediateContexts)
throws NamingException {
+        protected final void addDeepBinding(String name, Object value, boolean createIntermediateContexts)
throws NamingException {
             throw new OperationNotSupportedException("Context is immutable");
         }
 
-        protected void addBinding(String name, Object value, boolean rebind) throws NamingException
{
+        protected final void addBinding(String name, Object value, boolean rebind) throws
NamingException {
             throw new OperationNotSupportedException("Context is immutable");
         }
 
-        protected void removeDeepBinding(Name name, boolean pruneEmptyContexts) throws NamingException
{
+        protected final void removeDeepBinding(Name name, boolean pruneEmptyContexts) throws
NamingException {
             throw new OperationNotSupportedException("Context is immutable");
         }
 
-        protected void removeBinding(String name) throws NamingException {
+        protected final void removeBinding(String name) throws NamingException {
             throw new OperationNotSupportedException("Context is immutable");
         }
 
@@ -166,8 +218,60 @@
             return new NestedImmutableContext(path, bindings);
         }
 
-        private ImmutableContext getImmutableContext() {
+        protected ImmutableContext getImmutableContext() {
             return ImmutableContext.this;
+        }
+
+        public final void bind(Name name, Object obj) throws NamingException {
+            throw new OperationNotSupportedException("Context is read only");
+        }
+
+        public final void bind(String name, Object obj) throws NamingException {
+            throw new OperationNotSupportedException("Context is read only");
+        }
+
+        public final void close() throws NamingException {
+            throw new OperationNotSupportedException("Context is read only");
+        }
+
+        public final Context createSubcontext(Name name) throws NamingException {
+            throw new OperationNotSupportedException("Context is read only");
+        }
+
+        public final Context createSubcontext(String name) throws NamingException {
+            throw new OperationNotSupportedException("Context is read only");
+        }
+
+        public final void destroySubcontext(Name name) throws NamingException {
+            throw new OperationNotSupportedException("Context is read only");
+        }
+
+        public final void destroySubcontext(String name) throws NamingException {
+            throw new OperationNotSupportedException("Context is read only");
+        }
+
+        public final void rebind(Name name, Object obj) throws NamingException {
+            throw new OperationNotSupportedException("Context is read only");
+        }
+
+        public final void rebind(String name, Object obj) throws NamingException {
+            throw new OperationNotSupportedException("Context is read only");
+        }
+
+        public final void rename(Name oldName, Name newName) throws NamingException {
+            throw new OperationNotSupportedException("Context is read only");
+        }
+
+        public final void rename(String oldName, String newName) throws NamingException {
+            throw new OperationNotSupportedException("Context is read only");
+        }
+
+        public final void unbind(Name name) throws NamingException {
+            throw new OperationNotSupportedException("Context is read only");
+        }
+
+        public final void unbind(String name) throws NamingException {
+            throw new OperationNotSupportedException("Context is read only");
         }
     }
 }

Modified: geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/UnmodifiableContext.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/UnmodifiableContext.java?rev=433410&r1=433409&r2=433410&view=diff
==============================================================================
--- geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/UnmodifiableContext.java
(original)
+++ geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/UnmodifiableContext.java
Mon Aug 21 15:58:28 2006
@@ -16,180 +16,109 @@
  */
 package org.apache.xbean.naming.context;
 
-import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicReference;
-import edu.emory.mathcs.backport.java.util.concurrent.locks.Lock;
-import edu.emory.mathcs.backport.java.util.concurrent.locks.ReentrantLock;
-import org.apache.xbean.naming.reference.CachingReference;
-
-import javax.naming.NameAlreadyBoundException;
-import javax.naming.NamingException;
 import javax.naming.Context;
-import javax.naming.NameNotFoundException;
+import javax.naming.Name;
+import javax.naming.NamingException;
 import javax.naming.OperationNotSupportedException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
 import java.util.Map;
 
 /**
  * @version $Rev: 417891 $ $Date: 2006-06-28 15:45:07 -0700 (Wed, 28 Jun 2006) $
  */
-public class UnmodifiableContext extends AbstractUnmodifiableContext {
-    private final Lock writeLock = new ReentrantLock();
-    private final AtomicReference bindingsRef;
-    private final AtomicReference indexRef;
-    public static final int MAX_WRITE_ATTEMPTS = 3;
+public class UnmodifiableContext extends WritableContext {
+    public UnmodifiableContext() throws NamingException {
+    }
+
+    public UnmodifiableContext(String nameInNamespace) throws NamingException {
+        super(nameInNamespace);
+    }
 
     public UnmodifiableContext(Map bindings) throws NamingException {
-        this("", bindings, true);
+        super(bindings);
     }
 
     public UnmodifiableContext(Map bindings, boolean cacheReferences) throws NamingException
{
-        this("", bindings, cacheReferences);
+        super(bindings, cacheReferences);
     }
 
     public UnmodifiableContext(String nameInNamespace, Map bindings, boolean cacheReferences)
throws NamingException {
-        super(nameInNamespace);
+        super(nameInNamespace, bindings, cacheReferences);
+    }
 
-        if (cacheReferences) {
-            bindings = CachingReference.wrapReferences(bindings);
+    public boolean isNestedSubcontext(Object value) {
+        if (value instanceof NestedUnmodifiableContext) {
+            NestedUnmodifiableContext context = (NestedUnmodifiableContext) value;
+            return this == context.getUnmodifiableContext();
         }
-
-        Map localBindings = ContextUtil.createBindings(bindings, this);
-
-        this.bindingsRef = new AtomicReference(Collections.unmodifiableMap(localBindings));
-        this.indexRef = new AtomicReference(Collections.unmodifiableMap(buildIndex("", localBindings)));
+        return false;
     }
 
-    protected void addBinding(String name, Object value, boolean rebind) throws NamingException
{
-        if (rebind) {
-            throw new OperationNotSupportedException("This conext does not support rebind");
-        }
+    public Context createNestedSubcontext(String path, Map bindings) {
+        return new NestedUnmodifiableContext(path,bindings);
+    }
 
-        writeLock.lock();
-        try {
-            Map bindings = (Map) bindingsRef.get();
-            if (bindings.containsKey(name)) {
-                throw new NameAlreadyBoundException(name);
-            }
+    public final void bind(Name name, Object obj) throws NamingException {
+        throw new OperationNotSupportedException("Context is read only");
+    }
 
-            Map newBindings = new HashMap(bindings);
-            newBindings.put(name,value);
-            bindingsRef.set(newBindings);
+    public final void bind(String name, Object obj) throws NamingException {
+        throw new OperationNotSupportedException("Context is read only");
+    }
 
-            Map newIndex = addToIndex(name, value);
-            indexRef.set(newIndex);
-        } finally {
-            writeLock.unlock();
-        }
+    public final void close() throws NamingException {
+        throw new OperationNotSupportedException("Context is read only");
     }
 
-    private Map addToIndex(String name, Object value) {
-        Map index = (Map) indexRef.get();
-        Map newIndex = new HashMap(index);
-        newIndex.put(name, value);
-        if (value instanceof NestedUnmodifiableContext) {
-            NestedUnmodifiableContext nestedcontext = (NestedUnmodifiableContext) value;
-            Map newIndexValues = buildIndex(name, nestedcontext.getBindings());
-            newIndex.putAll(newIndexValues);
-        }
-        return newIndex;
+    public final Context createSubcontext(Name name) throws NamingException {
+        throw new OperationNotSupportedException("Context is read only");
     }
 
-    protected void removeBinding(String name) throws NamingException {
-        writeLock.lock();
-        try {
-            Map bindings = (Map) bindingsRef.get();
-            if (!bindings.containsKey(name)) {
-                throw new NameNotFoundException(name);
-            }
+    public final Context createSubcontext(String name) throws NamingException {
+        throw new OperationNotSupportedException("Context is read only");
+    }
 
-            Map newBindings = new HashMap(bindings);
-            newBindings.remove(name);
-            bindingsRef.set(newBindings);
-
-            Map newIndex = removeFromIndex(name);
-            indexRef.set(newIndex);
-        } finally {
-            writeLock.unlock();
-        }
+    public final void destroySubcontext(Name name) throws NamingException {
+        throw new OperationNotSupportedException("Context is read only");
     }
 
-    private Map removeFromIndex(String name) {
-        Map index = (Map) indexRef.get();
-        Map newIndex = new HashMap(index);
-        Object oldValue = newIndex.remove(name);
-        if (oldValue instanceof NestedUnmodifiableContext) {
-            NestedUnmodifiableContext nestedcontext = (NestedUnmodifiableContext) oldValue;
-            Map removedIndexValues = buildIndex(name, nestedcontext.getBindings());
-            for (Iterator iterator = removedIndexValues.keySet().iterator(); iterator.hasNext();)
{
-                String key = (String) iterator.next();
-                newIndex.remove(key);
-            }
-        }
-        return newIndex;
+    public final void destroySubcontext(String name) throws NamingException {
+        throw new OperationNotSupportedException("Context is read only");
     }
 
-    public boolean isNestedSubcontext(Object value) {
-        if (value instanceof NestedUnmodifiableContext) {
-            NestedUnmodifiableContext context = (NestedUnmodifiableContext) value;
-            return this == context.getUnmodifiableContext();
-        }
-        return false;
+    public final void rebind(Name name, Object obj) throws NamingException {
+        throw new OperationNotSupportedException("Context is read only");
     }
 
-    public Context createNestedSubcontext(String path, Map bindings) {
-        return new NestedUnmodifiableContext(path,bindings);
+    public final void rebind(String name, Object obj) throws NamingException {
+        throw new OperationNotSupportedException("Context is read only");
     }
 
-    private static Map buildIndex(String nameInNamespace, Map bindings) {
-        String path = nameInNamespace;
-        if (path.length() > 0 && !path.endsWith("/")) {
-            path += "/";
-        }
+    public final void rename(Name oldName, Name newName) throws NamingException {
+        throw new OperationNotSupportedException("Context is read only");
+    }
 
-        Map absoluteIndex = new HashMap();
-        for (Iterator iterator = bindings.entrySet().iterator(); iterator.hasNext();) {
-            Map.Entry entry = (Map.Entry) iterator.next();
-            String name = (String) entry.getKey();
-            Object value = entry.getValue();
-            if (value instanceof UnmodifiableContext.NestedUnmodifiableContext) {
-                UnmodifiableContext.NestedUnmodifiableContext nestedContext = (UnmodifiableContext.NestedUnmodifiableContext)value;
-                absoluteIndex.putAll(UnmodifiableContext.buildIndex(nestedContext.pathWithSlash,
nestedContext.getBindings()));
-            }
-            absoluteIndex.put(path + name, value);
-        }
-        return absoluteIndex;
+    public final void rename(String oldName, String newName) throws NamingException {
+        throw new OperationNotSupportedException("Context is read only");
     }
 
-    protected Object getDeepBinding(String name) {
-        Map index = (Map) indexRef.get();
-        return index.get(name);
+    public final void unbind(Name name) throws NamingException {
+        throw new OperationNotSupportedException("Context is read only");
     }
 
-    protected Map getBindings() {
-        Map bindings = (Map) bindingsRef.get();
-        return bindings;
+    public final void unbind(String name) throws NamingException {
+        throw new OperationNotSupportedException("Context is read only");
     }
 
     /**
      * Nested context which shares the absolute index map in MapContext.
      */
-    public final class NestedUnmodifiableContext extends AbstractUnmodifiableContext {
-        private final AtomicReference bindingsRef;
-        private final String pathWithSlash;
-
+    public class NestedUnmodifiableContext extends NestedWritableContext {
         public NestedUnmodifiableContext(String path, String key, Object value) {
-            this(path, Collections.singletonMap(key, value));
+            super(path, key, value);
         }
 
         public NestedUnmodifiableContext(String path, Map bindings) {
-            super(UnmodifiableContext.this.getNameInNamespace(path));
-
-            if (!path.endsWith("/")) path += "/";
-            this.pathWithSlash = path;
-
-            this.bindingsRef = new AtomicReference(Collections.unmodifiableMap(bindings));
+            super(path, bindings);
         }
 
         public boolean isNestedSubcontext(Object value) {
@@ -204,54 +133,60 @@
             return new NestedUnmodifiableContext(path, bindings);
         }
 
-        protected Object getDeepBinding(String name) {
-            String absoluteName = pathWithSlash + name;
-            return UnmodifiableContext.this.getDeepBinding(absoluteName);
+        protected UnmodifiableContext getUnmodifiableContext() {
+            return UnmodifiableContext.this;
+        }
+        public final void bind(Name name, Object obj) throws NamingException {
+            throw new OperationNotSupportedException("Context is read only");
         }
 
-        protected Map getBindings() {
-            Map bindings = (Map) bindingsRef.get();
-            return bindings;
+        public final void bind(String name, Object obj) throws NamingException {
+            throw new OperationNotSupportedException("Context is read only");
         }
 
-        protected void addBinding(String name, Object value, boolean rebind) throws NamingException
{
-            if (rebind) {
-                throw new OperationNotSupportedException("This conext does not support rebind");
-            }
+        public final void close() throws NamingException {
+            throw new OperationNotSupportedException("Context is read only");
+        }
 
-            writeLock.lock();
-            try {
-                Map currentBindings = (Map) bindingsRef.get();
-                Map newBindings = new HashMap(currentBindings);
-                newBindings.put(name, value);
-                newBindings = Collections.unmodifiableMap(newBindings);
-                bindingsRef.set(newBindings);
-
-                Map newIndex = addToIndex(name, value);
-                indexRef.set(newIndex);
-            } finally {
-                writeLock.unlock();
-            }
+        public final Context createSubcontext(Name name) throws NamingException {
+            throw new OperationNotSupportedException("Context is read only");
         }
 
-        protected void removeBinding(String name) {
-            writeLock.lock();
-            try {
-                Map currentBindings = (Map) bindingsRef.get();
-                Map newBindings = new HashMap(currentBindings);
-                newBindings.remove(name);
-                newBindings = Collections.unmodifiableMap(newBindings);
-                bindingsRef.set(newBindings);
-
-                Map newIndex = removeFromIndex(name);
-                indexRef.set(newIndex);
-            } finally {
-                writeLock.unlock();
-            }
+        public final Context createSubcontext(String name) throws NamingException {
+            throw new OperationNotSupportedException("Context is read only");
         }
 
-        private UnmodifiableContext getUnmodifiableContext() {
-            return UnmodifiableContext.this;
+        public final void destroySubcontext(Name name) throws NamingException {
+            throw new OperationNotSupportedException("Context is read only");
+        }
+
+        public final void destroySubcontext(String name) throws NamingException {
+            throw new OperationNotSupportedException("Context is read only");
+        }
+
+        public final void rebind(Name name, Object obj) throws NamingException {
+            throw new OperationNotSupportedException("Context is read only");
+        }
+
+        public final void rebind(String name, Object obj) throws NamingException {
+            throw new OperationNotSupportedException("Context is read only");
+        }
+
+        public final void rename(Name oldName, Name newName) throws NamingException {
+            throw new OperationNotSupportedException("Context is read only");
+        }
+
+        public final void rename(String oldName, String newName) throws NamingException {
+            throw new OperationNotSupportedException("Context is read only");
+        }
+
+        public final void unbind(Name name) throws NamingException {
+            throw new OperationNotSupportedException("Context is read only");
+        }
+
+        public final void unbind(String name) throws NamingException {
+            throw new OperationNotSupportedException("Context is read only");
         }
+
     }
 }

Modified: geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/WritableContext.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/WritableContext.java?rev=433410&r1=433409&r2=433410&view=diff
==============================================================================
--- geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/WritableContext.java
(original)
+++ geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/WritableContext.java
Mon Aug 21 15:58:28 2006
@@ -16,53 +16,251 @@
  */
 package org.apache.xbean.naming.context;
 
+import edu.emory.mathcs.backport.java.util.concurrent.locks.Lock;
+import edu.emory.mathcs.backport.java.util.concurrent.locks.ReentrantLock;
+import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicReference;
+
 import javax.naming.Context;
 import javax.naming.NameAlreadyBoundException;
 import javax.naming.NamingException;
+import javax.naming.OperationNotSupportedException;
+import javax.naming.NameNotFoundException;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Collections;
+import java.util.Iterator;
+
+import org.apache.xbean.naming.reference.CachingReference;
 
 /**
  * @version $Rev$ $Date$
  */
 public class WritableContext extends AbstractContext {
-    protected final Map bindings;
+    private final Lock writeLock = new ReentrantLock();
+    private final AtomicReference bindingsRef;
+    private final AtomicReference indexRef;
+    public static final int MAX_WRITE_ATTEMPTS = 3;
 
-    public WritableContext() {
-        super("");
-        bindings = new HashMap();
+    public WritableContext() throws NamingException {
+        this("", Collections.EMPTY_MAP, true);
     }
 
-    public WritableContext(String nameInNamespace) {
+    public WritableContext(String nameInNamespace) throws NamingException {
+        this(nameInNamespace, Collections.EMPTY_MAP, true);
+    }
+
+    public WritableContext(Map bindings) throws NamingException {
+        this("", bindings, true);
+    }
+
+    public WritableContext(Map bindings, boolean cacheReferences) throws NamingException
{
+        this("", bindings, cacheReferences);
+    }
+
+    public WritableContext(String nameInNamespace, Map bindings, boolean cacheReferences)
throws NamingException {
         super(nameInNamespace);
-        bindings = new HashMap();
+
+        if (cacheReferences) {
+            bindings = CachingReference.wrapReferences(bindings);
+        }
+
+        Map localBindings = ContextUtil.createBindings(bindings, this);
+
+        this.bindingsRef = new AtomicReference(Collections.unmodifiableMap(localBindings));
+        this.indexRef = new AtomicReference(Collections.unmodifiableMap(buildIndex("", localBindings)));
+    }
+
+    protected void addBinding(String name, Object value, boolean rebind) throws NamingException
{
+        if (rebind) {
+            throw new OperationNotSupportedException("This conext does not support rebind");
+        }
+
+        writeLock.lock();
+        try {
+            Map bindings = (Map) bindingsRef.get();
+            if (bindings.containsKey(name)) {
+                throw new NameAlreadyBoundException(name);
+            }
+
+            Map newBindings = new HashMap(bindings);
+            newBindings.put(name,value);
+            bindingsRef.set(newBindings);
+
+            Map newIndex = addToIndex(name, value);
+            indexRef.set(newIndex);
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    private Map addToIndex(String name, Object value) {
+        Map index = (Map) indexRef.get();
+        Map newIndex = new HashMap(index);
+        newIndex.put(name, value);
+        if (value instanceof NestedWritableContext) {
+            NestedWritableContext nestedcontext = (NestedWritableContext) value;
+            Map newIndexValues = buildIndex(name, nestedcontext.getBindings());
+            newIndex.putAll(newIndexValues);
+        }
+        return newIndex;
+    }
+
+    protected void removeBinding(String name) throws NamingException {
+        writeLock.lock();
+        try {
+            Map bindings = (Map) bindingsRef.get();
+            if (!bindings.containsKey(name)) {
+                throw new NameNotFoundException(name);
+            }
+
+            Map newBindings = new HashMap(bindings);
+            newBindings.remove(name);
+            bindingsRef.set(newBindings);
+
+            Map newIndex = removeFromIndex(name);
+            indexRef.set(newIndex);
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    private Map removeFromIndex(String name) {
+        Map index = (Map) indexRef.get();
+        Map newIndex = new HashMap(index);
+        Object oldValue = newIndex.remove(name);
+        if (oldValue instanceof NestedWritableContext) {
+            NestedWritableContext nestedcontext = (NestedWritableContext) oldValue;
+            Map removedIndexValues = buildIndex(name, nestedcontext.getBindings());
+            for (Iterator iterator = removedIndexValues.keySet().iterator(); iterator.hasNext();)
{
+                String key = (String) iterator.next();
+                newIndex.remove(key);
+            }
+        }
+        return newIndex;
     }
 
     public boolean isNestedSubcontext(Object value) {
+        if (value instanceof NestedWritableContext) {
+            NestedWritableContext context = (NestedWritableContext) value;
+            return this == context.getUnmodifiableContext();
+        }
         return false;
     }
 
     public Context createNestedSubcontext(String path, Map bindings) {
-        return new WritableContext(getNameInNamespace(path));
+        return new NestedWritableContext(path,bindings);
+    }
+
+    private static Map buildIndex(String nameInNamespace, Map bindings) {
+        String path = nameInNamespace;
+        if (path.length() > 0 && !path.endsWith("/")) {
+            path += "/";
+        }
+
+        Map absoluteIndex = new HashMap();
+        for (Iterator iterator = bindings.entrySet().iterator(); iterator.hasNext();) {
+            Map.Entry entry = (Map.Entry) iterator.next();
+            String name = (String) entry.getKey();
+            Object value = entry.getValue();
+            if (value instanceof NestedWritableContext) {
+                NestedWritableContext nestedContext = (NestedWritableContext)value;
+                absoluteIndex.putAll(buildIndex(nestedContext.pathWithSlash, nestedContext.getBindings()));
+            }
+            absoluteIndex.put(path + name, value);
+        }
+        return absoluteIndex;
+    }
+
+    protected Object getDeepBinding(String name) {
+        Map index = (Map) indexRef.get();
+        return index.get(name);
     }
 
     protected Map getBindings() {
+        Map bindings = (Map) bindingsRef.get();
         return bindings;
     }
 
-    protected void addBinding(String name, Object value, boolean rebind) throws NamingException
{
-        synchronized (bindings) {
-            if (rebind || !bindings.containsKey(name)) {
-                bindings.put(name, value);
-            } else {
-                throw new NameAlreadyBoundException("The name " + name + " is already bound");
+    /**
+     * Nested context which shares the absolute index map in MapContext.
+     */
+    public class NestedWritableContext extends AbstractContext {
+        private final AtomicReference bindingsRef;
+        private final String pathWithSlash;
+
+        public NestedWritableContext(String path, String key, Object value) {
+            this(path, Collections.singletonMap(key, value));
+        }
+
+        public NestedWritableContext(String path, Map bindings) {
+            super(WritableContext.this.getNameInNamespace(path));
+
+            if (!path.endsWith("/")) path += "/";
+            this.pathWithSlash = path;
+
+            this.bindingsRef = new AtomicReference(Collections.unmodifiableMap(bindings));
+        }
+
+        public boolean isNestedSubcontext(Object value) {
+            if (value instanceof NestedWritableContext) {
+                NestedWritableContext context = (NestedWritableContext) value;
+                return getUnmodifiableContext() == context.getUnmodifiableContext();
             }
+            return false;
         }
-    }
 
-    protected void removeBinding(String name) throws NamingException {
-        synchronized (bindings) {
-            bindings.remove(name);
+        public Context createNestedSubcontext(String path, Map bindings) {
+            return new NestedWritableContext(path, bindings);
+        }
+
+        protected Object getDeepBinding(String name) {
+            String absoluteName = pathWithSlash + name;
+            return WritableContext.this.getDeepBinding(absoluteName);
+        }
+
+        protected Map getBindings() {
+            Map bindings = (Map) bindingsRef.get();
+            return bindings;
+        }
+
+        protected void addBinding(String name, Object value, boolean rebind) throws NamingException
{
+            if (rebind) {
+                throw new OperationNotSupportedException("This conext does not support rebind");
+            }
+
+            writeLock.lock();
+            try {
+                Map currentBindings = (Map) bindingsRef.get();
+                Map newBindings = new HashMap(currentBindings);
+                newBindings.put(name, value);
+                newBindings = Collections.unmodifiableMap(newBindings);
+                bindingsRef.set(newBindings);
+
+                Map newIndex = addToIndex(name, value);
+                indexRef.set(newIndex);
+            } finally {
+                writeLock.unlock();
+            }
+        }
+
+        protected void removeBinding(String name) {
+            writeLock.lock();
+            try {
+                Map currentBindings = (Map) bindingsRef.get();
+                Map newBindings = new HashMap(currentBindings);
+                newBindings.remove(name);
+                newBindings = Collections.unmodifiableMap(newBindings);
+                bindingsRef.set(newBindings);
+
+                Map newIndex = removeFromIndex(name);
+                indexRef.set(newIndex);
+            } finally {
+                writeLock.unlock();
+            }
+        }
+
+        private WritableContext getUnmodifiableContext() {
+            return WritableContext.this;
         }
     }
 }



Mime
View raw message