You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by jc...@apache.org on 2007/01/29 21:38:29 UTC

svn commit: r501176 [5/6] - in /directory/sandbox/jconlon/osgi-services/configuration-service: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/configuration/ src/main/java/org/apache/configuration/...

Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/dao/jndi/impl/ConfigurationDaoIntegrationTest.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/dao/jndi/impl/ConfigurationDaoIntegrationTest.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/dao/jndi/impl/ConfigurationDaoIntegrationTest.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/dao/jndi/impl/ConfigurationDaoIntegrationTest.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,542 @@
+/*
+ * Copyright 2006 the original author or authors.
+ * 
+ * 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.configuration.dao.jndi.impl;
+
+import java.io.File;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Vector;
+
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingException;
+import javax.naming.directory.InitialDirContext;
+import javax.naming.spi.InitialContextFactory;
+
+import org.apache.configuration.dao.ConfigurationDao;
+import org.apache.configuration.dao.ConfigurationDaoException;
+import org.apache.configuration.dao.ConfigurationDaoListener;
+import org.apache.configuration.dao.jndi.ContextMapping;
+import org.apache.configuration.dao.jndi.NameMapping;
+import org.apache.configuration.impl.ConfigurationDictionary;
+import org.apache.configuration.util.ApacheDSUtil;
+import org.apache.directory.shared.ldap.exception.LdapSchemaViolationException;
+import org.osgi.framework.Constants;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
+
+
+/**
+ * 
+ * ConfigurationDaoIntegrationTest tests the service locally (outside of OSGi) within a Spring container.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class ConfigurationDaoIntegrationTest  extends AbstractDependencyInjectionSpringContextTests
+{
+    private static final String CN_1 = "mytestConfiguration";
+    private static final String SOME_FACTORY = "some.factory";
+    private static final String SOME_PID = "some.pid";
+    /** the log for this class */
+    private static final Logger log = LoggerFactory.getLogger( ConfigurationDaoIntegrationTest.class );
+    
+    static{
+        File file = new File("server-work");
+        if(file.exists()){
+            log.debug( "Removing the server-work directory. " );
+            ApacheDSUtil.deleteDir(file);
+        }
+    }
+    
+    
+    private ConfigurationDao configurationDao;
+    private InitialContextFactory initialContextFactory;
+    public ConfigurationDao getConfigurationDao()
+    {
+        return configurationDao;
+    }
+
+
+
+    public void setConfigurationDao( ConfigurationDao configurationDao )
+    {
+        this.configurationDao = configurationDao;
+    }
+
+
+    protected String[] getConfigLocations()
+    {
+        return new String[]
+            { "mockInitialContextFactory.xml", "META-INF/spring/daoJndi.xml" };
+    }
+
+
+
+
+    /* ==================================== Tests ===================================================*/
+    public void testEnvironment()
+    {
+        assertNotNull( configurationDao );
+        assertNotNull(initialContextFactory);
+    }
+    
+    public void testWithACleanEnvironment(){
+        List<ConfigurationDictionary> configs = configurationDao.findAll();
+        if(configs==null || configs.isEmpty()){
+            return;
+        }
+        
+        log.debug( "Deleting {} configurationDictionary entries {}.", configs.size(),configs );
+        for ( ConfigurationDictionary configurationDictionary : configs )
+        {
+            
+            log.debug( "Deleting configurationDictionary entry {}.", configurationDictionary );
+            configurationDao.delete( configurationDictionary );
+        }
+    }
+    
+    public void testEnvironmentInitialContext()
+    {
+        
+        assertNotNull(initialContextFactory);
+        assertTrue(initialContextFactory instanceof MockInitialContextFactory);
+        try
+        {
+            InitialDirContext initialContext = (InitialDirContext)initialContextFactory.getInitialContext( null) ;
+            assertNotNull(initialContext);
+            initialContext.close();
+        }
+        catch ( NamingException e )
+        {
+           log.error( "Failed to get InitialContext.",e);
+           fail( "Failed to get InitialContext.");
+        }
+        try
+        {
+            InitialDirContext initialContext = (InitialDirContext)initialContextFactory.getInitialContext( null) ;
+            assertNotNull(initialContext);
+            initialContext.close();
+            
+        }
+        catch ( NamingException e )
+        {
+           log.error( "Failed to get InitialContext.",e);
+           fail( "Failed to get InitialContext.");
+        }
+    }
+    
+    /**
+     * Test method for {@link org.apache.configuration.util.ConfigurationImpl#update()}.
+     */
+    public void testCreate()
+    {
+        log.debug( "Start test ======================================================" );
+        ConfigurationDictionary configurationDictionary = createConfigurationDictionaryInstance(
+            CN_1, SOME_PID, SOME_FACTORY);
+       
+        
+//      Should not modify my copy of the dictionary adversly
+        assertNull("Should not find key "+ContextMapping.APACHEDS_SERVICE_PID+" in "+configurationDictionary,
+            configurationDictionary.get( ContextMapping.APACHEDS_SERVICE_PID ));
+        
+        assertNotNull("Could not find key "+Constants.SERVICE_PID+" in "+configurationDictionary,
+            configurationDictionary.get( Constants.SERVICE_PID ));
+        
+        
+        configurationDictionary = createConfigurationDictionaryInstance(
+            CN_1, SOME_PID, SOME_FACTORY);
+        
+        String pid = configurationDao.create( configurationDictionary );
+        assertEquals(SOME_PID,pid);
+        
+        //      Should not modify my copy of the dictionary adversly
+        assertNull("Should not find key "+ContextMapping.APACHEDS_SERVICE_PID+" in "+configurationDictionary,
+            configurationDictionary.get( ContextMapping.APACHEDS_SERVICE_PID ));
+        
+        assertNotNull("Could not find key "+Constants.SERVICE_PID+" in "+configurationDictionary,
+            configurationDictionary.get( Constants.SERVICE_PID ));
+        
+    }
+    
+    public void testCreateWithNoCN()
+    {
+        log.debug( "Start test ======================================================" );
+        ConfigurationDictionary configurationDictionary = createConfigurationDictionaryInstance(
+            "mytestConfiguration2", "alternate2.name.pid", SOME_FACTORY);
+        configurationDictionary.remove( "cn" );
+        
+        try
+        {
+            configurationDao.create( configurationDictionary );
+            fail("There was no cn property. An UncategorizedLdapException should have been thrown.");
+        }
+        catch (ConfigurationDaoException e)
+        {
+            log.error( "Failed to create.",e );
+            assertTrue(e.getCause() instanceof LdapSchemaViolationException); 
+        }  
+    }
+    
+    public void testCreateWithIllegalArgument()
+    {
+        log.debug( "Start test ======================================================" );
+        ConfigurationDictionary configurationDictionary = createConfigurationDictionaryInstance(
+            "mytestConfiguration2", "alternate2.name.pid", SOME_FACTORY);
+        configurationDictionary.remove( Constants.SERVICE_PID );
+        
+        try
+        {
+            configurationDao.create( configurationDictionary );
+            fail("There was no pid property. An UncategorizedLdapException should have been thrown.");
+        }
+        catch (IllegalArgumentException e)
+        { 
+            assertEquals("Could not determine the service pid.",e.getMessage()); 
+        }
+        
+    }
+    
+    public void testCreateWithOutObjectClass(){
+        String cn = "dowecare";
+        String pid = "someOtherPid";
+        String factory = "bull";
+        
+        
+        Dictionary<String,Object> dictionary = new Hashtable<String,Object>();
+        dictionary.put( Constants.SERVICE_PID, pid );
+        if(factory !=null){
+            dictionary.put( ConfigurationAdmin.SERVICE_FACTORYPID , factory );
+        }
+        
+        dictionary.put( "cn", cn );
+        
+        // Add a ServiceBundleLocation to see if it is remove before the create
+        dictionary.put( ConfigurationAdmin.SERVICE_BUNDLELOCATION, "Just some string." );
+        
+        ConfigurationDictionary configurationDictionary = new ConfigurationDictionary(dictionary);
+        try
+        {
+            configurationDao.create( configurationDictionary );
+            fail("There was no objectclass property. An IllegalArgumentException should have been thrown.");
+        }
+        catch (IllegalArgumentException e)
+        { 
+            assertEquals("There was no objectclass properties defined.",e.getMessage()); 
+        }
+        catch (Exception e){
+            fail("There was no objectclass property. An IllegalArgumentException should have been thrown."+e.toString());
+        }
+    }
+
+    
+    public void testRead()
+    {
+        log.debug( "Start test ======================================================" );
+        ConfigurationDictionary configurationDictionary = configurationDao.read( SOME_PID );
+        assertNotNull(configurationDictionary);
+        log.debug( "Retrieved configuration {}.", configurationDictionary );
+        assertEquals(CN_1, configurationDictionary.get( "cn" ));
+        assertEquals(SOME_PID, configurationDictionary.get( Constants.SERVICE_PID ));
+        assertEquals(SOME_FACTORY, configurationDictionary.get( ConfigurationAdmin.SERVICE_FACTORYPID ));
+        
+        
+    }
+    
+    
+    
+    public void testListAll()
+    {
+        log.debug( "Start test ======================================================" );
+        List<ConfigurationDictionary> configurationDictionaries = configurationDao.findAll();
+        assertNotNull(configurationDictionaries);
+        
+        assertFalse(configurationDictionaries.isEmpty());
+        
+        assertEquals(1, configurationDictionaries.size());
+        
+        ConfigurationDictionary afterUpdateConfigurationDictionary = configurationDictionaries.get( 0 );
+        assertNotNull(afterUpdateConfigurationDictionary);
+        assertEquals(CN_1, afterUpdateConfigurationDictionary.get( "cn" ));
+        
+        assertNotNull("No ServicePid in conguration.", afterUpdateConfigurationDictionary.get( Constants.SERVICE_PID ));
+        assertEquals(SOME_PID, afterUpdateConfigurationDictionary.get( Constants.SERVICE_PID ));
+        
+    }
+
+    /**
+     * Test method for {@link org.apache.configuration.util.ConfigurationImpl#update()}.
+     */
+    public void testUpdateInitial()
+    {
+        log.debug( "Start test ======================================================" );
+        
+       
+        String cn = "mytestConfiguration2";
+        String pid = "alternate2.name.pid";
+        String factory = SOME_FACTORY;
+        ConfigurationDictionary configurationDictionary = createConfigurationDictionaryInstance(
+            cn, pid, factory);
+        
+        configurationDao.update( configurationDictionary );
+        
+        //Should not modify my copy of the dictionary adversly
+        assertNull("Should not find key "+ContextMapping.APACHEDS_SERVICE_PID+" in "+configurationDictionary,
+            configurationDictionary.get( ContextMapping.APACHEDS_SERVICE_PID ));
+        
+        assertNotNull("Could not find key "+Constants.SERVICE_PID+" in "+configurationDictionary,
+            configurationDictionary.get( Constants.SERVICE_PID ));
+        
+        
+        ConfigurationDictionary configurationDictionary3 = configurationDao.read( pid );
+        assertNotNull(configurationDictionary3);
+        
+    }
+
+
+
+    
+    
+    public void testUpdateRemovals()
+    {
+        log.debug( "Start test ======================================================" );
+        
+        String pid = "alternate3.name.pid";
+        String factory = SOME_FACTORY;
+        String cn = "mytestConfiguration2";
+        
+        ConfigurationDictionary configurationDictionary = createConfigurationDictionaryInstance(
+            cn, pid, factory);
+        
+        configurationDao.create( configurationDictionary );
+        
+        ConfigurationDictionary initialConfigurationDictionary = configurationDao.read( pid );
+        assertNotNull(initialConfigurationDictionary);
+        assertEquals(cn, initialConfigurationDictionary.get( "cn" ));
+        
+        //      Remove the factory attribute
+        configurationDictionary = createConfigurationDictionaryInstance(
+            cn, pid, factory);
+        configurationDictionary.remove( ConfigurationAdmin.SERVICE_FACTORYPID);
+        try
+        {
+            configurationDao.update( configurationDictionary );
+        }
+        catch ( RuntimeException e )
+        {
+            e.printStackTrace();
+           fail("Failed to remove the factory attribute. "+e.toString());
+        }
+        ConfigurationDictionary afterUpdateConfigurationDictionary = configurationDao.read( pid );
+        assertNotNull(afterUpdateConfigurationDictionary);
+        assertNull("Failed to remove factory attribute. ", 
+            afterUpdateConfigurationDictionary.get( ConfigurationAdmin.SERVICE_FACTORYPID ));
+        
+    }
+    
+    public void testUpdateAdding()
+    {
+        log.debug( "Start test ======================================================" );
+        String cn = "mytestConfiguration2";
+        String pid = "alternate4.name.pid";
+        String factory = SOME_FACTORY;
+        ConfigurationDictionary configurationDictionary = createConfigurationDictionaryInstance(
+            cn, pid, factory);
+        configurationDictionary.remove( ConfigurationAdmin.SERVICE_FACTORYPID);
+        
+        configurationDao.create( configurationDictionary );
+        
+        ConfigurationDictionary initialConfigurationDictionary = configurationDao.read( pid );
+        assertNotNull(initialConfigurationDictionary);
+        assertEquals(cn, initialConfigurationDictionary.get( "cn" ));
+        assertNull("Initial persisted entry still has a factory prop.",initialConfigurationDictionary.get(ConfigurationAdmin.SERVICE_FACTORYPID ));
+        
+        
+        
+        //      Add the factory back in
+        configurationDictionary = createConfigurationDictionaryInstance(
+            cn, pid, factory);
+       
+       
+        try
+        {
+            configurationDao.update( configurationDictionary );
+        }
+        catch ( RuntimeException e )
+        {
+           e.printStackTrace();
+            fail("Failed to add a new attribute. "+e.toString());
+        }
+        ConfigurationDictionary afterUpdateConfigurationDictionary = configurationDao.read( pid );
+        assertNotNull(afterUpdateConfigurationDictionary);
+        assertNotNull("Failed to add a new attribute. ", afterUpdateConfigurationDictionary.get( ConfigurationAdmin.SERVICE_FACTORYPID ));
+        assertEquals("Failed to correctly add a new attribute. ",SOME_FACTORY, afterUpdateConfigurationDictionary.get( ConfigurationAdmin.SERVICE_FACTORYPID ));
+        
+    }
+    
+    public void testUpdateReplacing()
+    {
+        log.debug( "Start test ======================================================" );
+        String cn = "mytestConfiguration2";
+        String pid = "alternate5.name.pid";
+        String factory = SOME_FACTORY;
+        String replacedFactory ="replaced.factory";
+        ConfigurationDictionary configurationDictionary = createConfigurationDictionaryInstance(
+            cn, pid, factory);
+        configurationDao.create( configurationDictionary );
+        
+        //Replace the factory with a new name
+        configurationDictionary = createConfigurationDictionaryInstance(
+            cn, pid, replacedFactory);
+        
+        try
+        {
+            configurationDao.update( configurationDictionary );
+        }
+        catch ( RuntimeException e )
+        {
+           fail("Failed to update with a replacement attribute. "+e.toString());
+        }
+        ConfigurationDictionary afterUpdateConfigurationDictionary = configurationDao.read( pid);
+        assertNotNull(afterUpdateConfigurationDictionary);
+        assertEquals("Failed to update with a replacement attribute. ",
+            replacedFactory, afterUpdateConfigurationDictionary.get( ConfigurationAdmin.SERVICE_FACTORYPID ));
+        
+    }
+    
+    public void testConfigurationDaoDelete()
+    {
+        log.debug( "Start test ======================================================" );
+        ConfigurationDictionary initialConfigurationDictionary = configurationDao.read( SOME_PID );
+        assertNotNull(initialConfigurationDictionary);
+        
+        configurationDao.delete( initialConfigurationDictionary );
+        
+       
+        try
+        {
+            configurationDao.read( SOME_PID );
+            fail("There should be no entry. An EntryNotFoundException should have been thrown.");
+        }
+        catch (ConfigurationDaoException e)
+        {
+            assertTrue(e.getCause() instanceof NameNotFoundException);
+           
+        }
+        
+    }
+    Dictionary changedConfiguration = null;
+    public void testListener(){
+        log.debug( "Start test ======================================================" );
+        String servicePid = "alternate11.name.pid";
+         
+        configurationDao.setConfigurationListener( new ConfigurationDaoListener() {
+
+            public void configurationChanged(ChangeType changeType, ConfigurationDictionary configuration )
+            {
+                log.debug( "Found a listener." );
+                changedConfiguration=configuration;
+                
+            }}   );
+        ConfigurationDictionary configurationDictionary = createConfigurationDictionaryInstance(
+            "mytestConfiguration2", servicePid, SOME_FACTORY);
+        
+        String pid = configurationDao.create( configurationDictionary );
+        
+        assertEquals(servicePid,pid);
+        
+        assertNotNull(changedConfiguration);
+        log.debug( "Heard that the configuration {} was created.",changedConfiguration );
+        
+        assertEquals("No ServicePid check for translation fault.",servicePid, changedConfiguration.get( Constants.SERVICE_PID ));
+    }
+    
+  
+  
+  /**
+   * Test method for {@link org.apache.configuration.util.ConfigurationImpl#update()}.
+   * 
+   */
+  public void testCreateWithExplicitName()
+  {
+      log.debug( "Start test ======================================================" );
+      Vector<String> objectclass = new Vector<String>();
+      objectclass.add( "top" );
+      objectclass.add( ContextMapping.APACHEDS_SERVICE_CONFIGURATION_OBJECTCLASS );
+      Dictionary<String,Object> dictionary = new Hashtable<String,Object>();
+      dictionary.put( Constants.SERVICE_PID, "alternate.name.pid" );
+      dictionary.put( ConfigurationAdmin.SERVICE_FACTORYPID , SOME_FACTORY );
+      dictionary.put( "objectclass", objectclass );
+      dictionary.put( "cn", CN_1 );
+      dictionary.put( NameMapping.APACHEDS_NAMIMG_KEY, 
+          "cn=mytestConfiguration,ou=services,ou=configuration,ou=system" );
+     
+      ConfigurationDictionary configurationDictionary = new ConfigurationDictionary(dictionary);
+      String pid = configurationDao.create( configurationDictionary );
+      assertEquals("alternate.name.pid",pid);
+      
+      ConfigurationDictionary configurationDictionary2 = configurationDao.read( pid );
+      assertNotNull(configurationDictionary2);
+      
+      log.debug( "Deleting configurationDictionary entry {}.", configurationDictionary2 );
+      try
+    {
+        configurationDao.delete( configurationDictionary2 );
+    }
+    catch ( RuntimeException e )
+    {
+        e.printStackTrace();
+        fail("Could not delete the configurationDictionary with an alternative naming scheme.");
+    }
+  }
+    
+
+    private ConfigurationDictionary createConfigurationDictionaryInstance(String cn, String pid, String factory)
+    {
+        Vector<String> objectclass = new Vector<String>();
+        objectclass.add( "top" );
+        objectclass.add( ContextMapping.APACHEDS_SERVICE_CONFIGURATION_OBJECTCLASS );
+        Dictionary<String,Object> dictionary = new Hashtable<String,Object>();
+        dictionary.put( Constants.SERVICE_PID, pid );
+        if(factory !=null){
+            dictionary.put( ConfigurationAdmin.SERVICE_FACTORYPID , factory );
+        }
+        dictionary.put( "objectclass", objectclass );
+        dictionary.put( "cn", cn );
+        
+       
+        ConfigurationDictionary configurationDictionary = new ConfigurationDictionary(dictionary);
+        
+        return configurationDictionary;
+    }
+
+
+
+    public InitialContextFactory getInitialContextFactory()
+    {
+        return initialContextFactory;
+    }
+
+
+
+    public void setInitialContextFactory( InitialContextFactory initialContextFactory )
+    {
+        this.initialContextFactory = initialContextFactory;
+    }
+
+}

Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/dao/jndi/impl/MockInitialContextFactory.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/dao/jndi/impl/MockInitialContextFactory.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/dao/jndi/impl/MockInitialContextFactory.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/dao/jndi/impl/MockInitialContextFactory.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2006 the original author or authors.
+ * 
+ * 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.configuration.dao.jndi.impl;
+
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.InitialDirContext;
+import javax.naming.spi.InitialContextFactory;
+
+import org.apache.directory.server.core.authn.AuthenticationService;
+import org.apache.directory.server.core.authz.AuthorizationService;
+import org.apache.directory.server.core.authz.DefaultAuthorizationService;
+import org.apache.directory.server.core.collective.CollectiveAttributeService;
+import org.apache.directory.server.core.configuration.InterceptorConfiguration;
+import org.apache.directory.server.core.configuration.MutableInterceptorConfiguration;
+import org.apache.directory.server.core.configuration.MutableStartupConfiguration;
+import org.apache.directory.server.core.configuration.ShutdownConfiguration;
+import org.apache.directory.server.core.event.EventService;
+import org.apache.directory.server.core.exception.ExceptionService;
+import org.apache.directory.server.core.interceptor.Interceptor;
+import org.apache.directory.server.core.jndi.CoreContextFactory;
+import org.apache.directory.server.core.normalization.NormalizationService;
+import org.apache.directory.server.core.operational.OperationalAttributeService;
+import org.apache.directory.server.core.partition.impl.btree.MutableBTreePartitionConfiguration;
+import org.apache.directory.server.core.referral.ReferralService;
+import org.apache.directory.server.core.schema.SchemaService;
+import org.apache.directory.server.core.subtree.SubentryService;
+
+import com.sun.jndi.ldap.LdapCtxFactory;
+
+
+
+
+/**
+ * 
+ * MockInitialContextFactory provides a mock JNDI initial context factory for the 
+ * test spring configuration mockInitialContextFactory.xml.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class MockInitialContextFactory implements InitialContextFactory
+{
+    
+//    private static Properties env = new Properties();
+    private boolean embeded;
+    
+    
+
+
+    public MockInitialContextFactory() throws NamingException
+    {
+        this(true);
+    }
+    
+    public MockInitialContextFactory(boolean embeded) throws NamingException{
+        this.embeded=embeded;
+    }
+   
+
+    public  Context getInitialContext( java.util.Hashtable<?, ?> environment ) throws NamingException
+    {
+        Properties env = null;
+        if(embeded){
+           env= createEmbeded();
+        }else{
+           env= createLocal();
+        }
+        return new InitialDirContext( env );
+    }
+    
+    @SuppressWarnings("unchecked")
+    private  Properties createEmbeded() throws NamingException{
+        Properties env = new Properties();
+      env.setProperty( Context.INITIAL_CONTEXT_FACTORY, CoreContextFactory.class.getName() );
+      //Create a configuration instruction.
+      MutableStartupConfiguration cfg = new MutableStartupConfiguration();
+      
+      List<InterceptorConfiguration> interceptorConfigurations = new ArrayList<InterceptorConfiguration>();
+      interceptorConfigurations.add( createInterceptor( "normalizationService", new NormalizationService() ));
+      interceptorConfigurations.add( createInterceptor( "authenticationService", new AuthenticationService() ));
+      interceptorConfigurations.add( createInterceptor( "referralService", new ReferralService() ));
+      
+      interceptorConfigurations.add( createInterceptor( "authorizationService", new AuthorizationService() ));
+      interceptorConfigurations.add( createInterceptor( "defaultAuthorizationService", new DefaultAuthorizationService() ));
+      interceptorConfigurations.add( createInterceptor( "exceptionService", new ExceptionService() ));
+      interceptorConfigurations.add( createInterceptor( "schemaService", new SchemaService() ));
+      interceptorConfigurations.add( createInterceptor( "subentryService", new SubentryService() ));
+      interceptorConfigurations.add( createInterceptor( "operationalAttributeService", new OperationalAttributeService() ));
+      interceptorConfigurations.add( createInterceptor( "collectiveAttributeService", new CollectiveAttributeService() ));
+      interceptorConfigurations.add( createInterceptor( "eventService", new EventService() ));
+      
+      
+      cfg.setInterceptorConfigurations( interceptorConfigurations );
+      //Put the configuration instruction to the environment variable.
+      MutableBTreePartitionConfiguration systemPartitionConfiguration = new MutableBTreePartitionConfiguration();
+      systemPartitionConfiguration.setName( "system" );
+      systemPartitionConfiguration.setSuffix( "ou=system" );
+      Attributes rootEntry = new BasicAttributes(); 
+      rootEntry.put( "objectClass", "top" );
+      rootEntry.put( "objectClass", "organizationalUnit" );
+      rootEntry.put( "objectClass", "extensibleObject" );
+      rootEntry.put( "objectClass", "system" );
+
+      systemPartitionConfiguration.setContextEntry( rootEntry );
+      cfg.setSystemPartitionConfiguration( systemPartitionConfiguration );
+      //      cfg.setDenormalizeOpAttrsEnabled( false );
+      //        cfg.setBootstrapSchemas( bootstrapSchemas );
+      env.putAll( cfg.toJndiEnvironment() );
+      env.put("java.naming.security.authentication","simple");
+      env.put("java.naming.security.principal","uid=admin,ou=system");
+      env.put("java.naming.security.credentials", "secret");
+      return env;
+    }
+    
+    private Properties createLocal() throws NamingException{
+        Properties env = new Properties();
+      env.setProperty( Context.INITIAL_CONTEXT_FACTORY, LdapCtxFactory.class.getName() );
+      env.setProperty( Context.PROVIDER_URL, "ldap://localhost:10389" );
+      env.put("java.naming.security.authentication","simple");
+      env.put("java.naming.security.principal","uid=admin,ou=system");
+      env.put("java.naming.security.credentials", "secret");
+      return env;
+    }
+    
+    private static InterceptorConfiguration createInterceptor( String interceptorName, Interceptor interceptor )
+    {
+        MutableInterceptorConfiguration interceptorConfiguration = new MutableInterceptorConfiguration();
+        interceptorConfiguration.setName( interceptorName );
+        interceptorConfiguration.setInterceptor( interceptor );
+        return interceptorConfiguration;
+    }
+    
+    
+    public void cleanup() 
+    {
+        try
+        {
+            new InitialDirContext( new ShutdownConfiguration().toJndiEnvironment() );
+        }
+        catch ( NamingException e )
+        {
+            //ignore
+        }
+        
+    }
+}
\ No newline at end of file

Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/event/ConfigurationChangeIntegrationTest.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/event/ConfigurationChangeIntegrationTest.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/event/ConfigurationChangeIntegrationTest.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/event/ConfigurationChangeIntegrationTest.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,485 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you 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.configuration.event;
+
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Vector;
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import junit.framework.TestCase;
+
+import org.apache.configuration.dao.ConfigurationDao;
+import org.apache.configuration.dao.jndi.ContextMapping;
+import org.apache.configuration.impl.ConfigurationAdminServiceFactory;
+import org.apache.configuration.impl.ConfigurationDictionary;
+import org.apache.configuration.impl.ConfigurationStoreImpl;
+import org.apache.configuration.util.ApacheDSUtil;
+import org.osgi.framework.Constants;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.cm.ConfigurationEvent;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ConfigurationListener;
+import org.osgi.service.cm.ManagedService;
+import org.osgi.service.cm.ManagedServiceFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.springframework.osgi.mock.MockBundle;
+import org.springframework.osgi.mock.MockServiceRegistration;
+
+
+/**
+ * ConfigurationImplTest tests the ConfigurationImpl with an embeded JNDI ConfigurationDao infrastructure.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class ConfigurationChangeIntegrationTest extends TestCase implements ConfigurationListener
+{
+
+    private static final String SOME_FACTORY = "some.factory.pid";
+    private static final String SOME_PID = "some.pid";
+    private static final String SOME_CN = "someCn";
+    /** the log for this class */
+    private static final Logger log = LoggerFactory.getLogger( ConfigurationChangeIntegrationTest.class );
+
+    static
+    {
+        File file = new File( "server-work" );
+        if ( file.exists() )
+        {
+            log.debug( "Removing the server-work directory. " );
+            ApacheDSUtil.deleteDir(file);
+        }
+    }
+
+
+    private CyclicBarrier listenerReceivedEventBarrier;
+    private ConfigurationStoreImpl configurationStore;
+    private ConfigurationDao configurationDao;
+    private ConfigurationChangeManager configurationDaoEventListener;
+    
+    private MockManagedServiceTrackingDelegate mockManagedServiceTrackingDelegate;
+    private MockManagedServiceFactoryTrackingDelegate mockManagedServiceFactoryTrackingDelegate;
+
+    private ConfigurationAdminServiceFactory configurationAdminServiceFactory;
+    private Dictionary updatedManagedServiceDictionary;
+    private Dictionary updatedManagedServiceFactoryDictionary;
+    ConfigurationEvent event = null;
+    
+    /* (non-Javadoc)
+     * @see junit.framework.TestCase#setUp()
+     */
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+        listenerReceivedEventBarrier = new CyclicBarrier(2);
+        ApplicationContext ctx = new ClassPathXmlApplicationContext(
+            new String[]{ 
+                "mockInitialContextFactory.xml", 
+                "META-INF/spring/daoJndi.xml", 
+                "META-INF/spring/event.xml",
+                "META-INF/spring/configuration.xml",
+                "event.xml"});
+        
+        configurationStore = ( ConfigurationStoreImpl ) ctx.getBean( "configurationStore" );
+        configurationDao = ( ConfigurationDao ) ctx.getBean( "configurationDao" );
+        configurationAdminServiceFactory= 
+            ( ConfigurationAdminServiceFactory ) ctx.getBean( "configurationAdminServiceFactory" );
+        
+        configurationDaoEventListener=
+            ( ConfigurationChangeManager ) ctx.getBean( "configurationDaoEventListener" );
+        configurationDaoEventListener.setConfigurationListener( this );
+        
+        mockManagedServiceTrackingDelegate= ( MockManagedServiceTrackingDelegate ) ctx.getBean( "mockManagedServiceTrackingDelegate");
+        mockManagedServiceTrackingDelegate.setService( new MyManagedService() );
+        
+        
+        mockManagedServiceFactoryTrackingDelegate= ( MockManagedServiceFactoryTrackingDelegate ) ctx.getBean( "mockManagedServiceFactoryTrackingDelegate");
+        mockManagedServiceFactoryTrackingDelegate.setService( new MyManagedServiceFactory() );
+        
+    }
+
+
+    /* (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#tearDown()
+     */
+    protected void tearDown() throws Exception
+    {
+       
+        configurationDao=null;
+       
+        mockManagedServiceTrackingDelegate=null;
+        mockManagedServiceFactoryTrackingDelegate=null;
+        configurationStore = null;
+        updatedManagedServiceDictionary=null;
+        updatedManagedServiceFactoryDictionary = null;
+        configurationAdminServiceFactory=null;
+        event = null;
+
+        updatedManagedServiceDictionary = null;
+        updatedManagedServiceFactoryDictionary = null;
+        configurationDaoEventListener=null;
+        super.tearDown();
+    }
+
+    public void testEnvironment(){
+        assertNotNull( configurationDao);
+        assertNotNull( configurationStore);
+        assertNotNull( mockManagedServiceTrackingDelegate);
+        assertNotNull( mockManagedServiceFactoryTrackingDelegate);
+        assertNotNull( configurationAdminServiceFactory);
+        assertNotNull(configurationDaoEventListener);
+        Object o = configurationStore.getDelegatedConfigurationDaoListener();
+        assertNotNull(o);
+        assertTrue(o instanceof ConfigurationChangeManager);
+    }
+    
+    public void testWithACleanEnvironment(){
+        List<ConfigurationDictionary> configs = configurationDao.findAll();
+        if(configs==null || configs.isEmpty()){
+            return;
+        }
+        
+        log.debug( "Deleting {} configurationDictionary entries {}.", configs.size(),configs );
+        for ( ConfigurationDictionary configurationDictionary : configs )
+        {
+            
+            log.debug( "Deleting configurationDictionary entry {}.", configurationDictionary );
+            configurationDao.delete( configurationDictionary );
+        }
+        
+        assertTrue( configurationDao.findAll().isEmpty());
+        assertTrue( configurationStore.listPids().isEmpty());
+    }
+
+   
+    public void testCreateConfiguration(){
+       ConfigurationAdmin configurationAdmin = getConfigAdmin();
+       Configuration configuration = null;
+       try
+       {
+           configuration =configurationAdmin.getConfiguration( SOME_PID );
+       }
+       catch ( IOException e )
+       {
+           log.error( "Failed to getConfiguration.",e );
+           fail(e.toString());
+       }
+       assertNotNull(configuration);
+    }
+
+
+   
+    
+    /**
+     * 
+     * Update a configuration in the backend and asynchronously
+     * update the Service and send an event.
+     * 
+     */
+    public void testCreateAndUpdateManagedServiceConfiguration(){
+        ConfigurationAdmin configurationAdmin = getConfigAdmin();
+        Configuration configuration = null;
+        try
+        {
+            configuration =configurationAdmin.getConfiguration( SOME_PID );
+        }
+        catch ( IOException e )
+        {
+            log.error( "Failed to getConfiguration.",e );
+            fail(e.toString());
+        }
+        assertNotNull(configuration);
+        ConfigurationDictionary configurationDictionary = 
+            createConfigurationDictionaryInstance(SOME_CN, SOME_PID, null);
+        try
+        {
+            configuration.update(configurationDictionary);
+        }
+        catch ( IOException e )
+        {
+            fail(e.toString());
+        }
+        catch (Exception e)
+        {
+            fail(e.toString());
+        }
+        
+        //Wait for the update async event to be sent 
+        try
+        {
+            listenerReceivedEventBarrier.await( 3, TimeUnit.SECONDS );
+        }
+        catch ( InterruptedException e )
+        {
+            fail(e.toString());
+        }
+        catch ( BrokenBarrierException e )
+        {
+            fail(e.toString());
+        }
+        catch ( TimeoutException e )
+        {
+            fail(e.toString());
+        }
+        assertNotNull(event);
+        assertNotNull(updatedManagedServiceDictionary);
+        assertNull(updatedManagedServiceFactoryDictionary);
+        
+        //Wait for the async delete event to be sent 
+        listenerReceivedEventBarrier = new CyclicBarrier(2);
+        event=null;
+        try
+        {
+            configuration.delete();
+        }
+        catch ( IOException e )
+        {
+            fail(e.toString());
+        }
+        catch (Exception e)
+        {
+            fail(e.toString());
+        }
+        
+        try
+        {
+            listenerReceivedEventBarrier.await( 3, TimeUnit.SECONDS );
+        }
+        catch ( InterruptedException e )
+        {
+            fail(e.toString());
+        }
+        catch ( BrokenBarrierException e )
+        {
+            fail(e.toString());
+        }
+        catch ( TimeoutException e )
+        {
+            fail("Failed to delete the configuration.");
+        }
+        assertNotNull(event);
+        assertNull("Should have been nulled by the delete",updatedManagedServiceDictionary);
+        assertNull(updatedManagedServiceFactoryDictionary);
+     }
+    
+    
+    
+    
+    /**
+     * 
+     * Update a configuration in the backend and asynchronously
+     * update the Service and send an event.
+     * 
+     */
+    public void testCreateAndUpdateManagedServiceFactoryConfiguration(){
+        ConfigurationAdmin configurationAdmin = getConfigAdmin();
+        Configuration configuration = null;
+        try
+        {
+            configuration =configurationAdmin.createFactoryConfiguration( SOME_FACTORY );
+        }
+        catch ( IOException e )
+        {
+            log.error( "Failed to getConfiguration.",e );
+            fail(e.toString());
+        }
+        assertNotNull(configuration);
+        ConfigurationDictionary configurationDictionary = 
+            createConfigurationDictionaryInstance(SOME_CN, SOME_PID, SOME_FACTORY);
+        try
+        {
+            configuration.update(configurationDictionary);
+        }
+        catch ( IOException e )
+        {
+            fail(e.toString());
+        }
+        catch (Exception e)
+        {
+            fail(e.toString());
+        }
+        
+        //Wait for the async event to be sent 
+        try
+        {
+            listenerReceivedEventBarrier.await( 3, TimeUnit.SECONDS );
+        }
+        catch ( InterruptedException e )
+        {
+            fail(e.toString());
+        }
+        catch ( BrokenBarrierException e )
+        {
+            fail(e.toString());
+        }
+        catch ( TimeoutException e )
+        {
+            fail("Failed to update the ManagedServiceFactory.");
+        }
+        assertNotNull(event);
+        assertNotNull(updatedManagedServiceFactoryDictionary);
+        assertNull(updatedManagedServiceDictionary);
+        
+        //Setup for delete 
+        listenerReceivedEventBarrier = new CyclicBarrier(2);
+        event=null;
+        try
+        {
+            configuration.delete();
+        }
+        catch ( IOException e )
+        {
+            fail(e.toString());
+        }
+        catch (Exception e)
+        {
+            fail(e.toString());
+        }
+        
+        //Wait for the async event to be sent 
+        try
+        {
+            listenerReceivedEventBarrier.await( 3, TimeUnit.SECONDS );
+        }
+        catch ( InterruptedException e )
+        {
+            fail(e.toString());
+        }
+        catch ( BrokenBarrierException e )
+        {
+            fail(e.toString());
+        }
+        catch ( TimeoutException e )
+        {
+            fail("Failed to update the ManagedServiceFactory.");
+        }
+        assertNotNull(event);
+        assertNull(updatedManagedServiceFactoryDictionary);
+        assertNull(updatedManagedServiceDictionary);
+        
+     }
+    
+    
+    /**
+     * A utility method for building a configAdmin.
+     *
+     * @return
+     */
+    private ConfigurationAdmin getConfigAdmin()
+    {
+        MockBundle bundle = new MockBundle();
+           MockServiceRegistration serviceRegistration = new MockServiceRegistration();
+           Object o = configurationAdminServiceFactory.getService( bundle, serviceRegistration );
+           assertNotNull(o);
+           assertTrue(o instanceof ConfigurationAdmin);
+           ConfigurationAdmin configurationAdmin = (ConfigurationAdmin)o;
+        return configurationAdmin;
+    }
+    
+    private ConfigurationDictionary createConfigurationDictionaryInstance(String cn, String pid, String factory)
+    {
+        Vector<String> objectclass = new Vector<String>();
+        objectclass.add( "top" );
+        objectclass.add( ContextMapping.APACHEDS_SERVICE_CONFIGURATION_OBJECTCLASS );
+        Dictionary<String,Object> dictionary = new Hashtable<String,Object>();
+        dictionary.put( Constants.SERVICE_PID, pid );
+        if(factory !=null){
+            dictionary.put( ConfigurationAdmin.SERVICE_FACTORYPID , factory );
+        }
+        dictionary.put( "objectclass", objectclass );
+        dictionary.put( "cn", cn );
+        
+        
+        ConfigurationDictionary configurationDictionary = new ConfigurationDictionary(dictionary);
+        
+        return configurationDictionary;
+    }
+    
+    /**
+     * Implements ConfigurationListener to receive configuration events
+     * coming from the executor.
+     */
+    public void configurationEvent( ConfigurationEvent event )
+    {
+        this.event=event;
+        try
+        {
+            listenerReceivedEventBarrier.await();
+        }
+        catch ( InterruptedException e )
+        {
+           log.error( "Barrier exception.",e );
+        }
+        catch ( BrokenBarrierException e )
+        {
+            log.error( "Barrier exception.",e );
+        }
+        
+    }
+    
+    class MyManagedService implements ManagedService {
+
+        public void updated( Dictionary properties ) throws ConfigurationException
+        {
+            updatedManagedServiceDictionary=properties;
+            
+        }
+        
+    }
+    
+    class MyManagedServiceFactory implements ManagedServiceFactory {
+        public void deleted( String pid )
+        {
+            if(updatedManagedServiceFactoryDictionary.get( Constants.SERVICE_PID ).equals( pid )){
+              updatedManagedServiceFactoryDictionary=null;
+            }else{
+                log.error( "Wrong deletion pid received "+pid );
+            }
+            
+        }
+
+        public String getName()
+        {
+//          ignore
+            return null;
+        }
+
+        public void updated( String pid, Dictionary properties ) throws ConfigurationException
+        {
+            updatedManagedServiceFactoryDictionary=properties;
+            
+        }
+        
+    }
+}

Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/event/ConfigurationChangeTest.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/event/ConfigurationChangeTest.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/event/ConfigurationChangeTest.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/event/ConfigurationChangeTest.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,334 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you 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.configuration.event;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Properties;
+import java.util.Vector;
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import junit.framework.TestCase;
+
+import org.apache.configuration.dao.ConfigurationDaoListener.ChangeType;
+import org.apache.configuration.dao.jndi.ContextMapping;
+import org.apache.configuration.impl.ConfigurationDictionary;
+import org.apache.configuration.impl.MockConfigurationTransformer;
+import org.osgi.framework.Constants;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.cm.ConfigurationEvent;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ConfigurationListener;
+import org.osgi.service.cm.ManagedService;
+import org.osgi.service.cm.ManagedServiceFactory;
+import org.springframework.osgi.mock.MockServiceReference;
+
+
+/**
+ * <p>A <tt>ConfigurationChangeTest</tt> 
+ * is not a full test of the {@link ConfigurationChangeManager}
+ * but it does test the asynchronous wiring infrastructure for event processing. 
+ * This includes {@link AsyncExecutorService}, and  {@link ConfigurationEventBroadcaster}.
+ * 
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class ConfigurationChangeTest extends TestCase implements ConfigurationListener
+{
+    
+    private static final String SOME_FACTORY = "some.factory";
+    private static final String SOME_PID = "some.pid";
+    private static final String SOME_CN = "someCn";
+    CyclicBarrier listenerReceivedEventBarrier = null;
+    AsyncExecutorService asyncExecutorService = null;
+    ConfigurationChangeManager configurationChangeManager =null;
+    ConfigurationEventBroadcaster configurationEventBroadcaster = null;
+    
+    ManagedServiceTrackerCustomizer managedServiceTrackerCustomizer = null;
+    MockManagedServiceTrackingDelegate mockManagedServiceTrackingDelegate= null;
+    ManagedServiceTrackingAdapter managedServiceTrackingAdapter = null;
+    
+    ManagedServiceFactoryTrackerCustomizer managedServiceFactoryTrackerCustomizer = null;
+    MockManagedServiceFactoryTrackingDelegate mockManagedServiceFactoryTrackingDelegate= null;
+    ManagedServiceFactoryTrackingAdapter managedServiceFactoryTrackingAdapter = null;
+    Executor executor = null;
+    ConfigurationEvent event = null;
+    List<ConfigurationListener> configurationListeners = null;
+    
+    private Dictionary updatedManagedServiceDictionary = null;
+    private Dictionary updatedManagedServiceFactoryDictionary = null;
+    
+    /* (non-Javadoc)
+     * @see junit.framework.TestCase#setUp()
+     */
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+        asyncExecutorService = new AsyncExecutorService();
+        executor = asyncExecutorService.getExecutor();
+        configurationEventBroadcaster = new ConfigurationEventBroadcaster();
+        configurationChangeManager = new ConfigurationChangeManager();
+        configurationChangeManager.setExecutor( executor );
+        configurationChangeManager.setConfigurationListener( configurationEventBroadcaster );
+        configurationChangeManager.setConfigurationTransformer( new MockConfigurationTransformer() );
+        
+        
+        managedServiceTrackerCustomizer = new ManagedServiceTrackerCustomizer(); //just a placeholder for now
+        mockManagedServiceTrackingDelegate = new MockManagedServiceTrackingDelegate();
+        MockServiceReference mockManagedServiceReference = new MockServiceReference();
+        Properties props = new Properties();
+        props.setProperty( Constants.SERVICE_PID, SOME_PID );
+        mockManagedServiceReference.setProperties(props);
+        
+        mockManagedServiceTrackingDelegate.setServiceReference( mockManagedServiceReference );
+        mockManagedServiceTrackingDelegate.setService( new MyManagedService() );
+        managedServiceTrackingAdapter = new ManagedServiceTrackingAdapter();
+        managedServiceTrackingAdapter.setDelegate( mockManagedServiceTrackingDelegate );
+        managedServiceTrackingAdapter.setServiceTrackerCustomizer( managedServiceTrackerCustomizer );
+         
+        
+        
+        
+        managedServiceFactoryTrackerCustomizer = null;//just a placeholder
+        mockManagedServiceFactoryTrackingDelegate= new MockManagedServiceFactoryTrackingDelegate();
+        MockServiceReference mockManagedFactoryServiceReference = new MockServiceReference();
+        Properties props2 = new Properties();
+//        props2.setProperty( Constants.SERVICE_PID, SOME_PID );
+        props2.setProperty( ConfigurationAdmin.SERVICE_FACTORYPID, SOME_FACTORY );
+        mockManagedFactoryServiceReference.setProperties(props2);
+        mockManagedServiceFactoryTrackingDelegate.setServiceReference( mockManagedFactoryServiceReference );
+        mockManagedServiceFactoryTrackingDelegate.setService( new MyManagedServiceFactory() );
+        managedServiceFactoryTrackingAdapter = new ManagedServiceFactoryTrackingAdapter();
+        managedServiceFactoryTrackingAdapter.setServiceTrackerCustomizer( managedServiceFactoryTrackerCustomizer );
+        managedServiceFactoryTrackingAdapter.setDelegate( mockManagedServiceFactoryTrackingDelegate );
+//        managedServiceFactoryTrackingAdapter = 
+//           new ManagedServiceFactoryTrackingAdapter(
+//                managedServiceFactoryTrackerCustomizer,
+//                mockManagedServiceFactoryTrackingDelegate);
+        
+        
+        configurationChangeManager.setManagedServiceFactoryTrackingAdapter( managedServiceFactoryTrackingAdapter );
+        configurationChangeManager.setManagedServiceTrackingAdapter( managedServiceTrackingAdapter );
+        configurationListeners = new ArrayList<ConfigurationListener>();
+        configurationListeners.add( this );
+        configurationEventBroadcaster.setListeners( configurationListeners );
+        listenerReceivedEventBarrier = new CyclicBarrier(2);
+    }
+
+
+    /* (non-Javadoc)
+     * @see junit.framework.TestCase#tearDown()
+     */
+    protected void tearDown() throws Exception
+    {
+        asyncExecutorService.destroy();
+        asyncExecutorService = null;
+        configurationChangeManager =null;
+        executor = null;
+        event=null;
+        listenerReceivedEventBarrier = null;
+        configurationEventBroadcaster = null;
+        configurationListeners = null;
+        updatedManagedServiceDictionary = null;
+        updatedManagedServiceFactoryDictionary = null;
+        super.tearDown();
+    }
+
+
+    /**
+     * Test method for {@link org.apache.configuration.event.ConfigurationChangeManager#sendEventToListener(org.apache.configuration.dao.ConfigurationDaoListener.ChangeType, org.apache.configuration.impl.ConfigurationDictionary, org.osgi.framework.ServiceReference)}.
+     * Sends event as a comand to the listener
+     */
+    public final void testSendEventToListener()
+    {
+        ConfigurationDictionary configurationDictionary = 
+            createConfigurationDictionaryInstance(SOME_CN, SOME_PID, SOME_FACTORY);
+       
+        configurationChangeManager.sendEventToListener( ChangeType.CREATED, configurationDictionary, null );
+        try
+        {
+            listenerReceivedEventBarrier.await( 3, TimeUnit.SECONDS );
+        }
+        catch ( InterruptedException e )
+        {
+            fail(e.toString());
+        }
+        catch ( BrokenBarrierException e )
+        {
+            fail(e.toString());
+        }
+        catch ( TimeoutException e )
+        {
+            fail(e.toString());
+        }
+        assertNotNull(event);
+        asyncExecutorService.destroy();
+    }
+
+    
+    /**
+     * Test method for {@link org.apache.configuration.event.ConfigurationChangeManager#configurationChanged( ChangeType changeType, ConfigurationDictionary configurationIn )}.
+     * 
+     * Note: this will log errors even when the test passes because there is no real configuration persisted.
+     */
+    public final void testManagedServiceFactoryConfigurationChanged()
+    {
+       ConfigurationDictionary configurationDictionary = 
+        createConfigurationDictionaryInstance(SOME_CN, SOME_PID, SOME_FACTORY);
+
+        configurationChangeManager.configurationChanged( ChangeType.CREATED, configurationDictionary );
+        try
+        {
+            listenerReceivedEventBarrier.await( 3, TimeUnit.SECONDS );
+        }
+        catch ( InterruptedException e )
+        {
+            fail(e.toString());
+        }
+        catch ( BrokenBarrierException e )
+        {
+            fail(e.toString());
+        }
+        catch ( TimeoutException e )
+        {
+            fail(e.toString());
+        }
+        assertNotNull(event);
+        assertNotNull(updatedManagedServiceFactoryDictionary);
+        assertNull(updatedManagedServiceDictionary);
+        
+        
+    }
+    
+    /**
+     * Test method for {@link org.apache.configuration.event.ConfigurationChangeManager#configurationChanged( ChangeType changeType, ConfigurationDictionary configurationIn )}.
+     */
+    public final void testManagedServiceConfigurationChanged()
+    {
+       ConfigurationDictionary configurationDictionary = 
+        createConfigurationDictionaryInstance(SOME_CN, SOME_PID, null);
+
+        configurationChangeManager.configurationChanged( ChangeType.CREATED, configurationDictionary );
+        try
+        {
+            listenerReceivedEventBarrier.await( 3, TimeUnit.SECONDS );
+        }
+        catch ( InterruptedException e )
+        {
+            fail(e.toString());
+        }
+        catch ( BrokenBarrierException e )
+        {
+            fail(e.toString());
+        }
+        catch ( TimeoutException e )
+        {
+            fail(e.toString());
+        }
+        assertNotNull(event);
+        assertNotNull(updatedManagedServiceDictionary);
+        assertNull(updatedManagedServiceFactoryDictionary);
+    }
+    
+    
+
+    private ConfigurationDictionary createConfigurationDictionaryInstance(String cn, String pid, String factory)
+    {
+        Vector<String> objectclass = new Vector<String>();
+        objectclass.add( "top" );
+        objectclass.add( ContextMapping.APACHEDS_SERVICE_CONFIGURATION_OBJECTCLASS );
+        Dictionary<String,Object> dictionary = new Hashtable<String,Object>();
+        dictionary.put( Constants.SERVICE_PID, pid );
+        if(factory !=null){
+            dictionary.put( ConfigurationAdmin.SERVICE_FACTORYPID , factory );
+        }
+        dictionary.put( "objectclass", objectclass );
+        dictionary.put( "cn", cn );
+        
+        
+        ConfigurationDictionary configurationDictionary = new ConfigurationDictionary(dictionary);
+        
+        return configurationDictionary;
+    }
+    /**
+     * Implements ConfigurationListener to receive configuration events
+     * coming from the executor.
+     */
+    public void configurationEvent( ConfigurationEvent event )
+    {
+        this.event=event;
+        try
+        {
+            listenerReceivedEventBarrier.await();
+        }
+        catch ( InterruptedException e )
+        {
+            fail(e.toString());
+        }
+        catch ( BrokenBarrierException e )
+        {
+            fail(e.toString());
+        }
+        
+    }
+
+
+    class MyManagedService implements ManagedService {
+
+        public void updated( Dictionary properties ) throws ConfigurationException
+        {
+            updatedManagedServiceDictionary=properties;
+            
+        }
+        
+    }
+    
+    class MyManagedServiceFactory implements ManagedServiceFactory {
+
+       
+        public void deleted( String pid )
+        {
+//          ignore
+            
+        }
+
+        public String getName()
+        {
+//          ignore
+            return null;
+        }
+
+        public void updated( String pid, Dictionary properties ) throws ConfigurationException
+        {
+            updatedManagedServiceFactoryDictionary=properties;
+            
+        }
+        
+    }
+  
+}

Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/event/ConfigurationNotifier.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/event/ConfigurationNotifier.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/event/ConfigurationNotifier.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/event/ConfigurationNotifier.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,105 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you 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.configuration.event;
+
+import org.apache.configuration.dao.ConfigurationDaoListener;
+import org.apache.configuration.impl.ConfigurationDictionary;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.ConfigurationEvent;
+import org.osgi.service.cm.ConfigurationListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * ConfigurationNotifier notifies ConfigurationListeners when changes to a 
+ * ConfigurationDaoNotifier are generated. 
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class ConfigurationNotifier implements ConfigurationDaoListener
+{
+
+    /** the log for this class */
+    private static final Logger log = LoggerFactory.getLogger( ConfigurationNotifier.class );
+
+    private ConfigurationListener configurationListener;
+    private final ServiceReference serviceReference;
+    /**
+     * 
+     * Creates a new instance of ConfigurationNotifier.
+     *
+     */
+    public ConfigurationNotifier()
+    {
+       this(null);
+    }
+  
+    
+    /**
+     * 
+     * Creates a new instance of ConfigurationNotifier.
+     *
+     * @param serviceReference
+     */
+    public ConfigurationNotifier(ServiceReference serviceReference)
+    {
+       this.serviceReference=serviceReference;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.configuration.dao.ConfigurationDaoListener#configurationChanged(org.apache.configuration.dao.ConfigurationDaoListener.ChangeType, org.apache.configuration.util.ConfigurationDictionary)
+     */
+    public void configurationChanged( ChangeType changeType, ConfigurationDictionary configurationDictionary )
+    {
+        log.debug( "Receieved an {} change for {}. ", changeType,configurationDictionary);
+        if(configurationListener==null){
+            return;
+        }
+        int type;
+        if(ChangeType.DELETED.equals( changeType )){
+            type=ConfigurationEvent.CM_DELETED;
+        }else{
+            type=ConfigurationEvent.CM_UPDATED;
+        }
+
+        ConfigurationEvent event = new ConfigurationEvent(serviceReference, 
+            type, 
+            configurationDictionary.getFactoryPid(), 
+            configurationDictionary.getServicePid());
+        
+        configurationListener.configurationEvent( event );
+    }
+
+
+    public ConfigurationListener getConfigurationListener()
+    {
+        return configurationListener;
+    }
+
+
+    public void setConfigurationListener( ConfigurationListener configurationListener )
+    {
+        this.configurationListener = configurationListener;
+    }
+
+}

Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/event/MockConfigurationDaoListener.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/event/MockConfigurationDaoListener.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/event/MockConfigurationDaoListener.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/event/MockConfigurationDaoListener.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,41 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you 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.configuration.event;
+
+import org.apache.configuration.dao.ConfigurationDaoListener;
+import org.apache.configuration.impl.ConfigurationDictionary;
+
+/**
+ *  MockConfigurationDaoListener.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class MockConfigurationDaoListener implements ConfigurationDaoListener
+{
+
+    public void configurationChanged( ChangeType changeType, ConfigurationDictionary configurationDictionary )
+    {
+        // Ignore
+        
+    }
+
+}

Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/event/MockConfigurationListener.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/event/MockConfigurationListener.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/event/MockConfigurationListener.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/event/MockConfigurationListener.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,46 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you 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.configuration.event;
+
+import org.osgi.service.cm.ConfigurationEvent;
+import org.osgi.service.cm.ConfigurationListener;
+
+/**
+ * MockConfigurationListener does nothing.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class MockConfigurationListener implements ConfigurationListener
+{
+
+
+
+    /* (non-Javadoc)
+     * @see org.osgi.service.cm.ConfigurationListener#configurationEvent(org.osgi.service.cm.ConfigurationEvent)
+     */
+    public void configurationEvent( ConfigurationEvent event )
+    {
+//      ignore
+
+    }
+
+}

Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/event/MockManagedServiceFactoryTrackingDelegate.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/event/MockManagedServiceFactoryTrackingDelegate.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/event/MockManagedServiceFactoryTrackingDelegate.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/event/MockManagedServiceFactoryTrackingDelegate.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,170 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you 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.configuration.event;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.configuration.springosgi.ServiceTracking;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.ManagedServiceFactory;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+/**
+ * MockManagedServiceTrackingDelegate.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class MockManagedServiceFactoryTrackingDelegate implements ServiceTracking<ManagedServiceFactory>
+{
+
+    ServiceReference serviceReference;
+    
+    List<ServiceReference> serviceReferences;
+    
+    List<ManagedServiceFactory> services;
+    
+    ManagedServiceFactory service;
+    
+    
+    
+    
+    public ManagedServiceFactory getService( ServiceReference reference )
+    {
+        
+        return service;
+    }
+
+    public ManagedServiceFactory getService()
+    {
+        
+        return service;
+    }
+
+    public ServiceReference getServiceReference()
+    {
+        
+        return serviceReference;
+    }
+
+    public List<ServiceReference> getServiceReferences()
+    {
+        if(serviceReferences == null){
+            setServiceReferences();
+        }
+        return serviceReferences;
+    }
+
+    /**
+     * 
+     *
+     */
+    private void setServiceReferences()
+    {
+        if(serviceReference ==null){
+            throw new IllegalStateException("Set a mock serviceReference.");
+        }
+        serviceReferences = new ArrayList<ServiceReference>();
+        serviceReferences.add( serviceReference );
+    }
+    
+    private void setServices()
+    {
+        if(service ==null){
+            throw new IllegalStateException("Set a mock service.");
+        }
+        services = new ArrayList<ManagedServiceFactory>();
+        services.add( service );
+    }
+
+    public List<ManagedServiceFactory> getServices()
+    {
+        if(services == null){
+            setServices();
+        }
+        return services;
+    }
+
+    public int getTrackingCount()
+    {
+        
+        return services!=null?services.size():1;
+    }
+
+    public void remove( ServiceReference reference )
+    {
+//      ignore
+        
+    }
+
+    public void setServiceTrackerCustomizer( ServiceTrackerCustomizer serviceTrackerCustomizer )
+    {
+        // ignore
+        
+    }
+
+    public int size()
+    {
+        return services!=null?services.size():1;
+    }
+
+    public ManagedServiceFactory waitForService( long timeout ) throws InterruptedException
+    {
+       
+        return null;
+    }
+
+    /**
+     * @param service the service to set
+     */
+    public void setService( ManagedServiceFactory service )
+    {
+        this.service = service;
+    }
+
+    /**
+     * @param serviceReference the serviceReference to set
+     */
+    public void setServiceReference( ServiceReference serviceReference )
+    {
+        this.serviceReference = serviceReference;
+    }
+
+    /**
+     * @param serviceReferences the serviceReferences to set
+     */
+    public void setServiceReferences( List<ServiceReference> serviceReferences )
+    {
+        this.serviceReferences = serviceReferences;
+    }
+
+    /**
+     * @param services the services to set
+     */
+    public void setServices( List<ManagedServiceFactory> services )
+    {
+        this.services = services;
+    }
+
+
+
+}

Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/event/MockManagedServiceTrackingDelegate.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/event/MockManagedServiceTrackingDelegate.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/event/MockManagedServiceTrackingDelegate.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/event/MockManagedServiceTrackingDelegate.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,170 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you 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.configuration.event;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.configuration.springosgi.ServiceTracking;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.ManagedService;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+/**
+ * MockManagedServiceTrackingDelegate.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class MockManagedServiceTrackingDelegate implements ServiceTracking<ManagedService>
+{
+    
+    ServiceReference serviceReference;
+    
+    List<ServiceReference> serviceReferences;
+    
+    List<ManagedService> services;
+    
+    ManagedService service;
+    
+
+    public ManagedService getService( ServiceReference reference )
+    {
+        
+        return service;
+    }
+
+    public ManagedService getService()
+    {
+        
+        return service;
+    }
+
+    public ServiceReference getServiceReference()
+    {
+       
+        return serviceReference;
+    }
+
+    public List<ServiceReference> getServiceReferences()
+    {
+        if(serviceReferences == null){
+            setServiceReferences();
+        }
+        return serviceReferences;
+    }
+    
+
+    public List<ManagedService> getServices()
+    {
+        if(services == null){
+            setServices();
+        }
+        return services;
+    }
+
+
+    public int getTrackingCount()
+    {
+        
+        return services!=null?services.size():1;
+    }
+
+    public void remove( ServiceReference reference )
+    {
+        
+    }
+
+    public void setServiceTrackerCustomizer( ServiceTrackerCustomizer serviceTrackerCustomizer )
+    {
+       
+        
+    }
+
+    public int size()
+    {
+        
+        return services!=null?services.size():1;
+    }
+
+    public ManagedService waitForService( long timeout ) throws InterruptedException
+    {
+        
+        return service;
+    }
+
+    /**
+     * 
+     *
+     */
+    private void setServiceReferences()
+    {
+        if(serviceReference ==null){
+            throw new IllegalStateException("Set a mock serviceReference.");
+        }
+        serviceReferences = new ArrayList<ServiceReference>();
+        serviceReferences.add( serviceReference );
+    }
+    
+    private void setServices()
+    {
+        if(service ==null){
+            throw new IllegalStateException("Set a mock service.");
+        }
+        services = new ArrayList<ManagedService>();
+        services.add( service );
+    }
+    
+    /**
+     * @param service the service to set
+     */
+    public void setService( ManagedService service )
+    {
+        this.service = service;
+    }
+
+    /**
+     * @param serviceReference the serviceReference to set
+     */
+    public void setServiceReference( ServiceReference serviceReference )
+    {
+        this.serviceReference = serviceReference;
+    }
+
+    /**
+     * @param serviceReferences the serviceReferences to set
+     */
+    public void setServiceReferences( List<ServiceReference> serviceReferences )
+    {
+        this.serviceReferences = serviceReferences;
+    }
+
+    /**
+     * @param services the services to set
+     */
+    public void setServices( List<ManagedService> services )
+    {
+        this.services = services;
+    }
+
+
+
+}