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/23 22:29:24 UTC
svn commit: r434162 - in /geronimo/xbean/branches/colossus/xbean-naming/src:
main/java/org/apache/xbean/naming/context/
test/java/org/apache/xbean/naming/context/
Author: dain
Date: Wed Aug 23 13:29:23 2006
New Revision: 434162
URL: http://svn.apache.org/viewvc?rev=434162&view=rev
Log:
Added basic support for federation
Added:
geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/ContextFederation.java
geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/VirtualSubcontext.java
geronimo/xbean/branches/colossus/xbean-naming/src/test/java/org/apache/xbean/naming/context/FederationTest.java
Modified:
geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/AbstractContext.java
geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/ContextUtil.java
geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/NestedContextFactory.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
geronimo/xbean/branches/colossus/xbean-naming/src/test/java/org/apache/xbean/naming/context/AbstractContextTest.java
Modified: geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/AbstractContext.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/AbstractContext.java?rev=434162&r1=434161&r2=434162&view=diff
==============================================================================
--- geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/AbstractContext.java (original)
+++ geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/AbstractContext.java Wed Aug 23 13:29:23 2006
@@ -36,9 +36,15 @@
public abstract class AbstractContext implements Context, NestedContextFactory, Serializable {
private static final long serialVersionUID = 6481918425692261483L;
private final String nameInNamespace;
+ private final Name parsedNameInNamespace;
protected AbstractContext(String nameInNamespace) {
this.nameInNamespace = nameInNamespace;
+ try {
+ this.parsedNameInNamespace = getNameParser().parse(nameInNamespace);
+ } catch (NamingException e) {
+ throw new RuntimeException(e);
+ }
}
@@ -134,6 +140,21 @@
}
// if we didn't find an entry, it may be an absolute name
+ Object value = faultLookup(stringName, parsedName);
+ if (value != null) {
+ return value;
+ }
+ throw new NameNotFoundException(stringName);
+ }
+
+ /**
+ * When a value can not be found within this context, this method is called as a last ditch effort befrore
+ * thowing a null pointer exception.
+ * @param stringName the string version of the name; will not be null
+ * @param parsedName the parsed name; will not be null
+ * @return the value or null if no fault value could be found
+ */
+ protected Object faultLookup(String stringName, Name parsedName) {
if (stringName.indexOf(':') > 0) {
try {
Context ctx = new InitialContext();
@@ -142,7 +163,7 @@
// thrown below
}
}
- throw new NameNotFoundException(stringName);
+ return null;
}
protected Context lookupFinalContext(Name name) throws NamingException {
@@ -456,6 +477,15 @@
}
/**
+ * Gets the name of this context withing the global namespace. This method may return null
+ * if the location of the node in the global namespace is not known
+ * @return the name of this context within the global namespace or null if unknown.
+ */
+ protected Name getParsedNameInNamespace() {
+ return parsedNameInNamespace;
+ }
+
+ /**
* Gets the name of a path withing the global namespace context.
*/
protected String getNameInNamespace(String path) {
@@ -464,6 +494,18 @@
return path;
} else {
return nameInNamespace + "/" + path;
+ }
+ }
+
+ /**
+ * Gets the name of a path withing the global namespace context.
+ */
+ protected Name getNameInNamespace(Name path) throws NamingException {
+ Name nameInNamespace = getParsedNameInNamespace();
+ if (nameInNamespace == null || nameInNamespace.size() == 0) {
+ return path;
+ } else {
+ return composeName(nameInNamespace, path);
}
}
Added: geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/ContextFederation.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/ContextFederation.java?rev=434162&view=auto
==============================================================================
--- geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/ContextFederation.java (added)
+++ geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/ContextFederation.java Wed Aug 23 13:29:23 2006
@@ -0,0 +1,106 @@
+/**
+ *
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.xbean.naming.context;
+
+import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicReference;
+
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.NamingException;
+import javax.naming.NamingEnumeration;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ContextFederation {
+ private final Context actualContext;
+ private final AtomicReference federatedContextRef = new AtomicReference(Collections.EMPTY_SET);
+ public static final int MAX_WRITE_ATTEMPTS = 10;
+
+ public ContextFederation(Context actualContext) {
+ this.actualContext = actualContext;
+ }
+
+ public void addContext(Context context) {
+ Set federatedContext;
+ Set newFederatedContext;
+ for (int i = 0; i < MAX_WRITE_ATTEMPTS; i++) {
+ federatedContext = getFederatedContexts();
+
+ newFederatedContext = new LinkedHashSet(federatedContext);
+ newFederatedContext.add(context);
+ newFederatedContext = Collections.unmodifiableSet(newFederatedContext);
+ if (federatedContextRef.compareAndSet(federatedContext, newFederatedContext)) {
+ return;
+ }
+ }
+ throw new RuntimeException("Unable to update federatedContextRef within " + MAX_WRITE_ATTEMPTS + " attempts");
+ }
+
+ public Set getFederatedContexts() {
+ return (Set) federatedContextRef.get();
+ }
+
+ public Map getFederatedBindings() throws NamingException {
+ Map bindings = new HashMap();
+ for (Iterator iterator = getFederatedContexts().iterator(); iterator.hasNext();) {
+ Context context = (Context) iterator.next();
+
+ // list federated context
+ NamingEnumeration namingEnumeration = context.listBindings("");
+
+ // add to bindings
+ Map map = ContextUtil.listBindingsToMap(namingEnumeration);
+ bindings.putAll(map);
+ }
+ return bindings;
+ }
+
+ public Object lookup(Name name) {
+ for (Iterator iterator = getFederatedContexts().iterator(); iterator.hasNext();) {
+ try {
+ Context federatedContext = (Context) iterator.next();
+ Object value = federatedContext.lookup(name);
+ if (value instanceof Context) {
+ return new VirtualSubcontext(name, actualContext);
+ } else {
+ return value;
+ }
+ } catch (NamingException ignored) {
+ }
+ }
+ return null;
+ }
+
+ public ContextFederation createSubcontextFederation(String subcontextName, Context actualSubcontext) throws NamingException {
+ Name parsedSubcontextName = actualContext.getNameParser("").parse(subcontextName);
+
+ ContextFederation subcontextFederation = new ContextFederation(actualSubcontext);
+ for (Iterator iterator = getFederatedContexts().iterator(); iterator.hasNext();) {
+ Context federatedContext = (Context) iterator.next();
+ VirtualSubcontext virtualSubcontext = new VirtualSubcontext(parsedSubcontextName, federatedContext);
+ subcontextFederation.addContext(virtualSubcontext);
+ }
+ return subcontextFederation;
+ }
+}
Modified: geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/ContextUtil.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/ContextUtil.java?rev=434162&r1=434161&r2=434162&view=diff
==============================================================================
--- geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/ContextUtil.java (original)
+++ geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/ContextUtil.java Wed Aug 23 13:29:23 2006
@@ -20,20 +20,20 @@
import javax.naming.Binding;
import javax.naming.CompoundName;
+import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NameClassPair;
import javax.naming.NameParser;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.Reference;
-import javax.naming.Context;
import javax.naming.spi.NamingManager;
+import java.util.Enumeration;
+import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
-import java.util.HashMap;
-import java.util.Enumeration;
/**
* @version $Rev$ $Date$
@@ -86,6 +86,26 @@
}
}
+ public static Map listToMap(NamingEnumeration enumeration) {
+ Map result = new HashMap();
+ while (enumeration.hasMoreElements()) {
+ NameClassPair nameClassPair = (NameClassPair) enumeration.nextElement();
+ String name = nameClassPair.getName();
+ result.put(name, nameClassPair.getClassName());
+ }
+ return result;
+ }
+
+ public static Map listBindingsToMap(NamingEnumeration enumeration) {
+ Map result = new HashMap();
+ while (enumeration.hasMoreElements()) {
+ Binding binding = (Binding) enumeration.nextElement();
+ String name = binding.getName();
+ result.put(name, binding.getObject());
+ }
+ return result;
+ }
+
public static final class ListEnumeration implements NamingEnumeration {
private final Iterator iterator;
@@ -226,7 +246,7 @@
return localBindings;
}
- private static Map createBindings(String nameInNameSpace, Node node, NestedContextFactory factory) {
+ private static Map createBindings(String nameInNameSpace, Node node, NestedContextFactory factory) throws NamingException {
Map bindings = new HashMap(node.size());
for (Iterator iterator = node.entrySet().iterator(); iterator.hasNext();) {
Map.Entry entry = (Map.Entry) iterator.next();
Modified: geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/NestedContextFactory.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/NestedContextFactory.java?rev=434162&r1=434161&r2=434162&view=diff
==============================================================================
--- geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/NestedContextFactory.java (original)
+++ geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/NestedContextFactory.java Wed Aug 23 13:29:23 2006
@@ -17,6 +17,7 @@
package org.apache.xbean.naming.context;
import javax.naming.Context;
+import javax.naming.NamingException;
import java.util.Map;
/**
@@ -36,5 +37,5 @@
* @param bindings the initial bindings for the context
* @return the new nested context
*/
- Context createNestedSubcontext(String path, Map bindings);
+ Context createNestedSubcontext(String path, Map bindings) throws NamingException;
}
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=434162&r1=434161&r2=434162&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 Wed Aug 23 13:29:23 2006
@@ -53,8 +53,8 @@
return false;
}
- public Context createNestedSubcontext(String path, Map bindings) {
- return new NestedUnmodifiableContext(path,bindings);
+ public Context createNestedSubcontext(String path, Map bindings) throws NamingException {
+ return new NestedUnmodifiableContext(path, bindings, contextFederation);
}
public final void bind(Name name, Object obj) throws NamingException {
@@ -113,12 +113,8 @@
* Nested context which shares the absolute index map in MapContext.
*/
public class NestedUnmodifiableContext extends NestedWritableContext {
- public NestedUnmodifiableContext(String path, String key, Object value) {
- super(path, key, value);
- }
-
- public NestedUnmodifiableContext(String path, Map bindings) {
- super(path, bindings);
+ public NestedUnmodifiableContext(String path, Map bindings, ContextFederation contextFederation) throws NamingException {
+ super(path, bindings, contextFederation);
}
public boolean isNestedSubcontext(Object value) {
@@ -129,8 +125,8 @@
return false;
}
- public Context createNestedSubcontext(String path, Map bindings) {
- return new NestedUnmodifiableContext(path, bindings);
+ public Context createNestedSubcontext(String path, Map bindings) throws NamingException {
+ return new NestedUnmodifiableContext(path, bindings, contextFederation);
}
protected UnmodifiableContext getUnmodifiableContext() {
Added: geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/VirtualSubcontext.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/VirtualSubcontext.java?rev=434162&view=auto
==============================================================================
--- geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/VirtualSubcontext.java (added)
+++ geronimo/xbean/branches/colossus/xbean-naming/src/main/java/org/apache/xbean/naming/context/VirtualSubcontext.java Wed Aug 23 13:29:23 2006
@@ -0,0 +1,169 @@
+/**
+ *
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.xbean.naming.context;
+
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.NamingException;
+import javax.naming.NamingEnumeration;
+import javax.naming.NameParser;
+import java.util.Hashtable;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class VirtualSubcontext implements Context {
+ private final Name nameInContext;
+ private final Context context;
+
+ public VirtualSubcontext(Name nameInContext, Context context) throws NamingException {
+ if (context instanceof VirtualSubcontext) {
+ VirtualSubcontext virtualSubcontext = (VirtualSubcontext) context;
+ this.nameInContext = virtualSubcontext.getNameInContext(nameInContext);
+ this.context = virtualSubcontext.context;
+ } else {
+ this.nameInContext = nameInContext;
+ this.context = context;
+ }
+ }
+
+ private Name getNameInContext(Name name) throws NamingException {
+ return context.composeName(nameInContext, name);
+ }
+
+ private Name getNameInContext(String name) throws NamingException {
+ Name parsedName = context.getNameParser("").parse(name);
+ return context.composeName(nameInContext, parsedName);
+ }
+
+ public Object lookup(Name name) throws NamingException {
+ return context.lookup(getNameInContext(name));
+ }
+
+ public Object lookup(String name) throws NamingException {
+ return context.lookup(getNameInContext(name));
+ }
+
+ public void bind(Name name, Object obj) throws NamingException {
+ context.bind(getNameInContext(name), obj);
+ }
+
+ public void bind(String name, Object obj) throws NamingException {
+ context.bind(getNameInContext(name), obj);
+ }
+
+ public void rebind(Name name, Object obj) throws NamingException {
+ context.rebind(getNameInContext(name), obj);
+ }
+
+ public void rebind(String name, Object obj) throws NamingException {
+ context.rebind(getNameInContext(name), obj);
+ }
+
+ public void unbind(Name name) throws NamingException {
+ context.unbind(getNameInContext(name));
+ }
+
+ public void unbind(String name) throws NamingException {
+ context.unbind(getNameInContext(name));
+ }
+
+ public void rename(Name oldName, Name newName) throws NamingException {
+ context.rename(getNameInContext(oldName), getNameInContext(newName));
+ }
+
+ public void rename(String oldName, String newName) throws NamingException {
+ context.rename(getNameInContext(oldName), getNameInContext(newName));
+ }
+
+ public NamingEnumeration list(Name name) throws NamingException {
+ return context.list(getNameInContext(name));
+ }
+
+ public NamingEnumeration list(String name) throws NamingException {
+ return context.list(getNameInContext(name));
+ }
+
+ public NamingEnumeration listBindings(Name name) throws NamingException {
+ return context.listBindings(getNameInContext(name));
+ }
+
+ public NamingEnumeration listBindings(String name) throws NamingException {
+ return context.listBindings(getNameInContext(name));
+ }
+
+ public void destroySubcontext(Name name) throws NamingException {
+ context.destroySubcontext(getNameInContext(name));
+ }
+
+ public void destroySubcontext(String name) throws NamingException {
+ context.destroySubcontext(getNameInContext(name));
+ }
+
+ public Context createSubcontext(Name name) throws NamingException {
+ return context.createSubcontext(getNameInContext(name));
+ }
+
+ public Context createSubcontext(String name) throws NamingException {
+ return context.createSubcontext(getNameInContext(name));
+ }
+
+ public Object lookupLink(Name name) throws NamingException {
+ return context.lookupLink(getNameInContext(name));
+ }
+
+ public Object lookupLink(String name) throws NamingException {
+ return context.lookupLink(getNameInContext(name));
+ }
+
+ public NameParser getNameParser(Name name) throws NamingException {
+ return context.getNameParser(getNameInContext(name));
+ }
+
+ public NameParser getNameParser(String name) throws NamingException {
+ return context.getNameParser(getNameInContext(name));
+ }
+
+ public Name composeName(Name name, Name prefix) throws NamingException {
+ return context.composeName(name, prefix);
+ }
+
+ public String composeName(String name, String prefix) throws NamingException {
+ return context.composeName(name, prefix);
+ }
+
+ public Object addToEnvironment(String propName, Object propVal) throws NamingException {
+ return context.addToEnvironment(propName, propVal);
+ }
+
+ public Object removeFromEnvironment(String propName) throws NamingException {
+ return context.removeFromEnvironment(propName);
+ }
+
+ public Hashtable getEnvironment() throws NamingException {
+ return context.getEnvironment();
+ }
+
+ public void close() throws NamingException {
+ context.close();
+ }
+
+ public String getNameInNamespace() throws NamingException {
+ Name parsedNameInNamespace = context.getNameParser("").parse(context.getNameInNamespace());
+ return context.composeName(parsedNameInNamespace, nameInContext).toString();
+ }
+}
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=434162&r1=434161&r2=434162&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 Wed Aug 23 13:29:23 2006
@@ -16,21 +16,20 @@
*/
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 edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicReference;
+import org.apache.xbean.naming.reference.CachingReference;
import javax.naming.Context;
-import javax.naming.NameAlreadyBoundException;
-import javax.naming.NamingException;
-import javax.naming.OperationNotSupportedException;
+import javax.naming.Name;
import javax.naming.NameNotFoundException;
-import java.util.HashMap;
-import java.util.Map;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
import java.util.Collections;
+import java.util.HashMap;
import java.util.Iterator;
-
-import org.apache.xbean.naming.reference.CachingReference;
+import java.util.Map;
/**
* @version $Rev$ $Date$
@@ -39,7 +38,7 @@
private final Lock writeLock = new ReentrantLock();
private final AtomicReference bindingsRef;
private final AtomicReference indexRef;
- public static final int MAX_WRITE_ATTEMPTS = 3;
+ protected final ContextFederation contextFederation = new ContextFederation(this);
public WritableContext() throws NamingException {
this("", Collections.EMPTY_MAP, true);
@@ -70,12 +69,55 @@
this.indexRef = new AtomicReference(Collections.unmodifiableMap(buildIndex("", localBindings)));
}
+ protected Object faultLookup(String stringName, Name parsedName) {
+ Object value = contextFederation.lookup(parsedName);
+ if (value != null) {
+ return value;
+ }
+ return super.faultLookup(stringName, parsedName);
+ }
+
+ protected NamingEnumeration list() throws NamingException {
+ Map bindings = getListBindings();
+ return new ContextUtil.ListEnumeration(bindings);
+ }
+
+ protected NamingEnumeration listBindings() throws NamingException {
+ Map bindings = getListBindings();
+ return new ContextUtil.ListBindingEnumeration(bindings);
+ }
+
+ protected Map getListBindings() throws NamingException {
+ Map bindings = new HashMap();
+ bindings.putAll(getBindings());
+ bindings.putAll(contextFederation.getFederatedBindings());
+ return bindings;
+ }
+
protected void addBinding(String name, Object value, boolean rebind) throws NamingException {
+ addBinding(bindingsRef, name, value);
+ }
+
+ protected void addBinding(AtomicReference bindingsRef, String name, Object value) throws NamingException {
writeLock.lock();
try {
Map bindings = (Map) bindingsRef.get();
- if (bindings.containsKey(name)) {
- throw new NameAlreadyBoundException(name);
+
+ if (value instanceof Context && !isNestedSubcontext(value)) {
+ Context federatedContext = (Context) value;
+
+ // if we already have a context bound at the specified value
+ if (bindings.containsKey(name)) {
+ NestedWritableContext nestedContext = (NestedWritableContext) bindings.get(name);
+ // push new context into all children
+ Map nestedBindings = (Map) nestedContext.bindingsRef.get();
+ addFederatedContext(nestedBindings, federatedContext);
+ return;
+ }
+
+ NestedWritableContext nestedContext = (NestedWritableContext) createNestedSubcontext(name, Collections.EMPTY_MAP);
+ nestedContext.contextFederation.addContext(federatedContext);
+ value = nestedContext;
}
Map newBindings = new HashMap(bindings);
@@ -89,6 +131,18 @@
}
}
+ protected void addFederatedContext(Map bindings, Context federatedContext) {
+ for (Iterator iterator = bindings.values().iterator(); iterator.hasNext();) {
+ Object value = iterator.next();
+ if (value instanceof NestedWritableContext) {
+ NestedWritableContext nestedContext = (NestedWritableContext) value;
+ nestedContext.contextFederation.addContext(federatedContext);
+ Map nestedBindings = (Map) nestedContext.bindingsRef.get();
+ addFederatedContext(nestedBindings, federatedContext);
+ }
+ }
+ }
+
private Map addToIndex(String name, Object value) {
Map index = (Map) indexRef.get();
Map newIndex = new HashMap(index);
@@ -102,6 +156,10 @@
}
protected void removeBinding(String name) throws NamingException {
+ removeBinding(bindingsRef, name);
+ }
+
+ private void removeBinding(AtomicReference bindingsRef, String name) throws NameNotFoundException {
writeLock.lock();
try {
Map bindings = (Map) bindingsRef.get();
@@ -143,8 +201,8 @@
return false;
}
- public Context createNestedSubcontext(String path, Map bindings) {
- return new NestedWritableContext(path,bindings);
+ public Context createNestedSubcontext(String path, Map bindings) throws NamingException {
+ return new NestedWritableContext(path,bindings, contextFederation);
}
private static Map buildIndex(String nameInNamespace, Map bindings) {
@@ -183,18 +241,17 @@
public class NestedWritableContext extends AbstractContext {
private final AtomicReference bindingsRef;
private final String pathWithSlash;
+ protected final ContextFederation contextFederation;
- public NestedWritableContext(String path, String key, Object value) {
- this(path, Collections.singletonMap(key, value));
- }
-
- public NestedWritableContext(String path, Map bindings) {
+ public NestedWritableContext(String path, Map bindings, ContextFederation parentContextFederation) throws NamingException {
super(WritableContext.this.getNameInNamespace(path));
if (!path.endsWith("/")) path += "/";
this.pathWithSlash = path;
this.bindingsRef = new AtomicReference(Collections.unmodifiableMap(bindings));
+
+ this.contextFederation = parentContextFederation.createSubcontextFederation(path, this);
}
public boolean isNestedSubcontext(Object value) {
@@ -205,8 +262,8 @@
return false;
}
- public Context createNestedSubcontext(String path, Map bindings) {
- return new NestedWritableContext(path, bindings);
+ public Context createNestedSubcontext(String path, Map bindings) throws NamingException {
+ return new NestedWritableContext(path, bindings, contextFederation);
}
protected Object getDeepBinding(String name) {
@@ -219,40 +276,37 @@
return bindings;
}
- protected void addBinding(String name, Object value, boolean rebind) throws NamingException {
- if (rebind) {
- throw new OperationNotSupportedException("This conext does not support rebind");
+ protected Object faultLookup(String stringName, Name parsedName) {
+ Object value = contextFederation.lookup(parsedName);
+ if (value != null) {
+ return value;
}
+ return super.faultLookup(stringName, parsedName);
+ }
- 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 NamingEnumeration list() throws NamingException {
+ Map bindings = getListBindings();
+ return new ContextUtil.ListEnumeration(bindings);
}
- 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();
- }
+ protected NamingEnumeration listBindings() throws NamingException {
+ Map bindings = getListBindings();
+ return new ContextUtil.ListBindingEnumeration(bindings);
+ }
+
+ protected Map getListBindings() throws NamingException {
+ Map bindings = new HashMap();
+ bindings.putAll(getBindings());
+ bindings.putAll(contextFederation.getFederatedBindings());
+ return bindings;
+ }
+
+ protected void addBinding(String name, Object value, boolean rebind) throws NamingException {
+ WritableContext.this.addBinding(bindingsRef, name, value);
+ }
+
+ protected void removeBinding(String name) throws NameNotFoundException {
+ WritableContext.this.removeBinding(bindingsRef, name);
}
private WritableContext getUnmodifiableContext() {
Modified: geronimo/xbean/branches/colossus/xbean-naming/src/test/java/org/apache/xbean/naming/context/AbstractContextTest.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/branches/colossus/xbean-naming/src/test/java/org/apache/xbean/naming/context/AbstractContextTest.java?rev=434162&r1=434161&r2=434162&view=diff
==============================================================================
--- geronimo/xbean/branches/colossus/xbean-naming/src/test/java/org/apache/xbean/naming/context/AbstractContextTest.java (original)
+++ geronimo/xbean/branches/colossus/xbean-naming/src/test/java/org/apache/xbean/naming/context/AbstractContextTest.java Wed Aug 23 13:29:23 2006
@@ -22,12 +22,9 @@
import javax.naming.NamingException;
import javax.naming.Name;
import javax.naming.NamingEnumeration;
-import javax.naming.NameClassPair;
-import javax.naming.Binding;
import java.util.Map;
import java.util.Iterator;
import java.util.TreeSet;
-import java.util.HashMap;
/**
* @version $Rev$ $Date$
@@ -114,9 +111,9 @@
public static void assertListResults(ContextUtil.Node node, NamingEnumeration enumeration, String contextName, String name, boolean wasListBinding) {
Map actualValues;
if (wasListBinding) {
- actualValues = AbstractContextTest.toListBindingResults(enumeration);
+ actualValues = ContextUtil.listBindingsToMap(enumeration);
} else {
- actualValues = AbstractContextTest.toListResults(enumeration);
+ actualValues = ContextUtil.listToMap(enumeration);
}
for (Iterator iterator = node.entrySet().iterator(); iterator.hasNext();) {
@@ -129,14 +126,14 @@
assertNotNull("list of " + name + " on " + contextName + " did not find value for " + name, actualValue);
if (wasListBinding) {
if (expectedValue instanceof ContextUtil.Node) {
- assertTrue("Expected list of " + name + " on " + contextName + " result value for " + name + " to return a Context, but got a " + actualValue.getClass().getName(),
+ assertTrue("Expected list of " + name + " on " + contextName + " result value for " + expectedName + " to return a Context, but got a " + actualValue.getClass().getName(),
actualValue instanceof Context);
} else {
- assertEquals("list of " + name + " on " + contextName + " for value for " + name, expectedValue, actualValue);
+ assertEquals("list of " + name + " on " + contextName + " for value for " + expectedName, expectedValue, actualValue);
}
} else {
if (!(expectedValue instanceof ContextUtil.Node)) {
- assertEquals("list of " + name + " on " + contextName + " for value for " + name, expectedValue.getClass().getName(), actualValue);
+ assertEquals("list of " + name + " on " + contextName + " for value for " + expectedName, expectedValue.getClass().getName(), actualValue);
} else {
// can't really test this since it the value is the name of a nested node class
}
@@ -146,29 +143,7 @@
TreeSet extraNames = new TreeSet(actualValues.keySet());
extraNames.removeAll(node.keySet());
if (!extraNames.isEmpty()) {
- fail("list of " + name + " on " + contextName + " found extra values: " + extraNames);
+ fail("list of " + name + " on " + contextName + " did not find values: " + extraNames);
}
- }
-
- private static Map toListResults(NamingEnumeration enumeration) {
- Map result = new HashMap();
- while (enumeration.hasMoreElements()) {
- NameClassPair nameClassPair = (NameClassPair) enumeration.nextElement();
- String name = nameClassPair.getName();
- assertFalse(result.containsKey(name));
- result.put(name, nameClassPair.getClassName());
- }
- return result;
- }
-
- private static Map toListBindingResults(NamingEnumeration enumeration) {
- Map result = new HashMap();
- while (enumeration.hasMoreElements()) {
- Binding binding = (Binding) enumeration.nextElement();
- String name = binding.getName();
- assertFalse(result.containsKey(name));
- result.put(name, binding.getObject());
- }
- return result;
}
}
Added: geronimo/xbean/branches/colossus/xbean-naming/src/test/java/org/apache/xbean/naming/context/FederationTest.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/branches/colossus/xbean-naming/src/test/java/org/apache/xbean/naming/context/FederationTest.java?rev=434162&view=auto
==============================================================================
--- geronimo/xbean/branches/colossus/xbean-naming/src/test/java/org/apache/xbean/naming/context/FederationTest.java (added)
+++ geronimo/xbean/branches/colossus/xbean-naming/src/test/java/org/apache/xbean/naming/context/FederationTest.java Wed Aug 23 13:29:23 2006
@@ -0,0 +1,141 @@
+/**
+ *
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.xbean.naming.context;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.Name;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Iterator;
+
+/**
+ * @version $Rev: 355877 $ $Date: 2005-12-10 18:48:27 -0800 (Sat, 10 Dec 2005) $
+ */
+public class FederationTest extends AbstractContextTest {
+ private static final String STRING_VAL = "some string";
+
+ public void testBasic() throws Exception {
+ Map map = new HashMap();
+ map.put("string", FederationTest.STRING_VAL);
+ map.put("nested/context/string", FederationTest.STRING_VAL);
+ map.put("java:comp/env/string", FederationTest.STRING_VAL);
+ map.put("java:comp/env/one", new Integer(1));
+ map.put("java:comp/env/two", new Integer(2));
+ map.put("java:comp/env/three", new Integer(3));
+
+ Context context = new WritableContext();
+ FederationTest.bind(context, map);
+
+ assertEq(map, context);
+
+ Map env2Map = new HashMap();
+ env2Map.put("string", FederationTest.STRING_VAL);
+ env2Map.put("one", new Integer(1));
+ env2Map.put("two", new Integer(2));
+ env2Map.put("three", new Integer(3));
+
+ ImmutableContext actualEnv2Context = new ImmutableContext(env2Map);
+ assertEq(env2Map, actualEnv2Context);
+
+ context.bind("java:comp/env2", actualEnv2Context);
+
+ Context env2Context = (Context) context.lookup("java:comp/env2");
+ assertEq(env2Map, env2Context);
+
+ putAllBindings(map, "java:comp/env2", env2Map);
+ assertEq(map, context);
+ }
+
+ public void testAddBinding() throws Exception {
+ Map map = new HashMap();
+ map.put("string", FederationTest.STRING_VAL);
+ map.put("nested/context/string", FederationTest.STRING_VAL);
+ map.put("a/b/c/d/e/string", FederationTest.STRING_VAL);
+ map.put("a/b/c/d/e/one", new Integer(1));
+ map.put("a/b/c/d/e/two", new Integer(2));
+ map.put("a/b/c/d/e/three", new Integer(3));
+
+ Context context = new WritableContext();
+ FederationTest.bind(context, map);
+
+ assertEq(map, context);
+
+ // add a new deep tree
+ map.put("a/b/c/d/e/forty-two", new Integer(42));
+ context.bind("a/b/c/d/e/forty-two", new Integer(42));
+
+ assertEq(map, context);
+
+ }
+
+
+ public void testRemoveBinding() throws Exception {
+ Map map = new HashMap();
+ map.put("string", FederationTest.STRING_VAL);
+ map.put("nested/context/string", FederationTest.STRING_VAL);
+ map.put("a/b/c/d/e/string", FederationTest.STRING_VAL);
+ map.put("a/b/c/d/e/one", new Integer(1));
+ map.put("a/b/c/d/e/two", new Integer(2));
+ map.put("a/b/c/d/e/three", new Integer(3));
+
+ Context context = new WritableContext();
+ FederationTest.bind(context, map);
+
+ assertEq(map, context);
+
+ // remove from an exisitng node
+ map.remove("a/b/c/d/e/three");
+ context.unbind("a/b/c/d/e/three");
+
+ assertEq(map, context);
+ }
+
+ public static void putAllBindings(Map rootBindings, String nestedPath, Map nestedBindings) {
+ for (Iterator iterator = nestedBindings.entrySet().iterator(); iterator.hasNext();) {
+ Map.Entry entry = (Map.Entry) iterator.next();
+ String name = (String) entry.getKey();
+ Object value = entry.getValue();
+ String fullName = nestedPath + "/" + name;
+ rootBindings.put(fullName, value);
+ }
+ }
+
+ public static void bind(Context context, Map bindings) throws NamingException {
+ for (Iterator iterator = bindings.entrySet().iterator(); iterator.hasNext();) {
+ Map.Entry entry = (Map.Entry) iterator.next();
+ String name = (String) entry.getKey();
+ Object value = entry.getValue();
+ Name parsedName = context.getNameParser("").parse(name);
+ for (int i =1; i < parsedName.size(); i++) {
+ Name contextName = parsedName.getPrefix(i);
+ if (!FederationTest.bindingExists(context, contextName)) {
+ context.createSubcontext(contextName);
+ }
+ }
+ context.bind(name, value);
+ }
+ }
+
+ public static boolean bindingExists(Context context, Name contextName) {
+ try {
+ return context.lookup(contextName) != null;
+ } catch (NamingException e) {
+ }
+ return false;
+ }
+}