You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by fm...@apache.org on 2009/07/28 16:06:59 UTC

svn commit: r798531 - in /felix/trunk/scr/src/main/java/org/apache/felix/scr/impl: ./ config/ manager/ metadata/

Author: fmeschbe
Date: Tue Jul 28 14:06:58 2009
New Revision: 798531

URL: http://svn.apache.org/viewvc?rev=798531&view=rev
Log:
FELIX-1416 Implement new ComponentHolder abstraction and adapt uses.

Added:
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/ComponentRegistry.java   (with props)
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/AbstractComponentHolder.java   (with props)
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ComponentHolder.java   (with props)
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurationComponentRegistry.java   (with props)
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfiguredComponentHolder.java   (with props)
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/UnconfiguredComponentHolder.java   (with props)
Modified:
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/Activator.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DelayedComponentManager.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/metadata/ComponentMetadata.java

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/Activator.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/Activator.java?rev=798531&r1=798530&r2=798531&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/Activator.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/Activator.java Tue Jul 28 14:06:58 2009
@@ -26,6 +26,7 @@
 import java.util.Iterator;
 import java.util.Map;
 
+import org.apache.felix.scr.impl.config.ConfigurationComponentRegistry;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
@@ -78,7 +79,7 @@
     {
         m_context = context;
         m_componentBundles = new HashMap();
-        m_componentRegistry = new ComponentRegistry( m_context );
+        m_componentRegistry = createComponentRegistry( context);
 
         // require the log service
         m_logService = new ServiceTracker( context, LOGSERVICE_CLASS, null );
@@ -135,7 +136,7 @@
         // 112.8.2 dispose off all active components
         disposeAllComponents();
 
-        // dispose off the component registry
+        // dispose component registry
         m_componentRegistry.dispose();
 
         // terminate the actor thread and wait for it for a limited time
@@ -293,6 +294,22 @@
     }
 
 
+    public static ComponentRegistry createComponentRegistry( BundleContext bundleContext )
+    {
+        try
+        {
+            return new ConfigurationComponentRegistry( bundleContext );
+        }
+        catch ( Throwable t )
+        {
+            log( LogService.LOG_INFO, bundleContext.getBundle(),
+                "ConfigurationAdmin supporting ComponentRegistry not available, not using ConfigurationAdmin", t );
+        }
+
+        return new ComponentRegistry( bundleContext );
+    }
+
+
     /**
      * Returns the <code>BundleContext</code> of the bundle.
      * <p>
@@ -426,7 +443,7 @@
      * @param ex An optional <code>Throwable</code> whose stack trace is written,
      *      or <code>null</code> to not log a stack trace.
      */
-    static void log( int level, Bundle bundle, String message, Throwable ex )
+    public static void log( int level, Bundle bundle, String message, Throwable ex )
     {
         if ( m_logLevel >= level )
         {

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java?rev=798531&r1=798530&r2=798531&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java Tue Jul 28 14:06:58 2009
@@ -29,17 +29,13 @@
 import java.util.List;
 import java.util.StringTokenizer;
 
+import org.apache.felix.scr.impl.config.ComponentHolder;
 import org.apache.felix.scr.impl.helper.Logger;
 import org.apache.felix.scr.impl.manager.AbstractComponentManager;
-import org.apache.felix.scr.impl.manager.ComponentFactoryImpl;
-import org.apache.felix.scr.impl.manager.DelayedComponentManager;
-import org.apache.felix.scr.impl.manager.ImmediateComponentManager;
-import org.apache.felix.scr.impl.manager.ServiceFactoryComponentManager;
 import org.apache.felix.scr.impl.metadata.ComponentMetadata;
 import org.apache.felix.scr.impl.metadata.XmlHandler;
 import org.apache.felix.scr.impl.parser.KXml2SAXParser;
 import org.osgi.framework.BundleContext;
-import org.osgi.service.cm.ConfigurationAdmin;
 import org.osgi.service.component.ComponentException;
 import org.osgi.service.log.LogService;
 import org.osgi.util.tracker.ServiceTracker;
@@ -62,9 +58,6 @@
     private List m_managers = new ArrayList();
 
     // The Configuration Admin tracker providing configuration for components
-    private ServiceTracker m_configurationAdmin;
-
-    // The Configuration Admin tracker providing configuration for components
     private ServiceTracker m_logService;
 
     // thread acting upon configurations
@@ -88,8 +81,8 @@
      *
      * @throws ComponentException if any error occurrs initializing this class
      */
-    BundleComponentActivator( ComponentRegistry componentRegistry, ComponentActorThread componentActor,
-        BundleContext context, int logLevel ) throws ComponentException
+    BundleComponentActivator( ComponentRegistry componentRegistry,
+        ComponentActorThread componentActor, BundleContext context, int logLevel ) throws ComponentException
     {
         // keep the parameters for later
         m_componentRegistry = componentRegistry;
@@ -99,10 +92,6 @@
         // mark this instance active
         m_active = true;
 
-        // have the Configuration Admin Service handy (if available)
-        m_configurationAdmin = new ServiceTracker( context, ConfigurationAdmin.class.getName(), null );
-        m_configurationAdmin.open();
-
         // have the LogService handy (if available)
         m_logService = new ServiceTracker( context, Activator.LOGSERVICE_CLASS, null );
         m_logService.open();
@@ -176,46 +165,18 @@
                         metadata.validate( this );
 
                         // Request creation of the component manager
-                        AbstractComponentManager manager;
-                        if ( metadata.isFactory() )
-                        {
-                            // 112.2.4 SCR must register a Component Factory
-                            // service on behalf ot the component
-                            // as soon as the component factory is satisfied
-                            manager = new ComponentFactoryImpl( this, metadata, m_componentRegistry );
-                        }
-                        else if ( metadata.isImmediate() )
-                        {
-                            manager = new ImmediateComponentManager( this, metadata, m_componentRegistry );
-                        }
-                        else if ( metadata.getServiceMetadata() != null )
-                        {
-                            if ( metadata.getServiceMetadata().isServiceFactory() )
-                            {
-                                manager = new ServiceFactoryComponentManager( this, metadata, m_componentRegistry );
-                            }
-                            else
-                            {
-                                manager = new DelayedComponentManager( this, metadata, m_componentRegistry );
-                            }
-                        }
-                        else
-                        {
-                            // if we get here, which is not expected after all, we fail
-                            throw new IllegalArgumentException( "Cannot create a component manager for "
-                                + metadata.getName() );
-                        }
+                        ComponentHolder holder = m_componentRegistry.createComponentHolder( this, metadata );
 
                         // register the component after validation
-                        m_componentRegistry.registerComponent( metadata.getName(), manager );
-                        m_managers.add( manager );
+                        m_componentRegistry.registerComponent( metadata.getName(), holder );
+                        m_managers.add( holder );
 
                         // enable the component
                         if ( metadata.isEnabled() )
                         {
-                            manager.enable();
+                            holder.enableComponents();
                         }
-                    }
+                   }
                     catch ( Throwable t )
                     {
                         // There is a problem with this particular component, we'll log the error
@@ -275,30 +236,24 @@
 
         while ( m_managers.size() != 0 )
         {
-            AbstractComponentManager manager = ( AbstractComponentManager ) m_managers.get( 0 );
+            ComponentHolder holder = ( ComponentHolder ) m_managers.get( 0 );
             try
             {
-                m_managers.remove( manager );
-                manager.dispose( reason );
+                m_managers.remove( holder );
+                holder.disposeComponents( reason );
             }
             catch ( Exception e )
             {
-                log( LogService.LOG_ERROR, "BundleComponentActivator : Exception invalidating", manager
+                log( LogService.LOG_ERROR, "BundleComponentActivator : Exception invalidating", holder
                     .getComponentMetadata(), e );
             }
             finally
             {
-                m_componentRegistry.unregisterComponent( manager.getComponentMetadata().getName() );
+                m_componentRegistry.unregisterComponent( holder.getComponentMetadata().getName() );
             }
 
         }
 
-        // close the Configuration Admin tracker
-        if ( m_configurationAdmin != null )
-        {
-            m_configurationAdmin.close();
-        }
-
         log( LogService.LOG_DEBUG, "BundleComponentActivator : Bundle [" + m_context.getBundle().getBundleId()
             + "] STOPPED", null, null );
 
@@ -319,17 +274,6 @@
 
 
     /**
-     * Returns the list of instance references currently associated to this activator
-     *
-     * @return the list of instance references
-     */
-    public List getInstanceReferences()
-    {
-        return m_managers;
-    }
-
-
-    /**
     * Returns the BundleContext
     *
     * @return the BundleContext
@@ -341,18 +285,6 @@
 
 
     /**
-     * Returns the <code>ConfigurationAdmin</code> service used to retrieve
-     * configuration data for components managed by this activator or
-     * <code>null</code> if no Configuration Admin Service is available in the
-     * framework.
-     */
-    protected ConfigurationAdmin getConfigurationAdmin()
-    {
-        return ( ConfigurationAdmin ) m_configurationAdmin.getService();
-    }
-
-
-    /**
      * Implements the <code>ComponentContext.enableComponent(String)</code>
      * method by first finding the component(s) for the <code>name</code> and
      * then starting a thread to actually enable all components found.
@@ -365,21 +297,21 @@
      */
     public void enableComponent( String name )
     {
-        final AbstractComponentManager[] cm = getSelectedComponents( name );
-        if ( cm == null )
+        final ComponentHolder[] holder = getSelectedComponents( name );
+        if ( holder == null )
         {
             return;
         }
 
-        for ( int i = 0; i < cm.length; i++ )
+        for ( int i = 0; i < holder.length; i++ )
         {
             try
             {
-                cm[i].enable();
+                holder[i].enableComponents();
             }
             catch ( Throwable t )
             {
-                log( LogService.LOG_ERROR, "Cannot enable component", cm[i].getComponentMetadata(), t );
+                log( LogService.LOG_ERROR, "Cannot enable component", holder[i].getComponentMetadata(), t );
             }
         }
     }
@@ -398,22 +330,22 @@
      */
     public void disableComponent( String name )
     {
-        final AbstractComponentManager[] cm = getSelectedComponents( name );
-        if ( cm == null )
+        final ComponentHolder[] holder = getSelectedComponents( name );
+        if ( holder == null )
         {
             return;
         }
 
-        for ( int i = 0; i < cm.length; i++ )
+        for ( int i = 0; i < holder.length; i++ )
         {
             try
             {
-                log( LogService.LOG_DEBUG, "Disabling Component", cm[i].getComponentMetadata(), null );
-                cm[i].disable();
+                log( LogService.LOG_DEBUG, "Disabling Component", holder[i].getComponentMetadata(), null );
+                holder[i].disableComponents();
             }
             catch ( Throwable t )
             {
-                log( LogService.LOG_ERROR, "Cannot disable component", cm[i].getComponentMetadata(), t );
+                log( LogService.LOG_ERROR, "Cannot disable component", holder[i].getComponentMetadata(), t );
             }
         }
     }
@@ -434,12 +366,12 @@
      *      to the <code>name</code> parameter or <code>null</code> if no
      *      component manager with the given name is currently registered.
      */
-    private AbstractComponentManager[] getSelectedComponents( String name )
+    private ComponentHolder[] getSelectedComponents( String name )
     {
         // if all components are selected
         if ( name == null )
         {
-            return (org.apache.felix.scr.impl.manager.AbstractComponentManager[] ) m_managers.toArray( new AbstractComponentManager[m_managers.size()] );
+            return ( ComponentHolder[] ) m_managers.toArray( new ComponentHolder[m_managers.size()] );
         }
 
         if ( m_componentRegistry.getComponent( name ) != null )
@@ -448,10 +380,10 @@
             Iterator it = m_managers.iterator();
             while ( it.hasNext() )
             {
-                AbstractComponentManager cm = ( AbstractComponentManager ) it.next();
+                ComponentHolder cm = ( ComponentHolder ) it.next();
                 if ( name.equals( cm.getComponentMetadata().getName() ) )
                 {
-                    return new AbstractComponentManager[]
+                    return new ComponentHolder[]
                         { cm };
                 }
             }
@@ -462,6 +394,16 @@
     }
 
 
+    //---------- Component ID support
+
+    public long registerComponentId(AbstractComponentManager componentManager) {
+        return m_componentRegistry.registerComponentId(componentManager);
+    }
+
+    public void unregisterComponentId(AbstractComponentManager componentManager) {
+        m_componentRegistry.unregisterComponentId(componentManager.getId());
+    }
+
     //---------- Asynchronous Component Handling ------------------------------
 
     /**

Added: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/ComponentRegistry.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/ComponentRegistry.java?rev=798531&view=auto
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/ComponentRegistry.java (added)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/ComponentRegistry.java Tue Jul 28 14:06:58 2009
@@ -0,0 +1,327 @@
+/*
+ * 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.felix.scr.impl;
+
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.felix.scr.Component;
+import org.apache.felix.scr.ScrService;
+import org.apache.felix.scr.impl.config.ComponentHolder;
+import org.apache.felix.scr.impl.config.UnconfiguredComponentHolder;
+import org.apache.felix.scr.impl.manager.AbstractComponentManager;
+import org.apache.felix.scr.impl.manager.ComponentFactoryImpl;
+import org.apache.felix.scr.impl.metadata.ComponentMetadata;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.component.ComponentException;
+
+
+/**
+ * The <code>ComponentRegistry</code> class acts as the global registry for
+ * components by name and by component ID. As such the component registry also
+ * registers itself as the {@link ScrService} to support access to the
+ * registered components.
+ */
+public class ComponentRegistry implements ScrService
+{
+
+    /**
+     * The map of known components indexed by component name. The values are
+     * either the component names (for name reservations) or implementations
+     * of the {@link ComponentHolder} interface.
+     * <p>
+     * The {@link #checkComponentName(String)} will first add an entry to this
+     * map being the name of the component to reserve the name. After setting up
+     * the component, the {@link #registerComponent(String, ComponentHolder)}
+     * method replaces the value of the named entry with the actual
+     * {@link ComponentHolder}.
+     *
+     * @see #checkComponentName(String)
+     * @see #registerComponent(String, ComponentHolder)
+     * @see #unregisterComponent(String)
+     */
+    private Map m_componentsByName;
+
+    /**
+     * Map of components by component ID. This map indexed by the component
+     * ID number (<code>java.lang.Long</code>) contains the actual
+     * {@link AbstractComponentManager} instances existing in the system.
+     *
+     * @see #registerComponentId(AbstractComponentManager)
+     * @see #unregisterComponentId(long)
+     */
+    private Map m_componentsById;
+
+    /**
+     * Counter to setup the component IDs as issued by the
+     * {@link #registerComponentId(AbstractComponentManager)} method. This
+     * counter is only incremented.
+     */
+    private volatile long m_componentCounter;
+
+    /**
+     * The OSGi service registration for the ScrService provided by this
+     * instance.
+     */
+    private ServiceRegistration m_registration;
+
+
+    protected ComponentRegistry( BundleContext context )
+    {
+        m_componentsByName = new HashMap();
+        m_componentsById = new HashMap();
+        m_componentCounter = -1;
+
+        // register as ScrService
+        Dictionary props = new Hashtable();
+        props.put( Constants.SERVICE_DESCRIPTION, "Declarative Services Management Agent" );
+        props.put( Constants.SERVICE_VENDOR, "The Apache Software Foundation" );
+        m_registration = context.registerService( new String[]
+            { ScrService.class.getName(), }, this, props );
+    }
+
+
+    public void dispose()
+    {
+        if ( m_registration != null )
+        {
+            m_registration.unregister();
+            m_registration = null;
+        }
+    }
+
+
+    //---------- ScrService interface
+
+    public Component[] getComponents()
+    {
+        if ( m_componentsById.isEmpty() )
+        {
+            return null;
+        }
+
+        return ( org.apache.felix.scr.Component[] ) m_componentsById.values().toArray(
+            new Component[m_componentsById.size()] );
+    }
+
+
+    public Component[] getComponents( Bundle bundle )
+    {
+        Component[] all = getComponents();
+        if ( all == null || all.length == 0 )
+        {
+            return null;
+        }
+
+        // compare the bundle by its id
+        long bundleId = bundle.getBundleId();
+
+        // scan the components for the the desired components
+        List perBundle = new ArrayList();
+        for ( int i = 0; i < all.length; i++ )
+        {
+            if ( all[i].getBundle().getBundleId() == bundleId )
+            {
+                perBundle.add( all[i] );
+            }
+        }
+
+        // nothing to return
+        if ( perBundle.isEmpty() )
+        {
+            return null;
+        }
+
+        return ( org.apache.felix.scr.Component[] ) perBundle.toArray( new Component[perBundle.size()] );
+    }
+
+
+    public Component getComponent( long componentId )
+    {
+        return ( Component ) m_componentsById.get( new Long( componentId ) );
+    }
+
+
+    //---------- ComponentManager registration by component Id
+
+    /**
+     * Assigns a unique ID to the component, internally registers the
+     * component under that ID and returns the assigned component ID.
+     *
+     * @param componentManager The {@link AbstractComponentManager} for which
+     *      to assign a component ID and which is to be internally registered
+     *
+     * @return the assigned component ID
+     */
+    final long registerComponentId( final AbstractComponentManager componentManager )
+    {
+        long componentId;
+        synchronized ( this )
+        {
+            m_componentCounter++;
+            componentId = m_componentCounter;
+        }
+
+        m_componentsById.put( new Long( componentId ), componentManager );
+
+        return componentId;
+    }
+
+
+    /**
+     * Unregisters the component with the given component ID from the internal
+     * registry. After unregistration, the component ID should be considered
+     * invalid.
+     *
+     * @param componentId The ID of the component to be removed from the
+     *      internal component registry.
+     */
+    final void unregisterComponentId( final long componentId )
+    {
+        m_componentsById.remove( new Long( componentId ) );
+    }
+
+
+    //---------- ComponentHolder registration by component name
+
+    /**
+     * Checks whether the component name is "globally" unique or not. If it is
+     * unique, it is reserved until the actual component is registered with
+     * {@link #registerComponent(String, AbstractComponentManager)} or until
+     * it is unreserved by calling {@link #unregisterComponent(String)}.
+     * If a component with the same name has already been reserved or registered
+     * a ComponentException is thrown with a descriptive message.
+     *
+     * @param name the component name to check and reserve
+     * @throws ComponentException if the name is already in use by another
+     *      component.
+     */
+    final void checkComponentName( String name )
+    {
+        if ( m_componentsByName.containsKey( name ) )
+        {
+            String message = "The component name '" + name + "' has already been registered";
+
+            Object co = m_componentsByName.get( name );
+            if ( co instanceof ComponentHolder )
+            {
+                ComponentHolder c = ( ComponentHolder ) co;
+                Bundle cBundle = c.getActivator().getBundleContext().getBundle();
+                ComponentMetadata cMeta = c.getComponentMetadata();
+
+                StringBuffer buf = new StringBuffer( message );
+                buf.append( " by Bundle " ).append( cBundle.getBundleId() );
+                if ( cBundle.getSymbolicName() != null )
+                {
+                    buf.append( " (" ).append( cBundle.getSymbolicName() ).append( ")" );
+                }
+                buf.append( " as Component of Class " ).append( cMeta.getImplementationClassName() );
+                message = buf.toString();
+            }
+
+            throw new ComponentException( message );
+        }
+
+        // reserve the name
+        m_componentsByName.put( name, name );
+    }
+
+
+    /**
+     * Registers the given component under the given name. If the name has not
+     * already been reserved calling {@link #checkComponentName(String)} this
+     * method throws a {@link ComponentException}.
+     *
+     * @param name The name to register the component under
+     * @param component The component to register
+     *
+     * @throws ComponentException if the name has not been reserved through
+     *      {@link #checkComponentName(String)} yet.
+     */
+    final void registerComponent( String name, ComponentHolder component )
+    {
+        // only register the component if there is a m_registration for it !
+        if ( !name.equals( m_componentsByName.get( name ) ) )
+        {
+            // this is not expected if all works ok
+            throw new ComponentException( "The component name '" + name + "' has already been registered." );
+        }
+
+        m_componentsByName.put( name, component );
+    }
+
+
+    /**
+     * Returns the component registered under the given name or <code>null</code>
+     * if no component is registered yet.
+     */
+    public final ComponentHolder getComponent( String name )
+    {
+        Object entry = m_componentsByName.get( name );
+
+        // only return the entry if non-null and not a reservation
+        if ( entry instanceof ComponentHolder )
+        {
+            return ( ComponentHolder ) entry;
+        }
+
+        return null;
+    }
+
+
+    /**
+     * Removes the component registered under that name. If no component is
+     * yet registered but the name is reserved, it is unreserved.
+     * <p>
+     * After calling this method, the name can be reused by other components.
+     */
+    final void unregisterComponent( String name )
+    {
+        m_componentsByName.remove( name );
+    }
+
+
+    //---------- base configuration support
+
+    /**
+     * Factory method to issue {@link ComponentHolder} instances to manage
+     * components described by the given component <code>metadata</code>.
+     */
+    public ComponentHolder createComponentHolder( BundleComponentActivator activator, ComponentMetadata metadata )
+    {
+        if ( metadata.isFactory() )
+        {
+            // 112.2.4 SCR must register a Component Factory
+            // service on behalf ot the component
+            // as soon as the component factory is satisfied
+            return new ComponentFactoryImpl( activator, metadata );
+        }
+
+        return new UnconfiguredComponentHolder( activator, metadata );
+    }
+
+}

Propchange: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/ComponentRegistry.java
------------------------------------------------------------------------------
    svn:mergeinfo = 

Added: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/AbstractComponentHolder.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/AbstractComponentHolder.java?rev=798531&view=auto
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/AbstractComponentHolder.java (added)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/AbstractComponentHolder.java Tue Jul 28 14:06:58 2009
@@ -0,0 +1,94 @@
+/*
+ * 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.felix.scr.impl.config;
+
+
+import org.apache.felix.scr.impl.BundleComponentActivator;
+import org.apache.felix.scr.impl.manager.DelayedComponentManager;
+import org.apache.felix.scr.impl.manager.ImmediateComponentManager;
+import org.apache.felix.scr.impl.manager.ServiceFactoryComponentManager;
+import org.apache.felix.scr.impl.metadata.ComponentMetadata;
+
+
+abstract class AbstractComponentHolder implements ComponentHolder
+{
+
+    private final BundleComponentActivator m_activator;
+
+    private final ComponentMetadata m_componentMetadata;
+
+
+    public AbstractComponentHolder( final BundleComponentActivator activator, final ComponentMetadata metadata )
+    {
+        this.m_activator = activator;
+        this.m_componentMetadata = metadata;
+    }
+
+
+    protected ImmediateComponentManager createComponentManager()
+    {
+
+        ImmediateComponentManager manager;
+        if ( m_componentMetadata.isFactory() )
+        {
+            throw new IllegalArgumentException( "Cannot create component factory for " + m_componentMetadata.getName() );
+        }
+        else if ( m_componentMetadata.isImmediate() )
+        {
+            manager = new ImmediateComponentManager( m_activator, m_componentMetadata );
+        }
+        else if ( m_componentMetadata.getServiceMetadata() != null )
+        {
+            if ( m_componentMetadata.getServiceMetadata().isServiceFactory() )
+            {
+                manager = new ServiceFactoryComponentManager( m_activator, m_componentMetadata );
+            }
+            else
+            {
+                manager = new DelayedComponentManager( m_activator, m_componentMetadata );
+            }
+        }
+        else
+        {
+            // if we get here, which is not expected after all, we fail
+            throw new IllegalArgumentException( "Cannot create a component manager for "
+                + m_componentMetadata.getName() );
+        }
+
+        return manager;
+    }
+
+
+    public final BundleComponentActivator getActivator()
+    {
+        return m_activator;
+    }
+
+
+    public final ComponentMetadata getComponentMetadata()
+    {
+        return m_componentMetadata;
+    }
+
+
+    protected final String getComponentName()
+    {
+        return getComponentMetadata().getName();
+    }
+}

Propchange: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/AbstractComponentHolder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/AbstractComponentHolder.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Added: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ComponentHolder.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ComponentHolder.java?rev=798531&view=auto
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ComponentHolder.java (added)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ComponentHolder.java Tue Jul 28 14:06:58 2009
@@ -0,0 +1,89 @@
+/*
+ * 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.felix.scr.impl.config;
+
+
+import java.util.Dictionary;
+
+import org.apache.felix.scr.impl.BundleComponentActivator;
+import org.apache.felix.scr.impl.metadata.ComponentMetadata;
+
+
+/**
+ * The <code>ComponentHolder</code> interface provides the API for supporting
+ * component instances configured through either singleton configurations (or
+ * no configuration at all) and factory configurations.
+ * <p>
+ * Instances of this interface are managed by the {@link ConfigurationSupport}
+ * class on behalf of the
+ * {@link org.apache.felix.scr.impl.BundleComponentActivator} and the
+ * {@link org.apache.felix.scr.impl.ComponentRegistry}.
+ */
+public interface ComponentHolder
+{
+
+    /**
+     * Returns the {@link BundleComponentActivator} owning this component
+     * holder.
+     */
+    BundleComponentActivator getActivator();
+
+
+    /**
+     * Returns the {@link ComponentMetadata} describing and declaring this
+     * component.
+     */
+    ComponentMetadata getComponentMetadata();
+
+
+    /**
+     * The configuration with the given PID has been deleted from the
+     * Configuration Admin service.
+     *
+     * @param pid The PID of the deleted configuration
+     */
+    void configurationDeleted( String pid );
+
+
+    /**
+     * Configure a component with configuration from the given PID.
+     *
+     * @param pid The PID of the configuration used to configure the component
+     */
+    void configurationUpdated( String pid, Dictionary props );
+
+
+    /**
+     * Enables all components of this holder.
+     */
+    void enableComponents();
+
+
+    /**
+     * Disables all components of this holder.
+     */
+    void disableComponents();
+
+
+    /**
+     * Disposes off all components of this holder.
+     * @param reason
+     */
+    void disposeComponents( int reason );
+}

Propchange: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ComponentHolder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ComponentHolder.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Added: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurationComponentRegistry.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurationComponentRegistry.java?rev=798531&view=auto
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurationComponentRegistry.java (added)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurationComponentRegistry.java Tue Jul 28 14:06:58 2009
@@ -0,0 +1,263 @@
+/*
+ * 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.felix.scr.impl.config;
+
+
+import java.io.IOException;
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.apache.felix.scr.impl.Activator;
+import org.apache.felix.scr.impl.BundleComponentActivator;
+import org.apache.felix.scr.impl.ComponentRegistry;
+import org.apache.felix.scr.impl.manager.ComponentFactoryImpl;
+import org.apache.felix.scr.impl.metadata.ComponentMetadata;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+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.osgi.service.log.LogService;
+
+
+public class ConfigurationComponentRegistry extends ComponentRegistry implements ConfigurationListener
+{
+
+    // the service m_registration of the ConfigurationListener service
+    private ServiceRegistration m_registration;
+
+
+    public ConfigurationComponentRegistry( final BundleContext context )
+    {
+        super( context );
+
+        // register as ScrService
+        Dictionary props = new Hashtable();
+        props.put( Constants.SERVICE_DESCRIPTION, "Declarative Services Configuration Support Listener" );
+        props.put( Constants.SERVICE_VENDOR, "The Apache Software Foundation" );
+        m_registration = context.registerService( new String[]
+            { ConfigurationListener.class.getName() }, this, props );
+    }
+
+
+    public void dispose()
+    {
+        if ( m_registration != null )
+        {
+            m_registration.unregister();
+            m_registration = null;
+        }
+
+        super.dispose();
+    }
+
+
+    //---------- BaseConfigurationSupport overwrites
+
+    public ComponentHolder createComponentHolder( final BundleComponentActivator activator,
+        final ComponentMetadata metadata )
+    {
+        // 112.7 configure unless configuration not required
+        if ( metadata.isConfigurationIgnored() )
+        {
+            return super.createComponentHolder( activator, metadata );
+        }
+
+        // prepare the configuration holder
+        final ComponentHolder holder;
+        if ( metadata.isFactory() )
+        {
+            holder = new ComponentFactoryImpl( activator, metadata );
+        }
+        else
+        {
+            holder = new ConfiguredComponentHolder( activator, metadata );
+        }
+
+        final BundleContext bundleContext = activator.getBundleContext();
+        final String bundleLocation = bundleContext.getBundle().getLocation();
+        final String name = metadata.getName();
+
+        final ServiceReference caRef = bundleContext.getServiceReference( ConfigurationAdmin.class.getName() );
+        if ( caRef != null )
+        {
+            final ConfigurationAdmin ca = ( ConfigurationAdmin ) bundleContext.getService( caRef );
+            if ( ca != null )
+            {
+                final Configuration[] factory = findFactoryConfigurations( ca, name );
+                if ( factory != null )
+                {
+                    for ( int i = 0; i < factory.length; i++ )
+                    {
+                        final String pid = factory[i].getPid();
+                        final Dictionary props = getConfiguration( ca, pid, bundleLocation );
+                        holder.configurationUpdated( pid, props );
+                    }
+                }
+                else
+                {
+                    // check for configuration and configure the holder
+                    final Configuration singleton = findSingletonConfiguration( ca, name );
+                    if ( singleton != null )
+                    {
+                        final Dictionary props = getConfiguration( ca, name, bundleLocation );
+                        holder.configurationUpdated( name, props );
+                    }
+                }
+            }
+        }
+
+        return holder;
+    }
+
+
+    //---------- ConfigurationListener
+
+    public void configurationEvent( ConfigurationEvent event )
+    {
+        final String pid = event.getPid();
+        final String factoryPid = event.getFactoryPid();
+
+        final ComponentHolder cm;
+        if ( factoryPid == null )
+        {
+            cm = getComponent( pid );
+        }
+        else
+        {
+            cm = getComponent( factoryPid );
+        }
+
+        if ( cm != null && !cm.getComponentMetadata().isConfigurationIgnored() )
+        {
+            switch ( event.getType() )
+            {
+                case ConfigurationEvent.CM_DELETED:
+                    cm.configurationDeleted( pid );
+                    break;
+
+                case ConfigurationEvent.CM_UPDATED:
+                    final BundleContext bundleContext = cm.getActivator().getBundleContext();
+                    final ServiceReference caRef = bundleContext.getServiceReference( ConfigurationAdmin.class
+                        .getName() );
+                    if ( caRef != null )
+                    {
+                        final ConfigurationAdmin ca = ( ConfigurationAdmin ) bundleContext.getService( caRef );
+                        if ( ca != null )
+                        {
+                            try
+                            {
+                                final Dictionary dict = getConfiguration( ca, pid, bundleContext.getBundle().getLocation() );
+                                if ( dict != null )
+                                {
+                                    cm.configurationUpdated( pid, dict );
+                                }
+                            }
+                            finally
+                            {
+                                bundleContext.ungetService( caRef );
+                            }
+                        }
+                    }
+                    break;
+
+                default:
+                    Activator.log( LogService.LOG_WARNING, null, "Unknown ConfigurationEvent type " + event.getType(),
+                        null );
+            }
+        }
+    }
+
+
+    private Dictionary getConfiguration( final ConfigurationAdmin ca, final String pid, final String bundleLocation )
+    {
+        try
+        {
+            final Configuration cfg = ca.getConfiguration( pid );
+            if ( bundleLocation.equals( cfg.getBundleLocation() ) )
+            {
+                return cfg.getProperties();
+            }
+
+            // configuration belongs to another bundle, cannot be used here
+            Activator.log( LogService.LOG_ERROR, null, "Cannot use configuration pid=" + pid + " for bundle "
+                + bundleLocation + " because it belongs to bundle " + cfg.getBundleLocation(), null );
+        }
+        catch ( IOException ioe )
+        {
+            Activator.log( LogService.LOG_WARNING, null, "Failed reading configuration for pid=" + pid, ioe );
+        }
+
+        return null;
+    }
+
+
+    /**
+     * Returns the configuration whose PID equals the given pid. If no such
+     * configuration exists, <code>null</code> is returned.
+     * @param ctx
+     * @param pid
+     * @return
+     */
+    public Configuration findSingletonConfiguration( final ConfigurationAdmin ca, final String pid )
+    {
+        final String filter = "(service.pid=" + pid + ")";
+        final Configuration[] cfg = findConfigurations( ca, filter );
+        return ( cfg == null || cfg.length == 0 ) ? null : cfg[0];
+    }
+
+
+    /**
+     * Returns all configurations whose factory PID equals the given factory PID
+     * or <code>null</code> if no such configurations exist
+     * @param ctx
+     * @param factoryPid
+     * @return
+     */
+    public Configuration[] findFactoryConfigurations( final ConfigurationAdmin ca, final String factoryPid )
+    {
+        final String filter = "(service.factoryPid=" + factoryPid + ")";
+        return findConfigurations( ca, filter );
+    }
+
+
+    private Configuration[] findConfigurations( final ConfigurationAdmin ca, final String filter )
+    {
+        try
+        {
+            return ca.listConfigurations( filter );
+        }
+        catch ( IOException ioe )
+        {
+            Activator
+                .log( LogService.LOG_WARNING, null, "Problem listing configurations for filter=" + filter, ioe );
+        }
+        catch ( InvalidSyntaxException ise )
+        {
+            Activator.log( LogService.LOG_ERROR, null, "Invalid Configuration selection filter " + filter, ise );
+        }
+
+        // no factories in case of problems
+        return null;
+    }
+}

Propchange: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurationComponentRegistry.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurationComponentRegistry.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Added: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfiguredComponentHolder.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfiguredComponentHolder.java?rev=798531&view=auto
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfiguredComponentHolder.java (added)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfiguredComponentHolder.java Tue Jul 28 14:06:58 2009
@@ -0,0 +1,336 @@
+/*
+ * 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.felix.scr.impl.config;
+
+
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.felix.scr.impl.BundleComponentActivator;
+import org.apache.felix.scr.impl.manager.ImmediateComponentManager;
+import org.apache.felix.scr.impl.metadata.ComponentMetadata;
+import org.osgi.service.component.ComponentConstants;
+
+
+/**
+ * The <code>ConfiguredComponentHolder</code> class is a
+ * {@link ComponentHolder} for one or more components instances configured by
+ * singleton or factory configuration objects received from the Configuration
+ * Admin service.
+ * <p>
+ * This holder is used only for components configured (optionally or required)
+ * by the Configuration Admin service. It is not used for components declared
+ * as ignoring configuration or if no Configuration Admin service is available.
+ * <p>
+ * The holder copes with three situations:
+ * <ul>
+ * <li>No configuration is available for the held component. That is there is
+ * no configuration whose <code>service.pid</code> or
+ * <code>service.factoryPid</code> equals the component name.</li>
+ * <li>A singleton configuration is available whose <code>service.pid</code>
+ * equals the component name.</li>
+ * <li>One or more factory configurations exist whose
+ * <code>service.factoryPid</code> equals the component name.</li>
+ * </ul>
+ */
+public class ConfiguredComponentHolder extends AbstractComponentHolder
+{
+
+    /**
+     * A map of components configured with factory configuration. The indices
+     * are the PIDs (<code>service.pid</code>) of the configuration objects.
+     * The values are the {@link ImmediateComponentManager component instances}
+     * created on behalf of the configurations.
+     */
+    private final Map m_components;
+
+    /**
+     * The special component used if there is no configuration or a singleton
+     * configuration. This field is always non-<code>null</code> and is first
+     * created in the constructor. As factory configurations are provided this
+     * instance may be configured or "deconfigured".
+     * <p>
+     * Expected invariants:
+     * <ul>
+     * <li>This field is never <code>null</code></li>
+     * <li>The {@link #m_components} map is empty or the component pointed to
+     * by this field is also contained in the map</li>
+     * <ul>
+     */
+    private ImmediateComponentManager m_singleComponent;
+
+    /**
+     * Whether components have already been enabled by calling the
+     * {@link #enableComponents()} method. If this field is <code>true</code>
+     * component instances created per configuration by the
+     * {@link #configurationUpdated(String, Dictionary)} method are also
+     * enabled. Otherwise they are not enabled immediately.
+     */
+    private boolean m_enabled;
+
+
+    ConfiguredComponentHolder( final BundleComponentActivator activator, final ComponentMetadata metadata )
+    {
+        super( activator, metadata );
+
+        this.m_components = new HashMap();
+        this.m_singleComponent = createComponentManager();
+        this.m_enabled = false;
+    }
+
+
+    /**
+     * The configuration with the given <code>pid</code>
+     * (<code>service.pid</code> of the configuration object) is deleted.
+     * <p>
+     * The following situations are supported:
+     * <ul>
+     * <li>The configuration was a singleton configuration (pid equals the
+     * component name). In this case the internal component map is empty and
+     * the single component has been configured by the singleton configuration
+     * and is no "deconfigured".</li>
+     * <li>A factory configuration object has been deleted and the configured
+     * object is set as the single component. If the single component held the
+     * last factory configuration object, it is deconfigured. Otherwise the
+     * single component is disposed off and replaced by another component in
+     * the map of existing components.</li>
+     * <li>A factory configuration object has been deleted and the configured
+     * object is not set as the single component. In this case the component is
+     * simply disposed off and removed from the internal map.</li>
+     * </ul>
+     */
+    public void configurationDeleted( final String pid )
+    {
+        if ( pid.equals( getComponentName() ) )
+        {
+            // singleton configuration deleted
+            m_singleComponent.reconfigure( null );
+        }
+        else
+        {
+            // remove the component configured with the deleted configuration
+            ImmediateComponentManager icm = removeComponentManager( pid );
+            if ( icm != null )
+            {
+                // special casing if the single component is deconfigured
+                if ( m_singleComponent == icm )
+                {
+
+                    // if the single component is the last remaining, deconfi
+                    if ( m_components.isEmpty() )
+                    {
+
+                        // if the single component is the last remaining
+                        // deconfigure it
+                        icm.reconfigure( null );
+                        icm = null;
+
+                    }
+                    else
+                    {
+
+                        // replace the single component field with another
+                        // entry from the map
+                        m_singleComponent = ( ImmediateComponentManager ) m_components.values().iterator().next();
+
+                    }
+                }
+
+                // icm may be null if the last configuration deleted was the
+                // single component's configuration. Otherwise the component
+                // is not the "last" and has to be disposed off
+                if ( icm != null )
+                {
+                    icm.dispose( ComponentConstants.DEACTIVATION_REASON_CONFIGURATION_DELETED );
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Configures a component with the given configuration. This configuration
+     * update may happen in various situations:
+     * <ul>
+     * <li>The <code>pid</code> equals the component name. Hence we have a
+     * singleton configuration for the single component held by this holder</li>
+     * <li>The configuration is a factory configuration and is the first
+     * configuration provided. In this case the single component is provided
+     * with the configuration and also stored in the map.</li>
+     * <li>The configuration is a factory configuration but not the first. In
+     * this case a new component is created, configured and stored in the map</li>
+     * </ul>
+     */
+    public void configurationUpdated( final String pid, final Dictionary props )
+    {
+        if ( pid.equals( getComponentName() ) )
+        {
+            // singleton configuration has pid equal to component name
+            m_singleComponent.reconfigure( props );
+        }
+        else
+        {
+            // factory configuration update or created
+            final ImmediateComponentManager icm = getComponentManager( pid );
+            if ( icm != null )
+            {
+                // factory configuration updated for existing component instance
+                icm.reconfigure( props );
+            }
+            else
+            {
+                // factory configuration created
+                final ImmediateComponentManager newIcm;
+                if ( !m_singleComponent.hasConfiguration() )
+                {
+                    // configure the single instance if this is not configured
+                    newIcm = m_singleComponent;
+                }
+                else
+                {
+                    // otherwise create a new instance to provide the config to
+                    newIcm = createComponentManager();
+                }
+
+                // configure the component
+                newIcm.reconfigure( props );
+
+                // enable the component if it is initially enabled
+                if ( m_enabled && getComponentMetadata().isEnabled() )
+                {
+                    newIcm.enable();
+                }
+
+                // store the component in the map
+                putComponentManager( pid, newIcm );
+            }
+        }
+    }
+
+
+    public void enableComponents()
+    {
+        final ImmediateComponentManager[] cms = getComponentManagers( false );
+        if ( cms == null )
+        {
+            m_singleComponent.enable();
+        }
+        else
+        {
+            for ( int i = 0; i < cms.length; i++ )
+            {
+                cms[i].enable();
+            }
+        }
+
+        m_enabled = true;
+    }
+
+
+    public void disableComponents()
+    {
+        final ImmediateComponentManager[] cms = getComponentManagers( false );
+        if ( cms == null )
+        {
+            m_singleComponent.disable();
+        }
+        else
+        {
+            for ( int i = 0; i < cms.length; i++ )
+            {
+                cms[i].disable();
+            }
+        }
+    }
+
+
+    public void disposeComponents( final int reason )
+    {
+        final ImmediateComponentManager[] cms = getComponentManagers( true );
+        if ( cms == null )
+        {
+            m_singleComponent.dispose( reason );
+        }
+        else
+        {
+            for ( int i = 0; i < cms.length; i++ )
+            {
+                cms[i].dispose( reason );
+            }
+        }
+    }
+
+
+    //---------- internal
+
+    private ImmediateComponentManager getComponentManager( String pid )
+    {
+        synchronized ( m_components )
+        {
+            return ( ImmediateComponentManager ) m_components.get( pid );
+        }
+    }
+
+
+    private ImmediateComponentManager removeComponentManager( String pid )
+    {
+        synchronized ( m_components )
+        {
+            return ( ImmediateComponentManager ) m_components.remove( pid );
+        }
+    }
+
+
+    private void putComponentManager( String pid, ImmediateComponentManager componentManager )
+    {
+        synchronized ( m_components )
+        {
+            m_components.put( pid, componentManager );
+        }
+    }
+
+
+    /**
+     * Returns all components from the map, optionally also removing them
+     * from the map. If there are no components in the map, <code>null</code>
+     * is returned.
+     */
+    private ImmediateComponentManager[] getComponentManagers( final boolean clear )
+    {
+        synchronized ( m_components )
+        {
+            // fast exit if there is no component in the map
+            if ( m_components.isEmpty() )
+            {
+                return null;
+            }
+
+            final ImmediateComponentManager[] cm = new ImmediateComponentManager[m_components.size()];
+            m_components.values().toArray( cm );
+
+            if ( clear )
+            {
+                m_components.clear();
+            }
+
+            return cm;
+        }
+    }
+}

Propchange: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfiguredComponentHolder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/ConfiguredComponentHolder.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Added: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/UnconfiguredComponentHolder.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/UnconfiguredComponentHolder.java?rev=798531&view=auto
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/UnconfiguredComponentHolder.java (added)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/UnconfiguredComponentHolder.java Tue Jul 28 14:06:58 2009
@@ -0,0 +1,74 @@
+/*
+ * 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.felix.scr.impl.config;
+
+
+import java.util.Dictionary;
+
+import org.apache.felix.scr.impl.BundleComponentActivator;
+import org.apache.felix.scr.impl.manager.ImmediateComponentManager;
+import org.apache.felix.scr.impl.metadata.ComponentMetadata;
+
+
+/**
+ * The <code>SingletonHolder</code> class is {@link ComponentHolder} for a
+ * component configured by a singleton configuration or no configuration
+ * at all.
+ */
+public class UnconfiguredComponentHolder extends AbstractComponentHolder
+{
+
+    private final ImmediateComponentManager m_component;
+
+
+    public UnconfiguredComponentHolder( BundleComponentActivator activator, ComponentMetadata metadata )
+    {
+        super( activator, metadata );
+
+        m_component = createComponentManager();
+    }
+
+
+    public void configurationDeleted( String pid )
+    {
+    }
+
+
+    public void configurationUpdated( String pid, Dictionary props )
+    {
+    }
+
+
+    public void enableComponents()
+    {
+        m_component.enable();
+    }
+
+
+    public void disableComponents()
+    {
+        m_component.disable();
+    }
+
+
+    public void disposeComponents( int reason )
+    {
+        m_component.dispose( reason );
+    }
+}

Propchange: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/UnconfiguredComponentHolder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/config/UnconfiguredComponentHolder.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java?rev=798531&r1=798530&r2=798531&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java Tue Jul 28 14:06:58 2009
@@ -29,7 +29,6 @@
 import org.apache.felix.scr.Reference;
 import org.apache.felix.scr.impl.BundleComponentActivator;
 import org.apache.felix.scr.impl.ComponentActivatorTask;
-import org.apache.felix.scr.impl.ComponentRegistry;
 import org.apache.felix.scr.impl.metadata.ComponentMetadata;
 import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
 import org.osgi.framework.Bundle;
@@ -273,6 +272,16 @@
             acm.log( LogService.LOG_DEBUG, "Activating component", componentMetadata, null );
 
             // Before creating the implementation object, we are going to
+            // test if we have configuration if such is required
+            if ( !acm.hasConfiguration() && acm.getComponentMetadata().isConfigurationRequired() )
+            {
+                acm.log( LogService.LOG_INFO, "Missing required configuration, cannot activate", componentMetadata,
+                    null );
+                acm.changeState( Unsatisfied.getInstance() );
+                return;
+            }
+
+            // Before creating the implementation object, we are going to
             // test if all the mandatory dependencies are satisfied
             if ( !acm.verifyDependencyManagers( acm.getProperties()) )
             {
@@ -458,14 +467,14 @@
      *
      * @param activator
      * @param metadata
-     * @param componentId
      */
-    protected AbstractComponentManager( BundleComponentActivator activator, ComponentMetadata metadata,
-        ComponentRegistry componentRegistry )
+    protected AbstractComponentManager( BundleComponentActivator activator, ComponentMetadata metadata )
     {
         m_activator = activator;
         m_componentMetadata = metadata;
-        m_componentId = componentRegistry.createComponentId();
+
+        // for some testing, the activator may be null
+        m_componentId = ( activator != null ) ? activator.registerComponentId( this ) : -1;
 
         m_state = Disabled.getInstance();
         loadDependencyManagers( metadata );
@@ -753,12 +762,20 @@
         return m_serviceRegistration;
     }
 
+
     void clear()
     {
-        m_activator = null;
+        // for some testing, the activator may be null
+        if ( m_activator != null )
+        {
+            m_activator.unregisterComponentId( this );
+            m_activator = null;
+        }
+
         m_dependencyManagers.clear();
     }
 
+
     void log( int level, String message, ComponentMetadata metadata, Throwable ex )
     {
         BundleComponentActivator activator = getActivator();
@@ -785,17 +802,6 @@
     }
 
     /**
-     * Reconfigures this component by deactivating and activating it. During
-     * activation the new configuration data is retrieved from the Configuration
-     * Admin Service.
-     */
-    public final void reconfigure( final int reason )
-    {
-        log( LogService.LOG_DEBUG, "Deactivating and Activating to reconfigure", m_componentMetadata, null );
-        reactivate( reason );
-    }
-
-    /**
      * Cycles this component by deactivating it and - if still satisfied -
      * activating it again asynchronously.
      * <p>
@@ -851,7 +857,7 @@
         }
     }
 
-    private boolean verifyDependencyManagers( Dictionary properties )
+    protected boolean verifyDependencyManagers( Dictionary properties )
     {
         // indicates whether all dependencies are satisfied
         boolean satisfied = true;
@@ -914,6 +920,8 @@
      */
     public abstract Object getInstance();
 
+    public abstract boolean hasConfiguration();
+
     public abstract Dictionary getProperties();
 
     /**

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java?rev=798531&r1=798530&r2=798531&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java Tue Jul 28 14:06:58 2009
@@ -50,7 +50,7 @@
         return m_componentManager;
     }
 
-    public Dictionary getProperties()
+    public final Dictionary getProperties()
     {
         // 112.11.3.5 The Dictionary is read-only and cannot be modified
         return new ReadOnlyDictionary( m_componentManager.getProperties() );

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java?rev=798531&r1=798530&r2=798531&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java Tue Jul 28 14:06:58 2009
@@ -25,11 +25,10 @@
 import java.util.Map;
 
 import org.apache.felix.scr.impl.BundleComponentActivator;
-import org.apache.felix.scr.impl.ComponentRegistry;
+import org.apache.felix.scr.impl.config.ComponentHolder;
 import org.apache.felix.scr.impl.metadata.ComponentMetadata;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.cm.Configuration;
 import org.osgi.service.component.ComponentConstants;
 import org.osgi.service.component.ComponentFactory;
 import org.osgi.service.component.ComponentInstance;
@@ -38,12 +37,9 @@
 /**
  * The <code>ComponentFactoryImpl</code> TODO
  */
-public class ComponentFactoryImpl extends AbstractComponentManager implements ComponentFactory
+public class ComponentFactoryImpl extends AbstractComponentManager implements ComponentFactory, ComponentHolder
 {
 
-    // The component registry used to retrieve component IDs
-    private ComponentRegistry m_componentRegistry;
-
     // The map of components created from Configuration objects
     // maps PID to ImmediateComponentManager for configuration updating
     // this map is lazily created
@@ -53,13 +49,20 @@
     // no IdentityHashSet and HashSet internally uses a HashMap anyway
     private final Map m_createdComponents;
 
+    // configuration of the component factory
+    private Dictionary m_configuration;
+
+    // whether this instance supports creating component instances for factory
+    // configuration instances. This is backwards compatibility behaviour and
+    // contradicts the specification (Section 112.7)
+    private final boolean m_isConfigurationFactory;
+
 
-    public ComponentFactoryImpl( BundleComponentActivator activator, ComponentMetadata metadata,
-        ComponentRegistry componentRegistry )
+    public ComponentFactoryImpl( BundleComponentActivator activator, ComponentMetadata metadata )
     {
-        super( activator, metadata, componentRegistry );
-        m_componentRegistry = componentRegistry;
+        super( activator, metadata );
         m_createdComponents = new IdentityHashMap();
+        m_isConfigurationFactory = "true".equals( activator.getBundleContext().getProperty( "ds.factory.enabled" ) );
     }
 
 
@@ -94,16 +97,6 @@
     {
         log( LogService.LOG_DEBUG, "registering component factory", getComponentMetadata(), null );
 
-        Configuration[] cfg = m_componentRegistry.getConfigurations( getActivator().getBundleContext(),
-            getComponentMetadata().getName() );
-        if ( cfg != null )
-        {
-            for ( int i = 0; i < cfg.length; i++ )
-            {
-                updated( cfg[i].getPid(), cfg[i].getProperties() );
-            }
-        }
-
         Dictionary serviceProperties = getProperties();
         return getActivator().getBundleContext().registerService( new String[]
             { ComponentFactory.class.getName() }, getService(), serviceProperties );
@@ -117,6 +110,12 @@
     }
 
 
+    public boolean hasConfiguration()
+    {
+        return true;
+    }
+
+
     public Dictionary getProperties()
     {
         Dictionary props = new Hashtable();
@@ -143,63 +142,129 @@
     }
 
 
-    //---------- ManagedServiceFactory interface ------------------------------
+    public String getName()
+    {
+        return "Component Factory " + getComponentMetadata().getName();
+    }
+
+
+    //---------- ComponentHolder interface
 
-    public void updated( String pid, Dictionary configuration )
+    public void configurationDeleted( String pid )
     {
-        if ( getState() == STATE_FACTORY )
+        if ( pid.equals( getComponentMetadata().getName() ) )
         {
-            ImmediateComponentManager cm;
-            if ( m_configuredServices != null )
-            {
-                cm = ( ImmediateComponentManager ) m_configuredServices.get( pid );
-            }
-            else
+            m_configuration = null;
+            reconfigureComponents( null );
+        }
+        else if ( m_isConfigurationFactory && getState() == STATE_FACTORY && m_configuredServices != null )
+        {
+            ImmediateComponentManager cm = ( ImmediateComponentManager ) m_configuredServices.remove( pid );
+            if ( cm != null )
             {
-                m_configuredServices = new HashMap();
-                cm = null;
+                log( LogService.LOG_DEBUG, "Disposing component after configuration deletion", getComponentMetadata(),
+                    null );
+
+                disposeComponentManager( cm, ComponentConstants.DEACTIVATION_REASON_CONFIGURATION_DELETED );
             }
+        }
+    }
 
-            if ( cm == null )
-            {
-                // create a new instance with the current configuration
-                cm = createComponentManager( configuration, false );
 
-                // keep a reference for future updates
-                m_configuredServices.put( pid, cm );
-            }
-            else
+    public void configurationUpdated( String pid, Dictionary configuration )
+    {
+        if ( pid.equals( getComponentMetadata().getName() ) )
+        {
+            m_configuration = configuration;
+            reconfigureComponents( configuration );
+        }
+        else if ( m_isConfigurationFactory )
+        {
+            if ( getState() == STATE_FACTORY )
             {
-                // update the configuration as if called as ManagedService
-                cm.reconfigure( configuration );
+                // configuration for factory configuration instances
+
+                ImmediateComponentManager cm;
+                if ( m_configuredServices != null )
+                {
+                    cm = ( ImmediateComponentManager ) m_configuredServices.get( pid );
+                }
+                else
+                {
+                    m_configuredServices = new HashMap();
+                    cm = null;
+                }
+
+                if ( cm == null )
+                {
+                    // create a new instance with the current configuration
+                    cm = createComponentManager( configuration, false );
+
+                    // keep a reference for future updates
+                    m_configuredServices.put( pid, cm );
+                }
+                else
+                {
+                    // update the configuration as if called as ManagedService
+                    cm.reconfigure( configuration );
+                }
             }
         }
+        else
+        {
+            // 112.7 Factory Configuration not allowed for factory component
+            getActivator().log( LogService.LOG_ERROR,
+                "Component Factory cannot be configured by factory configuration", getComponentMetadata(), null );
+        }
     }
 
-    public void deleted( String pid )
+
+    // TODO: correct ???
+    public void enableComponents()
     {
-        if ( getState() == STATE_FACTORY && m_configuredServices != null )
+        ImmediateComponentManager[] cms = getComponentManagers( false );
+        for ( int i = 0; i < cms.length; i++ )
         {
-            ImmediateComponentManager cm = ( ImmediateComponentManager ) m_configuredServices.remove( pid );
-            if ( cm != null )
-            {
-                log( LogService.LOG_DEBUG, "Disposing component after configuration deletion", getComponentMetadata(),
-                        null );
+            cms[i].enable();
+        }
+    }
 
-                disposeComponentManager( cm, ComponentConstants.DEACTIVATION_REASON_CONFIGURATION_DELETED );
-            }
+
+    // update components with this configuration
+    private void reconfigureComponents( Dictionary configuration )
+    {
+        ImmediateComponentManager[] cms = getComponentManagers( false );
+        for ( int i = 0; i < cms.length; i++ )
+        {
+            cms[i].reconfigure( configuration );
         }
+    }
+
 
+    // TODO: correct ???
+    public void disableComponents()
+    {
+        ImmediateComponentManager[] cms = getComponentManagers( false );
+        for ( int i = 0; i < cms.length; i++ )
+        {
+            cms[i].disable();
+        }
     }
 
 
-    public String getName()
+    // TODO: correct ???
+    public void disposeComponents( int reason )
     {
-        return "Component Factory " + getComponentMetadata().getName();
+        ImmediateComponentManager[] cms = getComponentManagers( true );
+        for ( int i = 0; i < cms.length; i++ )
+        {
+            cms[i].dispose( reason );
+        }
     }
 
 
-    //---------- internal -----------------------------------------------------
+    //---------- internal
+
     /**
      * ComponentManager instances created by this method are not registered
      * with the ComponentRegistry. Therefore, any configuration update to these
@@ -218,11 +283,7 @@
      */
     private ImmediateComponentManager createComponentManager( Dictionary configuration, boolean isNewInstance )
     {
-        ImmediateComponentManager cm = new ImmediateComponentManager( getActivator(), getComponentMetadata(),
-            m_componentRegistry );
-
-        // add the new component to the activators instances
-        getActivator().getInstanceReferences().add( cm );
+        ImmediateComponentManager cm = new ImmediateComponentManager( getActivator(), getComponentMetadata() );
 
         // register with the internal set of created components
         m_createdComponents.put( cm, cm );
@@ -231,6 +292,7 @@
         if ( isNewInstance )
         {
             cm.setFactoryProperties( configuration );
+            cm.reconfigure( m_configuration );
             // enable synchronously
             cm.enableInternal();
             cm.activateInternal();
@@ -252,10 +314,24 @@
         // remove from created components
         m_createdComponents.remove( cm );
 
-        // remove from activators list
-        getActivator().getInstanceReferences().remove( cm );
-
         // finally dispose it
         cm.dispose( reason );
     }
+
+
+    private ImmediateComponentManager[] getComponentManagers( boolean clear )
+    {
+        synchronized ( m_createdComponents )
+        {
+            ImmediateComponentManager[] cm = new ImmediateComponentManager[m_createdComponents.size()];
+            m_createdComponents.keySet().toArray( cm );
+
+            if ( clear )
+            {
+                m_createdComponents.clear();
+            }
+
+            return cm;
+        }
+    }
 }

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DelayedComponentManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DelayedComponentManager.java?rev=798531&r1=798530&r2=798531&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DelayedComponentManager.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DelayedComponentManager.java Tue Jul 28 14:06:58 2009
@@ -20,7 +20,6 @@
 
 
 import org.apache.felix.scr.impl.BundleComponentActivator;
-import org.apache.felix.scr.impl.ComponentRegistry;
 import org.apache.felix.scr.impl.metadata.ComponentMetadata;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.ServiceFactory;
@@ -36,12 +35,10 @@
     /**
      * @param activator
      * @param metadata
-     * @param componentId
      */
-    public DelayedComponentManager( BundleComponentActivator activator, ComponentMetadata metadata,
-        ComponentRegistry componentRegistry )
+    public DelayedComponentManager( BundleComponentActivator activator, ComponentMetadata metadata )
     {
-        super( activator, metadata, componentRegistry );
+        super( activator, metadata );
     }
 
 

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java?rev=798531&r1=798530&r2=798531&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java Tue Jul 28 14:06:58 2009
@@ -22,7 +22,6 @@
 import java.util.IdentityHashMap;
 
 import org.apache.felix.scr.impl.BundleComponentActivator;
-import org.apache.felix.scr.impl.ComponentRegistry;
 import org.apache.felix.scr.impl.metadata.ComponentMetadata;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.ServiceFactory;
@@ -47,12 +46,10 @@
     /**
      * @param activator
 	 * @param metadata
-	 * @param componentId
      */
-    public ServiceFactoryComponentManager( BundleComponentActivator activator, ComponentMetadata metadata,
-        ComponentRegistry componentRegistry )
+    public ServiceFactoryComponentManager( BundleComponentActivator activator, ComponentMetadata metadata )
     {
-        super( activator, metadata, componentRegistry );
+        super( activator, metadata );
     }
 
 

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/metadata/ComponentMetadata.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/metadata/ComponentMetadata.java?rev=798531&r1=798530&r2=798531&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/metadata/ComponentMetadata.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/metadata/ComponentMetadata.java Tue Jul 28 14:06:58 2009
@@ -494,6 +494,36 @@
 
 
     /**
+     * Returns <code>true</code> if the configuration policy is configured to
+     * {@link #CONFIGURATION_POLICY_REQUIRE}.
+     */
+    public boolean isConfigurationRequired()
+    {
+        return CONFIGURATION_POLICY_REQUIRE.equals( m_configurationPolicy );
+    }
+
+
+    /**
+     * Returns <code>true</code> if the configuration policy is configured to
+     * {@link #CONFIGURATION_POLICY_IGNORE}.
+     */
+    public boolean isConfigurationIgnored()
+    {
+        return CONFIGURATION_POLICY_IGNORE.equals( m_configurationPolicy );
+    }
+
+
+    /**
+     * Returns <code>true</code> if the configuration policy is configured to
+     * {@link #CONFIGURATION_POLICY_OPTIONAL}.
+     */
+    public boolean isConfigurationOptional()
+    {
+        return CONFIGURATION_POLICY_OPTIONAL.equals( m_configurationPolicy );
+    }
+
+
+    /**
      * Method used to verify if the semantics of this metadata are correct
      */
     public void validate( Logger logger )