523 lines · 18.4 KB · Java
RawDownload
/* * Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.jndi.toolkit.ctx; import java.util.Hashtable;import java.util.Enumeration; import javax.naming.*;import javax.naming.spi.Resolver;import javax.naming.spi.ResolveResult;import javax.naming.spi.NamingManager; /**  * PartialCompositeContext implements Context operations on  * composite names using implementations of the p_ interfaces  * defined by its subclasses.  *  * The main purpose provided by this class is that it deals with  * partial resolutions and continuations, so that callers of the  * Context operation don't have to.  *  * Types of clients that will be direct subclasses of  * PartialCompositeContext may be service providers that implement  * one of the JNDI protocols, but which do not deal with  * continuations.  Usually, service providers will be using  * one of the subclasses of PartialCompositeContext.  *  * @author Rosanna Lee  */  public abstract class PartialCompositeContext implements Context, Resolver {    protected static final int _PARTIAL = 1;    protected static final int _COMPONENT = 2;    protected static final int _ATOMIC = 3;     protected int _contextType = _PARTIAL;     static final CompositeName _EMPTY_NAME = new CompositeName();    static CompositeName _NNS_NAME;     static {        try {            _NNS_NAME = new CompositeName("/");        } catch (InvalidNameException e) {            // Should never happen        }    }     protected PartialCompositeContext() {    } // ------ Abstract methods whose implementations come from subclasses     /* Equivalent to method in  Resolver interface */    protected abstract ResolveResult p_resolveToClass(Name name,        Class contextType, Continuation cont) throws NamingException;     /* Equivalent to methods in Context interface */    protected abstract Object p_lookup(Name name, Continuation cont)        throws NamingException;    protected abstract Object p_lookupLink(Name name, Continuation cont)        throws NamingException;    protected abstract NamingEnumeration p_list(Name name,        Continuation cont) throws NamingException;    protected abstract NamingEnumeration p_listBindings(Name name,        Continuation cont) throws NamingException;    protected abstract void p_bind(Name name, Object obj, Continuation cont)        throws NamingException;    protected abstract void p_rebind(Name name, Object obj, Continuation cont)        throws NamingException;    protected abstract void p_unbind(Name name, Continuation cont)        throws NamingException;    protected abstract void p_destroySubcontext(Name name, Continuation cont)        throws NamingException;    protected abstract Context p_createSubcontext(Name name, Continuation cont)        throws NamingException;    protected abstract void p_rename(Name oldname, Name newname,                                     Continuation cont)        throws NamingException;    protected abstract NameParser p_getNameParser(Name name, Continuation cont)        throws NamingException; // ------ should be overridden by subclass;// ------ not abstract only for backward compatibility     /**     * A cheap way of getting the environment.     * Default implemenation is NOT cheap because it simply calls     * getEnvironment(), which most implementations clone before returning.     * Subclass should ALWAYS override this with the cheapest possible way.     * The toolkit knows to clone when necessary.     * @return The possibly null environment of the context.     */    protected Hashtable p_getEnvironment() throws NamingException {        return getEnvironment();    }  // ------ implementations of methods in Resolver and Context// ------ using corresponding p_ methods provided by subclass     /* implementations for method in Resolver interface using p_ method */     public ResolveResult resolveToClass(String name,                                        Class<? extends Context> contextType)        throws NamingException    {        return resolveToClass(new CompositeName(name), contextType);    }     public ResolveResult resolveToClass(Name name,                                        Class<? extends Context> contextType)        throws NamingException    {        PartialCompositeContext ctx = this;        Hashtable env = p_getEnvironment();        Continuation cont = new Continuation(name, env);        ResolveResult answer;        Name nm = name;         try {            answer = ctx.p_resolveToClass(nm, contextType, cont);            while (cont.isContinue()) {                nm = cont.getRemainingName();                ctx = getPCContext(cont);                answer = ctx.p_resolveToClass(nm, contextType, cont);            }        } catch (CannotProceedException e) {            Context cctx = NamingManager.getContinuationContext(e);            if (!(cctx instanceof Resolver)) {                throw e;            }            answer = ((Resolver)cctx).resolveToClass(e.getRemainingName(),                                                     contextType);        }        return answer;    }     /* implementations for methods in Context interface using p_ methods */     public Object lookup(String name) throws NamingException {        return lookup(new CompositeName(name));    }     public Object lookup(Name name) throws NamingException {        PartialCompositeContext ctx = this;        Hashtable env = p_getEnvironment();        Continuation cont = new Continuation(name, env);        Object answer;        Name nm = name;         try {            answer = ctx.p_lookup(nm, cont);            while (cont.isContinue()) {                nm = cont.getRemainingName();                ctx = getPCContext(cont);                answer = ctx.p_lookup(nm, cont);            }        } catch (CannotProceedException e) {            Context cctx = NamingManager.getContinuationContext(e);            answer = cctx.lookup(e.getRemainingName());        }        return answer;    }     public void bind(String name, Object newObj) throws NamingException {        bind(new CompositeName(name), newObj);    }     public void bind(Name name, Object newObj) throws NamingException {        PartialCompositeContext ctx = this;        Name nm = name;        Hashtable env = p_getEnvironment();        Continuation cont = new Continuation(name, env);         try {            ctx.p_bind(nm, newObj, cont);            while (cont.isContinue()) {                nm = cont.getRemainingName();                ctx = getPCContext(cont);                ctx.p_bind(nm, newObj, cont);            }        } catch (CannotProceedException e) {            Context cctx = NamingManager.getContinuationContext(e);            cctx.bind(e.getRemainingName(), newObj);        }    }     public void rebind(String name, Object newObj) throws NamingException {        rebind(new CompositeName(name), newObj);    }    public void rebind(Name name, Object newObj) throws NamingException {        PartialCompositeContext ctx = this;        Name nm = name;        Hashtable env = p_getEnvironment();        Continuation cont = new Continuation(name, env);         try {            ctx.p_rebind(nm, newObj, cont);            while (cont.isContinue()) {                nm = cont.getRemainingName();                ctx = getPCContext(cont);                ctx.p_rebind(nm, newObj, cont);            }        } catch (CannotProceedException e) {            Context cctx = NamingManager.getContinuationContext(e);            cctx.rebind(e.getRemainingName(), newObj);        }    }     public void unbind(String name) throws NamingException {        unbind(new CompositeName(name));    }    public void unbind(Name name) throws NamingException {        PartialCompositeContext ctx = this;        Name nm = name;        Hashtable env = p_getEnvironment();        Continuation cont = new Continuation(name, env);         try {            ctx.p_unbind(nm, cont);            while (cont.isContinue()) {                nm = cont.getRemainingName();                ctx = getPCContext(cont);                ctx.p_unbind(nm, cont);            }        } catch (CannotProceedException e) {            Context cctx = NamingManager.getContinuationContext(e);            cctx.unbind(e.getRemainingName());        }    }     public void rename(String oldName, String newName) throws NamingException {        rename(new CompositeName(oldName), new CompositeName(newName));    }    public void rename(Name oldName, Name newName)        throws NamingException    {        PartialCompositeContext ctx = this;        Name nm = oldName;        Hashtable env = p_getEnvironment();        Continuation cont = new Continuation(oldName, env);         try {            ctx.p_rename(nm, newName, cont);            while (cont.isContinue()) {                nm = cont.getRemainingName();                ctx = getPCContext(cont);                ctx.p_rename(nm, newName, cont);            }        } catch (CannotProceedException e) {            Context cctx = NamingManager.getContinuationContext(e);            if (e.getRemainingNewName() != null) {                // %%% e.getRemainingNewName() should never be null                newName = e.getRemainingNewName();            }            cctx.rename(e.getRemainingName(), newName);        }    }     public NamingEnumeration<NameClassPair> list(String name)        throws NamingException    {        return list(new CompositeName(name));    }     public NamingEnumeration<NameClassPair> list(Name name)        throws NamingException    {        PartialCompositeContext ctx = this;        Name nm = name;        NamingEnumeration answer;        Hashtable env = p_getEnvironment();        Continuation cont = new Continuation(name, env);         try {            answer = ctx.p_list(nm, cont);            while (cont.isContinue()) {                nm = cont.getRemainingName();                ctx = getPCContext(cont);                answer = ctx.p_list(nm, cont);            }        } catch (CannotProceedException e) {            Context cctx = NamingManager.getContinuationContext(e);            answer = cctx.list(e.getRemainingName());        }        return answer;    }     public NamingEnumeration<Binding> listBindings(String name)        throws NamingException    {        return listBindings(new CompositeName(name));    }     public NamingEnumeration<Binding> listBindings(Name name)        throws NamingException    {        PartialCompositeContext ctx = this;        Name nm = name;        NamingEnumeration answer;        Hashtable env = p_getEnvironment();        Continuation cont = new Continuation(name, env);         try {            answer = ctx.p_listBindings(nm, cont);            while (cont.isContinue()) {                nm = cont.getRemainingName();                ctx = getPCContext(cont);                answer = ctx.p_listBindings(nm, cont);            }        } catch (CannotProceedException e) {            Context cctx = NamingManager.getContinuationContext(e);            answer = cctx.listBindings(e.getRemainingName());        }        return answer;    }     public void destroySubcontext(String name) throws NamingException {        destroySubcontext(new CompositeName(name));    }     public void destroySubcontext(Name name) throws NamingException {        PartialCompositeContext ctx = this;        Name nm = name;        Hashtable env = p_getEnvironment();        Continuation cont = new Continuation(name, env);         try {            ctx.p_destroySubcontext(nm, cont);            while (cont.isContinue()) {                nm = cont.getRemainingName();                ctx = getPCContext(cont);                ctx.p_destroySubcontext(nm, cont);            }        } catch (CannotProceedException e) {            Context cctx = NamingManager.getContinuationContext(e);            cctx.destroySubcontext(e.getRemainingName());        }    }     public Context createSubcontext(String name) throws NamingException {        return createSubcontext(new CompositeName(name));    }     public Context createSubcontext(Name name) throws NamingException {        PartialCompositeContext ctx = this;        Name nm = name;        Context answer;        Hashtable env = p_getEnvironment();        Continuation cont = new Continuation(name, env);         try {            answer = ctx.p_createSubcontext(nm, cont);            while (cont.isContinue()) {                nm = cont.getRemainingName();                ctx = getPCContext(cont);                answer = ctx.p_createSubcontext(nm, cont);            }        } catch (CannotProceedException e) {            Context cctx = NamingManager.getContinuationContext(e);            answer = cctx.createSubcontext(e.getRemainingName());        }        return answer;    }     public Object lookupLink(String name) throws NamingException {        return lookupLink(new CompositeName(name));    }     public Object lookupLink(Name name) throws NamingException {        PartialCompositeContext ctx = this;        Hashtable env = p_getEnvironment();        Continuation cont = new Continuation(name, env);        Object answer;        Name nm = name;         try {            answer = ctx.p_lookupLink(nm, cont);            while (cont.isContinue()) {                nm = cont.getRemainingName();                ctx = getPCContext(cont);                answer = ctx.p_lookupLink(nm, cont);            }        } catch (CannotProceedException e) {            Context cctx = NamingManager.getContinuationContext(e);            answer = cctx.lookupLink(e.getRemainingName());        }        return answer;    }     public NameParser getNameParser(String name) throws NamingException {        return getNameParser(new CompositeName(name));    }     public NameParser getNameParser(Name name) throws NamingException {        PartialCompositeContext ctx = this;        Name nm = name;        NameParser answer;        Hashtable env = p_getEnvironment();        Continuation cont = new Continuation(name, env);         try {            answer = ctx.p_getNameParser(nm, cont);            while (cont.isContinue()) {                nm = cont.getRemainingName();                ctx = getPCContext(cont);                answer = ctx.p_getNameParser(nm, cont);            }        } catch (CannotProceedException e) {            Context cctx = NamingManager.getContinuationContext(e);            answer = cctx.getNameParser(e.getRemainingName());        }        return answer;    }     public String composeName(String name, String prefix)            throws NamingException {        Name fullName = composeName(new CompositeName(name),                                    new CompositeName(prefix));        return fullName.toString();    }     /**     * This default implementation simply concatenates the two names.     * There's one twist when the "java.naming.provider.compose.elideEmpty"     * environment setting is set to "true":  if each name contains a     * nonempty component, and if 'prefix' ends with an empty component or     * 'name' starts with one, then one empty component is dropped.     * For example:     * <pre>     *                            elideEmpty=false     elideEmpty=true     * {"a"} + {"b"}          =>  {"a", "b"}           {"a", "b"}     * {"a"} + {""}           =>  {"a", ""}            {"a", ""}     * {"a"} + {"", "b"}      =>  {"a", "", "b"}       {"a", "b"}     * {"a", ""} + {"b", ""}  =>  {"a", "", "b", ""}   {"a", "b", ""}     * {"a", ""} + {"", "b"}  =>  {"a", "", "", "b"}   {"a", "", "b"}     * </pre>     */    public Name composeName(Name name, Name prefix) throws NamingException {        Name res = (Name)prefix.clone();        if (name == null) {            return res;        }        res.addAll(name);         String elide = (String)            p_getEnvironment().get("java.naming.provider.compose.elideEmpty");        if (elide == null || !elide.equalsIgnoreCase("true")) {            return res;        }         int len = prefix.size();         if (!allEmpty(prefix) && !allEmpty(name)) {            if (res.get(len - 1).equals("")) {                res.remove(len - 1);            } else if (res.get(len).equals("")) {                res.remove(len);            }        }        return res;    }  // ------ internal methods used by PartialCompositeContext     /**     * Tests whether a name contains a nonempty component.     */    protected static boolean allEmpty(Name name) {        Enumeration<String> enum_ = name.getAll();        while (enum_.hasMoreElements()) {            if (!enum_.nextElement().isEmpty()) {                return false;            }

Lines 1–500 of 523.