blob: 65cfa66c4f9923b28777faa46f6b2f83b9691ee3 [file] [log] [blame]
/*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.ldap.server.jndi;
import java.util.Hashtable;
import javax.naming.ConfigurationException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.naming.spi.InitialContextFactory;
import org.apache.ldap.server.configuration.Configuration;
import org.apache.ldap.server.configuration.ShutdownConfiguration;
import org.apache.ldap.server.configuration.StartupConfiguration;
import org.apache.ldap.server.configuration.SyncConfiguration;
/**
* A server-side JNDI provider implementation of {@link InitialContextFactory}.
* This class can be utilized via JNDI API in the standard fashion:
* <p>
* <code>
* Hashtable env = new Hashtable();
* env.put( Context.PROVIDER_URL, "ou=system" );
* env.put(
* Context.INITIAL_CONTEXT_FACTORY, "org.apache.ldap.server.jndi.CoreContextFactory" );
* InitialContext initialContext = new InitialContext( env );
* </code>
* <p>
* Unfortunately, {@link InitialContext} creates a new instance of
* {@link InitialContextFactory} implementation everytime it is instantiated,
* so this factory maintains only a static, singleton instance of
* {@link ContextFactoryService}, which provides actual implementation.
* Please note that you'll also have to maintain any stateful information
* as using singleton pattern if you're going to extend this factory.
* <p>
* This class implements {@link ContextFactoryServiceListener}. This means that
* you can listen to the changes occurs to {@link ContextFactoryService}, and
* react to it (e.g. executing additional business logic).
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
* @version $Rev$, $Date$
*
* @see javax.naming.spi.InitialContextFactory
*/
public abstract class AbstractContextFactory implements InitialContextFactory, ContextFactoryServiceListener
{
// ------------------------------------------------------------------------
// Members
// ------------------------------------------------------------------------
/** The singleton service instance */
private static final ContextFactoryService service = new DefaultContextFactoryService();
/**
* Creates a new instance.
*/
protected AbstractContextFactory()
{
}
public final synchronized Context getInitialContext( Hashtable env ) throws NamingException
{
Configuration cfg = Configuration.toConfiguration( env );
env = ( Hashtable ) env.clone();
String principal = extractPrincipal( env );
byte[] credential = extractCredential( env );
String authentication = extractAuthentication( env );
String providerUrl = extractProviderUrl( env );
// Execute configuration
if( cfg instanceof ShutdownConfiguration )
{
( ( DefaultContextFactoryService ) service ).shutdown();
}
else if( cfg instanceof SyncConfiguration )
{
service.sync();
}
else if( cfg instanceof StartupConfiguration )
{
service.startup( this, env );
}
else if( service == null )
{
throw new NamingException( "Unknown configuration: " + cfg );
}
return service.getConfiguration().getJndiContext( principal, credential, authentication, providerUrl );
}
private String extractProviderUrl( Hashtable env )
{
String providerUrl;
Object value;
value = env.remove( Context.PROVIDER_URL );
if( value == null )
{
value = "";
}
providerUrl = value.toString();
return providerUrl;
}
private String extractAuthentication( Hashtable env )
{
String authentication;
Object value = env.remove( Context.SECURITY_AUTHENTICATION );
if( value == null )
{
authentication = "none";
}
else
{
authentication = value.toString();
}
return authentication;
}
private byte[] extractCredential( Hashtable env ) throws ConfigurationException
{
byte[] credential;
Object value = env.remove( Context.SECURITY_CREDENTIALS );
if( value == null )
{
credential = null;
}
else if( value instanceof String )
{
credential = ( ( String ) value ).getBytes();
}
else if( value instanceof byte[] )
{
credential = ( byte[] ) value;
}
else
{
throw new ConfigurationException( "Can't convert '" + Context.SECURITY_CREDENTIALS + "' to byte[]." );
}
return credential;
}
private String extractPrincipal( Hashtable env )
{
String principal;
Object value = env.remove( Context.SECURITY_PRINCIPAL );
if( value == null )
{
principal = null;
}
else
{
principal = value.toString();
}
return principal;
}
}