/* * 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.realityforge.spice.jndikit; import java.util.Hashtable; import javax.naming.Binding; import javax.naming.CompositeName; import javax.naming.Context; import javax.naming.InvalidNameException; import javax.naming.Name; import javax.naming.NameClassPair; import javax.naming.NameParser; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.spi.ResolveResult; /** * Abstract JNDI Context that can be inherited from to provide a particular type of Context. */ public abstract class AbstractURLContext extends AbstractContext implements NameParser { private final String m_scheme; public AbstractURLContext( final String scheme, final Hashtable<String, Object> environment ) { super( environment ); m_scheme = scheme; } /** * {@inheritDoc} */ public Name parse( final String name ) throws NamingException { return ( new CompositeName().add( name ) ); } /** * {@inheritDoc} */ protected NameParser getNameParser() throws NamingException { return this; } /** * {@inheritDoc} */ protected void bind( final Name name, final Object object, final boolean rebind ) throws NamingException { final ResolveResult resolveResult = getBaseURLContext( name, getRawEnvironment() ); final Context context = (Context) resolveResult.getResolvedObj(); try { if ( rebind ) { context.rebind( resolveResult.getRemainingName(), object ); } else { context.bind( resolveResult.getRemainingName(), object ); } } finally { context.close(); } } /** * {@inheritDoc} */ public Context createSubcontext( final Name name ) throws NamingException { final ResolveResult resolveResult = getBaseURLContext( name, getRawEnvironment() ); final Context context = (Context) resolveResult.getResolvedObj(); try { return context.createSubcontext( resolveResult.getRemainingName() ); } finally { context.close(); } } /** * {@inheritDoc} */ public void destroySubcontext( final Name name ) throws NamingException { final ResolveResult resolveResult = getBaseURLContext( name, getRawEnvironment() ); final Context context = (Context) resolveResult.getResolvedObj(); try { context.destroySubcontext( resolveResult.getRemainingName() ); } finally { context.close(); } } /** * {@inheritDoc} */ public String getNameInNamespace() throws NamingException { return ""; } /** * {@inheritDoc} */ public NamingEnumeration<NameClassPair> list( final Name name ) throws NamingException { final ResolveResult resolveResult = getBaseURLContext( name, getRawEnvironment() ); final Context context = (Context) resolveResult.getResolvedObj(); try { return context.list( resolveResult.getRemainingName() ); } finally { context.close(); } } /** * {@inheritDoc} */ public NamingEnumeration<Binding> listBindings( final Name name ) throws NamingException { final ResolveResult resolveResult = getBaseURLContext( name, getRawEnvironment() ); final Context context = (Context) resolveResult.getResolvedObj(); try { return context.listBindings( resolveResult.getRemainingName() ); } finally { context.close(); } } /** * {@inheritDoc} */ public Object lookup( final Name name ) throws NamingException { final ResolveResult resolveResult = getBaseURLContext( name, getRawEnvironment() ); final Context context = (Context) resolveResult.getResolvedObj(); try { return context.lookup( resolveResult.getRemainingName() ); } finally { context.close(); } } /** * {@inheritDoc} */ public void unbind( final Name name ) throws NamingException { final ResolveResult resolveResult = getBaseURLContext( name, getRawEnvironment() ); final Context context = (Context) resolveResult.getResolvedObj(); try { context.unbind( resolveResult.getRemainingName() ); } finally { context.close(); } } protected ResolveResult getBaseURLContext( final Name name, final Hashtable environment ) throws NamingException { if ( name.isEmpty() ) { throw new InvalidNameException( "Unable to locate URLContext will empty name" ); } final String nameString = name.get( 0 ).toString(); int index = nameString.indexOf( ':' ); if ( -1 == index ) { final String explanation = "Unable to build URLContext as it does not specify scheme"; throw new InvalidNameException( explanation ); } final String scheme = nameString.substring( 0, index ); final int end = getEndIndexOfURLPart( nameString, index + 1 ); final String urlPart = nameString.substring( index + 1, end ); final String namePart = nameString.substring( end ); if ( !m_scheme.equals( scheme ) ) { final String explanation = "Bad Scheme use to build URLContext (" + scheme + "). " + "Expected " + m_scheme; throw new InvalidNameException( explanation ); } final Context context = newContext( urlPart ); return new ResolveResult( context, new CompositeName( namePart ) ); } /** * Find end index of url part in string. * Default implementation looks for * //.../[name-part] * ///[name-part] * //... (no name part) * [name-part] * * @param name the name * @param index the index where "scheme:" ends * @return the index where url ends * @throws NamingException if an error occurs */ protected int getEndIndexOfURLPart( final String name, final int index ) throws NamingException { int result = 0; //does it start with // if ( name.startsWith( "//", index ) ) { //does it have .../ following ??? int end = name.indexOf( "/", index + 2 ); if ( -1 != end ) { result = end; } else { result = name.length(); } } return result; } /** * Return a new instance of the base context for a URL. * This must be implemented in particular URLContext. * * @param urlPart the part of url string not including "scheme:" * @return a base URLContext for urlPart * @throws javax.naming.NamingException if an error occurs */ protected abstract Context newContext( String urlPart ) throws NamingException; }