You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by er...@apache.org on 2005/10/28 04:33:07 UTC

svn commit: r329044 - in /directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common: AbstractBackingStoreTest.java LdapLoader.java LoadStrategy.java MapAdapter.java PropsLoader.java ServiceConfiguration.java

Author: erodriguez
Date: Thu Oct 27 19:33:01 2005
New Revision: 329044

URL: http://svn.apache.org/viewcvs?rev=329044&view=rev
Log:
Common protocol support classes:
o  Base class for tests, now used by all protocol providers for full JNDI provider testing.
o  Configuration support using strategies for legacy properties loading and new DIT-backed config.
o  Adapter for adding the Map interface to Dictionary's, which are used in the OSGi API's.
o  Base class for configuration common to all protocol providers, such as IP address, port, and JNDI props.

Added:
    directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/AbstractBackingStoreTest.java   (with props)
    directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/LdapLoader.java   (with props)
    directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/LoadStrategy.java   (with props)
    directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/MapAdapter.java   (with props)
    directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/PropsLoader.java   (with props)
    directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/ServiceConfiguration.java   (with props)

Added: directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/AbstractBackingStoreTest.java
URL: http://svn.apache.org/viewcvs/directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/AbstractBackingStoreTest.java?rev=329044&view=auto
==============================================================================
--- directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/AbstractBackingStoreTest.java (added)
+++ directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/AbstractBackingStoreTest.java Thu Oct 27 19:33:01 2005
@@ -0,0 +1,529 @@
+/*
+ *   Copyright 2005 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.protocol.common;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.naming.CompoundName;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.Name;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.DirContext;
+import javax.security.auth.kerberos.KerberosKey;
+import javax.security.auth.kerberos.KerberosPrincipal;
+
+import junit.framework.TestCase;
+
+import org.apache.kerberos.store.KerberosAttribute;
+import org.apache.ldap.common.ldif.LdifIterator;
+import org.apache.ldap.common.ldif.LdifParser;
+import org.apache.ldap.common.ldif.LdifParserImpl;
+import org.apache.ldap.common.message.LockableAttributeImpl;
+import org.apache.ldap.common.message.LockableAttributesImpl;
+import org.apache.ldap.server.configuration.DirectoryPartitionConfiguration;
+import org.apache.ldap.server.configuration.MutableDirectoryPartitionConfiguration;
+import org.apache.ldap.server.configuration.MutableStartupConfiguration;
+import org.apache.ldap.server.configuration.ShutdownConfiguration;
+import org.apache.ldap.server.jndi.CoreContextFactory;
+import org.apache.ldap.server.schema.bootstrap.ApacheSchema;
+import org.apache.ldap.server.schema.bootstrap.ApachednsSchema;
+import org.apache.ldap.server.schema.bootstrap.CoreSchema;
+import org.apache.ldap.server.schema.bootstrap.CosineSchema;
+import org.apache.ldap.server.schema.bootstrap.InetorgpersonSchema;
+import org.apache.ldap.server.schema.bootstrap.Krb5kdcSchema;
+import org.apache.ldap.server.schema.bootstrap.SystemSchema;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Base class for testing protocol providers against the JNDI provider.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public abstract class AbstractBackingStoreTest extends TestCase
+{
+    /** the log for this class */
+    private static final Logger log = LoggerFactory.getLogger( AbstractBackingStoreTest.class );
+
+    /** a flag stating whether to delete the backing store for each test or not */
+    protected boolean doDelete = true;
+
+    /** the backing store configuration */
+    protected MutableStartupConfiguration config;
+
+    protected CoreContextFactory factory;
+    protected Hashtable env;
+
+    protected void setUp() throws Exception
+    {
+        env = new Hashtable( setUpPartition() );
+
+        env.put( Context.SECURITY_PRINCIPAL, "uid=admin,ou=system" );
+        env.put( Context.SECURITY_AUTHENTICATION, "simple" );
+        env.put( Context.SECURITY_CREDENTIALS, "secret" );
+        env.put( Context.INITIAL_CONTEXT_FACTORY, "org.apache.ldap.server.jndi.CoreContextFactory" );
+        env.put( Context.PROVIDER_URL, "ou=system" );
+
+        factory = new CoreContextFactory();
+    }
+
+    protected void loadPartition( String partition, String ldifFile ) throws NamingException
+    {
+        env.put( Context.PROVIDER_URL, partition );
+        DirContext ctx = (DirContext) factory.getInitialContext( env );
+        load( ctx, ldifFile );
+    }
+
+    /**
+     * Test that the system partition was set up properly.
+     *
+     * @throws NamingException if there are problems
+     */
+    protected void doTestSystemPartition() throws Exception
+    {
+        env.put( Context.PROVIDER_URL, "ou=system" );
+        DirContext ctx = (DirContext) factory.getInitialContext( env );
+        Attributes attributes = ctx.getAttributes( "cn=A,dc=www,dc=apache,dc=org,ou=Zones" );
+        assertEquals( 3, attributes.size() );
+    }
+
+    protected void doTestApacheZone() throws Exception
+    {
+        env.put( Context.PROVIDER_URL, "dc=apache,dc=org" );
+        DirContext ctx = (DirContext) factory.getInitialContext( env );
+        Attributes attributes = ctx.getAttributes( "cn=A,dc=www,dc=apache,dc=org,ou=Zones" );
+        assertEquals( 3, attributes.size() );
+    }
+
+    protected void doTestExampleZone() throws Exception
+    {
+        env.put( Context.PROVIDER_URL, "dc=example,dc=com" );
+        DirContext ctx = (DirContext) factory.getInitialContext( env );
+        Attributes attributes = ctx.getAttributes( "cn=A,dc=www,dc=example,dc=com,ou=Zones" );
+        assertEquals( 3, attributes.size() );
+    }
+
+    protected Hashtable setUpPartition()
+    {
+        config = new MutableStartupConfiguration();
+
+        Set schemas = new HashSet();
+        schemas.add( new CoreSchema() );
+        schemas.add( new CosineSchema() );
+        schemas.add( new ApacheSchema() );
+        schemas.add( new InetorgpersonSchema() );
+        schemas.add( new Krb5kdcSchema() );
+        schemas.add( new SystemSchema() );
+        schemas.add( new ApachednsSchema() );
+        config.setBootstrapSchemas( schemas );
+
+        Set partitions = new HashSet();
+        partitions.add( getExamplePartition() );
+        partitions.add( getApachePartition() );
+
+        config.setContextPartitionConfigurations( Collections.unmodifiableSet( partitions ) );
+
+        return config.toJndiEnvironment();
+    }
+
+    private DirectoryPartitionConfiguration getExamplePartition()
+    {
+        MutableDirectoryPartitionConfiguration partConfig = new MutableDirectoryPartitionConfiguration();
+        partConfig.setName( "example" );
+
+        HashSet indices = new HashSet();
+        indices.add( "dc" );
+        indices.add( "ou" );
+        indices.add( "objectClass" );
+        indices.add( "krb5PrincipalName" );
+        indices.add( "uid" );
+        partConfig.setIndexedAttributes( indices );
+
+        partConfig.setSuffix( "dc=example, dc=com" );
+
+        LockableAttributesImpl attrs = new LockableAttributesImpl();
+        LockableAttributeImpl objectClass = new LockableAttributeImpl( "objectClass" );
+        objectClass.add( "top" );
+        objectClass.add( "domain" );
+        attrs.put( objectClass );
+        attrs.put( "dc", "example" );
+        partConfig.setContextEntry( attrs );
+
+        return partConfig;
+    }
+
+    private DirectoryPartitionConfiguration getApachePartition()
+    {
+        MutableDirectoryPartitionConfiguration partConfig = new MutableDirectoryPartitionConfiguration();
+        partConfig.setName( "apache" );
+
+        HashSet indices = new HashSet();
+        indices.add( "dc" );
+        indices.add( "ou" );
+        indices.add( "objectClass" );
+        indices.add( "krb5PrincipalName" );
+        indices.add( "uid" );
+        partConfig.setIndexedAttributes( indices );
+
+        partConfig.setSuffix( "dc=apache, dc=org" );
+
+        LockableAttributesImpl attrs = new LockableAttributesImpl();
+        LockableAttributeImpl objectClass = new LockableAttributeImpl( "objectClass" );
+        objectClass.add( "top" );
+        objectClass.add( "domain" );
+        attrs.put( objectClass );
+        attrs.put( "dc", "apache" );
+        partConfig.setContextEntry( attrs );
+
+        return partConfig;
+    }
+
+    /**
+     * Shuts down the backing store, optionally deleting the database directory.
+     *
+     * @see junit.framework.TestCase#tearDown()
+     */
+    protected void tearDown() throws Exception
+    {
+        super.tearDown();
+
+        Hashtable env = new Hashtable();
+
+        env.put( Context.PROVIDER_URL, "ou=system" );
+        env.put( Context.INITIAL_CONTEXT_FACTORY, CoreContextFactory.class.getName() );
+        env.putAll( new ShutdownConfiguration().toJndiEnvironment() );
+        env.put( Context.SECURITY_PRINCIPAL, "uid=admin,ou=system" );
+        env.put( Context.SECURITY_CREDENTIALS, "secret" );
+        env.put( Context.SECURITY_AUTHENTICATION, "simple" );
+
+        new InitialContext( env );
+
+        doDelete( config.getWorkingDirectory() );
+    }
+
+    /**
+     * Deletes the working directory.
+     */
+    protected void doDelete( File wkdir ) throws IOException
+    {
+        if ( doDelete )
+        {
+            if ( wkdir.exists() )
+            {
+                recursiveRemoveDir( wkdir );
+            }
+
+            if ( wkdir.exists() )
+            {
+                throw new IOException( "Failed to delete: " + wkdir );
+            }
+        }
+    }
+
+    private void recursiveRemoveDir( File directory )
+    {
+        String[] filelist = directory.list();
+        File tmpFile = null;
+
+        for ( int ii = 0; ii < filelist.length; ii++ )
+        {
+            tmpFile = new File( directory.getAbsolutePath(), filelist[ ii ] );
+            if ( tmpFile.isDirectory() )
+            {
+                recursiveRemoveDir( tmpFile );
+            }
+            else
+            {
+                if ( tmpFile.isFile() )
+                {
+                    tmpFile.delete();
+                }
+            }
+        }
+
+        directory.delete();
+    }
+
+    /**
+     * Opens the LDIF file and loads the entries into the context.
+     */
+    protected void load( DirContext ctx, String ldifPath )
+    {
+        Name rdn = null;
+
+        try
+        {
+            InputStream in = getLdifStream( ldifPath );
+
+            LdifIterator iterator = new LdifIterator( in );
+
+            LdifParser ldifParser = new LdifParserImpl();
+
+            while ( iterator.hasNext() )
+            {
+                String ldif = (String) iterator.next();
+
+                Attributes attributes = new LockableAttributesImpl();
+                ldifParser.parse( attributes, ldif );
+
+                String dn = (String) attributes.remove( "dn" ).get();
+
+                if ( attributes.get( "objectClass" ).contains( "krb5KDCEntry" ) )
+                {
+                    String pw = (String) attributes.get( "userpassword" ).get();
+                    String krbPrincipal = (String) attributes.get( KerberosAttribute.PRINCIPAL ).get();
+
+                    KerberosPrincipal principal = new KerberosPrincipal( krbPrincipal );
+                    KerberosKey key = new KerberosKey( principal, pw.toCharArray(), "DES" );
+
+                    byte[] encodedKey = key.getEncoded();
+
+                    attributes.put( KerberosAttribute.KEY, encodedKey );
+                    attributes.put( KerberosAttribute.VERSION, Integer.toString( key.getVersionNumber() ) );
+                    attributes.put( KerberosAttribute.TYPE, Integer.toString( key.getKeyType() ) );
+                }
+
+                rdn = getRelativeName( ctx.getNameInNamespace(), dn );
+
+                try
+                {
+                    ctx.lookup( rdn );
+
+                    log.info( "Found " + rdn + ", will not create." );
+                }
+                catch ( Exception e )
+                {
+                    ctx.createSubcontext( rdn, attributes );
+
+                    log.info( "Created " + rdn + "." );
+                }
+            }
+        }
+        catch ( FileNotFoundException fnfe )
+        {
+            log.error( "LDIF file does not exist." );
+            return;
+        }
+        catch ( IOException ioe )
+        {
+            log.error( "Failed to import LDIF into backing store.", ioe );
+            return;
+        }
+        catch ( NamingException ne )
+        {
+            log.error( "Failed to import LDIF into backing store.", ne );
+            return;
+        }
+
+        try
+        {
+            InputStream in = getLdifStream( ldifPath );
+
+            LdifIterator iterator = new LdifIterator( in );
+
+            LdifParser ldifParser = new LdifParserImpl();
+
+            while ( iterator.hasNext() )
+            {
+                String ldif = (String) iterator.next();
+
+                Attributes attributes = new LockableAttributesImpl();
+
+                ldifParser.parse( attributes, ldif );
+
+                String dn = (String) attributes.remove( "dn" ).get();
+
+                rdn = getRelativeName( ctx.getNameInNamespace(), dn );
+
+                Object stored = ctx.lookup( rdn );
+
+                log.debug( "Lookup for " + rdn + " returned " + stored + "." );
+
+                if ( stored == null )
+                {
+                    log.error( rdn + " was null." );
+
+                    throw new IllegalStateException( "LDIF entries not being pushed to disk." );
+                }
+            }
+        }
+        catch ( Exception e )
+        {
+            log.error( "Failed to find " + rdn );
+
+            if ( log.isDebugEnabled() )
+            {
+                log.error( "Failed to import LDIF into backing store.", e );
+            }
+            else
+            {
+                log.error( "Failed to import LDIF into backing store." );
+            }
+
+            return;
+        }
+    }
+
+    /**
+     * Tries to find an LDIF file either on the file system or packaged within a jar.
+     *
+     * @return the input stream to the ldif file.
+     * @throws FileNotFoundException if the file cannot be found.
+     */
+    private InputStream getLdifStream( String ldifPath ) throws FileNotFoundException
+    {
+        File file = new File( ldifPath );
+
+        InputStream in = null;
+
+        if ( file.exists() )
+        {
+            in = new FileInputStream( file );
+        }
+        else
+        {
+            // if file not on system see if something is bundled with the jar ...
+            in = getClass().getResourceAsStream( ldifPath );
+
+            if ( in == null )
+            {
+                throw new FileNotFoundException( "LDIF file does not exist." );
+            }
+        }
+
+        // in = loadClass.getResourceAsStream( ldifPath );
+
+        return in;
+    }
+
+    protected Name getRelativeName( String nameInNamespace, String baseDn ) throws NamingException
+    {
+        Properties props = new Properties();
+        props.setProperty( "jndi.syntax.direction", "right_to_left" );
+        props.setProperty( "jndi.syntax.separator", "," );
+        props.setProperty( "jndi.syntax.ignorecase", "true" );
+        props.setProperty( "jndi.syntax.trimblanks", "true" );
+
+        Name searchBaseDn = null;
+
+        Name ctxRoot = new CompoundName( nameInNamespace, props );
+        searchBaseDn = new CompoundName( baseDn, props );
+
+        if ( !searchBaseDn.startsWith( ctxRoot ) )
+        {
+            throw new NamingException( "Invalid search base " + baseDn );
+        }
+
+        for ( int ii = 0; ii < ctxRoot.size(); ii++ )
+        {
+            searchBaseDn.remove( 0 );
+        }
+
+        return searchBaseDn;
+    }
+
+    /*
+     * escape LDAP filter characters as \HH (hex value).
+     */
+    protected String escapedValue( String value )
+    {
+        StringBuffer escapedBuf = new StringBuffer();
+        String specialChars = "*()\\";
+        char c;
+
+        for ( int i = 0; i < value.length(); ++i )
+        {
+            c = value.charAt( i );
+            if ( specialChars.indexOf( c ) >= 0 )
+            { // escape it
+                escapedBuf.append( '\\' );
+                String hexString = Integer.toHexString( c );
+                if ( hexString.length() < 2 )
+                {
+                    escapedBuf.append( '0' );
+                }
+                escapedBuf.append( hexString );
+            }
+            else
+            {
+                escapedBuf.append( c );
+            }
+        }
+        return escapedBuf.toString();
+    }
+
+    protected void printAttr( Attributes attrs, String id )
+    {
+        if ( attrs == null || id == null )
+        {
+            System.out.println( "No attribute" );
+            return;
+        }
+
+        try
+        {
+            Attribute attr;
+            String a = ( attr = attrs.get( id ) ) != null ? (String) attr.get() : null;
+            System.out.println( attr.getID() + ":\t" + a );
+        }
+        catch ( NamingException e )
+        {
+            e.printStackTrace();
+        }
+    }
+
+    protected void printAttrs( Attributes attrs )
+    {
+        if ( attrs == null )
+        {
+            System.out.println( "No attributes" );
+            return;
+        }
+
+        try
+        {
+            for ( NamingEnumeration ae = attrs.getAll(); ae.hasMore(); )
+            {
+                final Attribute attr = (Attribute) ae.next();
+
+                for ( NamingEnumeration e = attr.getAll(); e.hasMore(); )
+                {
+                    System.out.println( attr.getID() + ":\t" + e.next() );
+                }
+            }
+        }
+        catch ( NamingException e )
+        {
+            e.printStackTrace();
+        }
+    }
+}

Propchange: directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/AbstractBackingStoreTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/LdapLoader.java
URL: http://svn.apache.org/viewcvs/directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/LdapLoader.java?rev=329044&view=auto
==============================================================================
--- directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/LdapLoader.java (added)
+++ directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/LdapLoader.java Thu Oct 27 19:33:01 2005
@@ -0,0 +1,34 @@
+/*
+ *   Copyright 2005 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.protocol.common;
+
+import java.util.Map;
+
+/**
+ * Load strategy for configuration properties coming from LDAP.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class LdapLoader implements LoadStrategy
+{
+    public Map load( String prefix, Map properties )
+    {
+        return properties;
+    }
+}

Propchange: directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/LdapLoader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/LoadStrategy.java
URL: http://svn.apache.org/viewcvs/directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/LoadStrategy.java?rev=329044&view=auto
==============================================================================
--- directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/LoadStrategy.java (added)
+++ directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/LoadStrategy.java Thu Oct 27 19:33:01 2005
@@ -0,0 +1,34 @@
+/*
+ *   Copyright 2005 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.protocol.common;
+
+import java.util.Map;
+
+/**
+ * Load strategy interface for configuration properties.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public interface LoadStrategy
+{
+    public static final int LDAP = 1;
+    public static final int PROPS = 2;
+
+    public Map load( String prefix, Map properties );
+}

Propchange: directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/LoadStrategy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/MapAdapter.java
URL: http://svn.apache.org/viewcvs/directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/MapAdapter.java?rev=329044&view=auto
==============================================================================
--- directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/MapAdapter.java (added)
+++ directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/MapAdapter.java Thu Oct 27 19:33:01 2005
@@ -0,0 +1,159 @@
+/*
+ *   Copyright 2005 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.protocol.common;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Adapter to add the Map interface to Dictionary's.  Many of the OSGi interfaces use
+ * Dictionary's for legacy reasons, but the Dictionary is obsolete.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class MapAdapter implements Map
+{
+    private Dictionary dictionary;
+
+    public MapAdapter( Dictionary dictionary )
+    {
+        this.dictionary = dictionary;
+    }
+
+    /**
+     * @see java.util.Map#clear()
+     */
+    public void clear()
+    {
+        dictionary = new Hashtable();
+    }
+
+    /**
+     * @see java.util.Map#containsKey(java.lang.Object)
+     */
+    public boolean containsKey( Object key )
+    {
+        return Collections.list( dictionary.keys() ).contains( key );
+    }
+
+    /**
+     * @see java.util.Map#containsValue(java.lang.Object)
+     */
+    public boolean containsValue( Object value )
+    {
+        return Collections.list( dictionary.elements() ).contains( value );
+    }
+
+    /**
+     * @see java.util.Map#entrySet()
+     */
+    public Set entrySet()
+    {
+        Map map = new HashMap();
+
+        Enumeration e = dictionary.keys();
+
+        while ( e.hasMoreElements() )
+        {
+            Object key = e.nextElement();
+            Object value = dictionary.get( key );
+            map.put( key, value );
+        }
+
+        return map.entrySet();
+    }
+
+    /**
+     * @see java.util.Map#get(java.lang.Object)
+     */
+    public Object get( Object key )
+    {
+        return dictionary.get( key );
+    }
+
+    /**
+     * @see java.util.Map#isEmpty()
+     */
+    public boolean isEmpty()
+    {
+        return dictionary.isEmpty();
+    }
+
+    /**
+     * @see java.util.Map#keySet()
+     */
+    public Set keySet()
+    {
+        return new HashSet( Collections.list( dictionary.keys() ) );
+    }
+
+    /**
+     * @see java.util.Map#put(java.lang.Object, java.lang.Object)
+     */
+    public Object put( Object arg0, Object arg1 )
+    {
+        return dictionary.put( arg0, arg1 );
+    }
+
+    /**
+     * @see java.util.Map#putAll(java.util.Map)
+     */
+    public void putAll( Map arg0 )
+    {
+        Iterator it = arg0.entrySet().iterator();
+
+        while ( it.hasNext() )
+        {
+            Map.Entry entry = (Map.Entry) it.next();
+            dictionary.put( entry.getKey(), entry.getValue() );
+        }
+    }
+
+    /**
+     * @see java.util.Map#remove(java.lang.Object)
+     */
+    public Object remove( Object key )
+    {
+        return dictionary.remove( key );
+    }
+
+    /**
+     * @see java.util.Map#size()
+     */
+    public int size()
+    {
+        return dictionary.size();
+    }
+
+    /**
+     * @see java.util.Map#values()
+     */
+    public Collection values()
+    {
+        return Collections.list( dictionary.elements() );
+    }
+}

Propchange: directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/MapAdapter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/PropsLoader.java
URL: http://svn.apache.org/viewcvs/directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/PropsLoader.java?rev=329044&view=auto
==============================================================================
--- directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/PropsLoader.java (added)
+++ directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/PropsLoader.java Thu Oct 27 19:33:01 2005
@@ -0,0 +1,57 @@
+/*
+ *   Copyright 2005 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.protocol.common;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Load strategy for configuration properties coming from a properties file.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class PropsLoader implements LoadStrategy
+{
+    public Map load( String prefix, Map properties )
+    {
+        Map configuration = new HashMap( properties.size() );
+
+        Iterator it = properties.keySet().iterator();
+
+        while ( it.hasNext() )
+        {
+            String key = (String) it.next();
+
+            if ( properties.get( key ) instanceof String )
+            {
+                String value = (String) properties.get( key );
+
+                if ( key.startsWith( prefix ) )
+                {
+                    key = key.substring( key.indexOf( "." ) + 1 );
+                }
+
+                configuration.put( key, value );
+            }
+        }
+
+        return configuration;
+    }
+}

Propchange: directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/PropsLoader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/ServiceConfiguration.java
URL: http://svn.apache.org/viewcvs/directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/ServiceConfiguration.java?rev=329044&view=auto
==============================================================================
--- directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/ServiceConfiguration.java (added)
+++ directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/ServiceConfiguration.java Thu Oct 27 19:33:01 2005
@@ -0,0 +1,133 @@
+/*
+ *   Copyright 2005 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.protocol.common;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.ldap.server.configuration.Configuration;
+
+/**
+ * Base class shared by all protocol providers for configuration.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public abstract class ServiceConfiguration extends Configuration
+{
+    /** the prop key const for the port */
+    public static final String IP_PORT_KEY = "ipPort";
+
+    /** the prop key const for the port */
+    public static final String IP_ADDRESS_KEY = "ipAddress";
+
+    /** the prop key const for the catalog's base DN */
+    public static final String CATALOG_BASEDN_KEY = "catalogBaseDn";
+
+    /**
+     * The key of the property specifying the single location where entries
+     * are stored.  If this property is not set the store will search the system
+     * partition configuration for catalog entries.
+     */
+    public static final String ENTRY_BASEDN_KEY = "entryBaseDn";
+
+    public static final String INITIAL_CONTEXT_FACTORY_KEY = "initialContextFactory";
+
+    public static final String APACHE_SERVICE_PID_KEY = "apacheServicePid";
+    public static final String APACHE_FACTORY_PID_KEY = "apacheServiceFactoryPid";
+
+    /** the prop key const for buffer.size */
+    public static final String BUFFER_SIZE_KEY = "buffer.size";
+
+    public static final String DEFAULT_ENTRY_BASEDN = "dc=example,dc=com";
+
+    public static final String DEFAULT_INITIAL_CONTEXT_FACTORY = "org.apache.ldap.server.jndi.CoreContextFactory";
+
+    public static final String APACHE_SERVICE_CONFIGURATION = "apacheServiceConfiguration";
+
+    public static final String SERVICE_PID = "service.pid";
+    public static final String SERVICE_FACTORYPID = "service.factoryPid";
+
+    /** the default buffer size */
+    public static final int DEFAULT_BUFFER_SIZE = 1024;
+
+    /** the number of milliseconds in a minute */
+    public static final int MINUTE = 60000;
+
+    /** the map of configuration */
+    protected Map configuration = new HashMap();
+
+    public String getCatalogBaseDn()
+    {
+        String key = CATALOG_BASEDN_KEY;
+
+        if ( configuration.containsKey( key ) )
+        {
+            return get( key );
+        }
+
+        return null;
+    }
+
+    public String getEntryBaseDn()
+    {
+        String key = ENTRY_BASEDN_KEY;
+
+        if ( configuration.containsKey( key ) )
+        {
+            return get( key );
+        }
+
+        return DEFAULT_ENTRY_BASEDN;
+    }
+
+    public String getInitialContextFactory()
+    {
+        String key = INITIAL_CONTEXT_FACTORY_KEY;
+
+        if ( configuration.containsKey( key ) )
+        {
+            return get( key );
+        }
+
+        return DEFAULT_INITIAL_CONTEXT_FACTORY;
+    }
+
+    protected void loadProperties( String prefix, Map properties, int strategy )
+    {
+        LoadStrategy loader;
+
+        switch ( strategy )
+        {
+            case LoadStrategy.LDAP:
+                loader = new LdapLoader();
+                break;
+            case LoadStrategy.PROPS:
+            default:
+                loader = new PropsLoader();
+                break;
+        }
+
+        configuration.putAll( loader.load( prefix, properties ) );
+    }
+
+    protected String get( String key )
+    {
+        return (String) configuration.get( key );
+    }
+}

Propchange: directory/shared/protocol/trunk/common/src/main/java/org/apache/protocol/common/ServiceConfiguration.java
------------------------------------------------------------------------------
    svn:eol-style = native