From 7484651941e49b278521924d870260944299e745 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Tue, 4 Jun 2019 19:32:53 +0200 Subject: [PATCH] Issue #3729 concurrent JNDI access + concurrent map for the NamingContext bindings + refactored duplicate code into common methods + simplified deepBindSupport Signed-off-by: Greg Wilkins --- .../eclipse/jetty/jndi/ContextFactory.java | 4 - .../jetty/jndi/InitialContextFactory.java | 2 - .../org/eclipse/jetty/jndi/NamingContext.java | 581 +++-------- .../jetty/jndi/local/localContextRoot.java | 955 +++++------------- 4 files changed, 381 insertions(+), 1161 deletions(-) diff --git a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/ContextFactory.java b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/ContextFactory.java index ab1601b274c..a6a0666fc62 100644 --- a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/ContextFactory.java +++ b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/ContextFactory.java @@ -18,12 +18,10 @@ package org.eclipse.jetty.jndi; - import java.io.IOException; import java.util.Hashtable; import java.util.Map; import java.util.WeakHashMap; - import javax.naming.Context; import javax.naming.Name; import javax.naming.NameParser; @@ -77,8 +75,6 @@ public class ContextFactory implements ObjectFactory * when finding the comp context. */ private static final ThreadLocal __threadClassLoader = new ThreadLocal(); - - /** * Find or create a context which pertains to a classloader. diff --git a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/InitialContextFactory.java b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/InitialContextFactory.java index ab90fe0c684..06b1e335ace 100644 --- a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/InitialContextFactory.java +++ b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/InitialContextFactory.java @@ -18,10 +18,8 @@ package org.eclipse.jetty.jndi; - import java.util.Hashtable; import java.util.Properties; - import javax.naming.CompoundName; import javax.naming.Context; import javax.naming.Name; diff --git a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/NamingContext.java b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/NamingContext.java index 49c85e06123..e694d247e55 100644 --- a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/NamingContext.java +++ b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/NamingContext.java @@ -22,11 +22,10 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.Hashtable; import java.util.List; -import java.util.Map; - +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import javax.naming.Binding; import javax.naming.CompoundName; import javax.naming.Context; @@ -56,7 +55,7 @@ import org.eclipse.jetty.util.log.Logger; * All Names are expected to be Compound, not Composite. */ @SuppressWarnings("unchecked") -public class NamingContext implements Context, Cloneable, Dumpable +public class NamingContext implements Context, Dumpable { private final static Logger __log=NamingUtil.__log; private final static List __empty = Collections.emptyList(); @@ -64,9 +63,22 @@ public class NamingContext implements Context, Cloneable, Dumpable public static final String LOCK_PROPERTY = "org.eclipse.jetty.jndi.lock"; public static final String UNLOCK_PROPERTY = "org.eclipse.jetty.jndi.unlock"; - protected final Hashtable _env = new Hashtable(); - private boolean _supportDeepBinding = false; - protected Map _bindings = new HashMap(); + /* + * The env is stored as a Hashtable to be compatible with the API. + * There is no need for concurrent protection (see Concurrent Access section + * of the {@link Context} javadoc), so multiple threads acting on the same + * Context env need to self - mutually exclude. + */ + protected final Hashtable _env = new Hashtable<>(); + + /* + * This contexts bindings are stored as a ConcurrentHashMap. + * There is generally no need for concurrent protection (see Concurrent Access section + * of the {@link Context} javadoc), However, the NamingContext is used for root contexts and + * we do not mutually exclude when initializing, so instead we do make the bindings + * thread safe (unlike the env where we expect users to respect the Concurrent Access requirements). + */ + protected final ConcurrentMap _bindings; protected NamingContext _parent = null; protected String _name = null; @@ -99,7 +111,7 @@ public class NamingContext implements Context, Cloneable, Dumpable /** * Constructor * - * @param env environment properties + * @param env environment properties which are copied into this Context's environment * @param name relative name of this context * @param parent immediate ancestor Context (can be null) * @param parser NameParser for this Context @@ -108,53 +120,48 @@ public class NamingContext implements Context, Cloneable, Dumpable String name, NamingContext parent, NameParser parser) + { + this(env, name, parent, parser, null); + } + + private NamingContext(Hashtable env, + String name, + NamingContext parent, + NameParser parser, + ConcurrentMap bindings) { if (env != null) - { _env.putAll(env); - // look for deep binding support in _env - Object support = _env.get(DEEP_BINDING); - if (support == null) - _supportDeepBinding = false; - else - _supportDeepBinding = support != null?Boolean.parseBoolean(support.toString()):false; - } - else - { - // no env? likely this is a root context (java or local) that - // was created without an _env. Look for a system property. - String value = System.getProperty(DEEP_BINDING,"false"); - _supportDeepBinding = Boolean.parseBoolean(value); - // put what we discovered into the _env for later sub-contexts - // to utilize. - _env.put(DEEP_BINDING,_supportDeepBinding); - } _name = name; _parent = parent; _parser = parser; + _bindings = bindings==null ? new ConcurrentHashMap<>() : bindings; if(__log.isDebugEnabled()) - __log.debug("supportDeepBinding={}",_supportDeepBinding); + __log.debug("new {}", this); } - - /*------------------------------------------------*/ /** - * Clone this NamingContext - * - * @return copy of this NamingContext - * @exception CloneNotSupportedException if an error occurs + * @return A shallow copy of the Context with the same bindings, but a copy of the Env */ - @Override - public Object clone () - throws CloneNotSupportedException + public NamingContext shallowCopy() { - NamingContext ctx = (NamingContext)super.clone(); - ctx._env.putAll(_env); - ctx._bindings.putAll(_bindings); - return ctx; + return new NamingContext(_env, _name, _parent, _parser, _bindings); } + public boolean isDeepBindingSupported() + { + // look for deep binding support in _env + Object support = _env.get(DEEP_BINDING); + if (support!=null) + return Boolean.parseBoolean(String.valueOf(support)); + + if (_parent!=null) + return _parent.isDeepBindingSupported(); + // probably a root context + return Boolean.parseBoolean(System.getProperty(DEEP_BINDING,"false")); + } + /*------------------------------------------------*/ /** * Getter for _name @@ -190,20 +197,54 @@ public class NamingContext implements Context, Cloneable, Dumpable if(env == null) return; _env.putAll(env); - _supportDeepBinding = _env.containsKey(DEEP_BINDING); } - - public Map getBindings () + private Object dereference(Object ctx, String firstComponent) throws NamingException { - return _bindings; + if (ctx instanceof Reference) + { + //deference the object + try + { + return NamingManager.getObjectInstance(ctx, _parser.parse(firstComponent), this, _env); + } + catch (NamingException e) + { + throw e; + } + catch (Exception e) + { + __log.warn("",e); + throw new NamingException (e.getMessage()); + } + } + return ctx; } - public void setBindings(Map bindings) + private Context getContext(Name cname) throws NamingException { - _bindings = bindings; + String firstComponent = cname.get(0); + + if (firstComponent.equals("")) + return this; + + Binding binding = getBinding (firstComponent); + if (binding == null) + { + NameNotFoundException nnfe = new NameNotFoundException(firstComponent + " is not bound"); + nnfe.setRemainingName(cname); + throw nnfe; + } + + Object ctx = dereference(binding.getObject(), firstComponent); + + if (!(ctx instanceof Context)) + throw new NotContextException(firstComponent + " not a context in " + this.getNameInNamespace()); + + return (Context)ctx; } + /*------------------------------------------------*/ /** * Bind a name to an object @@ -244,7 +285,8 @@ public class NamingContext implements Context, Cloneable, Dumpable } else { - if(__log.isDebugEnabled())__log.debug("Checking for existing binding for name="+cname+" for first element of name="+cname.get(0)); + if(__log.isDebugEnabled()) + __log.debug("Checking for existing binding for name="+cname+" for first element of name="+cname.get(0)); //walk down the subcontext hierarchy //need to ignore trailing empty "" name components @@ -256,13 +298,13 @@ public class NamingContext implements Context, Cloneable, Dumpable ctx = this; else { - Binding binding = getBinding (firstComponent); - if (binding == null) { - if (_supportDeepBinding) + if (binding == null) + { + if (isDeepBindingSupported()) { Name subname = _parser.parse(firstComponent); - Context subctx = new NamingContext((Hashtable)_env.clone(),firstComponent,this,_parser); + Context subctx = new NamingContext(_env,firstComponent,this,_parser, null); addBinding(subname,subctx); binding = getBinding(subname); } @@ -272,28 +314,9 @@ public class NamingContext implements Context, Cloneable, Dumpable } } - ctx = binding.getObject(); - - if (ctx instanceof Reference) - { - //deference the object - try - { - ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), this, _env); - } - catch (NamingException e) - { - throw e; - } - catch (Exception e) - { - __log.warn("",e); - throw new NamingException (e.getMessage()); - } - } + ctx = dereference(binding.getObject(),firstComponent); } - if (ctx instanceof Context) { ((Context)ctx).bind (cname.getSuffix(1), obj); @@ -354,57 +377,14 @@ public class NamingContext implements Context, Cloneable, Dumpable if (binding != null) throw new NameAlreadyBoundException (cname.toString()); - Context ctx = new NamingContext ((Hashtable)_env.clone(), cname.get(0), this, _parser); + Context ctx = new NamingContext (_env, cname.get(0), this, _parser); addBinding (cname, ctx); return ctx; } - - //If the name has multiple subcontexts, walk the hierarchy by - //fetching the first one. All intermediate subcontexts in the - //name must already exist. - String firstComponent = cname.get(0); - Object ctx = null; - - if (firstComponent.equals("")) - ctx = this; - else - { - Binding binding = getBinding (firstComponent); - if (binding == null) - throw new NameNotFoundException (firstComponent + " is not bound"); - - ctx = binding.getObject(); - - if (ctx instanceof Reference) - { - //deference the object - if(__log.isDebugEnabled())__log.debug("Object bound at "+firstComponent +" is a Reference"); - try - { - ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), this, _env); - } - catch (NamingException e) - { - throw e; - } - catch (Exception e) - { - __log.warn("",e); - throw new NamingException (e.getMessage()); - } - } - } - - if (ctx instanceof Context) - { - return ((Context)ctx).createSubcontext (cname.getSuffix(1)); - } - else - throw new NotContextException (firstComponent +" is not a Context"); + return getContext(cname).createSubcontext (cname.getSuffix(1)); } - /*------------------------------------------------*/ /** * Create a Context as a child of this one @@ -420,8 +400,6 @@ public class NamingContext implements Context, Cloneable, Dumpable return createSubcontext(_parser.parse(name)); } - - /*------------------------------------------------*/ /** * @@ -436,8 +414,6 @@ public class NamingContext implements Context, Cloneable, Dumpable removeBinding(_parser.parse(name)); } - - /*------------------------------------------------*/ /** * @@ -468,14 +444,10 @@ public class NamingContext implements Context, Cloneable, Dumpable if ((cname == null) || (cname.size() == 0)) { - __log.debug("Null or empty name, returning copy of this context"); - NamingContext ctx = new NamingContext (_env, _name, _parent, _parser); - ctx._bindings=_bindings; - return ctx; + __log.debug("Null or empty name, returning shallowCopy of this context"); + return shallowCopy(); } - - if (cname.size() == 1) { Binding binding = getBinding (cname); @@ -486,7 +458,6 @@ public class NamingContext implements Context, Cloneable, Dumpable throw nnfe; } - Object o = binding.getObject(); //handle links by looking up the link @@ -505,7 +476,7 @@ public class NamingContext implements Context, Cloneable, Dumpable } else if (o instanceof Reference) { - //deference the object + // TODO use deference ?? try { return NamingManager.getObjectInstance(o, cname, this, _env); @@ -524,54 +495,9 @@ public class NamingContext implements Context, Cloneable, Dumpable return o; } - //it is a multipart name, recurse to the first subcontext - - String firstComponent = cname.get(0); - Object ctx = null; - - if (firstComponent.equals("")) - ctx = this; - else - { - - Binding binding = getBinding (firstComponent); - if (binding == null) - { - NameNotFoundException nnfe = new NameNotFoundException(); - nnfe.setRemainingName(cname); - throw nnfe; - } - - //as we have bound a reference to an object factory - //for the component specific contexts - //at "comp" we need to resolve the reference - ctx = binding.getObject(); - - if (ctx instanceof Reference) - { - //deference the object - try - { - ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), this, _env); - } - catch (NamingException e) - { - throw e; - } - catch (Exception e) - { - __log.warn("",e); - throw new NamingException (e.getMessage()); - } - } - } - if (!(ctx instanceof Context)) - throw new NotContextException(); - - return ((Context)ctx).lookup (cname.getSuffix(1)); + return getContext(cname).lookup (cname.getSuffix(1)); } - /*------------------------------------------------*/ /** * Lookup binding of an object by name @@ -587,8 +513,6 @@ public class NamingContext implements Context, Cloneable, Dumpable return lookup (_parser.parse(name)); } - - /*------------------------------------------------*/ /** * Lookup link bound to name @@ -603,12 +527,11 @@ public class NamingContext implements Context, Cloneable, Dumpable { Name cname = toCanonicalName(name); - if (cname == null) + if (cname == null || name.isEmpty()) { - NamingContext ctx = new NamingContext (_env, _name, _parent, _parser); - ctx._bindings=_bindings; - return ctx; + return shallowCopy(); } + if (cname.size() == 0) throw new NamingException ("Name is empty"); @@ -618,75 +541,12 @@ public class NamingContext implements Context, Cloneable, Dumpable if (binding == null) throw new NameNotFoundException(); - Object o = binding.getObject(); - - //handle links by looking up the link - if (o instanceof Reference) - { - //deference the object - try - { - return NamingManager.getObjectInstance(o, cname.getPrefix(1), this, _env); - } - catch (NamingException e) - { - throw e; - } - catch (Exception e) - { - __log.warn("",e); - throw new NamingException (e.getMessage()); - } - } - else - { - //object is either a LinkRef which we don't dereference - //or a plain object in which case spec says we return it - return o; - } + return dereference(binding.getObject(), cname.getPrefix(1).toString()); } - - //it is a multipart name, recurse to the first subcontext - String firstComponent = cname.get(0); - Object ctx = null; - - if (firstComponent.equals("")) - ctx = this; - else - { - Binding binding = getBinding (firstComponent); - if (binding == null) - throw new NameNotFoundException (); - - ctx = binding.getObject(); - - if (ctx instanceof Reference) - { - //deference the object - try - { - ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), this, _env); - } - catch (NamingException e) - { - throw e; - } - catch (Exception e) - { - __log.warn("",e); - throw new NamingException (e.getMessage()); - } - } - } - - if (!(ctx instanceof Context)) - throw new NotContextException(); - - return ((Context)ctx).lookup (cname.getSuffix(1)); + return getContext(cname).lookup (cname.getSuffix(1)); } - /*------------------------------------------------*/ /** * Lookup link bound to name @@ -702,7 +562,6 @@ public class NamingContext implements Context, Cloneable, Dumpable return lookupLink (_parser.parse(name)); } - /*------------------------------------------------*/ /** * List all names bound at Context named by Name @@ -718,62 +577,20 @@ public class NamingContext implements Context, Cloneable, Dumpable if(__log.isDebugEnabled())__log.debug("list() on Context="+getName()+" for name="+name); Name cname = toCanonicalName(name); - - if (cname == null) { return new NameEnumeration(__empty.iterator()); } - if (cname.size() == 0) { return new NameEnumeration (_bindings.values().iterator()); } - - //multipart name - String firstComponent = cname.get(0); - Object ctx = null; - - if (firstComponent.equals("")) - ctx = this; - else - { - Binding binding = getBinding (firstComponent); - if (binding == null) - throw new NameNotFoundException (); - - ctx = binding.getObject(); - - if (ctx instanceof Reference) - { - //deference the object - if(__log.isDebugEnabled())__log.debug("Dereferencing Reference for "+name.get(0)); - try - { - ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), this, _env); - } - catch (NamingException e) - { - throw e; - } - catch (Exception e) - { - __log.warn("",e); - throw new NamingException (e.getMessage()); - } - } - } - - if (!(ctx instanceof Context)) - throw new NotContextException(); - - return ((Context)ctx).list (cname.getSuffix(1)); + return getContext(cname).list (cname.getSuffix(1)); } - /*------------------------------------------------*/ /** * List all names bound at Context named by Name @@ -789,8 +606,6 @@ public class NamingContext implements Context, Cloneable, Dumpable return list(_parser.parse(name)); } - - /*------------------------------------------------*/ /** * List all Bindings present at Context named by Name @@ -815,48 +630,7 @@ public class NamingContext implements Context, Cloneable, Dumpable return new BindingEnumeration (_bindings.values().iterator()); } - - - //multipart name - String firstComponent = cname.get(0); - Object ctx = null; - - //if a name has a leading "/" it is parsed as "" so ignore it by staying - //at this level in the tree - if (firstComponent.equals("")) - ctx = this; - else - { - //it is a non-empty name component - Binding binding = getBinding (firstComponent); - if (binding == null) - throw new NameNotFoundException (); - - ctx = binding.getObject(); - - if (ctx instanceof Reference) - { - //deference the object - try - { - ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), this, _env); - } - catch (NamingException e) - { - throw e; - } - catch (Exception e) - { - __log.warn("",e); - throw new NamingException (e.getMessage()); - } - } - } - - if (!(ctx instanceof Context)) - throw new NotContextException(); - - return ((Context)ctx).listBindings (cname.getSuffix(1)); + return getContext(cname).listBindings (cname.getSuffix(1)); } @@ -917,49 +691,7 @@ public class NamingContext implements Context, Cloneable, Dumpable } else { - //walk down the subcontext hierarchy - if(__log.isDebugEnabled())__log.debug("Checking for existing binding for name="+cname+" for first element of name="+cname.get(0)); - - String firstComponent = cname.get(0); - Object ctx = null; - - - if (firstComponent.equals("")) - ctx = this; - else - { - Binding binding = getBinding (name.get(0)); - if (binding == null) - throw new NameNotFoundException (name.get(0)+ " is not bound"); - - ctx = binding.getObject(); - - - if (ctx instanceof Reference) - { - //deference the object - try - { - ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), this, _env); - } - catch (NamingException e) - { - throw e; - } - catch (Exception e) - { - __log.warn("",e); - throw new NamingException (e.getMessage()); - } - } - } - - if (ctx instanceof Context) - { - ((Context)ctx).rebind (cname.getSuffix(1), obj); - } - else - throw new NotContextException ("Object bound at "+firstComponent +" is not a Context"); + getContext(cname).rebind (cname.getSuffix(1), obj); } } @@ -1020,7 +752,6 @@ public class NamingContext implements Context, Cloneable, Dumpable if (cname.size() == 0) throw new NamingException ("Name is empty"); - //if no subcontexts, just unbind it if (cname.size() == 1) { @@ -1028,48 +759,7 @@ public class NamingContext implements Context, Cloneable, Dumpable } else { - //walk down the subcontext hierarchy - if(__log.isDebugEnabled())__log.debug("Checking for existing binding for name="+cname+" for first element of name="+cname.get(0)); - - String firstComponent = cname.get(0); - Object ctx = null; - - - if (firstComponent.equals("")) - ctx = this; - else - { - Binding binding = getBinding (name.get(0)); - if (binding == null) - throw new NameNotFoundException (name.get(0)+ " is not bound"); - - ctx = binding.getObject(); - - if (ctx instanceof Reference) - { - //deference the object - try - { - ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), this, _env); - } - catch (NamingException e) - { - throw e; - } - catch (Exception e) - { - __log.warn("",e); - throw new NamingException (e.getMessage()); - } - } - } - - if (ctx instanceof Context) - { - ((Context)ctx).unbind (cname.getSuffix(1)); - } - else - throw new NotContextException ("Object bound at "+firstComponent +" is not a Context"); + getContext(cname).unbind (cname.getSuffix(1)); } } @@ -1277,7 +967,7 @@ public class NamingContext implements Context, Cloneable, Dumpable @Override public Hashtable getEnvironment () { - return (Hashtable)_env.clone(); + return _env; } /*------------------------------------------------*/ @@ -1307,8 +997,10 @@ public class NamingContext implements Context, Cloneable, Dumpable if (binding!=null) { - if (_bindings.containsKey(key)) { - if(_supportDeepBinding) { + if (_bindings.putIfAbsent(key, binding)!=null) + { + if(isDeepBindingSupported()) + { // quietly return (no exception) // this is jndi spec breaking, but is added to support broken // jndi users like openejb. @@ -1316,7 +1008,6 @@ public class NamingContext implements Context, Cloneable, Dumpable } throw new NameAlreadyBoundException(name.toString()); } - _bindings.put(key,binding); } } @@ -1329,10 +1020,9 @@ public class NamingContext implements Context, Cloneable, Dumpable */ public Binding getBinding (Name name) { - return (Binding) _bindings.get(name.toString()); + return _bindings.get(name.toString()); } - /*------------------------------------------------*/ /** * Get a name to object binding from this Context @@ -1342,7 +1032,7 @@ public class NamingContext implements Context, Cloneable, Dumpable */ public Binding getBinding (String name) { - return (Binding) _bindings.get(name); + return _bindings.get(name); } /*------------------------------------------------*/ @@ -1406,49 +1096,14 @@ public class NamingContext implements Context, Cloneable, Dumpable @Override public String dump() { - StringBuilder buf = new StringBuilder(); - try - { - dump(buf,""); - } - catch(Exception e) - { - __log.warn(e); - } - return buf.toString(); + return Dumpable.dump(this); } - /* ------------------------------------------------------------ */ @Override public void dump(Appendable out,String indent) throws IOException { - out.append(this.getClass().getSimpleName()).append("@").append(Long.toHexString(this.hashCode())).append("\n"); - int size=_bindings.size(); - int i=0; - for (Map.Entry entry : ((Map)_bindings).entrySet()) - { - boolean last=++i==size; - out.append(indent).append(" +- ").append(entry.getKey()).append(": "); - - Binding binding = entry.getValue(); - Object value = binding.getObject(); - - if ("comp".equals(entry.getKey()) && value instanceof Reference && "org.eclipse.jetty.jndi.ContextFactory".equals(((Reference)value).getFactoryClassName())) - { - ContextFactory.dump(out,indent+(last?" ":" | ")); - } - else if (value instanceof Dumpable) - { - ((Dumpable)value).dump(out,indent+(last?" ":" | ")); - } - else - { - out.append(value.getClass().getSimpleName()).append("="); - out.append(String.valueOf(value).replace('\n','|').replace('\r','|')); - out.append("\n"); - } - } + Dumpable.dumpObjects(out,indent,this, _bindings); } private Collection findListeners() diff --git a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/local/localContextRoot.java b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/local/localContextRoot.java index 1fb4183b438..75a0364b8b6 100644 --- a/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/local/localContextRoot.java +++ b/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/local/localContextRoot.java @@ -18,11 +18,8 @@ package org.eclipse.jetty.jndi.local; -import java.util.Collections; import java.util.Hashtable; -import java.util.List; import java.util.Properties; - import javax.naming.Binding; import javax.naming.CompoundName; import javax.naming.Context; @@ -40,8 +37,6 @@ import javax.naming.Reference; import javax.naming.Referenceable; import javax.naming.spi.NamingManager; -import org.eclipse.jetty.jndi.BindingEnumeration; -import org.eclipse.jetty.jndi.NameEnumeration; import org.eclipse.jetty.jndi.NamingContext; import org.eclipse.jetty.jndi.NamingUtil; import org.eclipse.jetty.util.log.Logger; @@ -62,7 +57,6 @@ public class localContextRoot implements Context protected final static NamingContext __root = new NamingRoot(); private final Hashtable _env; - static class NamingRoot extends NamingContext { public NamingRoot() @@ -71,8 +65,6 @@ public class localContextRoot implements Context } } - - static class LocalNameParser implements NameParser { Properties syntax = new Properties(); @@ -100,10 +92,6 @@ public class localContextRoot implements Context */ - - - - public static NamingContext getRoot() { return __root; @@ -122,7 +110,6 @@ public class localContextRoot implements Context @Override public void close() throws NamingException { - } /** @@ -136,7 +123,6 @@ public class localContextRoot implements Context return ""; } - /** * * @@ -145,13 +131,9 @@ public class localContextRoot implements Context @Override public void destroySubcontext(Name name) throws NamingException { - synchronized (__root) - { - __root.destroySubcontext(getSuffix(name)); - } + __root.destroySubcontext(getSuffix(name)); } - /** * * @@ -160,14 +142,9 @@ public class localContextRoot implements Context @Override public void destroySubcontext(String name) throws NamingException { - synchronized (__root) - { - - destroySubcontext(__root.getNameParser("").parse(getSuffix(name))); - } + destroySubcontext(__root.getNameParser("").parse(getSuffix(name))); } - /** * * @@ -179,7 +156,49 @@ public class localContextRoot implements Context return _env; } + private Object dereference(Object ctx, String firstComponent) throws NamingException + { + if (ctx instanceof Reference) + { + //deference the object + try + { + return NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), __root, _env); + } + catch (NamingException e) + { + throw e; + } + catch (Exception e) + { + __log.warn(e); + throw new NamingException (e.getMessage()); + } + } + return ctx; + } + private Context getContext(Name cname) throws NamingException + { + String firstComponent = cname.get(0); + + if (firstComponent.equals("")) + return this; + + Binding binding = __root.getBinding (firstComponent); + if (binding == null) + { + NameNotFoundException nnfe = new NameNotFoundException(firstComponent + " is not bound"); + nnfe.setRemainingName(cname); + throw nnfe; + } + Object ctx = dereference(binding.getObject(), firstComponent); + + if (!(ctx instanceof Context)) + throw new NotContextException(firstComponent + " not a context in " + this.getNameInNamespace()); + + return (Context)ctx; + } /** * @@ -189,79 +208,30 @@ public class localContextRoot implements Context @Override public void unbind(Name name) throws NamingException { - synchronized (__root) + //__root.unbind(getSuffix(name)); + + if (name.size() == 0) + return; + + if (__root.isLocked()) + throw new NamingException ("This context is immutable"); + + Name cname = __root.toCanonicalName(name); + + if (cname == null) + throw new NamingException ("Name is null"); + + if (cname.size() == 0) + throw new NamingException ("Name is empty"); + + //if no subcontexts, just unbind it + if (cname.size() == 1) { - //__root.unbind(getSuffix(name)); - - if (name.size() == 0) - return; - - - if (__root.isLocked()) - throw new NamingException ("This context is immutable"); - - Name cname = __root.toCanonicalName(name); - - if (cname == null) - throw new NamingException ("Name is null"); - - if (cname.size() == 0) - throw new NamingException ("Name is empty"); - - - //if no subcontexts, just unbind it - if (cname.size() == 1) - { - __root.removeBinding (cname); - } - else - { - //walk down the subcontext hierarchy - if(__log.isDebugEnabled())__log.debug("Checking for existing binding for name="+cname+" for first element of name="+cname.get(0)); - - String firstComponent = cname.get(0); - Object ctx = null; - - - if (firstComponent.equals("")) - ctx = this; - else - { - Binding binding = __root.getBinding (name.get(0)); - if (binding == null) - throw new NameNotFoundException (name.get(0)+ " is not bound"); - - ctx = binding.getObject(); - - if (ctx instanceof Reference) - { - //deference the object - try - { - ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), __root, _env); - } - catch (NamingException e) - { - throw e; - } - catch (Exception e) - { - __log.warn("",e); - throw new NamingException (e.getMessage()); - } - } - } - - if (ctx instanceof Context) - { - ((Context)ctx).unbind (cname.getSuffix(1)); - } - else - throw new NotContextException ("Object bound at "+firstComponent +" is not a Context"); - } - - - + __root.removeBinding (cname); + } + else + { + getContext(cname).unbind (cname.getSuffix(1)); } } @@ -276,8 +246,6 @@ public class localContextRoot implements Context unbind(__root.getNameParser("").parse(getSuffix(name))); } - - /** * * @@ -286,10 +254,7 @@ public class localContextRoot implements Context @Override public Object lookupLink(String name) throws NamingException { - synchronized (__root) - { - return lookupLink(__root.getNameParser("").parse(getSuffix(name))); - } + return lookupLink(__root.getNameParser("").parse(getSuffix(name))); } /** @@ -300,101 +265,54 @@ public class localContextRoot implements Context @Override public Object lookupLink(Name name) throws NamingException { - synchronized (__root) + Name cname = __root.toCanonicalName(name); + + if (cname == null || cname.isEmpty()) { - //return __root.lookupLink(getSuffix(name)); + //If no name create copy of this context with same bindings, but with copy of the environment so it can be modified + return __root.shallowCopy(); + } + if (cname.size() == 0) + throw new NamingException ("Name is empty"); - Name cname = __root.toCanonicalName(name); + if (cname.size() == 1) + { + Binding binding = __root.getBinding (cname); + if (binding == null) + throw new NameNotFoundException(); - if (cname == null) + Object o = binding.getObject(); + + //handle links by looking up the link + if (o instanceof Reference) { - //If no name create copy of this context with same bindings, but with copy of the environment so it can be modified - NamingContext ctx = new NamingContext (_env, null, null, __root.getNameParser("")); - ctx.setBindings(__root.getBindings()); - return ctx; - } - - if (cname.size() == 0) - throw new NamingException ("Name is empty"); - - if (cname.size() == 1) - { - Binding binding = __root.getBinding (cname); - if (binding == null) - throw new NameNotFoundException(); - - Object o = binding.getObject(); - - //handle links by looking up the link - if (o instanceof Reference) + //deference the object + try { - //deference the object - try - { - return NamingManager.getObjectInstance(o, cname.getPrefix(1), __root, _env); - } - catch (NamingException e) - { - throw e; - } - catch (Exception e) - { - __log.warn("",e); - throw new NamingException (e.getMessage()); - } + return NamingManager.getObjectInstance(o, cname.getPrefix(1), __root, _env); } - else + catch (NamingException e) { - //object is either a LinkRef which we don't dereference - //or a plain object in which case spec says we return it - return o; + throw e; + } + catch (Exception e) + { + __log.warn("",e); + throw new NamingException (e.getMessage()); } } - - - //it is a multipart name, recurse to the first subcontext - String firstComponent = cname.get(0); - Object ctx = null; - - if (firstComponent.equals("")) - ctx = this; else { - Binding binding = __root.getBinding (firstComponent); - if (binding == null) - throw new NameNotFoundException (); - - ctx = binding.getObject(); - - if (ctx instanceof Reference) - { - //deference the object - try - { - ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), __root, _env); - } - catch (NamingException e) - { - throw e; - } - catch (Exception e) - { - __log.warn("",e); - throw new NamingException (e.getMessage()); - } - } + //object is either a LinkRef which we don't dereference + //or a plain object in which case spec says we return it + return o; } - - if (!(ctx instanceof Context)) - throw new NotContextException(); - - return ((Context)ctx).lookup (cname.getSuffix(1)); - - } - } + //it is a multipart name, recurse to the first subcontext + return getContext(cname).lookup (cname.getSuffix(1)); + } /** * @@ -407,7 +325,6 @@ public class localContextRoot implements Context return _env.remove(propName); } - /** * * @@ -416,122 +333,65 @@ public class localContextRoot implements Context @Override public Object lookup(Name name) throws NamingException { - synchronized (__root) + if(__log.isDebugEnabled())__log.debug("Looking up name=\""+name+"\""); + Name cname = __root.toCanonicalName(name); + + if ((cname == null) || cname.isEmpty()) { - //return __root.lookup(getSuffix(name)); - - if(__log.isDebugEnabled())__log.debug("Looking up name=\""+name+"\""); - Name cname = __root.toCanonicalName(name); - - if ((cname == null) || (cname.size() == 0)) - { - __log.debug("Null or empty name, returning copy of this context"); - NamingContext ctx = new NamingContext (_env, null, null, __root.getNameParser("")); - ctx.setBindings(__root.getBindings()); - return ctx; - } - - - - if (cname.size() == 1) - { - Binding binding = __root.getBinding (cname); - if (binding == null) - { - NameNotFoundException nnfe = new NameNotFoundException(); - nnfe.setRemainingName(cname); - throw nnfe; - } - - - Object o = binding.getObject(); - - //handle links by looking up the link - if (o instanceof LinkRef) - { - //if link name starts with ./ it is relative to current context - String linkName = ((LinkRef)o).getLinkName(); - if (linkName.startsWith("./")) - return lookup (linkName.substring(2)); - else - { - //link name is absolute - InitialContext ictx = new InitialContext(); - return ictx.lookup (linkName); - } - } - else if (o instanceof Reference) - { - //deference the object - try - { - return NamingManager.getObjectInstance(o, cname, __root, _env); - } - catch (NamingException e) - { - throw e; - } - catch (final Exception e) - { - throw new NamingException (e.getMessage()) - { - { initCause(e);} - }; - } - } - else - return o; - } - - //it is a multipart name, get the first subcontext - - String firstComponent = cname.get(0); - Object ctx = null; - - if (firstComponent.equals("")) - ctx = this; - else - { - - Binding binding = __root.getBinding (firstComponent); - if (binding == null) - { - NameNotFoundException nnfe = new NameNotFoundException(); - nnfe.setRemainingName(cname); - throw nnfe; - } - - //as we have bound a reference to an object factory - //for the component specific contexts - //at "comp" we need to resolve the reference - ctx = binding.getObject(); - - if (ctx instanceof Reference) - { - //deference the object - try - { - ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), __root, _env); - } - catch (NamingException e) - { - throw e; - } - catch (Exception e) - { - __log.warn("",e); - throw new NamingException (e.getMessage()); - } - } - } - if (!(ctx instanceof Context)) - throw new NotContextException(); - - return ((Context)ctx).lookup (cname.getSuffix(1)); - + return __root.shallowCopy(); } - } + if (cname.size() == 1) + { + Binding binding = __root.getBinding (cname); + if (binding == null) + { + NameNotFoundException nnfe = new NameNotFoundException(); + nnfe.setRemainingName(cname); + throw nnfe; + } + + Object o = binding.getObject(); + + //handle links by looking up the link + if (o instanceof LinkRef) + { + //if link name starts with ./ it is relative to current context + String linkName = ((LinkRef)o).getLinkName(); + if (linkName.startsWith("./")) + return lookup (linkName.substring(2)); + else + { + //link name is absolute + InitialContext ictx = new InitialContext(); + return ictx.lookup (linkName); + } + } + else if (o instanceof Reference) + { + // TODO use deference + try + { + return NamingManager.getObjectInstance(o, cname, __root, _env); + } + catch (NamingException e) + { + throw e; + } + catch (final Exception e) + { + throw new NamingException (e.getMessage()) + { + { initCause(e);} + }; + } + } + else + return o; + } + + return getContext(cname).lookup(cname.getSuffix(1)); + } /** * @@ -541,13 +401,9 @@ public class localContextRoot implements Context @Override public Object lookup(String name) throws NamingException { - synchronized (__root) - { - return lookup(__root.getNameParser("").parse(getSuffix(name))); - } + return lookup(__root.getNameParser("").parse(getSuffix(name))); } - /** * * @@ -556,14 +412,9 @@ public class localContextRoot implements Context @Override public void bind(String name, Object obj) throws NamingException { - synchronized (__root) - { - bind(__root.getNameParser("").parse(getSuffix(name)), obj); - - } + bind(__root.getNameParser("").parse(getSuffix(name)), obj); } - /** * * @@ -572,85 +423,37 @@ public class localContextRoot implements Context @Override public void bind(Name name, Object obj) throws NamingException { - synchronized (__root) + if (__root.isLocked()) + throw new NamingException ("This context is immutable"); + + Name cname = __root.toCanonicalName(name); + + if (cname == null) + throw new NamingException ("Name is null"); + + if (cname.size() == 0) + throw new NamingException ("Name is empty"); + + //if no subcontexts, just bind it + if (cname.size() == 1) { - // __root.bind(getSuffix(name), obj); - - - if (__root.isLocked()) - throw new NamingException ("This context is immutable"); - - Name cname = __root.toCanonicalName(name); - - if (cname == null) - throw new NamingException ("Name is null"); - - if (cname.size() == 0) - throw new NamingException ("Name is empty"); - - - //if no subcontexts, just bind it - if (cname.size() == 1) + //get the object to be bound + Object objToBind = NamingManager.getStateToBind(obj, name,this, _env); + // Check for Referenceable + if (objToBind instanceof Referenceable) { - //get the object to be bound - Object objToBind = NamingManager.getStateToBind(obj, name,this, _env); - // Check for Referenceable - if (objToBind instanceof Referenceable) - { - objToBind = ((Referenceable)objToBind).getReference(); - } - - //anything else we should be able to bind directly - __root.addBinding (cname, objToBind); + objToBind = ((Referenceable)objToBind).getReference(); } - else - { - if(__log.isDebugEnabled())__log.debug("Checking for existing binding for name="+cname+" for first element of name="+cname.get(0)); - //walk down the subcontext hierarchy - //need to ignore trailing empty "" name components + //anything else we should be able to bind directly + __root.addBinding (cname, objToBind); + } + else + { + if(__log.isDebugEnabled()) + __log.debug("Checking for existing binding for name="+cname+" for first element of name="+cname.get(0)); - String firstComponent = cname.get(0); - Object ctx = null; - - if (firstComponent.equals("")) - ctx = this; - else - { - - Binding binding = __root.getBinding (firstComponent); - if (binding == null) - throw new NameNotFoundException (firstComponent+ " is not bound"); - - ctx = binding.getObject(); - - if (ctx instanceof Reference) - { - //deference the object - try - { - ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), this, _env); - } - catch (NamingException e) - { - throw e; - } - catch (Exception e) - { - __log.warn("",e); - throw new NamingException (e.getMessage()); - } - } - } - - - if (ctx instanceof Context) - { - ((Context)ctx).bind (cname.getSuffix(1), obj); - } - else - throw new NotContextException ("Object bound at "+firstComponent +" is not a Context"); - } + getContext(cname).bind (cname.getSuffix(1), obj); } } @@ -662,82 +465,37 @@ public class localContextRoot implements Context @Override public void rebind(Name name, Object obj) throws NamingException { - synchronized (__root) + if (__root.isLocked()) + throw new NamingException ("This context is immutable"); + + Name cname = __root.toCanonicalName(name); + + if (cname == null) + throw new NamingException ("Name is null"); + + if (cname.size() == 0) + throw new NamingException ("Name is empty"); + + //if no subcontexts, just bind it + if (cname.size() == 1) { - //__root.rebind(getSuffix(name), obj); + //check if it is a Referenceable + Object objToBind = NamingManager.getStateToBind(obj, name, __root, _env); - - if (__root.isLocked()) - throw new NamingException ("This context is immutable"); - - Name cname = __root.toCanonicalName(name); - - if (cname == null) - throw new NamingException ("Name is null"); - - if (cname.size() == 0) - throw new NamingException ("Name is empty"); - - - //if no subcontexts, just bind it - if (cname.size() == 1) + if (objToBind instanceof Referenceable) { - //check if it is a Referenceable - Object objToBind = NamingManager.getStateToBind(obj, name, __root, _env); - - if (objToBind instanceof Referenceable) - { - objToBind = ((Referenceable)objToBind).getReference(); - } - __root.removeBinding(cname); - __root.addBinding (cname, objToBind); + objToBind = ((Referenceable)objToBind).getReference(); } - else - { - //walk down the subcontext hierarchy - if(__log.isDebugEnabled())__log.debug("Checking for existing binding for name="+cname+" for first element of name="+cname.get(0)); + __root.removeBinding(cname); + __root.addBinding (cname, objToBind); + } + else + { + //walk down the subcontext hierarchy + if(__log.isDebugEnabled()) + __log.debug("Checking for existing binding for name="+cname+" for first element of name="+cname.get(0)); - String firstComponent = cname.get(0); - Object ctx = null; - - - if (firstComponent.equals("")) - ctx = this; - else - { - Binding binding = __root.getBinding (name.get(0)); - if (binding == null) - throw new NameNotFoundException (name.get(0)+ " is not bound"); - - ctx = binding.getObject(); - - - if (ctx instanceof Reference) - { - //deference the object - try - { - ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), __root, _env); - } - catch (NamingException e) - { - throw e; - } - catch (Exception e) - { - __log.warn("",e); - throw new NamingException (e.getMessage()); - } - } - } - - if (ctx instanceof Context) - { - ((Context)ctx).rebind (cname.getSuffix(1), obj); - } - else - throw new NotContextException ("Object bound at "+firstComponent +" is not a Context"); - } + getContext(cname).rebind (cname.getSuffix(1), obj); } } @@ -749,11 +507,9 @@ public class localContextRoot implements Context @Override public void rebind(String name, Object obj) throws NamingException { - synchronized (__root) - { - rebind(__root.getNameParser("").parse(getSuffix(name)), obj); - } + rebind(__root.getNameParser("").parse(getSuffix(name)), obj); } + /** * * @@ -762,10 +518,7 @@ public class localContextRoot implements Context @Override public void rename(Name oldName, Name newName) throws NamingException { - synchronized (__root) - { - throw new OperationNotSupportedException(); - } + throw new OperationNotSupportedException(); } /** @@ -776,10 +529,7 @@ public class localContextRoot implements Context @Override public void rename(String oldName, String newName) throws NamingException { - synchronized (__root) - { - throw new OperationNotSupportedException(); - } + throw new OperationNotSupportedException(); } /** @@ -790,18 +540,15 @@ public class localContextRoot implements Context @Override public Context createSubcontext(String name) throws NamingException { - synchronized (__root) - { - //if the subcontext comes directly off the root, use the env of the InitialContext - //as the root itself has no environment. Otherwise, it inherits the env of the parent - //Context further down the tree. - //NamingContext ctx = (NamingContext)__root.createSubcontext(name); - //if (ctx.getParent() == __root) - // ctx.setEnv(_env); - //return ctx; + //if the subcontext comes directly off the root, use the env of the InitialContext + //as the root itself has no environment. Otherwise, it inherits the env of the parent + //Context further down the tree. + //NamingContext ctx = (NamingContext)__root.createSubcontext(name); + //if (ctx.getParent() == __root) + // ctx.setEnv(_env); + //return ctx; - return createSubcontext(__root.getNameParser("").parse(name)); - } + return createSubcontext(__root.getNameParser("").parse(name)); } /** @@ -812,92 +559,45 @@ public class localContextRoot implements Context @Override public Context createSubcontext(Name name) throws NamingException { - synchronized (__root) + //if the subcontext comes directly off the root, use the env of the InitialContext + //as the root itself has no environment. Otherwise, it inherits the env of the parent + //Context further down the tree. + //NamingContext ctx = (NamingContext)__root.createSubcontext(getSuffix(name)); + //if (ctx.getParent() == __root) + // ctx.setEnv(_env); + //return ctx; + + if (__root.isLocked()) { - //if the subcontext comes directly off the root, use the env of the InitialContext - //as the root itself has no environment. Otherwise, it inherits the env of the parent - //Context further down the tree. - //NamingContext ctx = (NamingContext)__root.createSubcontext(getSuffix(name)); - //if (ctx.getParent() == __root) - // ctx.setEnv(_env); - //return ctx; - - - - - if (__root.isLocked()) - { - NamingException ne = new NamingException ("This context is immutable"); - ne.setRemainingName(name); - throw ne; - } - - Name cname = __root.toCanonicalName (name); - - if (cname == null) - throw new NamingException ("Name is null"); - if (cname.size() == 0) - throw new NamingException ("Name is empty"); - - if (cname.size() == 1) - { - //not permitted to bind if something already bound at that name - Binding binding = __root.getBinding (cname); - if (binding != null) - throw new NameAlreadyBoundException (cname.toString()); - - //make a new naming context with the root as the parent - Context ctx = new NamingContext ((Hashtable)_env.clone(), cname.get(0), __root, __root.getNameParser("")); - __root.addBinding (cname, ctx); - return ctx; - } - - - //If the name has multiple subcontexts, walk the hierarchy by - //fetching the first one. All intermediate subcontexts in the - //name must already exist. - String firstComponent = cname.get(0); - Object ctx = null; - - if (firstComponent.equals("")) - ctx = this; - else - { - Binding binding = __root.getBinding (firstComponent); - if (binding == null) - throw new NameNotFoundException (firstComponent + " is not bound"); - - ctx = binding.getObject(); - - if (ctx instanceof Reference) - { - //deference the object - if(__log.isDebugEnabled())__log.debug("Object bound at "+firstComponent +" is a Reference"); - try - { - ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), __root, _env); - } - catch (NamingException e) - { - throw e; - } - catch (Exception e) - { - __log.warn("",e); - throw new NamingException (e.getMessage()); - } - } - } - - if (ctx instanceof Context) - { - return ((Context)ctx).createSubcontext (cname.getSuffix(1)); - } - else - throw new NotContextException (firstComponent +" is not a Context"); + NamingException ne = new NamingException ("This context is immutable"); + ne.setRemainingName(name); + throw ne; } - } + Name cname = __root.toCanonicalName (name); + + if (cname == null) + throw new NamingException ("Name is null"); + if (cname.size() == 0) + throw new NamingException ("Name is empty"); + + if (cname.size() == 1) + { + //not permitted to bind if something already bound at that name + Binding binding = __root.getBinding (cname); + if (binding != null) + throw new NameAlreadyBoundException (cname.toString()); + + //make a new naming context with the root as the parent + Context ctx = new NamingContext (_env, cname.get(0), __root, __root.getNameParser("")); + __root.addBinding (cname, ctx); + return ctx; + } + + //If the name has multiple subcontexts, + return getContext(cname).createSubcontext(cname.getSuffix(1)); + + } /** * @@ -929,13 +629,9 @@ public class localContextRoot implements Context @Override public NamingEnumeration list(String name) throws NamingException { - synchronized (__root) - { - return list(__root.getNameParser("").parse(getSuffix(name))); - } + return __root.list(name); } - /** * * @@ -944,67 +640,7 @@ public class localContextRoot implements Context @Override public NamingEnumeration list(Name name) throws NamingException { - synchronized (__root) - { - //return __root.list(getSuffix(name)); - - - Name cname = __root.toCanonicalName(name); - - if (cname == null) - { - List empty = Collections.emptyList(); - return new NameEnumeration(empty.iterator()); - } - - - if (cname.size() == 0) - { - return new NameEnumeration (__root.getBindings().values().iterator()); - } - - - - //multipart name - String firstComponent = cname.get(0); - Object ctx = null; - - if (firstComponent.equals("")) - ctx = this; - else - { - Binding binding = __root.getBinding (firstComponent); - if (binding == null) - throw new NameNotFoundException (); - - ctx = binding.getObject(); - - if (ctx instanceof Reference) - { - //deference the object - if(__log.isDebugEnabled())__log.debug("Dereferencing Reference for "+name.get(0)); - try - { - ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), __root, _env); - } - catch (NamingException e) - { - throw e; - } - catch (Exception e) - { - __log.warn("",e); - throw new NamingException (e.getMessage()); - } - } - } - - if (!(ctx instanceof Context)) - throw new NotContextException(); - - return ((Context)ctx).list (cname.getSuffix(1)); - - } + return __root.list(name); } /** @@ -1015,70 +651,9 @@ public class localContextRoot implements Context @Override public NamingEnumeration listBindings(Name name) throws NamingException { - synchronized (__root) - { - //return __root.listBindings(getSuffix(name)); - - Name cname = __root.toCanonicalName (name); - - if (cname == null) - { - List empty = Collections.emptyList(); - return new BindingEnumeration(empty.iterator()); - } - - if (cname.size() == 0) - { - return new BindingEnumeration (__root.getBindings().values().iterator()); - } - - - - //multipart name - String firstComponent = cname.get(0); - Object ctx = null; - - //if a name has a leading "/" it is parsed as "" so ignore it by staying - //at this level in the tree - if (firstComponent.equals("")) - ctx = this; - else - { - //it is a non-empty name component - Binding binding = __root.getBinding (firstComponent); - if (binding == null) - throw new NameNotFoundException (); - - ctx = binding.getObject(); - - if (ctx instanceof Reference) - { - //deference the object - try - { - ctx = NamingManager.getObjectInstance(ctx, getNameParser("").parse(firstComponent), __root, _env); - } - catch (NamingException e) - { - throw e; - } - catch (Exception e) - { - __log.warn("",e); - throw new NamingException (e.getMessage()); - } - } - } - - if (!(ctx instanceof Context)) - throw new NotContextException(); - - return ((Context)ctx).listBindings (cname.getSuffix(1)); - - } + return __root.listBindings(name); } - /** * * @@ -1087,13 +662,9 @@ public class localContextRoot implements Context @Override public NamingEnumeration listBindings(String name) throws NamingException { - synchronized (__root) - { - return listBindings(__root.getNameParser("").parse(getSuffix(name))); - } + return __root.listBindings(name); } - /** * *