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 [2/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/dao/jndi/impl/JndiConfigurationDaoNotifierImpl.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/jndi/impl/JndiConfigurationDaoNotifierImpl.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/jndi/impl/JndiConfigurationDaoNotifierImpl.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/jndi/impl/JndiConfigurationDaoNotifierImpl.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,265 @@
+/*
+ * 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.dao.jndi.impl;
+
+import javax.naming.Binding;
+import javax.naming.NamingException;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.DirContext;
+import javax.naming.event.EventContext;
+import javax.naming.event.EventDirContext;
+import javax.naming.event.NamingEvent;
+import javax.naming.event.NamingExceptionEvent;
+import javax.naming.spi.InitialContextFactory;
+
+import org.apache.configuration.dao.ConfigurationDaoListener;
+import org.apache.configuration.dao.ConfigurationDaoListener.ChangeType;
+import org.apache.configuration.dao.jndi.ContextMapping;
+import org.apache.configuration.dao.jndi.JndiConfigurationDaoNotifier;
+import org.apache.configuration.dao.jndi.NameMapping;
+import org.apache.configuration.impl.ConfigurationDictionary;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * JndiConfigurationDaoNotifierImpl adapts directory events to configuration events.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class JndiConfigurationDaoNotifierImpl implements JndiConfigurationDaoNotifier
+{
+
+
+ /** the log for this class */
+ private static final Logger log = LoggerFactory.getLogger( JndiConfigurationDaoNotifierImpl.class );
+
+ private final String name;
+ private ConfigurationDaoListener configurationChangeListener;
+ private final ContextMapping contextMapping;
+ private final NameMapping nameMapper;
+ private final InitialContextFactory initialContextFactory;
+
+ EventDirContext eventDirContext = null;
+
+ /**
+ * Creates a new instance of JndiConfigurationDaoNotifierImpl.
+ * @deprecated pass a ContextMapping value into the other constructor
+ */
+ public JndiConfigurationDaoNotifierImpl()
+ {
+ this(new ContextMapper(), null, null);
+ }
+
+ /**
+ *
+ * Creates a new instance of JndiConfigurationDaoNotifierImpl.
+ * The name will be used to identify the instance.
+ *
+ * @param name
+ */
+ public JndiConfigurationDaoNotifierImpl(ContextMapping contextMapping,NameMapping nameMapper, InitialContextFactory initialContextFactory )
+ {
+ this.contextMapping = contextMapping;
+ this.name = "Listener-" + System.currentTimeMillis();
+ this.nameMapper=nameMapper;
+ this.initialContextFactory=initialContextFactory;
+ }
+
+
+ public void removeConfigurationListener()
+ {
+ this.configurationChangeListener = null;
+ try
+ {
+ eventDirContext.removeNamingListener( this );
+ }
+ catch ( NamingException e )
+ {
+ log.error( "Failed to remove this naming listener.",e );
+ }finally{
+ try
+ {
+ if(eventDirContext!=null){
+ eventDirContext.close();
+ }
+ }
+ catch ( NamingException e )
+ {
+ log.error( "Failed to close the eventDirContext.",e );
+ }finally{
+ eventDirContext = null;
+ }
+ }
+
+
+ }
+
+ public void setConfigurationListener( ConfigurationDaoListener configurationListener )
+ {
+ this.configurationChangeListener = configurationListener;
+ log.debug( "Adding a listener {}",configurationListener );
+ if(eventDirContext==null){
+ try
+ {
+ DirContext dirContext = (DirContext)initialContextFactory.getInitialContext( null) ;
+ eventDirContext = (EventDirContext)dirContext.lookup( "" );
+ eventDirContext.addNamingListener( nameMapper.getSearchBaseName(), EventContext.SUBTREE_SCOPE, this );
+ }
+ catch ( NamingException e )
+ {
+ log.error( "Failed to set a configurationDaoListener.",e );
+
+ }finally{
+ if(eventDirContext!=null){
+ try
+ {
+ eventDirContext.close();
+ }
+ catch ( NamingException e )
+ {
+ //ignore
+ }
+ }
+ }
+ }
+
+
+ }
+
+
+ public void objectAdded( NamingEvent evt )
+ {
+ log.debug( "Jndi bindings {}. ", evt.getNewBinding() );
+ if ( configurationChangeListener != null )
+ {
+ try
+ {
+ ConfigurationDictionary newConfig = transform( evt.getNewBinding() );
+ log.debug( "Translated configuration {}",newConfig );
+ configurationChangeListener.configurationChanged( ChangeType.CREATED, newConfig );
+ } catch (NamingException ne)
+ {
+ log.error( ne.getMessage(), ne );
+ }
+ }
+ }
+
+ /**
+ * When an object has been added, getOldBinding() will always return null
+ * because it wasn't in the namespace prior to its being added.
+ * @todo Implement method.
+ */
+ public void objectRemoved( NamingEvent evt )
+ {
+ log.debug( "Jndi bindings {}. ", evt.getOldBinding() );
+ if ( configurationChangeListener != null )
+ {
+ try
+ {
+ ConfigurationDictionary oldConfig = transform( evt.getOldBinding() );
+ log.debug( "Translated configuration {}",oldConfig );
+ configurationChangeListener.configurationChanged(ChangeType.DELETED, oldConfig );
+ } catch (NamingException ne)
+ {
+ log.error( ne.getMessage(), ne );
+ }
+ }
+ }
+
+ /**
+ * When an object has been removed, getNewBinding() will always be null
+ * because it won't be in the namespace after it has been removed.
+ */
+ public void objectRenamed( NamingEvent evt )
+ {
+
+ log.debug( "Renamed {} to {}", evt.getOldBinding(), evt.getNewBinding() );
+
+ if ( configurationChangeListener != null )
+ {
+ try
+ {
+ ConfigurationDictionary renamedConfig = transform( evt.getNewBinding() );
+
+ log.debug( "Translated configuration {}",renamedConfig );
+ configurationChangeListener.configurationChanged( ChangeType.UPDATED, renamedConfig );
+ } catch (NamingException ne)
+ {
+ log.error( ne.getMessage(), ne );
+ }
+ }
+ }
+
+ public void objectChanged( NamingEvent evt )
+ {
+ log.debug( name + " >>> directory object changed: " + evt.getNewBinding() + " from "
+ + evt.getOldBinding() );
+
+ if ( configurationChangeListener != null )
+ {
+ try
+ {
+ ConfigurationDictionary changedConfig = transform( evt.getNewBinding() );
+ log.debug( "Translated configuration {}",changedConfig );
+ configurationChangeListener.configurationChanged( ChangeType.UPDATED,changedConfig );
+ } catch (NamingException ne)
+ {
+ log.error( ne.getMessage(), ne );
+ }
+ }
+ }
+
+ public void namingExceptionThrown( NamingExceptionEvent evt )
+ {
+ log.error( name + " >>> exception: ", evt.getException() );
+ }
+
+ /**
+ * transform the binding to a Dictionary.
+ *
+ * LDAP attribute types do not contain periods, but some of the OSGi constants do.
+ * Conversion mapping once done in this method has been superceded by a more extensible set of
+ * mappings done by a ConfigurationPlugin Service.
+ *
+ *
+ *
+ * @param binding
+ * @return Hashtable
+ * @throws NamingException
+ *
+ */
+ private ConfigurationDictionary transform(Binding binding) throws NamingException
+ {
+ Attributes atts = (Attributes) binding.getObject();
+ ConfigurationDictionary transformedResults =contextMapping.transform( atts );
+ contextMapping.translateDirctoryKeysToOsgiKeys( transformedResults );
+ return transformedResults;
+
+
+ }
+
+ @Override
+ public String toString()
+ {
+ return name;
+ }
+
+
+}
Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/jndi/impl/KeyMapper.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/jndi/impl/KeyMapper.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/jndi/impl/KeyMapper.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/jndi/impl/KeyMapper.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,108 @@
+package org.apache.configuration.dao.jndi.impl;
+
+import java.util.Dictionary;
+
+import org.apache.configuration.dao.jndi.ContextMapping;
+import org.apache.configuration.dao.jndi.KeyMapping;
+import org.osgi.framework.Constants;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.event.EventConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * KeyMapper maps implementation specific configuration
+ * keys to OSGi generic dictionary keys.
+ *
+ * @author <a href="mailto:dev@directoryKey.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class KeyMapper implements KeyMapping{
+ private static final Logger log = LoggerFactory.getLogger(KeyMapper.class);
+
+
+ public static enum TranslationTable
+ {
+ EVENT_TOPIC ("osgieventtopics", EventConstants.EVENT_TOPIC ),
+ EVENT_FILTER ("osgieventfilter", EventConstants.EVENT_FILTER),
+ SERVICE_PID (ContextMapping.APACHEDS_SERVICE_PID, Constants.SERVICE_PID),
+ FACTORY_SERVICE_PID ("apacheservicefactorypid",ConfigurationAdmin.SERVICE_FACTORYPID );
+
+ private final String directoryKey;
+ private final String osgiKey;
+
+
+ TranslationTable(String directory, String osgi) {
+ this.directoryKey = directory;
+ this.osgiKey = osgi;
+ }
+
+ /**
+ *
+ * Convert a directoryKey dictionary to one for Osgi.
+ *
+ * @param directoryDictionary
+ */
+ private void directoryKeyToOsgiKey(Dictionary<String,Object> directoryDictionary){
+ if(directoryDictionary.get(directoryKey) != null){
+ log.debug("Renaming configuration attribute identifier {} to {}.",directoryKey,osgiKey);
+ directoryDictionary.put(osgiKey, directoryDictionary.get(directoryKey));
+ directoryDictionary.remove(directoryKey);
+ }
+
+ }
+ /**
+ *
+ * Convert an osgiKey dictionary to one for an Apache Directory.
+ *
+ * @param osgiDictionary
+ */
+ private void osgiKeyToDirectoryKey(Dictionary<String,Object> osgiDictionary){
+ if(osgiDictionary.get(osgiKey) != null){
+ log.debug("Renaming configuration attribute identifier {} to {}.",osgiKey,directoryKey);
+ osgiDictionary.put(directoryKey, osgiDictionary.get(osgiKey));
+ osgiDictionary.remove(osgiKey);
+ }
+
+ }
+ }
+
+ /**
+ *
+ * Creates a new instance of KeyNameMapper.
+ *
+ */
+ public KeyMapper() {
+ super();
+ }
+
+
+ /**
+ *
+ * ChangeType a dictionary from the directoryKey format to an OSGi configuration.
+ * @param directoryDictionary
+ */
+ @SuppressWarnings("unchecked")
+ public void translateDirctoryKeysToOsgiKeys(Dictionary directoryDictionary) {
+ log.debug("Processing directoryKey configuration to OSGi configuration dictionary{}.",directoryDictionary);
+ for (TranslationTable m : TranslationTable.values())
+ m.directoryKeyToOsgiKey( directoryDictionary );
+
+ }
+ /**
+ *
+ * ChangeType a OSGi configuration to a dictionary suitable for the directoryKey.
+ *
+ * @param configurationDictionary
+ */
+ @SuppressWarnings("unchecked")
+ public void translateOsgiKeysToDirectoryKeys(Dictionary configurationDictionary) {
+ log.debug("Processing OSGi configuration dictionary to a directoryKey configuration {}.",configurationDictionary);
+ for (TranslationTable m : TranslationTable.values())
+ m.osgiKeyToDirectoryKey( configurationDictionary );
+
+ }
+
+
+}
Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/jndi/impl/ListCommand.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/jndi/impl/ListCommand.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/jndi/impl/ListCommand.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/jndi/impl/ListCommand.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,168 @@
+/*
+ * 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.dao.jndi.impl;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.naming.Name;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+
+import org.apache.configuration.dao.ConfigurationDaoException;
+import org.apache.configuration.dao.jndi.Command;
+import org.apache.configuration.dao.jndi.ContextMapping;
+import org.apache.configuration.dao.jndi.NameMapping;
+import org.apache.configuration.impl.ConfigurationDictionary;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * ListCommand.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class ListCommand implements Command<List<ConfigurationDictionary>>
+{
+ private static final Logger log = LoggerFactory.getLogger( ListCommand.class );
+ private final String filter;
+ private final NameMapping nameMapping;
+ private final ContextMapping contextMapping;
+
+
+ /**
+ *
+ * Creates a new instance of ListCommand.
+ *
+ * @param filter
+ * @param baseDn
+ * @param contextMapping
+ */
+ public ListCommand( String filter, NameMapping nameMapping, ContextMapping contextMapping )
+ {
+ this.filter = filter;
+ this.nameMapping = nameMapping;
+ this.contextMapping=contextMapping;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.configuration.dao.jndi.Command#execute(javax.naming.directory.DirContext)
+ */
+ public List<ConfigurationDictionary> execute( DirContext dirContext )
+ {
+
+ try
+ {
+ return search(dirContext);
+ }
+ catch ( NamingException e )
+ {
+ log.error( "Could not list ConfigurationDictionaries." ,e );
+ throw new ConfigurationDaoException("Could not list ConfigurationDictionaries.",e);
+ }
+
+
+ }
+
+
+ private List<ConfigurationDictionary> search( DirContext dirContext ) throws NamingException
+ {
+ Name baseDn = nameMapping.getSearchBaseName();
+ List<ConfigurationDictionary> configurations = new ArrayList<ConfigurationDictionary>();
+ NamingEnumeration namingEnumeration = null;
+ SearchControls searchControls = new SearchControls();
+ searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
+ log.debug( "Searching directory from searchBase: {} using filter: {}", baseDn, filter );
+ NamingException exception = null;
+ try
+ {
+ namingEnumeration = dirContext.search( baseDn, filter, searchControls );
+ SearchResult searchResult = null;
+ ConfigurationDictionary configurationDictionary = null;
+ while ( namingEnumeration.hasMore() )
+ {
+ searchResult = ( SearchResult ) namingEnumeration.next();
+ configurationDictionary = createConfigurationDictionary(searchResult );
+
+ configurations.add( configurationDictionary );
+ }
+
+ if ( configurations.isEmpty() )
+ {
+ log.debug(
+ "Found no entry while searching directory from searchBase: {} using filter: ",baseDn,filter );
+ return null;
+ }
+ else
+ {
+ log.debug( "Found {} entries while searching directory from searchBase: {} using filter: {}",
+ new Object[] {configurations.size(), baseDn, filter} );
+ }
+ configurationDictionary = createConfigurationDictionary( searchResult );
+
+ }
+ catch ( NamingException e )
+ {
+ log.error( "Search the dirContex for " + filter + " failed.", e );
+ exception = e;
+ }
+ finally
+ {
+ if ( namingEnumeration != null )
+ {
+ try
+ {
+ namingEnumeration.close();
+ }
+ catch ( Exception e )
+ {
+ log.error( "Could not close the namingEnumeration", e );
+ }
+ }
+ }
+ if ( exception != null )
+ {
+ throw exception;
+ }
+ return configurations.isEmpty() ? null : configurations;
+ }
+
+
+ private ConfigurationDictionary createConfigurationDictionary(SearchResult searchResult ) throws NamingException
+ {
+ Attributes atts = searchResult.getAttributes();
+ String name = searchResult.getName();
+ ConfigurationDictionary configurationDictionary = contextMapping.transform( atts );
+ nameMapping.addAlternateName(configurationDictionary, name);
+ contextMapping.translateDirctoryKeysToOsgiKeys( configurationDictionary );
+ return configurationDictionary;
+ }
+
+
+
+}
Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/jndi/impl/SimpleDirContextAdapter.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/jndi/impl/SimpleDirContextAdapter.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/jndi/impl/SimpleDirContextAdapter.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/jndi/impl/SimpleDirContextAdapter.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,631 @@
+/*
+ * 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.dao.jndi.impl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Hashtable;
+
+import javax.naming.Binding;
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.NameClassPair;
+import javax.naming.NameNotFoundException;
+import javax.naming.NameParser;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.ModificationItem;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+
+/**
+ * SimpleDirContextAdapter is a simple DirContext used for saving objects in a
+ * directory DirContext.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class SimpleDirContextAdapter implements DirContext
+{
+
+ private static final String EMPTY = ""; //$NON-NLS-1$
+ private final Collection<Attribute> collectionOfAttributes = new ArrayList<Attribute>();
+
+
+
+ public void setAttribute(Attribute attribute){
+ collectionOfAttributes.add( attribute );
+ }
+
+ /* (non-Javadoc)
+ * @see javax.naming.directory.DirContext#bind(javax.naming.Name, java.lang.Object, javax.naming.directory.Attributes)
+ */
+ public void bind( Name name, Object obj, Attributes attrs ) throws NamingException
+ {
+ // ignored
+
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.directory.DirContext#bind(java.lang.String, java.lang.Object, javax.naming.directory.Attributes)
+ */
+ public void bind( String name, Object obj, Attributes attrs ) throws NamingException
+ {
+ // ignored
+
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.directory.DirContext#createSubcontext(javax.naming.Name, javax.naming.directory.Attributes)
+ */
+ public DirContext createSubcontext( Name name, Attributes attrs ) throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.directory.DirContext#createSubcontext(java.lang.String, javax.naming.directory.Attributes)
+ */
+ public DirContext createSubcontext( String name, Attributes attrs ) throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.directory.DirContext#getAttributes(javax.naming.Name)
+ */
+ public Attributes getAttributes( Name name ) throws NamingException
+ {
+ if (! EMPTY.equals(name)) {
+ throw new NameNotFoundException();
+ }
+
+ Attributes myAttrs = new BasicAttributes(true);
+ for ( Attribute attr : collectionOfAttributes )
+ {
+ myAttrs.put( attr ) ;
+ }
+ return myAttrs;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.directory.DirContext#getAttributes(java.lang.String)
+ */
+ public Attributes getAttributes(String name) throws NamingException {
+ if (! EMPTY.equals(name)) {
+ throw new NameNotFoundException();
+ }
+ Attributes myAttrs = new BasicAttributes(true);
+ for ( Attribute attr : collectionOfAttributes )
+ {
+ myAttrs.put( attr ) ;
+ }
+ return myAttrs;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.directory.DirContext#getAttributes(javax.naming.Name, java.lang.String[])
+ */
+ public Attributes getAttributes( Name name, String[] attrIds ) throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.directory.DirContext#getAttributes(java.lang.String, java.lang.String[])
+ */
+ public Attributes getAttributes( String name, String[] attrIds ) throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.directory.DirContext#getSchema(javax.naming.Name)
+ */
+ public DirContext getSchema( Name name ) throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.directory.DirContext#getSchema(java.lang.String)
+ */
+ public DirContext getSchema( String name ) throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.directory.DirContext#getSchemaClassDefinition(javax.naming.Name)
+ */
+ public DirContext getSchemaClassDefinition( Name name ) throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.directory.DirContext#getSchemaClassDefinition(java.lang.String)
+ */
+ public DirContext getSchemaClassDefinition( String name ) throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.directory.DirContext#modifyAttributes(javax.naming.Name, javax.naming.directory.ModificationItem[])
+ */
+ public void modifyAttributes( Name name, ModificationItem[] mods ) throws NamingException
+ {
+ // ignored
+
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.directory.DirContext#modifyAttributes(java.lang.String, javax.naming.directory.ModificationItem[])
+ */
+ public void modifyAttributes( String name, ModificationItem[] mods ) throws NamingException
+ {
+ // ignored
+
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.directory.DirContext#modifyAttributes(javax.naming.Name, int, javax.naming.directory.Attributes)
+ */
+ public void modifyAttributes( Name name, int mod_op, Attributes attrs ) throws NamingException
+ {
+ // ignored
+
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.directory.DirContext#modifyAttributes(java.lang.String, int, javax.naming.directory.Attributes)
+ */
+ public void modifyAttributes( String name, int mod_op, Attributes attrs ) throws NamingException
+ {
+ // ignored
+
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.directory.DirContext#rebind(javax.naming.Name, java.lang.Object, javax.naming.directory.Attributes)
+ */
+ public void rebind( Name name, Object obj, Attributes attrs ) throws NamingException
+ {
+ // ignored
+
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.directory.DirContext#rebind(java.lang.String, java.lang.Object, javax.naming.directory.Attributes)
+ */
+ public void rebind( String name, Object obj, Attributes attrs ) throws NamingException
+ {
+ // ignored
+
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.directory.DirContext#search(javax.naming.Name, javax.naming.directory.Attributes)
+ */
+ public NamingEnumeration<SearchResult> search( Name name, Attributes matchingAttributes ) throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.directory.DirContext#search(java.lang.String, javax.naming.directory.Attributes)
+ */
+ public NamingEnumeration<SearchResult> search( String name, Attributes matchingAttributes ) throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.directory.DirContext#search(javax.naming.Name, javax.naming.directory.Attributes, java.lang.String[])
+ */
+ public NamingEnumeration<SearchResult> search( Name name, Attributes matchingAttributes, String[] attributesToReturn )
+ throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.directory.DirContext#search(java.lang.String, javax.naming.directory.Attributes, java.lang.String[])
+ */
+ public NamingEnumeration<SearchResult> search( String name, Attributes matchingAttributes,
+ String[] attributesToReturn ) throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.directory.DirContext#search(javax.naming.Name, java.lang.String, javax.naming.directory.SearchControls)
+ */
+ public NamingEnumeration<SearchResult> search( Name name, String filter, SearchControls cons )
+ throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.directory.DirContext#search(java.lang.String, java.lang.String, javax.naming.directory.SearchControls)
+ */
+ public NamingEnumeration<SearchResult> search( String name, String filter, SearchControls cons )
+ throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.directory.DirContext#search(javax.naming.Name, java.lang.String, java.lang.Object[], javax.naming.directory.SearchControls)
+ */
+ public NamingEnumeration<SearchResult> search( Name name, String filterExpr, Object[] filterArgs,
+ SearchControls cons ) throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.directory.DirContext#search(java.lang.String, java.lang.String, java.lang.Object[], javax.naming.directory.SearchControls)
+ */
+ public NamingEnumeration<SearchResult> search( String name, String filterExpr, Object[] filterArgs,
+ SearchControls cons ) throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.Context#addToEnvironment(java.lang.String, java.lang.Object)
+ */
+ public Object addToEnvironment( String propName, Object propVal ) throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.Context#bind(javax.naming.Name, java.lang.Object)
+ */
+ public void bind( Name name, Object obj ) throws NamingException
+ {
+ // ignored
+
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.Context#bind(java.lang.String, java.lang.Object)
+ */
+ public void bind( String name, Object obj ) throws NamingException
+ {
+ // ignored
+
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.Context#close()
+ */
+ public void close() throws NamingException
+ {
+ // ignored
+
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.Context#composeName(javax.naming.Name, javax.naming.Name)
+ */
+ public Name composeName( Name name, Name prefix ) throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.Context#composeName(java.lang.String, java.lang.String)
+ */
+ public String composeName( String name, String prefix ) throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.Context#createSubcontext(javax.naming.Name)
+ */
+ public Context createSubcontext( Name name ) throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.Context#createSubcontext(java.lang.String)
+ */
+ public Context createSubcontext( String name ) throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.Context#destroySubcontext(javax.naming.Name)
+ */
+ public void destroySubcontext( Name name ) throws NamingException
+ {
+ // ignored
+
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.Context#destroySubcontext(java.lang.String)
+ */
+ public void destroySubcontext( String name ) throws NamingException
+ {
+ // ignored
+
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.Context#getEnvironment()
+ */
+ public Hashtable<?, ?> getEnvironment() throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.Context#getNameInNamespace()
+ */
+ public String getNameInNamespace() throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.Context#getNameParser(javax.naming.Name)
+ */
+ public NameParser getNameParser( Name name ) throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.Context#getNameParser(java.lang.String)
+ */
+ public NameParser getNameParser( String name ) throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.Context#list(javax.naming.Name)
+ */
+ public NamingEnumeration<NameClassPair> list( Name name ) throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.Context#list(java.lang.String)
+ */
+ public NamingEnumeration<NameClassPair> list( String name ) throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.Context#listBindings(javax.naming.Name)
+ */
+ public NamingEnumeration<Binding> listBindings( Name name ) throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.Context#listBindings(java.lang.String)
+ */
+ public NamingEnumeration<Binding> listBindings( String name ) throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.Context#lookup(javax.naming.Name)
+ */
+ public Object lookup( Name name ) throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.Context#lookup(java.lang.String)
+ */
+ public Object lookup( String name ) throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.Context#lookupLink(javax.naming.Name)
+ */
+ public Object lookupLink( Name name ) throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.Context#lookupLink(java.lang.String)
+ */
+ public Object lookupLink( String name ) throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.Context#rebind(javax.naming.Name, java.lang.Object)
+ */
+ public void rebind( Name name, Object obj ) throws NamingException
+ {
+ // ignored
+
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.Context#rebind(java.lang.String, java.lang.Object)
+ */
+ public void rebind( String name, Object obj ) throws NamingException
+ {
+ // ignored
+
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.Context#removeFromEnvironment(java.lang.String)
+ */
+ public Object removeFromEnvironment( String propName ) throws NamingException
+ {
+ // ignored
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.Context#rename(javax.naming.Name, javax.naming.Name)
+ */
+ public void rename( Name oldName, Name newName ) throws NamingException
+ {
+ // ignored
+
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.Context#rename(java.lang.String, java.lang.String)
+ */
+ public void rename( String oldName, String newName ) throws NamingException
+ {
+ // ignored
+
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.Context#unbind(javax.naming.Name)
+ */
+ public void unbind( Name name ) throws NamingException
+ {
+ // ignored
+
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.naming.Context#unbind(java.lang.String)
+ */
+ public void unbind( String name ) throws NamingException
+ {
+ // ignored
+
+ }
+
+}
Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/jndi/impl/SimpleReadCommand.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/jndi/impl/SimpleReadCommand.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/jndi/impl/SimpleReadCommand.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/jndi/impl/SimpleReadCommand.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,128 @@
+/*
+ * 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.dao.jndi.impl;
+
+import javax.naming.InvalidNameException;
+import javax.naming.Name;
+import javax.naming.NamingException;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.DirContext;
+import javax.naming.ldap.LdapName;
+
+import org.apache.configuration.dao.ConfigurationDaoException;
+import org.apache.configuration.dao.jndi.Command;
+import org.apache.configuration.dao.jndi.ContextMapping;
+import org.apache.configuration.dao.jndi.NameMapping;
+import org.apache.configuration.impl.ConfigurationDictionary;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * SimpleReadCommand reads a configurationDictionary from the directory.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ * @deprecated use DefaultReadCommand instead.
+ */
+public class SimpleReadCommand implements Command<ConfigurationDictionary>
+{
+
+ private static final Logger log = LoggerFactory.getLogger( SimpleReadCommand.class );
+ private final ContextMapping contextMapping;
+
+ private final Name name;
+ /**
+ * Creates a new instance of SimpleReadCommand.
+ *
+ */
+ public SimpleReadCommand(ContextMapping contextMapping, Name name)
+ {
+
+ this.name = name;
+ this.contextMapping=contextMapping;
+ }
+
+ /**
+ *
+ * Creates a new instance of SimpleReadCommand.
+ *
+ * @param nameMapping
+ * @param contextMapping
+ * @param pid
+ *
+ */
+ public SimpleReadCommand(NameMapping nameMapping, ContextMapping contextMapping, String pid)
+ {
+
+ this.name = getDistinguishedName( nameMapping, pid );
+ this.contextMapping=contextMapping;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.configuration.dao.jndi.Command#execute(javax.naming.directory.DirContext)
+ * an alternate would be to read an object by searching with a
+ * "(&(objectclass=apacheserviceconfiguration) (apacheservicefactorypid=" + factoryPid + "))";
+ */
+ public ConfigurationDictionary execute( DirContext dirContext )
+ {
+ ConfigurationDictionary configurationDictionary;
+ try
+ {
+ Attributes atts =dirContext.getAttributes( name );
+ configurationDictionary = createConfigurationDictionary( atts );
+ }
+ catch ( NamingException e )
+ {
+ log.error( name+" could not be read.",e );
+ throw new ConfigurationDaoException(name+" could not be read.",e);
+ }
+
+
+ return configurationDictionary;
+ }
+
+
+
+ private ConfigurationDictionary createConfigurationDictionary( Attributes atts ) throws NamingException
+ {
+ ConfigurationDictionary configurationDictionary = contextMapping.transform( atts );
+ contextMapping.translateDirctoryKeysToOsgiKeys( configurationDictionary );
+ return configurationDictionary;
+ }
+
+ private Name getDistinguishedName(NameMapping nameMapping, String pid )
+ {
+
+ LdapName dn;
+ try
+ {
+ dn = nameMapping.getDefaultNamingBaseName();
+ dn.add(ContextMapping.APACHEDS_SERVICE_PID +'='+ pid);
+ }
+ catch ( InvalidNameException e )
+ {
+ throw new IllegalArgumentException("Invalid Name "+ pid+ ' '+e.toString());
+ }
+
+ return dn;
+ }
+
+}
Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/jndi/impl/UpdateCommand.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/jndi/impl/UpdateCommand.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/jndi/impl/UpdateCommand.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/jndi/impl/UpdateCommand.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,310 @@
+/*
+ * 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.dao.jndi.impl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Vector;
+
+import javax.naming.Name;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.ModificationItem;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.configuration.dao.ConfigurationDaoException;
+import org.apache.configuration.dao.jndi.Command;
+import org.apache.configuration.dao.jndi.ContextMapping;
+import org.apache.configuration.dao.jndi.NameMapping;
+import org.apache.configuration.impl.ConfigurationDictionary;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * UpdateCommand command object for updating a ConfigurationDictionary directory entry.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class UpdateCommand implements Command<Boolean>
+{
+ private static final Logger log = LoggerFactory.getLogger( UpdateCommand.class );
+ private final ContextMapping contextMapping;
+ private final NameMapping nameMapping;
+ private final ConfigurationDictionary updatedConfigurationDictionary;
+
+ /**
+ * Creates a new instance of CreateCommand.
+ *
+ */
+ public UpdateCommand(NameMapping nameMapping, ContextMapping contextMapping, ConfigurationDictionary updatedConfigurationDictionary)
+ {
+ this.contextMapping=contextMapping;
+ this.nameMapping=nameMapping;
+ ConfigurationDictionary copy = updatedConfigurationDictionary.createCopy();
+ contextMapping.translateOsgiKeysToDirectoryKeys( copy );
+ this.updatedConfigurationDictionary= copy;
+ log.debug( "Created command to update {}.",updatedConfigurationDictionary );
+ }
+
+
+ /* (non-Javadoc)
+ *
+ * @see org.apache.configuration.dao.jndi.Command#execute(javax.naming.directory.DirContext)
+ */
+ public Boolean execute( DirContext dirContext )
+ {
+
+ String pid = nameMapping.getPid( updatedConfigurationDictionary );
+ Name name = nameMapping.getDistinguishedName( updatedConfigurationDictionary );
+ String filter = DefaultReadCommand.FILTER_PART_ONE + pid + "))";
+ Command<List<ConfigurationDictionary>> listCommand= new ListCommand(
+ filter,
+ nameMapping,
+ contextMapping);
+
+ List<ConfigurationDictionary> list = listCommand.execute( dirContext );
+
+ if(list==null || list.isEmpty()){
+ return false;
+ }
+
+ ConfigurationDictionary persistedConfigurationDictionary = list.get( 0 );
+ contextMapping.translateOsgiKeysToDirectoryKeys( persistedConfigurationDictionary );
+ log.debug( "Retrieved persistedConfigurationDictionary {}.",persistedConfigurationDictionary );
+ log.debug( "Changes in updatedConfigurationDictionary {}.",updatedConfigurationDictionary );
+ ModificationItem[] mods = modifications( persistedConfigurationDictionary);
+ for ( ModificationItem item : mods )
+ {
+ log.debug( "Modifing {} with {}. ",name, item );
+ }
+ try
+ {
+ dirContext.modifyAttributes( name, mods );
+ }
+ catch ( NamingException e )
+ {
+ log.error( "Could not modify "+name,e );
+ throw new ConfigurationDaoException("Could not modify "+name,e);
+ }
+
+ log.debug( "Modified entry {} with DN [{}].",updatedConfigurationDictionary, name );
+ return true;
+ }
+
+
+ private ModificationItem[] modifications(ConfigurationDictionary persistedConfigurationDictionary)
+ {
+ Collection<ModificationItem> modificationItems = listRemovalModifications(persistedConfigurationDictionary);
+ modificationItems.addAll( listAdditionModifications(persistedConfigurationDictionary));
+ modificationItems.addAll( listReplacementModifications(persistedConfigurationDictionary));
+ ModificationItem[] mods = (ModificationItem[]) modificationItems.toArray(new ModificationItem[0]);
+ log.debug( "Created {} modificationItems .",mods.length );
+ return mods;
+
+ }
+
+ /**
+ *
+ * @param persistedConfigurationDictionary
+ * @return collection of Replacement modificationItems
+ */
+ private Collection<ModificationItem> listReplacementModifications(ConfigurationDictionary persistedConfigurationDictionary){
+ Collection<ModificationItem> replacementMods = new ArrayList<ModificationItem>();
+ Collection<String> persistedKeys = getCollectionOfKeys( persistedConfigurationDictionary);
+ Collection<String> updatedKeys = getCollectionOfKeys( updatedConfigurationDictionary);
+ Collection<String> commonKeys = findKeysInCommon( persistedKeys, updatedKeys);
+ Attribute attributeToReplace = null;
+ for ( String key : commonKeys)
+ {
+ if(compareObjectOrVector(persistedConfigurationDictionary.get( key ),updatedConfigurationDictionary.get( key ) )){
+ continue;
+ }
+
+ log.debug( "Adding "+key+" updated value: {} to replace old value: {}.",updatedConfigurationDictionary.get( key ),persistedConfigurationDictionary.get( key ) );
+ attributeToReplace= new BasicAttribute(key);
+ Object value = updatedConfigurationDictionary.get( key );
+ contextMapping.addValueToAttribute(
+ value,
+ attributeToReplace );
+ replacementMods.add(
+ new ModificationItem(
+ DirContext.REPLACE_ATTRIBUTE,
+ attributeToReplace)
+ );
+
+ }
+ log.debug( "Created {} replaceModifications.",replacementMods.size() );
+ return replacementMods;
+ }
+
+ /**
+ *
+ * compare an object that may be a vector.
+ *
+ * @param updated
+ * @param persisted
+ * @return true if they are functionally the same.
+ */
+ private boolean compareObjectOrVector (Object updated, Object persisted){
+ if(updated instanceof Vector && persisted instanceof Vector) {
+ Vector u = (Vector)updated;
+ Vector p = (Vector)persisted;
+ if(u.size()!=p.size()){
+ return false;
+ }
+ if(CollectionUtils.subtract( u, p).isEmpty()){
+ return true;
+ }
+ return false;
+ }
+ if(persisted.equals( updated)){
+
+ return true;
+ }
+ log.debug( "updated value {} not the same as persisted value{}",updated,persisted );
+ return false;
+ }
+
+
+ /**
+ *
+ * @param persistedConfigurationDictionary
+ * @return collection of Addition modificationItems
+ */
+ private Collection<ModificationItem> listAdditionModifications(ConfigurationDictionary persistedConfigurationDictionary){
+ Collection<ModificationItem> addMods = new ArrayList<ModificationItem>();
+ Collection<String> persistedKeys = getCollectionOfKeys( persistedConfigurationDictionary );
+
+ Collection<String> updatedKeys = getCollectionOfKeys( updatedConfigurationDictionary);
+
+ Collection<String> keysToAddToPersisted = findKeysToAdd(
+ persistedKeys,
+ updatedKeys);
+ Attribute attributeToAdd = null;
+ for ( String key : keysToAddToPersisted )
+ {
+ attributeToAdd= new BasicAttribute(key);
+ Object value = updatedConfigurationDictionary.get( key );
+ contextMapping.addValueToAttribute(
+ value,
+ attributeToAdd );
+ addMods.add(
+ new ModificationItem(
+ DirContext.ADD_ATTRIBUTE,
+ attributeToAdd)
+ );
+ log.debug( "Created addModification for {}.",key );
+ }
+ log.debug( "Created {} addMods.",addMods.size() );
+ return addMods;
+ }
+
+
+
+
+ /**
+ *
+ * @param persistedConfigurationDictionary
+ * @return list of removal modificationItems
+ */
+ private Collection<ModificationItem> listRemovalModifications(ConfigurationDictionary persistedConfigurationDictionary){
+ Collection<ModificationItem> removeMods = new ArrayList<ModificationItem>();
+ Collection<String> persistedKeys = getCollectionOfKeys( persistedConfigurationDictionary);
+ Collection<String> updatedKeys = getCollectionOfKeys( updatedConfigurationDictionary);
+
+ Collection<String> keysToRemoveFromPersisted = findKeysToRemove(
+ persistedKeys,
+ updatedKeys);
+ Attribute att = null;
+// ModificationItem item = null;
+ for ( String key : keysToRemoveFromPersisted )
+ {
+ att = new BasicAttribute(key, persistedConfigurationDictionary.get( key ));
+
+ removeMods.add(
+ new ModificationItem(
+ DirContext.REMOVE_ATTRIBUTE,
+ att)
+ );
+ log.debug( "Created removeModification for {}.",key );
+ }
+ log.debug( "Created {} removeMods.",removeMods.size() );
+ return removeMods;
+ }
+
+ /**
+ *
+ * Find removed keys
+ *
+ * @param persistedKeys
+ * @param updatedKeys
+ * @return keys in persistedKeys that are not in updatedKeys
+ */
+ @SuppressWarnings("unchecked")
+ private Collection<String> findKeysToRemove(Collection<String> persistedKeys, Collection<String> updatedKeys){
+ Collection<String> keysToRemove = CollectionUtils.subtract( persistedKeys, updatedKeys );
+ log.debug( keysToRemove+" keys in {} that are not in {}.",persistedKeys,updatedKeys );
+ return keysToRemove;
+ }
+
+ /**
+ *
+ * Find additional keys
+ *
+ * @param persistedKeys
+ * @param updatedKeys
+ * @return keys in updatedKeys that are not in persistedKeys
+ */
+ @SuppressWarnings("unchecked")
+ private Collection<String> findKeysToAdd(Collection persistedKeys, Collection updatedKeys){
+ Collection<String> keysToAdd = CollectionUtils.subtract( updatedKeys, persistedKeys);
+ log.debug( keysToAdd+" keys in {} that are not in {}.",updatedKeys,persistedKeys );
+ return keysToAdd;
+ }
+
+
+ /**
+ *
+ * Find common keys
+ *
+ * @param persistedKeys
+ * @param updatedKeys
+ * @return findKeysInCommon
+ */
+ @SuppressWarnings("unchecked")
+ private Collection<String> findKeysInCommon(Collection persistedKeys, Collection updatedKeys){
+ Collection<String> keysInCommon = CollectionUtils.intersection( persistedKeys, updatedKeys );
+ log.debug( keysInCommon+" keys in {} that are also in {}.",updatedKeys,persistedKeys );
+ return keysInCommon;
+ }
+
+ private Collection<String> getCollectionOfKeys( ConfigurationDictionary persistedConfigurationDictionary )
+ {
+ Collection<String> persistedKeys = new ArrayList<String>();
+ CollectionUtils.addAll( persistedKeys, persistedConfigurationDictionary.keys());
+ return persistedKeys;
+ }
+
+}
Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/jndi/impl/package-info.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/jndi/impl/package-info.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/jndi/impl/package-info.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/jndi/impl/package-info.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,9 @@
+/**
+ * org.apache.configuration.dao.jndi.impl is the set of classes that implement the
+ * interfaces in org.apache.configuration.dao.jndi to create a JNDI based
+ * <em>Data Access Object</em> for persisting Configuration dictionariers in a
+ * JNDI backend store.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+package org.apache.configuration.dao.jndi.impl;
\ No newline at end of file
Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/jndi/package-info.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/jndi/package-info.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/jndi/package-info.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/jndi/package-info.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,8 @@
+/**
+ * org.apache.configuration.dao.jndi is the set of interfaces and classes that specify a
+ * <em>Data Access Object</em> for persisting Configurations dictionaries in a
+ * JNDI backend store that is found via an InitialContextFactory OSGi Service.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+package org.apache.configuration.dao.jndi;
\ No newline at end of file
Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/package-info.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/package-info.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/package-info.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/dao/package-info.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,8 @@
+/**
+ * org.apache.configuration.dao is the set of interfaces and classes that specify a
+ * <em>Data Access Object</em> for persisting Configurations dictionaries in a
+ * backend store.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+package org.apache.configuration.dao;
\ No newline at end of file
Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/event/AsyncExecutorService.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/event/AsyncExecutorService.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/event/AsyncExecutorService.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/event/AsyncExecutorService.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,51 @@
+/*
+ * 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.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+
+/**
+ * <p>A <tt>AsyncExecutorService</tt> encapsulates an {@link ExecutorService} to present
+ * a instanceFactory method for other <em>Spring</em> wired beans to obtain a {@link Executor} and
+ * to offer a <em>Spring bean destroy-method</em> for shuting down the execution of commands.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class AsyncExecutorService
+{
+
+ private ExecutorService executorService = Executors.newSingleThreadExecutor();
+
+
+ public void destroy()
+ {
+ executorService.shutdown();
+ }
+
+ public Executor getExecutor(){
+ return executorService;
+ }
+}
Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/event/ConfigurationChangeManager.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/event/ConfigurationChangeManager.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/event/ConfigurationChangeManager.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/event/ConfigurationChangeManager.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,378 @@
+/*
+ * 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.concurrent.Executor;
+
+import org.apache.configuration.dao.ConfigurationDaoListener;
+import org.apache.configuration.impl.ConfigurationDictionary;
+import org.apache.configuration.impl.ConfigurationStore;
+import org.apache.configuration.impl.ConfigurationTransformer;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.cm.ConfigurationEvent;
+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;
+
+
+/**
+ * ConfigurationChangeManager will asynchronously update ManageService and ManagedServiceFactory registered
+ * serviceReferences and ConfigurationListeners when changes occur on the backend ConfigurationStore.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ *
+ */
+public class ConfigurationChangeManager implements ConfigurationDaoListener
+{
+
+ /** the log for this class */
+ private static final Logger log = LoggerFactory.getLogger( ConfigurationChangeManager.class );
+
+ private Executor executor;
+
+ private ManagedServiceFactoryTrackingAdapter managedServiceFactoryTrackingAdapter;
+
+ private ManagedServiceTrackingAdapter managedServiceTrackingAdapter;
+
+ private ConfigurationStore configurationStore;
+
+ private ConfigurationTransformer configurationTransformer;
+
+ private ConfigurationListener configurationListener;
+
+
+ /**
+ * ChangeListner implementation that listens to Configuration change events coming
+ * from the ConfigurationStore and converts them into tasks that are sent
+ * to the executor queue.
+ *
+ * SERVICE_STORE_UPDATING and FACTORY_STORE_UPDATING are the two update types sent.
+ *
+ *
+ */
+ public void configurationChanged( ChangeType changeType, ConfigurationDictionary configurationIn )
+ {
+ ConfigurationDictionary configurationDictionary = new ConfigurationDictionary( configurationIn );
+
+ String servicePid = ( String ) configurationDictionary.get( Constants.SERVICE_PID );
+
+ if ( servicePid == null )
+ {
+ log.error( "A configuration change was detected but the servicePid could not be found in dictionary {}.",
+ configurationDictionary );
+ return;
+ }
+
+ Object factoryPidObject = configurationDictionary.get( ConfigurationAdmin.SERVICE_FACTORYPID );
+
+ ServiceReference serviceReference = null;
+ if ( factoryPidObject == null )
+ {
+ serviceReference = updateManagedService( servicePid, configurationDictionary, changeType );
+ }
+ else
+ {
+ String factoryPid = ( String ) factoryPidObject;
+ serviceReference = updateManagedServiceFactory( servicePid, factoryPid, configurationDictionary, changeType );
+ }
+ if ( serviceReference == null )
+ {
+ log.error( "Failed to find a serviceReference for updated configuration =" + configurationDictionary );
+ return;
+ }
+ sendEventToListener( changeType, configurationDictionary, serviceReference );
+
+ }
+
+
+ void sendEventToListener( ChangeType changeType, ConfigurationDictionary configurationDictionary,
+ ServiceReference serviceReference )
+ {
+ int type;
+ if ( ChangeType.DELETED.equals( changeType ) )
+ {
+ type = ConfigurationEvent.CM_DELETED;
+ }
+ else
+ {
+ type = ConfigurationEvent.CM_UPDATED;
+ }
+
+ final ConfigurationEvent event = new ConfigurationEvent( serviceReference, type, configurationDictionary
+ .getFactoryPid(), configurationDictionary.getServicePid() );
+
+ Runnable task = new Runnable()
+ {
+
+ public void run()
+ {
+ configurationListener.configurationEvent( event );
+
+ }
+
+ };
+
+ executor.execute( task );
+ }
+
+
+ /**
+ * @param servicePid
+ */
+ ServiceReference updateManagedService( final String servicePid,
+ final ConfigurationDictionary configurationDictionary, final ChangeType changeType )
+ {
+ final ServiceReference serviceReference = findManagedServiceReference( servicePid );
+ if ( serviceReference == null )
+ {
+ log.error( "Could not find a serviceReference for servicePid=" + servicePid );
+ return serviceReference;
+ }
+ Runnable command = new Runnable()
+ {
+
+ public void run()
+ {
+
+ try
+ {
+ String location = serviceReference.getBundle().getLocation();
+ if ( location == null )
+ {
+ log.error( "Could not get location from the serviceReferrence." );
+ return;
+ }
+ //Send Bind request to the configurationStore
+ if ( configurationStore != null )
+ {
+ configurationStore.retrieveAndBind( servicePid, location );
+ }
+ else
+ {
+ log.warn( "Did not bind pid {} and location {} to the persisted store.", servicePid, location );
+ }
+
+ ManagedService managedService = ( ManagedService ) managedServiceTrackingAdapter
+ .getService( serviceReference );
+ if ( managedService == null )
+ {
+ log.error( "Could not find a ManagedService from the associated with ServiceReference="
+ + serviceReference );
+ return;
+ }
+ if ( ChangeType.DELETED.equals( changeType ) )
+ {
+ managedService.updated( null );
+ }
+ else
+ {
+ managedService.updated( configurationTransformer.transform( serviceReference,
+ configurationDictionary ) );
+ }
+
+ }
+ catch ( Exception e )
+ {
+ log.error( "Failed to process store change for servicePid=" + servicePid, e );
+ }
+
+ }
+
+ };
+
+ executor.execute( command );
+ return serviceReference;
+ }
+
+
+ ServiceReference updateManagedServiceFactory( final String servicePid, final String factoryPid,
+ final ConfigurationDictionary configurationDictionary, final ChangeType changeType )
+ {
+ final ServiceReference serviceReference = findManagedServiceFactoryReference( factoryPid );
+ if ( serviceReference == null )
+ {
+ log.error( "Could not find a serviceReference for factoryPid=" + factoryPid );
+ return serviceReference;
+ }
+
+ Runnable command = new Runnable()
+ {
+
+ public void run()
+ {
+
+ try
+ {
+ String location = serviceReference.getBundle().getLocation();
+
+ if ( location == null )
+ {
+ log.error( "Could not get location from the serviceReferrence." );
+ return;
+ }
+
+ //Send Bind request to the configurationStore
+ if ( configurationStore != null )
+ {
+ configurationStore.retrieveAndBind( servicePid, location );
+ }
+ else
+ {
+ log.warn( "Did not bind pid {} and location {} to the persisted store.", servicePid, location );
+ }
+
+ ManagedServiceFactory managedServiceFactory = ( ManagedServiceFactory ) managedServiceFactoryTrackingAdapter
+ .getService( serviceReference );
+
+ if ( managedServiceFactory == null )
+ {
+ log.error( "Could not find a ManagedServiceFactory from the associated with ServiceReference="
+ + serviceReference );
+ return;
+ }
+ if ( ChangeType.DELETED.equals( changeType ) )
+ {
+ managedServiceFactory.deleted( servicePid );
+ }
+ else
+ {
+ managedServiceFactory.updated( servicePid, configurationTransformer.transform(
+ serviceReference, configurationDictionary ) );
+ }
+ }
+ catch ( Exception e )
+ {
+ log.error( "Failed to process store change for servicePid=" + servicePid + " factoryPid="
+ + servicePid + "", e );
+ }
+
+ }
+
+ };
+
+ executor.execute( command );
+ return serviceReference;
+ }
+
+
+ /**
+ *
+ * findManagedServiceFactory for a given factoryPid.
+ *
+ * @param factoryPid
+ * @return
+ */
+ private ServiceReference findManagedServiceFactoryReference( String factoryPid )
+ {
+
+ for ( ServiceReference serviceReference : managedServiceFactoryTrackingAdapter.getServiceReferences() )
+ {
+ if ( factoryPid.equals( serviceReference.getProperty( ConfigurationAdmin.SERVICE_FACTORYPID ) ) )
+ {
+ return serviceReference;
+ }
+ }
+ return null;
+ }
+
+
+ /**
+ *
+ * findManagedService for a given servicePid.
+ *
+ * @param servicePid
+ * @return
+ */
+ private ServiceReference findManagedServiceReference( String servicePid )
+ {
+
+ for ( ServiceReference serviceReference : managedServiceTrackingAdapter.getServiceReferences() )
+ {
+ if ( servicePid.equals( serviceReference.getProperty( Constants.SERVICE_PID ) ) )
+ {
+ return serviceReference;
+ }
+ }
+ return null;
+ }
+
+
+ /**
+ * @param executor the executor to set
+ */
+ public void setExecutor( Executor executor )
+ {
+ this.executor = executor;
+ }
+
+
+ /**
+ * @param configurationStore the configurationStore to set
+ */
+ public void setConfigurationStore( ConfigurationStore configurationStore )
+ {
+ this.configurationStore = configurationStore;
+ }
+
+
+ /**
+ * @param configurationTransformer
+ */
+ public void setConfigurationTransformer( ConfigurationTransformer configurationTransformer )
+ {
+ this.configurationTransformer = configurationTransformer;
+ }
+
+
+ /**
+ * @param configurationListener the configurationListener to set
+ */
+ public void setConfigurationListener( ConfigurationListener configurationListener )
+ {
+ this.configurationListener = configurationListener;
+ }
+
+
+ /**
+ * @param managedServiceFactoryTrackingAdapter the managedServiceFactoryTrackingAdapter to set
+ */
+ public void setManagedServiceFactoryTrackingAdapter(
+ ManagedServiceFactoryTrackingAdapter managedServiceFactoryTrackingAdapter )
+ {
+ this.managedServiceFactoryTrackingAdapter = managedServiceFactoryTrackingAdapter;
+ }
+
+
+ /**
+ * @param managedServiceTrackingAdapter the managedServiceTrackingAdapter to set
+ */
+ public void setManagedServiceTrackingAdapter( ManagedServiceTrackingAdapter managedServiceTrackingAdapter )
+ {
+ this.managedServiceTrackingAdapter = managedServiceTrackingAdapter;
+ }
+
+}
Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/event/ConfigurationEventBroadcaster.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/event/ConfigurationEventBroadcaster.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/event/ConfigurationEventBroadcaster.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/event/ConfigurationEventBroadcaster.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,59 @@
+/*
+ * 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.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.osgi.service.cm.ConfigurationEvent;
+import org.osgi.service.cm.ConfigurationListener;
+
+/**
+ * ConfigurationEventBroadcaster.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class ConfigurationEventBroadcaster implements ConfigurationListener
+{
+ List<ConfigurationListener> listeners = new CopyOnWriteArrayList<ConfigurationListener>();
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.cm.ConfigurationListener#configurationEvent(org.osgi.service.cm.ConfigurationEvent)
+ */
+ public void configurationEvent( ConfigurationEvent event )
+ {
+ for ( ConfigurationListener configurationListener : listeners )
+ {
+ configurationListener.configurationEvent( event );
+ }
+
+ }
+
+ /**
+ * @param listeners the listeners to set
+ */
+ public void setListeners( List<ConfigurationListener> listeners )
+ {
+ this.listeners = listeners;
+ }
+
+}
Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/event/ManagedServiceFactoryTrackerCustomizer.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/event/ManagedServiceFactoryTrackerCustomizer.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/event/ManagedServiceFactoryTrackerCustomizer.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/event/ManagedServiceFactoryTrackerCustomizer.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,190 @@
+/*
+ * 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.Set;
+import java.util.concurrent.Executor;
+
+import org.apache.configuration.impl.ConfigurationDictionary;
+import org.apache.configuration.impl.ConfigurationStore;
+import org.apache.configuration.impl.ConfigurationTransformer;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedServiceFactory;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * ManagedServiceTracker extends ServiceTracker to handle active ManagedServiceFactory Services.
+ *
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ *
+ */
+
+public class ManagedServiceFactoryTrackerCustomizer implements ServiceTrackerCustomizer
+{
+
+ /** the log for this class */
+ private final Logger log = LoggerFactory.getLogger( ManagedServiceFactoryTrackerCustomizer.class );
+ private ConfigurationStore configurationStore;
+// private BundleContext bundleContext;
+ private ConfigurationTransformer configurationTransformer;
+ private ManagedServiceFactoryTrackingAdapter managedServiceFactoryTrackingAdapter;
+ private Executor executor;
+
+
+
+ /* (non-Javadoc)
+ * @see org.osgi.util.tracker.ServiceTracker#addingService(org.osgi.framework.ServiceReference)
+ */
+
+ public Object addingService( final ServiceReference serviceReference )
+ {
+ Runnable command =
+ new Runnable() {
+
+ public void run()
+ {
+ String factoryPid = (String) serviceReference.getProperty(ConfigurationAdmin.SERVICE_FACTORYPID);
+ String location = serviceReference.getBundle().getLocation();
+ Set<String> pidsForFactory = configurationStore.listPids( factoryPid);
+ for ( String servicePid : pidsForFactory )
+ {
+ try
+ {
+ ConfigurationDictionary configurationDictionary;
+ try
+ {
+ configurationDictionary = configurationStore.retrieveAndBind( servicePid, location );
+ }
+ catch ( ConfigurationException e )
+ {
+ configurationDictionary=null;
+ log.error( "Failed to retrieve configuration from the backend.",e );
+ }
+// ManagedServiceFactory managedServiceFactory = (ManagedServiceFactory)bundleContext.getService( serviceReference );
+ ManagedServiceFactory managedServiceFactory = managedServiceFactoryTrackingAdapter.getService(serviceReference);
+ managedServiceFactory.updated( servicePid,configurationTransformer.transform( serviceReference, configurationDictionary) );
+ }
+ catch ( Exception e )
+ {
+ log.error( "Failed to update ManagedServiceFactory for factoryPid="+factoryPid,e );
+ }
+ }
+
+ }
+
+ };
+
+ executor.execute( command );
+ return serviceReference ;
+ }
+
+
+
+ /* (non-Javadoc)
+ * @see org.osgi.util.tracker.ServiceTracker#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
+ */
+
+ public void removedService( final ServiceReference serviceReference, Object service )
+ {
+ Runnable command =
+ new Runnable() {
+
+ public void run()
+ {
+ String factoryPid = (String) serviceReference.getProperty(ConfigurationAdmin.SERVICE_FACTORYPID);
+ Set<String> pidsForFactory = configurationStore.listPids( factoryPid);
+ for ( String servicePid : pidsForFactory )
+ {
+ configurationStore.unbind(servicePid);
+ }
+
+ }
+
+ };
+
+ executor.execute( command );
+
+ }
+
+ public void modifiedService( ServiceReference arg0, Object arg1 )
+ {
+// ignore
+
+ }
+
+
+
+// /**
+// * @param bundleContext the bundleContext to set
+// */
+// public void setBundleContext( BundleContext bundleContext )
+// {
+// this.bundleContext = bundleContext;
+// }
+
+
+
+ /**
+ * @param configurationStore the configurationStore to set
+ */
+ public void setConfigurationStore( ConfigurationStore configurationStore )
+ {
+ this.configurationStore = configurationStore;
+ }
+
+
+
+ /**
+ * @param configurationTransformer the configurationTransformer to set
+ */
+ public void setConfigurationTransformer( ConfigurationTransformer configurationTransformer )
+ {
+ this.configurationTransformer = configurationTransformer;
+ }
+
+
+
+ /**
+ * @param executor the executor to set
+ */
+ public void setExecutor( Executor executor )
+ {
+ this.executor = executor;
+ }
+
+
+
+ /**
+ * @param managedServiceFactoryTrackingAdapter the managedServiceFactoryTrackingAdapter to set
+ */
+ public void setManagedServiceFactoryTrackingAdapter(
+ ManagedServiceFactoryTrackingAdapter managedServiceFactoryTrackingAdapter )
+ {
+ this.managedServiceFactoryTrackingAdapter = managedServiceFactoryTrackingAdapter;
+ }
+
+}
Added: directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/event/ManagedServiceFactoryTrackingAdapter.java
URL: http://svn.apache.org/viewvc/directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/event/ManagedServiceFactoryTrackingAdapter.java?view=auto&rev=501176
==============================================================================
--- directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/event/ManagedServiceFactoryTrackingAdapter.java (added)
+++ directory/sandbox/jconlon/osgi-services/configuration-service/src/main/java/org/apache/configuration/event/ManagedServiceFactoryTrackingAdapter.java Mon Jan 29 12:38:25 2007
@@ -0,0 +1,44 @@
+/*
+ * 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.springosgi.ServiceTrackingAdapter;
+import org.osgi.service.cm.ManagedService;
+import org.osgi.service.cm.ManagedServiceFactory;
+
+/**
+ * A <tt>ManagedServiceFactoryTrackingAdapter</tt> is a {@link ServiceTrackingAdapter} for
+ * {@link ManagedService} serviceReferences.
+ *
+ * @see ServiceTrackingAdapter
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class ManagedServiceFactoryTrackingAdapter extends ServiceTrackingAdapter<ManagedServiceFactory>
+{
+
+ public ManagedServiceFactoryTrackingAdapter()
+ {
+ super(ManagedServiceFactory.class);
+ }
+
+
+}