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 [4/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/main/java/org/apache/configuration/impl/ConfigurationStore.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/impl/ConfigurationStore.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/impl/ConfigurationStore.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/impl/ConfigurationStore.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,128 @@
+/*
+ *   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.configuration.impl;
+
+import java.io.IOException;
+import java.util.Set;
+
+import org.apache.configuration.dao.ConfigurationDaoListener;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationException;
+
+/**
+ * 
+ * A <tt>ConfigurationStore</tt> is the primary interface to the backend store 
+ * implementations.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public interface ConfigurationStore
+{
+    public abstract Set<String> listPids();
+
+    public abstract Configuration[] listConfigurations( String filter ) throws IOException, InvalidSyntaxException;
+
+    public abstract Configuration getNewConfiguration( String bundleLocation, String factoryPid, String servicePid );
+
+    public abstract Configuration getNewConfiguration( String bundleLocation, String factoryPid, String servicePid,
+            ConfigurationDictionary properties );
+
+    
+    /**
+     * 
+     * Retrieves a ConfigurationDictionary from the store.
+     *
+     * @param pid
+     * @return configurationDictionary from the store or null.
+     * @throws IOException
+     */
+    public abstract ConfigurationDictionary retrieve( String pid ) throws IOException;
+
+    public abstract ConfigurationDictionary[] retrieveAll( String factoryPid ) throws IOException;
+    
+    /**
+     * 
+     * Update the configuration in the backend. This must trigger an event from 
+     * the backend that asynchronously notifies the {@link ManagedService} or 
+     * {@link ManagedServiceFactory}.
+     * <p>
+     * Invocation originated in ConfigurationAdmin client call to the 
+     * Configuration.update() or Configuration.update(...) methods.
+     *
+     * @param configuration
+     * @throws IOException
+     */
+    public abstract void update( ConfigurationDictionary configuration ) throws IOException;
+    
+    /**
+     * 
+     * Removes the configuration object from the persistent store based on the 
+     * pid. Notify asynchronously the corresponding Managed Service or Managed Service
+     * Factory. A <code>ManagedService</code> object is notified by a call to
+     * its <code>updated</code> method with a <code>null</code> properties
+     * argument. A <code>ManagedServiceFactory</code> object is notified by a
+     * call to its <code>deleted</code> method.
+     * 
+     * <p>
+     * Also intiates an asynchronous call to all
+     * <code>ConfigurationListener</code>s with a
+     * <code>ConfigurationEvent.CM_DELETED</code> event.
+     * 
+     * <p>
+     * Invocation originated in ConfigurationAdmin client call to the 
+     * Configuration.delete() method.
+     * 
+     * @param pid
+     * 
+     * @throws IOException If delete fails
+     */
+    public abstract void delete( String pid ) throws IOException;
+
+    public abstract void deleteAll( String factoryPid ) throws IOException;
+
+    public abstract String generatePid( String factoryPid ) throws IOException;
+    
+    /**
+     * 
+     * Unbind a dynamic bundleLocation from a stored ConfigurationDictionary
+     * specified by the servicePid.
+     *
+     * @param servicePid
+     */
+    public void unbind(String servicePid);
+    
+    /**
+     * 
+     * Get bundle from the store and bind it to that location.
+     *
+     * @param servicePid
+     * @param bundleLocation
+     * @return
+     * @throws ConfigurationException
+     */
+    public ConfigurationDictionary retrieveAndBind( String servicePid, String bundleLocation ) 
+          throws ConfigurationException;
+
+    
+    public abstract Set<String> listPids(String factoryPid);
+    
+    public abstract void setConfigurationDaoListener( ConfigurationDaoListener configurationListener );
+    
+}

Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/impl/ConfigurationStoreImpl.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/impl/ConfigurationStoreImpl.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/impl/ConfigurationStoreImpl.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/impl/ConfigurationStoreImpl.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,470 @@
+/*
+ *   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.impl;
+
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.configuration.dao.ConfigurationDao;
+import org.apache.configuration.dao.ConfigurationDaoException;
+import org.apache.configuration.dao.ConfigurationDaoListener;
+import org.apache.configuration.felix.framework.FilterImpl;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.cm.ConfigurationException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * ConfigurationStoreImpl is a DaoConfiguration backed ConfigurationStore that caches
+ * configuration in a concurrent list for mult-thread access.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class ConfigurationStoreImpl implements ConfigurationStore, ConfigurationDaoListener
+{
+
+    private final Logger log = LoggerFactory.getLogger( ConfigurationStoreImpl.class );
+    private final ConfigurationDao configurationDao;
+
+    private ConfigurationDaoListener delegatedConfigurationDaoListener;
+
+    private ConcurrentMap<String, ConfigurationDictionary> pidConfigsMap = 
+        new ConcurrentHashMap<String, ConfigurationDictionary>();
+
+
+    /**
+     * Creates a new instance of ConfigurationStoreImpl.
+     *
+     */
+    public ConfigurationStoreImpl( ConfigurationDao configurationDao )
+    {
+        this.configurationDao = configurationDao;
+
+    }
+
+
+    /**
+     * init the component.
+     *
+     * @param configurationDao
+     */
+    public void init()
+    {
+        loadCache();
+        configurationDao.setConfigurationListener( this );
+    }
+
+
+    private final void loadCache()
+    {
+        List<ConfigurationDictionary> configuarationDictionaries = configurationDao.findAll();
+        if ( configuarationDictionaries == null || configuarationDictionaries.isEmpty() )
+        {
+            return;
+        }
+        else
+        {
+            for ( ConfigurationDictionary dictionary : configuarationDictionaries )
+            {
+                pidConfigsMap.put( dictionary.getServicePid(), dictionary );
+            }
+
+        }
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.configuration.ConfigurationStore#delete(java.lang.String)
+     */
+    public void delete( String pid ) throws IOException
+    {
+        if ( pid == null )
+        {
+            throw new IllegalArgumentException( "pid argument cannot be null." );
+        }
+        ConfigurationDictionary configurationDictionary = null;
+        try
+        {
+            configurationDictionary = configurationDao.read( pid );
+        }
+        catch ( ConfigurationDaoException e )
+        {
+            throw new IOException( e.getMessage() );
+        }
+        configurationDao.delete( configurationDictionary );
+
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.configuration.ConfigurationStore#listPids()
+     */
+    public Set<String> listPids()
+    {
+        return new HashSet<String>( pidConfigsMap.keySet() );
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.configuration.ConfigurationStore#load(java.lang.String)
+     */
+    public ConfigurationDictionary retrieve( String pid ) throws IOException
+    {
+        return pidConfigsMap.get( pid );
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.configuration.ConfigurationStore#loadAll(java.lang.String)
+     */
+    public ConfigurationDictionary[] retrieveAll( String factoryPid ) throws IOException
+    {
+
+        if ( factoryPid == null )
+        {
+            throw new IllegalArgumentException( "factoryPid argument cannot be null." );
+        }
+        List<ConfigurationDictionary> results = listAllFactoryConfigurations( factoryPid );
+        ConfigurationDictionary[] dictionaries = new ConfigurationDictionary[results.size()];
+        ConfigurationDictionary[] returned = results.toArray( dictionaries );
+        return returned;
+    }
+
+
+    /**
+     * listAllFactoryConfigurations.
+     *
+     * @param factoryPid
+     * @return
+     */
+    private List<ConfigurationDictionary> listAllFactoryConfigurations( String factoryPid )
+    {
+        List<ConfigurationDictionary> results = new ArrayList<ConfigurationDictionary>();
+        for ( ConfigurationDictionary dictionary : pidConfigsMap.values() )
+        {
+            if ( factoryPid.equals( dictionary.getFactoryPid() ) )
+            {
+                results.add( dictionary );
+            }
+        }
+        return results;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.configuration.ConfigurationStore#deleteAll(java.lang.String)
+     */
+    public void deleteAll( String factoryPid ) throws IOException
+    {
+        List<ConfigurationDictionary> factoryConfigs = listAllFactoryConfigurations( factoryPid );
+        for ( ConfigurationDictionary configurationDictionary : factoryConfigs )
+        {
+            configurationDao.delete( configurationDictionary );
+        }
+
+    }
+
+
+    /**
+     * 
+     * Generate a servicePid for a given factory.
+     *
+     * @param factoryPid of the factory.
+     * @return generated servicePid.
+     * @throws IOException
+     */
+    public String generatePid( String factoryPid ) throws IOException
+    {
+
+        return new StringBuffer().append( factoryPid ).append( '.' )
+            .append( Long.toString( System.currentTimeMillis() ) ).toString();
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.configuration.ConfigurationStore#getNewConfiguration(java.lang.String, java.lang.String, java.lang.String)
+     */
+    public Configuration getNewConfiguration( String bundleLocation, 
+         String factoryPid, String servicePid )
+    {
+        log.debug( "Creating Configuration with bundleLocation={} factoryPid={} servicePid={}", new Object[]
+            { bundleLocation, factoryPid, servicePid } );
+        ConfigurationImpl config = new ConfigurationImpl( this, factoryPid, servicePid );
+        config.setBundleLocation( bundleLocation );
+        return config;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.configuration.ConfigurationStore#getNewConfiguration(java.lang.String, java.lang.String, java.lang.String, org.apache.configuration.ConfigurationDictionary)
+     */
+    public Configuration getNewConfiguration( String bundleLocation, String factoryPid, String servicePid,
+        ConfigurationDictionary properties )
+    {
+        log.debug( "Creating Configuration with bundleLocation={} factoryPid={} servicePid={} properties={}",
+            new Object[]
+                { bundleLocation, factoryPid, servicePid, properties } );
+
+        ConfigurationImpl config = new ConfigurationImpl( this, factoryPid, servicePid, properties );
+        config.setBundleLocation( bundleLocation );
+        return config;
+    }
+
+
+    /**
+     * 
+     * List Configurations using a filter string.
+     * 
+     * Delegate for ConfigurationAdmin.
+     *
+     * @param filterString
+     * @return
+     * @throws IOException
+     * @throws InvalidSyntaxException
+     */
+    public Configuration[] listConfigurations( String filterString ) throws IOException, InvalidSyntaxException
+    {
+        List<Configuration> results = new ArrayList<Configuration>();
+        Filter filter = null;
+        if ( filterString != null )
+        {
+            filter = new FilterImpl( filterString );
+        }
+        for ( String pid : pidConfigsMap.keySet() )
+        {
+            ConfigurationDictionary config = retrieve( pid );
+
+            if ( config != null )
+            {
+                if ( filter == null )
+                {
+                    results.add( new ConfigurationImpl( this, config ) );
+
+                }else{
+                    if ( filter.match( config ) )
+                    {
+                        results.add( new ConfigurationImpl( this, config ) );
+
+                    }
+                }
+                
+            }
+        }
+
+        return ( Configuration[] ) results.toArray( new Configuration[results.size()] );
+    }
+
+
+    /**
+     * 
+     * set the ConfigurationListener delegate.
+     *
+     * @param configurationListener
+     */
+    public void setConfigurationDaoListener( ConfigurationDaoListener configurationListener )
+    {
+        delegatedConfigurationDaoListener = configurationListener;
+
+    }
+
+
+    /**
+     * 
+     * Update the backend store.
+     *
+     * @param configurationDictionary
+     * @throws IOException
+     */
+    public void update( ConfigurationDictionary configurationDictionary ) throws IOException
+    {
+        configurationDao.update( configurationDictionary );
+
+    }
+
+
+    /**
+     * 
+     * Change occured on the persisted store update the cache and send the event to the 
+     * client for dispatch to the outside world.
+     * 
+     * Once loaded the cache will be kept in sync with this method.
+     *
+     * @param changeType
+     * @param configurationDictionary
+     */
+    public void configurationChanged( ChangeType changeType, ConfigurationDictionary configurationDictionary )
+    {
+
+        if ( ChangeType.CREATED.equals( changeType ) )
+        {
+            addToCache( configurationDictionary );
+        }
+        else if ( ChangeType.DELETED.equals( changeType ) )
+        {
+            removeFromCache( configurationDictionary );
+        }
+        else
+        {
+            updateInCache( configurationDictionary );
+        }
+        if ( delegatedConfigurationDaoListener != null )
+        {
+            delegatedConfigurationDaoListener.configurationChanged( changeType, configurationDictionary );
+        }
+    }
+
+
+    private void addToCache( ConfigurationDictionary configurationDictionary )
+    {
+        log.debug( "Add to the cache {}.", configurationDictionary );
+        pidConfigsMap.put( configurationDictionary.getServicePid(), configurationDictionary );
+
+    }
+
+
+    private void removeFromCache( ConfigurationDictionary configurationDictionary )
+    {
+
+        log.debug( "Remove from to the cache {}.", configurationDictionary );
+        pidConfigsMap.remove( configurationDictionary.getServicePid() );
+    }
+
+
+    private void updateInCache( ConfigurationDictionary configurationDictionary )
+    {
+        log.debug( "Update to the cache {}.", configurationDictionary );
+        pidConfigsMap.put( configurationDictionary.getServicePid(), configurationDictionary );
+    }
+
+
+    public Set<String> listPids( String factoryPid )
+    {
+        Set<String> results = new HashSet<String>();
+
+        Set<Entry<String, ConfigurationDictionary>> ls = pidConfigsMap.entrySet();
+        for ( Entry<String, ConfigurationDictionary> entry : ls )
+        {
+            if ( factoryPid.equals( entry.getValue().getFactoryPid() ) )
+            {
+                results.add( entry.getKey() );
+            }
+        }
+        return results;
+    }
+
+    /**
+     * 
+     * Retrieves and binds the configuration to the bundleLocation. 
+     *
+     * @param servicePid
+     * @param bundleLocation
+     * @return a bound ConfigurationDictionary
+     * @throws ConfigurationException if a problem with the retrieve or if a bind collision occured.
+     */
+    public ConfigurationDictionary retrieveAndBind( String servicePid, String bundleLocation )
+        throws ConfigurationException
+    {
+        ConfigurationDictionary configurationDictionary;
+        try
+        {
+            configurationDictionary = retrieve( servicePid );
+        }
+        catch ( IOException e )
+        {
+            throw new ConfigurationException( servicePid, "Failed to bind to bundleLocation, because: "
+                + e.getMessage() );
+
+        }
+        if ( configurationDictionary == null )
+        {
+            return configurationDictionary;
+        }
+        
+        if (configurationDictionary.getBundleLocation() == null){
+            configurationDictionary.setBundleLocation( bundleLocation );
+            return configurationDictionary;
+        }else{
+            if (configurationDictionary.getBundleLocation().equals( bundleLocation ) ){
+                return configurationDictionary;
+            }
+        }
+        
+            throw new ConfigurationException( ConfigurationAdmin.SERVICE_BUNDLELOCATION,
+                "Bundle at bundleLocation=" + bundleLocation + " is requesting configuration for servicePid="
+                    + servicePid + " that is already bound to bundleLocation=" + configurationDictionary.getBundleLocation() );    
+        
+       
+    }
+
+
+    public void unbind( String servicePid )
+    {
+        ConfigurationDictionary configurationDictionary;
+        try
+        {
+            configurationDictionary = retrieve( servicePid );
+        }
+        catch ( IOException e )
+        {
+            log.error( "Failed to unbind servicePid=" + servicePid, e );
+            return;
+        }
+
+        
+
+        if ( !configurationDictionary.isStaticBound() )
+        {
+            configurationDictionary.setBundleLocation( null );
+        }
+
+    }
+
+
+    /**
+     * @return the delegatedConfigurationDaoListener
+     */
+    public ConfigurationDaoListener getDelegatedConfigurationDaoListener()
+    {
+        return delegatedConfigurationDaoListener;
+    }
+
+
+    /**
+     * @param delegatedConfigurationDaoListener the delegatedConfigurationDaoListener to set
+     */
+    public void setDelegatedConfigurationDaoListener( ConfigurationDaoListener delegatedConfigurationDaoListener )
+    {
+        this.delegatedConfigurationDaoListener = delegatedConfigurationDaoListener;
+    }
+
+}

Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/impl/ConfigurationTransformer.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/impl/ConfigurationTransformer.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/impl/ConfigurationTransformer.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/impl/ConfigurationTransformer.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,38 @@
+/*
+ *   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.impl;
+
+import java.util.Dictionary;
+
+import org.osgi.framework.ServiceReference;
+
+/**
+ * A <tt>ConfigurationTransformer</tt> transforms a {@link ConfigurationDictionary}
+ * to a Dictionary.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public interface ConfigurationTransformer
+{
+
+    Dictionary transform(ServiceReference serviceReference, ConfigurationDictionary dictionary);
+}

Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/impl/package-info.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/impl/package-info.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/impl/package-info.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/impl/package-info.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,7 @@
+/**
+ * org.apache.configuration is the set of primary implemenations for the 
+ * ConfigurationAdmin service.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+package org.apache.configuration.impl;
\ No newline at end of file

Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/springosgi/BundleContextFactory.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/springosgi/BundleContextFactory.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/springosgi/BundleContextFactory.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/springosgi/BundleContextFactory.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,54 @@
+/*
+ *   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.springosgi;
+
+import org.osgi.framework.BundleContext;
+import org.springframework.osgi.context.BundleContextAware;
+
+/**
+ * A <tt>BundleContextFactory</tt> is a simple instance factory method for 
+ * retrieving a bundleContext within a Spring-OSGi production or testing context.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ * 
+ */
+public class BundleContextFactory implements BundleContextAware
+{
+    
+    private BundleContext bundleContext;
+    
+
+    public void setBundleContext( BundleContext bundleContext )
+    {
+        this.bundleContext=bundleContext;
+        
+    }
+
+    /**
+     * @return the bundleContext
+     */
+    public BundleContext getBundleContext()
+    {
+        return bundleContext;
+    }
+
+}

Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/springosgi/ServiceTracking.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/springosgi/ServiceTracking.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/springosgi/ServiceTracking.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/springosgi/ServiceTracking.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,166 @@
+/*
+ *   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.springosgi;
+
+import java.util.List;
+
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+/**
+ * A <tt>ServiceTracking</tt> is a generic interface for managing OSGi service
+ * dependencies based on type.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public interface ServiceTracking <T>
+{
+   
+    public void setServiceTrackerCustomizer(ServiceTrackerCustomizer serviceTrackerCustomizer);
+    
+    /**
+     * Wait for at least one service to be tracked by this
+     * <code>ServiceTracker</code> object.
+     * <p>
+     * It is strongly recommended that <code>waitForService</code> is not used
+     * during the calling of the <code>BundleActivator</code> methods.
+     * <code>BundleActivator</code> methods are expected to complete in a
+     * short period of time.
+     * 
+     * @param timeout time interval in milliseconds to wait. If zero, the method
+     *        will wait indefinately.
+     * @return Returns the result of <code>getService()</code>.
+     * @throws InterruptedException If another thread has interrupted the
+     *         current thread.
+     * @throws IllegalArgumentException If the value of timeout is negative.
+     */
+    public T waitForService(long timeout) throws InterruptedException ;
+
+    /**
+     * Return an array of <code>ServiceReference</code> objects for all
+     * serviceReferences being tracked by this <code>ServiceTracker</code> object.
+     * 
+     * @return Array of <code>ServiceReference</code> objects or
+     *         <code>null</code> if no service are being tracked.
+     */
+    public List<ServiceReference> getServiceReferences() ;
+
+    /**
+     * Returns a <code>ServiceReference</code> object for one of the serviceReferences
+     * being tracked by this <code>ServiceTracker</code> object.
+     * 
+     * <p>
+     * If multiple serviceReferences are being tracked, the service with the highest
+     * ranking (as specified in its <code>service.ranking</code> property) is
+     * returned.
+     * 
+     * <p>
+     * If there is a tie in ranking, the service with the lowest service ID (as
+     * specified in its <code>service.id</code> property); that is, the
+     * service that was registered first is returned.
+     * <p>
+     * This is the same algorithm used by
+     * <code>BundleContext.getServiceReference</code>.
+     * 
+     * @return <code>ServiceReference</code> object or <code>null</code> if
+     *         no service is being tracked.
+     * @since 1.1
+     */
+    public ServiceReference getServiceReference() ;
+
+    /**
+     * Returns the service object for the specified
+     * <code>ServiceReference</code> object if the referenced service is being
+     * tracked by this <code>ServiceTracker</code> object.
+     * 
+     * @param reference Reference to the desired service.
+     * @return Service object or <code>null</code> if the service referenced
+     *         by the specified <code>ServiceReference</code> object is not
+     *         being tracked.
+     */
+    public T getService(ServiceReference reference) ;
+
+    /**
+     * Return an array of service objects for all serviceReferences being tracked by this
+     * <code>ServiceTracker</code> object.
+     * 
+     * @return Array of service objects or <code>null</code> if no service are
+     *         being tracked.
+     */
+    public List<T> getServices() ;
+
+    /**
+     * Returns a service object for one of the serviceReferences being tracked by this
+     * <code>ServiceTracker</code> object.
+     * 
+     * <p>
+     * If any serviceReferences are being tracked, this method returns the result of
+     * calling <code>getService(getServiceReference())</code>.
+     * 
+     * @return Service object or <code>null</code> if no service is being
+     *         tracked.
+     */
+    public T getService() ;
+
+    /**
+     * Remove a service from this <code>ServiceTracker</code> object.
+     * 
+     * The specified service will be removed from this
+     * <code>ServiceTracker</code> object. If the specified service was being
+     * tracked then the <code>ServiceTrackerCustomizer.removedService</code>
+     * method will be called for that service.
+     * 
+     * @param reference Reference to the service to be removed.
+     */
+    public void remove(ServiceReference reference) ;
+
+    /**
+     * Return the number of serviceReferences being tracked by this
+     * <code>ServiceTracker</code> object.
+     * 
+     * @return Number of serviceReferences being tracked.
+     */
+    public int size() ;
+
+    /**
+     * Returns the tracking count for this <code>ServiceTracker</code> object.
+     * 
+     * The tracking count is initialized to 0 when this
+     * <code>ServiceTracker</code> object is opened. Every time a service is
+     * added or removed from this <code>ServiceTracker</code> object the
+     * tracking count is incremented.
+     * 
+     * <p>
+     * The tracking count can be used to determine if this
+     * <code>ServiceTracker</code> object has added or removed a service by
+     * comparing a tracking count value previously collected with the current
+     * tracking count value. If the value has not changed, then no service has
+     * been added or removed from this <code>ServiceTracker</code> object
+     * since the previous tracking count was collected.
+     * 
+     * @since 1.2
+     * @return The tracking count for this <code>ServiceTracker</code> object
+     *         or -1 if this <code>ServiceTracker</code> object is not open.
+     */
+    public int getTrackingCount() ;
+
+}

Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/springosgi/ServiceTrackingAdapter.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/springosgi/ServiceTrackingAdapter.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/springosgi/ServiceTrackingAdapter.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/springosgi/ServiceTrackingAdapter.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,226 @@
+/*
+ *   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.springosgi;
+
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+import org.springframework.osgi.context.BundleContextAware;
+
+
+/**
+ * <p>A <tt>ServiceTrackingAdapter</tt> is a generic wrapper around an
+ * OSGi ServiceTracker or a testing delegate.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class ServiceTrackingAdapter<T> implements ServiceTracking<T>, BundleContextAware
+{
+
+    private final Class<T> type;
+    private ServiceTrackerCustomizer serviceTrackerCustomizer ;
+    private BundleContext bundleContext;
+    private ServiceTracker serviceTracker;
+    private ServiceTracking<T> delegate;
+    
+    
+    /**
+     * Creates a new instance of ServiceTrackingAdapter.
+     *
+     * @param type
+     * @param serviceTracker
+     */
+    public ServiceTrackingAdapter(Class<T> type)
+    {
+        super();
+        this.type = type;
+    }
+
+   
+
+   
+    /**
+     * Creates a new instance of ServiceTrackingAdapter.
+     *
+     * @param type
+     * @param serviceTracker
+     * @deprecated
+     */
+    public ServiceTrackingAdapter( Class<T> type, ServiceTracking<T> delegate )
+    {
+        this(type, null, delegate);
+    }
+    
+    /**
+     * Creates a new instance of ServiceTrackingAdapter.
+     *
+     * @param type
+     * @param serviceTracker
+     * @deprecated
+     */
+    public ServiceTrackingAdapter( Class<T> type, ServiceTrackerCustomizer serviceTrackerCustomizer )
+    {
+        this(type, serviceTrackerCustomizer, null);
+    }
+    
+    /**
+     * Creates a new instance of ServiceTrackingAdapter.
+     *
+     * @param type
+     * @param serviceTracker
+     * @deprecated
+     */
+    public ServiceTrackingAdapter( Class<T> type, ServiceTrackerCustomizer serviceTrackerCustomizer, ServiceTracking<T> delegate )
+    {
+        super();
+        this.type = type;
+        this.serviceTrackerCustomizer =serviceTrackerCustomizer ;
+        this.delegate=delegate;
+    }
+
+    private boolean isDelegated(){
+        return delegate!=null;
+    }
+    public void init(){
+        if(isDelegated()){
+            delegate.setServiceTrackerCustomizer( serviceTrackerCustomizer );
+        }else{
+            serviceTracker = new ServiceTracker(bundleContext, type.getName(), serviceTrackerCustomizer  );
+            serviceTracker.open();
+        }
+    }
+    
+    public void destroy(){
+        if(isDelegated()){
+            //do nothing.
+        }else{
+            serviceTracker.close();
+        }
+        
+    }
+    
+
+    public void setServiceTrackerCustomizer(ServiceTrackerCustomizer serviceTrackerCustomizer){
+        this.serviceTrackerCustomizer=serviceTrackerCustomizer;
+    }
+
+    @SuppressWarnings("unchecked")
+    public T getService( ServiceReference reference )
+    {
+
+        return isDelegated()?delegate.getService(reference):(T) serviceTracker.getService( reference );
+    }
+
+
+    @SuppressWarnings("unchecked")
+    public T getService()
+    {
+        return isDelegated()?delegate.getService():(T)serviceTracker.getService();
+    }
+
+
+    public ServiceReference getServiceReference()
+    {
+
+        return isDelegated()?delegate.getServiceReference():serviceTracker.getServiceReference();
+    }
+
+
+    public List<ServiceReference> getServiceReferences()
+    {
+
+        return isDelegated()?delegate.getServiceReferences():Arrays.asList( serviceTracker.getServiceReferences() );
+    }
+
+
+    @SuppressWarnings("unchecked")
+    public List<T> getServices()
+    {      
+        return  isDelegated()?delegate.getServices(): Arrays.asList( (T[]) serviceTracker.getServices() ) ;
+    }
+
+
+    public int getTrackingCount()
+    {
+
+        return isDelegated()?delegate.getTrackingCount():serviceTracker.getTrackingCount();
+    }
+
+
+    public void remove( ServiceReference reference )
+    {
+        if(isDelegated()){
+            delegate.remove( reference );
+        }else{
+            serviceTracker.remove( reference );
+        }
+
+    }
+
+    public int size()
+    {
+        return isDelegated()?delegate.size():serviceTracker.size();
+    }
+
+
+    @SuppressWarnings("unchecked")
+    public T waitForService( long timeout ) throws InterruptedException
+    {
+
+        return isDelegated()?delegate.waitForService( timeout ):(T) serviceTracker.waitForService( timeout );
+    }
+
+
+    public void setBundleContext( BundleContext bundleContext )
+    {
+        this.bundleContext=bundleContext;
+        
+    }
+
+
+
+
+    /**
+     * @return the serviceTrackerCustomizer
+     */
+    ServiceTrackerCustomizer getServiceTrackerCustomizer()
+    {
+        return serviceTrackerCustomizer;
+    }
+
+
+
+
+    /**
+     * @param delegate the delegate to set
+     */
+    public void setDelegate( ServiceTracking<T> delegate )
+    {
+        this.delegate = delegate;
+    }
+
+}

Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/springosgi/package-info.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/springosgi/package-info.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/springosgi/package-info.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/springosgi/package-info.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,11 @@
+/**
+ * <p>org.apache.configuration.springosgi is the set of interfaces and classes that specify a
+ * a framework for referencing OSGi services through a Spring-OSGi container.
+ * </p>
+ * <p><em>Note:</em>This package is an interium solution for working with the SNAPSHOT
+ * versions of Spring-OSGi and will be replaced or removed as Spring-OSGi listener 
+ * support stablizes. 
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+package org.apache.configuration.springosgi;
\ No newline at end of file

Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/main/resources/META-INF/spring/configuration-osgi.xml
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/main/resources/META-INF/spring/configuration-osgi.xml?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/main/resources/META-INF/spring/configuration-osgi.xml (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/main/resources/META-INF/spring/configuration-osgi.xml Mon Jan 29 12:38:25 2007
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns:osgi="http://www.springframework.org/schema/osgi"
+	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+                      http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd">
+
+    <!-- Spring-OSGi published ConfigurationAdmin ServiceFactory. -->
+    <osgi:service ref="configurationAdminServiceFactory" 
+                  interface="org.osgi.service.cm.ConfigurationAdmin"/>
+                  
+    <!-- Spring-OSGi reference to an InitialContextFactory service. 
+    Use mockInitialContextFactory.xml for mock testing. -->
+	<osgi:reference id="initialContextFactory"
+		interface="javax.naming.spi.InitialContextFactory" />
+
+    <!-- Spring-OSGi reference to a Collection of ConfigurationListener services.
+    @TODO create mock replacement for testing. -->
+    <osgi:reference id="configListeners"
+                    interface="org.osgi.service.cm.ConfigurationListener" 
+                    cardinality="0..n"/>
+    
+    <!-- Internal infrastructure that implement Spring-OSGi BundleContextAware-->
+	<bean id="configurationTransformer"
+		class="org.apache.configuration.event.PluginManager"
+		init-method="init" destroy-method="destroy" />
+
+	<!-- Internal infrastructure that does not use Spring-OSGi-->
+    
+	<bean id="bundleContextFactory" class="org.apache.configuration.springosgi.BundleContextFactory"/>
+	
+	<!-- managedServiceTrackerCustomizer is in the event.xml file -->
+	<bean id="managedServiceTrackingAdapter" 
+         class="org.apache.configuration.event.ManagedServiceTrackingAdapter" 
+	   init-method="init" destroy-method="destroy">
+       <property name="serviceTrackerCustomizer" ref="managedServiceTrackerCustomizer"/>   
+   </bean>
+   
+   <!-- managedServiceFactoryTrackerCustomizer is in the event.xml file -->
+  <bean id="managedServiceFactoryTrackingAdapter" 
+         class="org.apache.configuration.event.ManagedServiceFactoryTrackingAdapter" 
+	   init-method="init" destroy-method="destroy">
+	   <property name="serviceTrackerCustomizer" ref="managedServiceFactoryTrackerCustomizer"/> 
+      
+   </bean>
+
+</beans>
\ No newline at end of file

Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/main/resources/META-INF/spring/configuration.xml
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/main/resources/META-INF/spring/configuration.xml?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/main/resources/META-INF/spring/configuration.xml (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/main/resources/META-INF/spring/configuration.xml Mon Jan 29 12:38:25 2007
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans 
+    xmlns="http://www.springframework.org/schema/beans"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
+
+   
+   <!-- ConfigurationStore references a configurationDao in daoJndi.xml config file and 
+   a configurationDaoEventListener in the mockInitialContexFactory.xml or in the configuration-osgi.xml -->
+   
+   <bean id="configurationStore" class="org.apache.configuration.impl.ConfigurationStoreImpl" init-method="init">
+       <constructor-arg ref="configurationDao" />
+       <property name="configurationDaoListener" ref="configurationDaoEventListener"/>
+    </bean>
+   
+   
+   <!-- Event handling executor that is used for asynchronous task processing. -->
+   <bean id="asyncExecutorService" class="org.apache.configuration.event.AsyncExecutorService" destroy-method="destroy"/>
+  
+   		
+   
+   <bean id="configurationAdminServiceFactory" class="org.apache.configuration.impl.ConfigurationAdminServiceFactory" >
+   		<property name="configurationStore" ref="configurationStore"/>
+   </bean>
+   
+   
+   
+   
+   
+  
+   
+   
+   
+   
+   
+   
+</beans>
+

Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/main/resources/META-INF/spring/daoJndi.xml
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/main/resources/META-INF/spring/daoJndi.xml?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/main/resources/META-INF/spring/daoJndi.xml (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/main/resources/META-INF/spring/daoJndi.xml Mon Jan 29 12:38:25 2007
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
+
+    <!-- References an initialContextFactory in the mockInitialCOntextFactory.xml or in the configuration-osgi.xml -->
+	<bean id="dirCommandProcessor"
+		class="org.apache.configuration.dao.jndi.impl.CommandProcessor">
+		<constructor-arg ref="initialContextFactory" />
+	</bean>
+	
+	<bean id="keyMapping"
+		class="org.apache.configuration.dao.jndi.impl.KeyMapper"/>
+
+	<bean id="contextMapper"
+		class="org.apache.configuration.dao.jndi.impl.ContextMapper">
+		<property name="keyMapping" ref="keyMapping"/>
+	</bean>
+	
+     <bean id="nameMapping"
+				class="org.apache.configuration.dao.jndi.impl.DefaultNameMapper">
+				<property name="searchBase"
+					value="ou=configuration,ou=system" />
+				<property name="defaultNamingBase"
+					value="ou=configuration,ou=system" />
+	</bean>
+
+    <bean id="jndiConfigurationDaoNotifier"
+		class="org.apache.configuration.dao.jndi.impl.JndiConfigurationDaoNotifierImpl">
+		<constructor-arg ref="contextMapper" />
+		<constructor-arg ref="nameMapping" />
+		<constructor-arg ref="initialContextFactory" />
+	</bean>
+	
+    
+	<bean id="configurationDaoNotifier"
+		class="org.apache.configuration.dao.jndi.impl.ConfigurationDaoNotifierImpl">
+		<property name="nameMapping" ref="nameMapping"/>
+		<property name="jndiConfigurationDaoNotifier" ref="jndiConfigurationDaoNotifier"/>
+		<property name="initialContextFactory" ref="initialContextFactory"/>
+	</bean>
+	
+	<bean id="configurationDao"
+		class="org.apache.configuration.dao.jndi.impl.ConfigurationDaoImpl">
+		<property name="dirCommandProcessor" ref="dirCommandProcessor" />
+		<property name="nameMapping" ref="nameMapping"/>
+		<property name="contextMapping" ref="contextMapper" />
+		<property name="configurationDaoEventGenerator" ref="configurationDaoNotifier"/>
+
+	</bean>
+
+</beans>
+

Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/main/resources/META-INF/spring/event.xml
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/main/resources/META-INF/spring/event.xml?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/main/resources/META-INF/spring/event.xml (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/main/resources/META-INF/spring/event.xml Mon Jan 29 12:38:25 2007
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns:osgi="http://www.springframework.org/schema/osgi"
+	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+                      http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd">
+
+	
+	<!-- Broadcasts events to all ConfigurationListeners.  
+	References the osgi reference proxy-->
+	<bean id="configurationListener" 
+	       class="org.apache.configuration.event.ConfigurationEventBroadcaster" >
+	      <property name="listeners" ref="configListeners" />
+	</bean>
+	
+	<!-- requires the configuration.xml  -->
+	<bean id="managedServiceTrackerCustomizer" 
+	  class="org.apache.configuration.event.ManagedServiceTrackerCustomizer">
+	  <property name="executor">
+		   <bean factory-bean="asyncExecutorService" factory-method="getExecutor" />
+		</property>
+		<property name="configurationStore" ref="configurationStore" />
+		<property name="configurationTransformer" ref="configurationTransformer" />
+		<!--  
+		<property name="bundleContext">
+		   <bean factory-bean="bundleContextFactory" factory-method="getBundleContext" />
+		</property>
+		-->
+		<property name="managedServiceTrackingAdapter" 
+		          ref="managedServiceTrackingAdapter" />
+	</bean>
+	
+	<bean id="managedServiceFactoryTrackerCustomizer" 
+	   class="org.apache.configuration.event.ManagedServiceFactoryTrackerCustomizer">
+	  <property name="executor">
+		   <bean factory-bean="asyncExecutorService" factory-method="getExecutor" />
+		</property>
+		<property name="configurationStore" ref="configurationStore" />
+		<property name="configurationTransformer" ref="configurationTransformer" />
+		<!--  
+		<property name="bundleContext">
+		   <bean factory-bean="bundleContextFactory" factory-method="getBundleContext" />
+		</property>
+		-->
+		<property name="managedServiceFactoryTrackingAdapter" 
+		          ref="managedServiceFactoryTrackingAdapter" />
+	</bean>
+
+	          
+	<bean id="configurationDaoEventListener" 
+	       class="org.apache.configuration.event.ConfigurationChangeManager">
+		<property name="executor">
+		   <bean factory-bean="asyncExecutorService" factory-method="getExecutor" />
+		</property>
+		<property name="configurationStore" ref="configurationStore" />
+		<property name="configurationTransformer" ref="configurationTransformer" />
+		<property name="managedServiceFactoryTrackingAdapter" ref="managedServiceFactoryTrackingAdapter" />
+		<property name="managedServiceTrackingAdapter" ref="managedServiceTrackingAdapter" />
+		<property name="configurationListener" ref="configurationListener"/>
+	</bean>
+
+</beans>
\ No newline at end of file

Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/ConfigurationAdminImplTest.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/ConfigurationAdminImplTest.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/ConfigurationAdminImplTest.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/ConfigurationAdminImplTest.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,262 @@
+/*
+ *   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;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+import org.apache.configuration.event.ConfigurationNotifier;
+import org.apache.configuration.impl.ConfigurationAdminImpl;
+import org.apache.configuration.impl.ConfigurationStore;
+import org.apache.configuration.util.ApacheDSUtil;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.cm.ConfigurationEvent;
+import org.osgi.service.cm.ConfigurationListener;
+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.MockBundleContext;
+
+/**
+ * ConfigurationAdminImplTest.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class ConfigurationAdminImplTest extends TestCase implements ConfigurationListener
+{
+
+    private static final String SOME_FACTORY = "some.factory";
+    private static final String FILTER = "(service.factoryPid=some*)";
+    private static final String SOME_PID = "some.pid";
+    private static final String SOME_LOCATION ="some.location";
+    /** the log for this class */
+    private static final Logger log = LoggerFactory.getLogger( ConfigurationAdminImplTest.class );
+    
+    static{
+        File file = new File("server-work");
+        if(file.exists()){
+            log.debug( "Removing the server-work directory. " );
+            ApacheDSUtil.deleteDir(file);
+        }
+    }
+    
+    private ConfigurationNotifier configurationNotifier;
+
+    private ConfigurationStore configurationStore;
+    private Bundle callingBundle;
+    private ConfigurationAdmin configurationAdmin;
+    
+
+
+    /* (non-Javadoc)
+     * @see junit.framework.TestCase#setUp()
+     */
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+        ApplicationContext ctx = new ClassPathXmlApplicationContext(
+            new String[]{ 
+                "mockInitialContextFactory.xml", 
+                "mockConfigurationDaoEventListener.xml",
+                "META-INF/spring/daoJndi.xml", 
+                "META-INF/spring/configuration.xml"});
+        
+        configurationNotifier = new ConfigurationNotifier();
+        configurationStore = ( ConfigurationStore ) ctx.getBean( "configurationStore" );
+        configurationStore.setConfigurationDaoListener(configurationNotifier );
+        configurationNotifier.setConfigurationListener( this );
+        BundleContext context = new MockBundleContext();
+        String location = "some location";
+        Dictionary headers = new Hashtable();
+       
+        callingBundle = new MockBundle(location, headers, context);
+        Set<String> pids = configurationStore.listPids();
+        for ( String pid : pids )
+        {
+            configurationStore.delete( pid );
+        }
+        
+        
+    }
+
+
+    /* (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#tearDown()
+     */
+    protected void tearDown() throws Exception
+    {
+        callingBundle=null;
+        configurationNotifier = null;
+        configurationAdmin=null;
+        configurationStore = null;
+        
+        super.tearDown();
+    }
+
+    /* ==================================== Tests ===================================================*/
+    
+    
+    
+    /**
+     * Test method for {@link org.apache.configuration.impl.ConfigurationAdminImpl#ConfigurationAdminImpl(org.apache.configuration.impl.ConfigurationStore, org.osgi.framework.Bundle)}.
+     */
+    public final void testConfigurationAdminImpl()
+    {
+        configurationAdmin = new ConfigurationAdminImpl(configurationStore, callingBundle);
+       assertNotNull( configurationAdmin);
+       
+    }
+
+
+    /**
+     * Test method for {@link org.apache.configuration.impl.ConfigurationAdminImpl#createFactoryConfiguration(java.lang.String)}.
+     */
+    public final void testCreateFactoryConfigurationWithFactoryPid()
+    {
+        configurationAdmin = new ConfigurationAdminImpl(configurationStore, callingBundle);
+        Configuration configuration = null;
+        try
+        {
+            configuration = configurationAdmin.createFactoryConfiguration( SOME_FACTORY );
+        }
+        catch ( IOException e )
+        {
+            
+            e.printStackTrace();
+            fail(e.toString());
+        }
+        
+        assertNotNull(configuration);
+    }
+
+
+    /**
+     * Test method for {@link org.apache.configuration.impl.ConfigurationAdminImpl#createFactoryConfiguration(java.lang.String, java.lang.String)}.
+     */
+    public final void testCreateFactoryConfigurationWithFactoryPidAndLocation()
+    {
+        configurationAdmin = new ConfigurationAdminImpl(configurationStore, callingBundle);
+        Configuration configuration = null;
+        try
+        {
+            configuration = configurationAdmin.createFactoryConfiguration( SOME_FACTORY, SOME_LOCATION );
+        }
+        catch ( IOException e )
+        {
+            
+            e.printStackTrace();
+            fail(e.toString());
+        }
+        
+        assertNotNull(configuration);
+    }
+
+
+    /**
+     * Test method for {@link org.apache.configuration.impl.ConfigurationAdminImpl#getConfiguration(java.lang.String)}.
+     * 
+     */
+    public final void testGetConfigurationServicePid()
+    {
+        configurationAdmin = new ConfigurationAdminImpl(configurationStore, callingBundle);
+        Configuration configuration = null;
+        try
+        {
+            configuration = configurationAdmin.getConfiguration( SOME_PID );
+        }
+        catch ( IOException e )
+        {
+            
+            e.printStackTrace();
+            fail(e.toString());
+        }
+        
+        assertNotNull(configuration);
+    }
+
+
+    /**
+     * Test method for {@link org.apache.configuration.impl.ConfigurationAdminImpl#getConfiguration(java.lang.String, java.lang.String)}.
+     */
+    public final void testGetConfigurationServicePidAndLocation()
+    {
+        configurationAdmin = new ConfigurationAdminImpl(configurationStore, callingBundle);
+        Configuration configuration = null;
+        try
+        {
+            configuration = configurationAdmin.getConfiguration( SOME_PID, SOME_LOCATION );
+        }
+        catch ( IOException e )
+        {
+            
+            e.printStackTrace();
+            fail(e.toString());
+        }
+        
+        assertNotNull(configuration);
+    }
+
+
+    /**
+     * Test method for {@link org.apache.configuration.impl.ConfigurationAdminImpl#listConfigurations(java.lang.String)}.
+     */
+    public final void testListConfigurations()
+    {
+        configurationAdmin = new ConfigurationAdminImpl(configurationStore, callingBundle);
+        Configuration[] configs = null;
+        try
+        {
+            configs = configurationAdmin.listConfigurations( FILTER  );
+        }
+        catch ( IOException e )
+        {
+            e.printStackTrace();
+            fail(e.toString());
+        }
+        catch ( InvalidSyntaxException e )
+        {
+            e.printStackTrace();
+            fail(e.toString());
+        }
+        
+        assertNotNull(configs);
+        assertEquals(0, configs.length);
+    }
+
+
+    public void configurationEvent( ConfigurationEvent event )
+    {
+        
+    }
+}

Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/ConfigurationImplTest.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/ConfigurationImplTest.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/ConfigurationImplTest.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/test/java/org/apache/configuration/ConfigurationImplTest.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,683 @@
+/*
+ *   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;
+
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Set;
+import java.util.Vector;
+
+import junit.framework.TestCase;
+
+import org.apache.configuration.dao.ConfigurationDao;
+import org.apache.configuration.dao.jndi.ContextMapping;
+import org.apache.configuration.dao.jndi.impl.ContextMapper;
+import org.apache.configuration.event.ConfigurationNotifier;
+import org.apache.configuration.impl.ConfigurationDictionary;
+import org.apache.configuration.impl.ConfigurationImpl;
+import org.apache.configuration.impl.ConfigurationStore;
+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.ConfigurationListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+
+/**
+ * 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 ConfigurationImplTest extends TestCase implements ConfigurationListener
+{
+
+    private static final String SOME_CN = "mytestConfiguration";
+    private static final String SOME_BUNDLELOCATION = "some.bundlelocation";
+    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( ConfigurationImplTest.class );
+
+    static
+    {
+        File file = new File( "server-work" );
+        if ( file.exists() )
+        {
+            log.debug( "Removing the server-work directory. " );
+            ApacheDSUtil.deleteDir(file);
+        }
+    }
+
+
+   
+    private ConfigurationStore configurationStore;
+    private ConfigurationDao configurationDao;
+    private ConfigurationEvent configurationEvent;
+    private ConfigurationNotifier configurationNotifier;
+
+
+    /* (non-Javadoc)
+     * @see junit.framework.TestCase#setUp()
+     */
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+        ApplicationContext ctx = new ClassPathXmlApplicationContext(
+            new String[]{ 
+                "mockInitialContextFactory.xml", 
+                "mockConfigurationDaoEventListener.xml",
+                "META-INF/spring/daoJndi.xml", 
+                "META-INF/spring/configuration.xml"});
+        
+       
+        configurationNotifier = new ConfigurationNotifier();
+        
+        configurationStore = ( ConfigurationStore ) ctx.getBean( "configurationStore" );
+        configurationDao = ( ConfigurationDao ) ctx.getBean( "configurationDao" );
+        configurationStore.setConfigurationDaoListener( configurationNotifier );
+       
+        configurationNotifier.setConfigurationListener( this );
+        
+        Set<String> pids = configurationStore.listPids();
+        for ( String pid : pids )
+        {
+            configurationStore.delete( pid );
+        }
+       
+    }
+
+
+    /* (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#tearDown()
+     */
+    protected void tearDown() throws Exception
+    {
+        configurationEvent=null;
+        configurationDao=null;
+        configurationNotifier = null;
+        
+        configurationStore = null;
+        
+        super.tearDown();
+    }
+
+    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());
+    }
+
+
+    /**
+     * 
+     * Test method for {@link org.apache.configuration.util.ConfigurationImpl#ConfigurationImpl(org.apache.configuration.impl.ConfigurationStore, java.lang.String, java.lang.String, java.lang.String)}.
+     * Creates a new configurationImpl of ConfigurationImpl.
+     *
+     * param configurationStore
+     * param bundleLocation
+     * param factoryPid
+     * param servicePid
+     */
+    public void testConstructorConfigurationDaoStringString()
+    {
+        
+        String factoryPid = "com.some.factory";
+        String servicePid = "com.some.service";
+        Configuration configuration = new ConfigurationImpl( configurationStore, factoryPid, servicePid );
+
+        assertNotNull( "Setup construction failed", configuration );
+        assertEquals(factoryPid, configuration.getFactoryPid());
+        assertEquals(servicePid, configuration.getPid());
+        assertNull(configuration.getProperties());
+        
+    }
+
+
+    /**
+     * Test method for {@link org.apache.configuration.util.ConfigurationImpl#ConfigurationImpl(org.apache.configuration.impl.ConfigurationStore, java.lang.String, java.lang.String, java.lang.String, org.apache.configuration.impl.ConfigurationDictionary)}.
+     * 
+     * store
+     * bundleLocation
+     * factoryPid
+     * servicePid
+     * properties
+     */
+    public void testConstructorConfigurationDaoConfigurationDictionary()
+    {
+        String cn = "loc";
+        String factoryPid = "com.some.factory";
+        String servicePid = "com.some.service";
+        ConfigurationDictionary configurationDictionary = createConfigurationDictionaryInstance( cn, servicePid, factoryPid );
+
+        Configuration configuration = new ConfigurationImpl( 
+            configurationStore, configurationDictionary );
+
+       
+        assertNotNull( "Setup construction failed", configuration );
+        assertEquals(servicePid, configuration.getPid());
+        assertEquals(factoryPid, configuration.getFactoryPid());
+        assertNull(configuration.getProperties());
+    }
+
+
+    /**
+     * 
+     * Test method for {@link org.apache.configuration.util.ConfigurationImpl#hashCode()}.
+     */
+    public void testHashCode()
+    {
+
+        String pid = "org.apache.pid1";
+        //Null and a pid
+        Configuration instance3 = new ConfigurationImpl( configurationStore, null, pid );
+        assertEquals( pid.hashCode(), instance3.hashCode() );
+
+    }
+
+
+    /**
+     * Test method for {@link org.apache.configuration.util.ConfigurationImpl#equals(java.lang.Object)}.
+     */
+    public void testEqualsObject()
+    {
+        
+        Configuration configurationImpl = new ConfigurationImpl( configurationStore, null, null );
+
+        Configuration instance2 = new ConfigurationImpl( configurationStore, null, null );
+        assertTrue( "Two configurations with null pids should be equal", configurationImpl.equals( instance2 ) );
+        assertTrue( "Two configurations with null pids should be equal", instance2.equals( configurationImpl ) );
+
+        //Null and a pid
+        Configuration instance3 = new ConfigurationImpl( configurationStore, null, "org.apache.pid1" );
+
+        assertFalse( "Two configurations with different pids should NOT be equal", configurationImpl.equals( instance3 ) );
+        assertFalse( "Two configurations with different pids should NOT be equal", instance3.equals( configurationImpl ) );
+
+        //Two similar pids
+        Configuration instance4 = new ConfigurationImpl( configurationStore, null, "org.apache.pid1" );
+        assertTrue( "Two configurations with equal pids should be equal", instance3.equals( instance4 ) );
+        assertTrue( "Two configurations with equal pids should be equal", instance4.equals( instance3 ) );
+
+        //Two different pids
+        Configuration instance5 = new ConfigurationImpl( configurationStore, null, "org.apache.pid2" );
+        assertFalse( "Two configurations with different pids should NOT be equal", instance4.equals( instance5 ) );
+        assertFalse( "Two configurations with different pids should NOT be equal", instance5.equals( instance4 ) );
+    }
+
+
+    /**
+     * Test method for {@link org.apache.configuration.util.ConfigurationImpl#getPid()}.
+     */
+    public void testGetPid()
+    {
+        Configuration instance3 = new ConfigurationImpl( configurationStore, null, "org.apache.pid1" );
+        assertEquals( "org.apache.pid1", instance3.getPid() );
+    }
+
+
+    /**
+     * Test method for {@link org.apache.configuration.util.ConfigurationImpl#getBundleLocation()}.
+     */
+    public void testGetSetBundleLocation()
+    {
+        String bundleLocation ="something";
+        String cn = "loc";
+        String factoryPid = "com.some.factory";
+        String servicePid = "com.some.service";
+        ConfigurationDictionary configurationDictionary = createConfigurationDictionaryInstance( 
+            cn, servicePid, factoryPid );
+
+
+        Configuration configuration = new ConfigurationImpl( configurationStore, configurationDictionary );
+
+        assertNull(configuration.getBundleLocation());
+        
+        configuration.setBundleLocation( bundleLocation );
+        assertEquals( "bundleLocations not equal", bundleLocation, configuration.getBundleLocation() );
+    }
+
+
+    /**
+     * Test method for {@link org.apache.configuration.util.ConfigurationImpl#getFactoryPid()}.
+     */
+    public void testGetFactoryPid()
+    {
+        String factoryPid = "com.some.factory";
+        String servicePid = "com.some.service";
+
+        Configuration instance2 = new ConfigurationImpl( configurationStore, factoryPid, servicePid );
+
+        assertEquals( "factoryPid not equal", factoryPid, instance2.getFactoryPid() );
+
+    }
+
+
+    /**
+     * Test method for {@link org.apache.configuration.util.ConfigurationImpl#update()}.
+     */
+    public void testUpdate()
+    {
+        
+        assertTrue( configurationDao.findAll().isEmpty());
+        assertTrue( configurationStore.listPids().isEmpty());
+        String cn = SOME_CN;
+        String factoryPid = SOME_FACTORY;
+        String servicePid = SOME_PID;
+        ConfigurationDictionary configurationDictionary = createConfigurationDictionaryInstance( cn, servicePid, factoryPid );
+        
+        Configuration configuration = new ConfigurationImpl( configurationStore, configurationDictionary );
+        
+        assertNull(configuration.getProperties());
+        
+        try
+        {
+            configuration.update();
+        }
+
+        catch ( IOException e )
+        {
+            fail( e.toString() );
+        }
+        assertEquals(1, configurationDao.findAll().size());
+        assertEquals(1, configurationStore.listPids().size());
+        
+        //At the Dao
+        ConfigurationDictionary configurationDictionaryDao = configurationDao.read( SOME_PID );
+        assertNull("Should not find key "+ContextMapping.APACHEDS_SERVICE_PID+" in "+configurationDictionaryDao,
+            configurationDictionaryDao.get( ContextMapping.APACHEDS_SERVICE_PID ));
+        
+        assertNotNull("Could not find key "+Constants.SERVICE_PID+" in "+configurationDictionaryDao,
+            configurationDictionaryDao.get( Constants.SERVICE_PID ));
+        
+        
+        //At the store
+        ConfigurationDictionary configurationDictionaryStore = null;
+        try
+        {
+            configurationDictionaryStore = configurationStore.retrieve( SOME_PID );
+        }
+        catch ( IOException e )
+        {
+            
+            log.error( "Failed to retrieve from the configurationStore.",e );
+            fail(e.toString());
+        }
+        assertNull("Should not find key "+ContextMapping.APACHEDS_SERVICE_PID+" in "+configurationDictionaryStore,
+            configurationDictionaryStore.get( ContextMapping.APACHEDS_SERVICE_PID ));
+        
+        assertNotNull("Could not find key "+Constants.SERVICE_PID+" in "+configurationDictionaryStore,
+            configurationDictionaryStore.get( Constants.SERVICE_PID ));
+        
+        
+        //THe configuration
+        assertNull("Should not find key "+ContextMapping.APACHEDS_SERVICE_PID+" in "+configuration.getProperties(),
+            configuration.getProperties().get( ContextMapping.APACHEDS_SERVICE_PID ));
+        
+        assertNotNull("Could not find key "+Constants.SERVICE_PID+" in "+configuration.getProperties(),
+            configuration.getProperties().get( Constants.SERVICE_PID ));
+        
+        ConfigurationDictionary configurationDictionary2 = configurationDao.read( servicePid );
+        assertNotNull(configurationDictionary2);
+        assertEquals(servicePid, configurationDictionary2.get(Constants.SERVICE_PID));
+        
+        assertNotNull(configurationEvent);
+        assertEquals(ConfigurationEvent.CM_UPDATED, configurationEvent.getType());
+        assertEquals(servicePid, configurationEvent.getPid());
+    }
+
+
+    public void testCreateConfigurationAndUpdateWithError(){
+        ConfigurationDictionary configurationDictionary = createConfigurationDictionaryInstance( "dontcare", SOME_PID, SOME_FACTORY );
+        //Add a ServiceBundleLocation to see if it is remove before the create
+        configurationDictionary.put( ConfigurationAdmin.SERVICE_BUNDLELOCATION, SOME_BUNDLELOCATION );
+        configurationDictionary.remove( "objectclass" );
+        Configuration configuration = new ConfigurationImpl( configurationStore, configurationDictionary );
+        
+      
+        try
+        {
+            configuration.update();
+            fail("Should throw an IOException.");
+        }
+        catch ( IOException e )
+        {
+           assertEquals("There was no objectclass properties defined.", e.getMessage());
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+            fail(e.toString());
+        }
+     }
+
+
+    /**
+     * Test method for {@link org.apache.configuration.util.ConfigurationImpl#setBundleLocation(java.lang.String)}.
+     */
+    public void testSetBundleLocation()
+    {
+        log.debug( "Starting test ---------------------------------------" );
+        String bundleLocation = "loc";
+        
+        String cn = "mytestConfiguration2";
+        String factoryPid = SOME_FACTORY;
+        String servicePid = SOME_PID;
+        ConfigurationDictionary configurationDictionary = createConfigurationDictionaryInstance( cn, servicePid, factoryPid );
+        
+        Configuration configuration = new ConfigurationImpl( configurationStore, configurationDictionary );
+        
+        try
+        {
+            configuration.setBundleLocation( bundleLocation );//Note this triggers an update to the backend
+        }
+        
+        catch ( Exception e )
+        {
+            
+            log.error( "Failed to setBundleLocation. {}", e.getMessage(), e.getCause() );
+            fail( e.getCause().toString() );
+        }
+        assertEquals( "bundleLocation not equal", bundleLocation, configuration.getBundleLocation() );
+    }
+
+
+    /**
+     * Test method for {@link org.apache.configuration.util.ConfigurationImpl#update(java.util.Dictionary)}.
+     */
+    public void testUpdateDictionary()
+    {
+        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, SOME_PID );
+        dictionary.put( ConfigurationAdmin.SERVICE_FACTORYPID, SOME_FACTORY );
+        dictionary.put( "objectclass", objectclass );
+        dictionary.put( "cn", "mytestConfiguration3" );
+
+        String servicePid = SOME_PID;
+        //Null and a pid
+        Configuration configuration = new ConfigurationImpl( configurationStore, null, servicePid );
+
+        ConfigurationDictionary configurationDictionary = new ConfigurationDictionary( dictionary );
+
+        try
+        {
+            configuration.update( configurationDictionary );
+        }
+        catch ( IOException e )
+        {
+            e.printStackTrace();
+            log.error( "Failed to update the configuration dictionary.", e );
+            fail( e.toString() );
+        }
+        
+        assertNull("Should not find key "+ContextMapping.APACHEDS_SERVICE_PID+" in "+configuration.getProperties(),
+            configuration.getProperties().get( ContextMapping.APACHEDS_SERVICE_PID ));
+        
+        assertNotNull("Could not find key "+Constants.SERVICE_PID+" in "+configuration.getProperties(),
+            configuration.getProperties().get( Constants.SERVICE_PID ));
+
+        dictionary = new Hashtable<String, Object>();
+        dictionary.put( Constants.SERVICE_PID, SOME_PID );
+        dictionary.put( ConfigurationAdmin.SERVICE_FACTORYPID, "some.other.factory" );
+        
+        dictionary.put( "objectclass", objectclass );
+        dictionary.put( "cn", "mytestConfiguration3" );
+       
+        try
+        {
+            configuration.update( dictionary );
+        }
+        catch ( IOException e )
+        {
+            e.printStackTrace();
+            fail( "Failed to update the properties a second time. "+e.toString() );
+        }
+        
+        assertNotNull(configurationEvent);
+        assertEquals(ConfigurationEvent.CM_UPDATED, configurationEvent.getType());
+        assertEquals(servicePid, configurationEvent.getPid());
+
+    }
+
+
+    /**
+     * Test method for {@link org.apache.configuration.util.ConfigurationImpl#getProperties()}.
+     */
+    public void testGetProperties()
+    {
+        assertTrue( configurationDao.findAll().isEmpty());
+        assertTrue( configurationStore.listPids().isEmpty());
+        
+        String servicePid = SOME_PID;
+        Vector<String> objectclass = new Vector<String>();
+        objectclass.add( "top" );
+        objectclass.add( ContextMapper.APACHEDS_SERVICE_CONFIGURATION_OBJECTCLASS );
+        Dictionary<String, Object> dictionary = new Hashtable<String, Object>();
+        dictionary.put( Constants.SERVICE_PID, servicePid );
+        dictionary.put( ConfigurationAdmin.SERVICE_FACTORYPID, SOME_FACTORY );
+        
+        dictionary.put( "objectclass", objectclass );
+        dictionary.put( "cn", "mytestConfiguration4" );
+        ConfigurationDictionary configurationDictionary = new ConfigurationDictionary( dictionary );
+        
+        
+        Configuration configuration = new ConfigurationImpl( configurationStore, configurationDictionary );
+
+        assertNull( "Update() was not called. Null should be returned.", configuration.getProperties() );
+
+        try
+        {
+            configuration.update();
+        }
+        catch ( IOException e )
+        {
+            fail( e.toString() );
+        }
+        configurationDictionary.remove( ConfigurationAdmin.SERVICE_BUNDLELOCATION );
+
+        Dictionary props = configuration.getProperties();
+        assertNotNull( "Update() was called. Nonull should be returned.", props );
+
+        assertNull("Should not find key "+ContextMapping.APACHEDS_SERVICE_PID+" in "+props,
+            props.get( ContextMapping.APACHEDS_SERVICE_PID ));
+        
+        assertNotNull("Could not find key "+Constants.SERVICE_PID+" in "+props,
+            props.get( Constants.SERVICE_PID ));
+        
+        
+        //Compare entries in the stored configuration.dictionary to the dictionary
+        // that was originally used to make the configuration object
+        Enumeration enumer = props.keys();
+        while ( enumer.hasMoreElements() )
+        {
+            String key = ( String ) enumer.nextElement();
+            String lKey = key.toLowerCase();
+            assertNotNull("Could not find value for key:"+key, props.get( lKey ) );
+            assertNotNull("Could not find key "+lKey+" in "+configurationDictionary,
+                configurationDictionary.get( lKey ));
+            assertEquals( props.get( lKey ), configurationDictionary.get( lKey ) );
+
+        }
+        assertNotNull(configurationEvent);
+        assertEquals(ConfigurationEvent.CM_UPDATED, configurationEvent.getType());
+        assertEquals(servicePid, configurationEvent.getPid());
+
+    }
+
+
+    public void testDeleteConfiguration()
+    {
+        log.debug( "Start test ======================================================" );
+        String cn = "loc";
+        String factoryPid = "com.some.factory";
+        String servicePid = "fiona.maria";
+        
+        ConfigurationDictionary configurationDictionary = 
+            createConfigurationDictionaryInstance( cn, servicePid, factoryPid);
+        Configuration configuration = 
+            new ConfigurationImpl( configurationStore, configurationDictionary );
+        try
+        {
+            configuration.update();
+        }
+        catch ( IOException e1 )
+        {
+            
+            e1.printStackTrace();
+            fail("Could not persist the configuation.");
+        }
+        
+        ConfigurationDictionary configurationDictionary2 = configurationDao.read( 
+            servicePid );
+        assertNotNull(configurationDictionary2);
+        assertEquals(servicePid, configurationDictionary2.get(Constants.SERVICE_PID));
+       
+        assertNotNull(configuration.getPid());
+        assertEquals( servicePid, configuration.getPid() );
+        try
+        {
+            configuration.delete();
+        }
+        catch ( IOException e )
+        {
+            e.printStackTrace();
+            fail("Failed to delete. "+e);
+        }
+
+    }
+    public void testDeleteWithNoPersisted()
+    {
+        log.debug( "Start test ======================================================" );
+        String pid = "test";
+        Configuration configuration = new ConfigurationImpl( configurationStore, null, pid );
+        assertEquals( pid, configuration.getPid() );
+        try
+        {
+            configuration.delete();
+            fail("Expected an IOException to be thrown because there was no test pid persisted.");
+        }
+        catch ( IOException e )
+        {
+            //expected
+        }
+
+    }
+//  TODO File Bug Report. This test sends a modification operation that is corrupting the directory server  
+//  // by leaving an entry that violates a schema. This is a ADS bug, but may not be one in the latest trunks.
+//    /**
+//     * Test method for {@link org.apache.configuration.util.ConfigurationImpl#update()}.
+//     */
+//    public void testUpdateFailure()
+//    {
+//        
+//        String cn = "mytestConfiguration";
+//        String factoryPid = "some.factory";
+//        String servicePid = "some.pid";
+//        ConfigurationDictionary configurationDictionary = createConfigurationDictionaryInstance( cn, servicePid, factoryPid );
+//        //Add a ServiceBundleLocation to see if it is remove before the create
+//        configurationDictionary.put( ConfigurationAdmin.SERVICE_BUNDLELOCATION, "some.bundlelocation" );
+//        configurationDictionary.remove( "cn" );
+//      
+//        
+//        Configuration configuration = new ConfigurationImpl( configurationStore, configurationDictionary );
+//        try
+//        {
+//            configuration.update();
+//            fail( "There was no cn property. An IllegalArgumentExeception should have been thrown." );
+//        }
+//        catch ( IllegalArgumentException e )
+//        {
+//            assertTrue( e.getCause() instanceof SchemaViolationException );
+//        }
+//        catch ( IOException e )
+//        {
+//            e.printStackTrace();
+//            fail( e.toString() );
+//        }
+//        
+//        
+////        try
+////        {
+////            //configurationDao.read( servicePid );
+////            configurationDao.findAll();
+////        }
+////        catch ( ConfigurationDaoException e )
+////        {
+////            e.printStackTrace();
+////            fail( e.toString() );
+////        }
+//    }
+
+
+
+    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 void configurationEvent( ConfigurationEvent event )
+    {
+        this.configurationEvent=event;
+        
+    }
+}