Package org.codehaus.spice.jndikit

Source Code of org.codehaus.spice.jndikit.AbstractLocalContext

/*
* Copyright (C) The Spice Group. All rights reserved.
*
* This software is published under the terms of the Spice
* Software License version 1.1, a copy of which has been included
* with this distribution in the LICENSE.txt file.
*/
package org.codehaus.spice.jndikit;

import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.ContextNotEmptyException;
import javax.naming.InvalidNameException;
import javax.naming.Name;
import javax.naming.NameAlreadyBoundException;
import javax.naming.NameParser;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.NotContextException;
import javax.naming.OperationNotSupportedException;
import javax.naming.Referenceable;

/**
* Abstract local JNDI Context that can be inherited from to
* provide a particular type of Context. These contexts are assumed to be
* on the same machine.
*
* @author Peter Donald
* @version $Revision: 1.3 $
*/
public abstract class AbstractLocalContext
    extends AbstractContext
{
    private Context m_parent;
    private Namespace m_namespace;

    public AbstractLocalContext( final Namespace namespace,
                                 final Hashtable environment,
                                 final Context parent )
    {
        super( environment );
        m_namespace = namespace;
        m_parent = parent;
    }

    /**
     * Utility method to retrieve parent Context.
     *
     * @return the parent Context if any
     */
    protected final Context getParent()
    {
        return m_parent;
    }

    /**
     * Utility method to retrieve the Namespace.
     *
     * @return the Namespace
     */
    protected final Namespace getNamespace()
    {
        return m_namespace;
    }

    protected boolean isDestroyableContext( final Object object )
        throws NamingException
    {
        return getClass().isInstance( object );
    }

    protected abstract Context newContext()
        throws NamingException;

    protected abstract Context cloneContext()
        throws NamingException;

    /**
     * Helper method to bind
     */
    protected void bind( final Name name, Object object, final boolean rebind )
        throws NamingException
    {
        if( isSelf( name ) )
        {
            throw new InvalidNameException( "Failed to bind self" );
        }

        if( 1 == name.size() )
        {
            boolean alreadyBound;
            try
            {
                localLookup( name );
                alreadyBound = true;
            }
            catch( final NamingException ne )
            {
                alreadyBound = false;
            }

            if( !rebind && alreadyBound )
            {
                throw new NameAlreadyBoundException( name.get( 0 ) );
            }
            else
            {
                if( object instanceof Referenceable )
                {
                    object = ( (Referenceable)object ).getReference();
                }

                // Call getStateToBind for using any state factories
                final Name atom = name.getPrefix( 1 );
                object = m_namespace.getStateToBind( object, atom, this, getRawEnvironment() );

                doLocalBind( name, object );
            }
        }
        else
        {
            final Context context = lookupSubContext( getPathName( name ) );
            if( rebind )
            {
                context.rebind( getLeafName( name ), object );
            }
            else
            {
                context.bind( getLeafName( name ), object );
            }
        }
    }

    protected abstract void doLocalBind( Name name, Object object )
        throws NamingException;

    public void close()
    {
        m_parent = null;
        m_namespace = null;
    }

    /**
     * Create a Subcontext.
     *
     * @param name the name of subcontext
     * @return the created context
     * @throws NamingException if an error occurs
     *         (ie context exists, badly formated name etc)
     */
    public Context createSubcontext( final Name name )
        throws NamingException
    {
        final Context context = newContext();
        bind( name, context );
        return context;
    }

    public void destroySubcontext( final Name name )
        throws NamingException
    {
        if( isSelf( name ) )
        {
            throw new InvalidNameException( "Failed to destroy self" );
        }

        if( 1 == name.size() )
        {
            Object object = null;
            try
            {
                object = localLookup( name );
            }
            catch( final NamingException ne )
            {
                return;
            }

            checkUnbindContext( name, object );

            doLocalUnbind( name );
        }
        else
        {
            final Context context = lookupSubContext( getPathName( name ) );

            Object object = null;

            final Name atom = getLeafName( name );
            try
            {
                object = context.lookup( atom );
            }
            catch( final NamingException ne )
            {
                return;
            }

            checkUnbindContext( atom, object );

            context.destroySubcontext( atom );
        }
    }

    protected void checkUnbindContext( final Name name, final Object entry )
        throws NamingException
    {
        if( !isDestroyableContext( entry ) )
        {
            throw new NotContextException( name.toString() );
        }

        final Context context = (Context)entry;
        if( context.list( "" ).hasMoreElements() )
        {
            throw new ContextNotEmptyException( name.toString() );
        }
    }

    public String getNameInNamespace()
        throws NamingException
    {
        throw new OperationNotSupportedException( "Namespace has no notion of a 'full name'" );
    }

    protected NameParser getNameParser()
        throws NamingException
    {
        return m_namespace.getNameParser();
    }

    /**
     * Enumerates the names bound in the named context.
     *
     * @param name the name of the context
     * @return the enumeration
     * @throws javax.naming.NamingException if an error occurs
     */
    public NamingEnumeration list( final Name name )
        throws NamingException
    {
        if( isSelf( name ) )
        {
            return doLocalList();
        }
        else
        {
            // Perhaps 'name' names a context
            final Context context = lookupSubContext( name );
            return context.list( "" );
        }
    }

    protected abstract NamingEnumeration doLocalList()
        throws NamingException;

    protected abstract NamingEnumeration doLocalListBindings()
        throws NamingException;

    /**
     * Enumerates the names bound in the named context, along with the objects bound to them.
     *
     * @param name the name of the context
     * @return the enumeration
     * @throws javax.naming.NamingException if an error occurs
     */
    public NamingEnumeration listBindings( final Name name )
        throws NamingException
    {
        if( isSelf( name ) )
        {
            return doLocalListBindings();
        }
        else
        {
            // Perhaps 'name' names a context
            final Context context = lookupSubContext( name );
            return context.listBindings( "" );
        }
    }

    /**
     * Get the object named.
     *
     * @param name the name
     * @return the object
     * @throws NamingException if an error occurs
     *         (ie object name is inavlid or unbound)
     */
    public Object lookup( final Name name )
        throws NamingException
    {
        //if it refers to base context return a copy of it.
        if( isSelf( name ) )
        {
            return cloneContext();
        }

        if( 1 == name.size() )
        {
            Object obj = localLookup( name );
            if (obj instanceof AbstractLocalContext)
            {
                return ((AbstractLocalContext) obj).cloneContext();
            }

            return obj;
        }
        else
        {
            final Context context = lookupSubContext( getPathName( name ) );

            return context.lookup( getLeafName( name ) );
        }
    }

    /**
     * Lookup entry in local context.
     *
     * @param name the name in local context (size() == 1)
     * @return the bound object
     * @throws javax.naming.NamingException if an error occurs
     */
    protected Object localLookup( final Name name )
        throws NamingException
    {
        final Object value = doLocalLookup( name );

        // Call getObjectInstance for using any object factories
        try
        {
            final Name atom = name.getPrefix( 1 );
            return m_namespace.getObjectInstance( value, atom, this, getRawEnvironment() );
        }
        catch( final Exception e )
        {
            final NamingException ne = new NamingException( "getObjectInstance failed" );
            ne.setRootCause( e );
            throw ne;
        }
    }

    /**
     * Actually lookup raw entry in local context.
     * When overidding this it is not neccesary to resolve references etc.
     *
     * @param name the name in local context (size() == 1)
     * @return the bound object
     * @throws javax.naming.NamingException if an error occurs
     */
    protected abstract Object doLocalLookup( Name name )
        throws NamingException;

    /**
     * Lookup a sub-context of current context.
     * Note that name must have 1 or more elements.
     *
     * @param name the name of subcontext
     * @return the sub-Context
     * @throws javax.naming.NamingException if an error occurs (like named entry is not a Context)
     */
    protected Context lookupSubContext( final Name name )
        throws NamingException
    {
        final Name atom = name.getPrefix( 1 );
        Object object = localLookup( atom );

        if( 1 != name.size() )
        {
            if( !( object instanceof Context ) )
            {
                throw new NotContextException( atom.toString() );
            }

            object = ( (Context)object ).lookup( name.getSuffix( 1 ) );
        }

        if( !( object instanceof Context ) )
        {
            throw new NotContextException( name.toString() );
        }

        //((Context)object).close();
        return (Context)object;
    }

    /**
     * Unbind a object from a name.
     *
     * @param name the name
     * @throws javax.naming.NamingException if an error occurs
     */
    public void unbind( final Name name )
        throws NamingException
    {
        if( isSelf( name ) )
        {
            throw new InvalidNameException( "Cannot unbind self" );
        }
        else if( 1 == name.size() )
        {
            doLocalUnbind( name );
        }
        else
        {
            final Context context = lookupSubContext( getPathName( name ) );
            context.unbind( getLeafName( name ) );
        }
    }

    /**
     * Actually unbind raw entry in local context.
     *
     * @param name the name in local context (size() == 1)
     * @throws javax.naming.NamingException if an error occurs
     */
    protected abstract void doLocalUnbind( Name name )
        throws NamingException;
}
TOP

Related Classes of org.codehaus.spice.jndikit.AbstractLocalContext

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.