You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by da...@apache.org on 2006/08/22 00:58:29 UTC
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
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;
}
}
}