Package winstone.jndi

Source Code of winstone.jndi.WinstoneContext

/*
* Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
* Distributed under the terms of either:
* - the common development and distribution license (CDDL), v1.0; or
* - the GNU Lesser General Public License, v2.1 or later
*/
package winstone.jndi;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.naming.CompositeName;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NameNotFoundException;
import javax.naming.NameParser;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.NotContextException;
import javax.naming.OperationNotSupportedException;
import javax.naming.spi.NamingManager;

import winstone.Logger;

/**
* The main jndi context implementation class.
*
* @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
* @version $Id: WinstoneContext.java,v 1.3 2006/02/28 07:32:48 rickknowles Exp $
*/
public class WinstoneContext implements Context {
    static final String PREFIX = "java:";
    static final String FIRST_CHILD = "comp";
    static final String BODGED_PREFIX = "java:comp";
   
    private Hashtable environment;
    private Hashtable bindings;
    private final static NameParser nameParser = new WinstoneNameParser();
    private WinstoneContext parent;
    private String myAbsoluteName;
    private Object contextLock;

    /**
     * Constructor - sets up environment
     */
    public WinstoneContext(Map sourceEnvironment, WinstoneContext parent,
            String absoluteName, Object contextLock) throws NamingException {
        this.environment = new Hashtable();
        List sourceKeys = new ArrayList(sourceEnvironment.keySet());
        for (Iterator i = sourceKeys.iterator(); i.hasNext();) {
            String key = (String) i.next();
            addToEnvironment(key, sourceEnvironment.get(key));
        }
        this.parent = parent;
        this.myAbsoluteName = absoluteName;
        this.contextLock = contextLock;
        this.bindings = new Hashtable();
        Logger.log(Logger.FULL_DEBUG, ContainerJNDIManager.JNDI_RESOURCES,
                "WinstoneContext.Initialised", this.myAbsoluteName);
    }

    /**
     * Constructor - sets up environment and copies the bindings across
     */
    protected WinstoneContext(Map sourceEnvironment, WinstoneContext parent,
            String absoluteName, Object contextLock, Hashtable bindings) throws NamingException {
        this.environment = new Hashtable();
        List sourceKeys = new ArrayList(sourceEnvironment.keySet());
        for (Iterator i = sourceKeys.iterator(); i.hasNext();) {
            String key = (String) i.next();
            addToEnvironment(key, sourceEnvironment.get(key));
        }
        this.parent = parent;
        this.myAbsoluteName = absoluteName;
        this.contextLock = contextLock;
        this.bindings = bindings;
        Logger.log(Logger.FULL_DEBUG, ContainerJNDIManager.JNDI_RESOURCES,
                "WinstoneContext.Copied", this.myAbsoluteName);
    }

    public void close() throws NamingException {
    }

    public Hashtable getEnvironment() throws NamingException {
        return new Hashtable(this.environment);
    }

    public Object removeFromEnvironment(String property) throws NamingException {
        return this.environment.remove(property);
    }

    public Object addToEnvironment(String property, Object value)
            throws NamingException {
        return this.environment.put(property, value);
    }

    /**
     * Handles the processing of relative and absolute names. If a relative name
     * is detected, it is processed by the name parser. If an absolute name is
     * detected, it determines first if the absolute name refers to this
     * context. If not, it then determines whether the request can be passed
     * back to the parent or not, and returns null if it can, and throws an
     * exception otherwise.
     */
    protected Name validateName(Name name) throws NamingException {
        // Check for absolute urls and redirect or correct
        if (name.isEmpty())
            return name;
        else if (name.get(0).equals(BODGED_PREFIX)) {
            Name newName = name.getSuffix(1).add(0, FIRST_CHILD).add(0, PREFIX);
            return validateName(newName);
        } else if (name.get(0).equals(PREFIX)) {
            String stringName = name.toString();
            if (stringName.equals(this.myAbsoluteName))
                return nameParser.parse("");
            else if (stringName.startsWith(this.myAbsoluteName))
                return nameParser.parse(stringName
                        .substring(this.myAbsoluteName.length() + 1));
            else if (this.parent != null)
                return null;
            else
                throw new NameNotFoundException(ContainerJNDIManager.JNDI_RESOURCES.getString(
                        "WinstoneContext.NameNotFound", name.toString()));
        } else if (name instanceof CompositeName)
            return nameParser.parse(name.toString());
        else
            return name;
    }

    /**
     * Lookup an object in the context. Returns a copy of this context if the
     * name is empty, or the specified resource (if we have it). If the name is
     * unknown, throws a NameNotFoundException.
     */
    public Object lookup(Name name) throws NamingException {
        Name searchName = validateName(name);

        // If null, it means we don't know how to handle this -> throw to the
        // parent
        if (searchName == null)
            return this.parent.lookup(name);
        // If empty name, return a copy of this Context
        else if (searchName.isEmpty())
            return new WinstoneContext(this.environment, this.parent,
                    this.myAbsoluteName, this.contextLock, this.bindings);

        String thisName = searchName.get(0);
        synchronized (this.contextLock) {
            Object thisValue = bindings.get(thisName);

            // If the name points to something in this level, try to find it,
            // and give
            // an error if not available
            if (searchName.size() == 1) {
                if (thisValue == null)
                    throw new NameNotFoundException(ContainerJNDIManager.JNDI_RESOURCES.getString(
                            "WinstoneContext.NameNotFound", name.toString()));

                try {
                    return NamingManager.getObjectInstance(thisValue,
                            new CompositeName().add(thisName), this,
                            this.environment);
                } catch (Exception e) {
                    NamingException ne = new NamingException(ContainerJNDIManager.JNDI_RESOURCES
                            .getString("WinstoneContext.FailedToGetInstance"));
                    ne.setRootCause(e);
                    throw ne;
                }
            }

            else if (thisValue == null)
                throw new NameNotFoundException(ContainerJNDIManager.JNDI_RESOURCES.getString(
                        "WinstoneContext.NameNotFound", thisName.toString()));

            // If it's not in this level and what we found is not a context,
            // complain
            else if (!(thisValue instanceof Context))
                throw new NotContextException(ContainerJNDIManager.JNDI_RESOURCES.getString(
                        "WinstoneContext.NotContext", new String[] {
                                thisName.toString(),
                                thisValue.getClass().getName() }));

            // Open the context, perform a lookup, then close the context we
            // opened
            else
                try {
                    return ((Context) thisValue)
                            .lookup(searchName.getSuffix(1));
                } finally {
                    ((Context) thisValue).close();
                }
        }
    }

    public Object lookup(String name) throws NamingException {
        return lookup(new CompositeName(name));
    }

    public Object lookupLink(Name name) throws NamingException {
        Logger.log(Logger.WARNING, ContainerJNDIManager.JNDI_RESOURCES,
                "WinstoneContext.LinkRefUnsupported");
        return lookup(name);
    }

    public Object lookupLink(String name) throws NamingException {
        return lookupLink(new CompositeName(name));
    }

    /**
     * Returns a list of objects bound to the context
     */
    public NamingEnumeration list(Name name) throws NamingException {
        Name searchName = validateName(name);

        // If null, it means we don't know how to handle this -> throw to the
        // parent
        if (searchName == null)
            return this.parent.list(name);
        // If empty name, return a copy of this Context
        else if (searchName.isEmpty()) {
            NamingEnumeration e = null;
            synchronized (this.contextLock) {
                e = new WinstoneNameEnumeration(this.bindings);
            }
            return e;
        }

        // Lookup the object - if it's not a context, throw an error
        else {
            Object ctx = this.lookup(searchName);
            if (ctx instanceof Context)
                try {
                    return ((Context) ctx).list(new CompositeName(""));
                } finally {
                    ((Context) ctx).close();
                }
            else if (ctx == null)
                throw new NameNotFoundException(ContainerJNDIManager.JNDI_RESOURCES.getString(
                        "WinstoneContext.NameNotFound", searchName.toString()));
            else
                throw new NotContextException(ContainerJNDIManager.JNDI_RESOURCES.getString(
                        "WinstoneContext.NotContext",
                        new String[] { searchName.toString(),
                                ctx.getClass().getName() }));
        }
    }

    public NamingEnumeration list(String name) throws NamingException {
        return list(new CompositeName(name));
    }

    public NamingEnumeration listBindings(Name name) throws NamingException {
        Name searchName = validateName(name);

        // If null, it means we don't know how to handle this -> throw to the
        // parent
        if (searchName == null)
            return this.parent.list(name);
        // If empty name, return a copy of this Context
        else if (searchName.isEmpty()) {
            NamingEnumeration e = null;
            synchronized (this.contextLock) {
                e = new WinstoneBindingEnumeration(this.bindings,
                        this.environment, this);
            }
            return e;
        }

        // Lookup the object - if it's not a context, throw an error
        else {
            Object ctx = this.lookup(searchName);
            if (ctx instanceof Context)
                try {
                    return ((Context) ctx).listBindings(new CompositeName(""));
                } finally {
                    ((Context) ctx).close();
                }
            else if (ctx == null)
                throw new NameNotFoundException(ContainerJNDIManager.JNDI_RESOURCES.getString(
                        "WinstoneContext.NameNotFound", searchName.toString()));
            else
                throw new NotContextException(ContainerJNDIManager.JNDI_RESOURCES.getString(
                        "WinstoneContext.NotContext",
                        new String[] { searchName.toString(),
                                ctx.getClass().getName() }));
        }
    }

    public NamingEnumeration listBindings(String name) throws NamingException {
        return listBindings(new CompositeName(name));
    }

    public NameParser getNameParser(Name name) throws NamingException {
        Object obj = lookup(name);
        if (obj instanceof Context) {
            ((Context) obj).close();
        }
        return nameParser;
    }

    public NameParser getNameParser(String name) throws NamingException {
        return getNameParser(new CompositeName(name));
    }

    public String getNameInNamespace() throws NamingException {
        return this.myAbsoluteName;
    }

    /***************************************************************************
     * Below here is for read-write contexts ... *
     **************************************************************************/

    public void bind(String name, Object value) throws NamingException {
        bind(new CompositeName(name), value);
    }

    public void bind(Name name, Object value) throws NamingException {
        bind(name, value, false);
    }

    protected void bind(Name name, Object value, boolean allowOverwrites)
            throws NamingException {
        Name bindName = validateName(name);

        // If null, it means we don't know how to handle this -> throw to the
        // parent
        if (bindName == null)
            this.parent.bind(name, value, allowOverwrites);
        // If empty name, complain - we should have a child name here
        else if (bindName.isEmpty())
            throw new NamingException(ContainerJNDIManager.JNDI_RESOURCES.getString(
                    "WinstoneContext.AlreadyExists", name.toString()));
        else if (bindName.size() > 1) {
            Object ctx = lookup(bindName.get(0));
            if (!(ctx instanceof Context))
                throw new NotContextException(ContainerJNDIManager.JNDI_RESOURCES.getString(
                        "WinstoneContext.NotContext", new String[] {
                                bindName.get(0), ctx.getClass().getName() }));
            else if (ctx == null)
                throw new NameNotFoundException(ContainerJNDIManager.JNDI_RESOURCES.getString(
                        "WinstoneContext.NameNotFound", bindName.get(0)));
            else
                try {
                    if (allowOverwrites)
                        ((Context) ctx).rebind(bindName.getSuffix(1), value);
                    else
                        ((Context) ctx).bind(bindName.getSuffix(1), value);
                } finally {
                    ((Context) ctx).close();
                }
        } else if ((!allowOverwrites) && this.bindings.get(name.get(0)) != null)
            throw new NamingException(ContainerJNDIManager.JNDI_RESOURCES.getString(
                    "WinstoneContext.AlreadyExists", name.toString()));
        else {
            value = NamingManager.getStateToBind(value, new CompositeName()
                    .add(bindName.get(0)), this, this.environment);
            synchronized (this.contextLock) {
                this.bindings.put(bindName.get(0), value);
            }
        }
    }

    public void rebind(String name, Object value) throws NamingException {
        rebind(new CompositeName(name), value);
    }

    public void rebind(Name name, Object value) throws NamingException {
        bind(name, value, true);
    }

    public void unbind(String name) throws NamingException {
        unbind(new CompositeName(name));
    }

    public void unbind(Name name) throws NamingException {
        Name unbindName = validateName(name);

        // If null, it means we don't know how to handle this -> throw to the
        // parent
        if (unbindName == null)
            this.parent.unbind(name);
        // If empty name, complain - we should have a child name here
        else if (unbindName.isEmpty())
            throw new NamingException(ContainerJNDIManager.JNDI_RESOURCES
                    .getString("WinstoneContext.CantUnbindEmptyName"));
        else if (unbindName.size() > 1) {
            Object ctx = lookup(unbindName.get(0));
            if (!(ctx instanceof Context))
                throw new NotContextException(ContainerJNDIManager.JNDI_RESOURCES.getString(
                        "WinstoneContext.NotContext", new String[] {
                                unbindName.get(0), ctx.getClass().getName() }));
            else if (ctx == null)
                throw new NameNotFoundException(ContainerJNDIManager.JNDI_RESOURCES.getString(
                        "WinstoneContext.NameNotFound", unbindName.get(0)));
            else
                try {
                    ((Context) ctx).unbind(unbindName.getSuffix(1));
                } finally {
                    ((Context) ctx).close();
                }
        } else if (this.bindings.get(name.get(0)) == null)
            throw new NamingException(ContainerJNDIManager.JNDI_RESOURCES.getString(
                    "WinstoneContext.NameNotFound", name.toString()));
        else {
            synchronized (this.contextLock) {
                // Object removing = this.bindings.get(unbindName.get(0));
                this.bindings.remove(unbindName.get(0));
            }
        }
    }

    public void rename(Name oldName, Name newName) throws NamingException {
        throw new OperationNotSupportedException(
                "rename not supported in Winstone java:/ context");
    }

    public void rename(String oldName, String newName) throws NamingException {
        rename(new CompositeName(oldName), new CompositeName(newName));
    }

    public Context createSubcontext(String name) throws NamingException {
        return createSubcontext(new CompositeName(name));
    }

    public Context createSubcontext(Name name) throws NamingException {
        Name childName = validateName(name);

        // If null, it means we don't know how to handle this -> throw to the
        // parent
        if (childName == null)
            return this.parent.createSubcontext(name);
        // If empty name, complain - we should have a child name here
        else if (childName.isEmpty())
            throw new NamingException(ContainerJNDIManager.JNDI_RESOURCES.getString(
                    "WinstoneContext.AlreadyExists", name.toString()));
        else if (childName.size() > 1) {
            Object ctx = lookup(childName.get(0));
            if (!(ctx instanceof Context))
                throw new NotContextException(ContainerJNDIManager.JNDI_RESOURCES.getString(
                        "WinstoneContext.NotContext", new String[] {
                                childName.get(0), ctx.getClass().getName() }));
            else if (ctx == null)
                throw new NameNotFoundException(ContainerJNDIManager.JNDI_RESOURCES.getString(
                        "WinstoneContext.NameNotFound", childName.get(0)));
            else
                try {
                    ((Context) ctx).createSubcontext(childName.getSuffix(1));
                } finally {
                    ((Context) ctx).close();
                }
        }

        Context childContext = null;
        synchronized (this.contextLock) {
            if (this.bindings.get(childName.get(0)) != null)
                throw new NamingException(ContainerJNDIManager.JNDI_RESOURCES.getString(
                        "WinstoneContext.AlreadyExists", childName.get(0)));
            else {
                childContext = new WinstoneContext(this.environment, this,
                        this.myAbsoluteName + "/" + childName.get(0),
                        new Boolean(true));
                this.bindings.put(childName.get(0), childContext);
            }
        }
        return childContext;
    }

    public void destroySubcontext(String name) throws NamingException {
        destroySubcontext(new CompositeName(name));
    }

    public void destroySubcontext(Name name) throws NamingException {
        Name childName = validateName(name);

        // If null, it means we don't know how to handle this -> throw to the parent
        if (childName == null)
            this.parent.destroySubcontext(name);
        // If absolutely referring to this context, tell the parent to delete this context
        else if (childName.isEmpty()) {
            if (!name.isEmpty())
                this.parent.destroySubcontext(name.getSuffix(name.size() - 2));
            else
                throw new NamingException(ContainerJNDIManager.JNDI_RESOURCES
                        .getString("WinstoneContext.CantDestroyEmptyName"));
        } else if (childName.size() > 1) {
            Object ctx = lookup(childName.get(0));
            if (!(ctx instanceof Context))
                throw new NotContextException(ContainerJNDIManager.JNDI_RESOURCES.getString(
                        "WinstoneContext.NotContext", new String[] {
                                childName.get(0), ctx.getClass().getName() }));
            else if (ctx == null)
                throw new NameNotFoundException(ContainerJNDIManager.JNDI_RESOURCES.getString(
                        "WinstoneContext.NameNotFound", childName.get(0)));
            else
                try {
                    ((Context) ctx).destroySubcontext(childName.getSuffix(1));
                } finally {
                    ((Context) ctx).close();
                }
        } else
            synchronized (this.contextLock) {
                Context childContext = (Context) lookup(childName.get(0));
                childContext.close();
                this.bindings.remove(childName.get(0));
            }
    }

    public String composeName(String name1, String name2)
            throws NamingException {
        Name name = composeName(new CompositeName(name1), new CompositeName(
                name2));
        return name == null ? null : name.toString();
    }

    public Name composeName(Name name1, Name name2) throws NamingException {
        throw new OperationNotSupportedException(
                "composeName not supported in Winstone java:/ namespace");
    }
}
TOP

Related Classes of winstone.jndi.WinstoneContext

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.