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 2007/03/28 16:34:04 UTC

svn commit: r523345 [1/2] - /incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/

Author: fmeschbe
Date: Wed Mar 28 07:34:01 2007
New Revision: 523345

URL: http://svn.apache.org/viewvc?view=rev&rev=523345
Log:
FELIX-258 Support Configuration Admin configuration
FELIX-259 Add support for factory components

Added:
    incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/AbstractComponentManager.java   (with props)
    incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentContextImpl.java   (with props)
    incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentFactoryImpl.java   (with props)
    incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentRegistry.java   (with props)
    incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/DelayedComponentManager.java   (with props)
    incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/DependencyManager.java   (with props)
    incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ImmediateComponentManager.java   (with props)
    incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ReadOnlyDictionary.java   (with props)
    incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ServiceFactoryComponentManager.java   (with props)
Removed:
    incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentManagerImpl.java
Modified:
    incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/Activator.java
    incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/BundleComponentActivator.java
    incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentManager.java
    incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ManagerFactory.java

Added: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/AbstractComponentManager.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/AbstractComponentManager.java?view=auto&rev=523345
==============================================================================
--- incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/AbstractComponentManager.java (added)
+++ incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/AbstractComponentManager.java Wed Mar 28 07:34:01 2007
@@ -0,0 +1,576 @@
+/* 
+ * 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;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceListener;
+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.component.ComponentConstants;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.ComponentInstance;
+
+
+/**
+ * The default ComponentManager. Objects of this class are responsible for managing
+ * implementation object's lifecycle.  
+ *
+ */
+abstract class AbstractComponentManager implements ComponentManager, ComponentInstance
+{
+    // manager has been newly created or disabled
+    static final int STATE_DISABLED = 1;
+    
+    // manager has just been enabled and is going to be activated
+    static final int STATE_ENABLED = 2;
+    
+    // manager has been enabled but not satisfied
+    static final int STATE_UNSATISFIED = 4;
+    
+    // manager is currently activating
+    static final int STATE_ACTIVATING = 8;
+    
+    // manager is now active
+    static final int STATE_ACTIVE = 16;
+
+    // manager for a delayed component has been registered (not active yet)
+    static final int STATE_REGISTERED = 32;
+    
+    // manager for a component factory has been registered
+    static final int STATE_FACTORY = 64;
+    
+	// manager is current deactivating
+    static final int STATE_DEACTIVATING = 128;
+
+    // manager has been destroyed and may not be used anymore
+    static final int STATE_DESTROYED = 256;
+    
+    // The state of this instance manager
+    private int m_state;
+
+    // The metadata
+    private ComponentMetadata m_componentMetadata;
+    
+    // The dependency managers that manage every dependency
+    private List m_dependencyManagers;
+
+    // A reference to the BundleComponentActivator
+    private BundleComponentActivator m_activator;
+
+    // The ServiceRegistration
+    private ServiceRegistration m_serviceRegistration;
+
+    /**
+     * The constructor receives both the activator and the metadata
+     * 
+     * @param activator
+     * @param metadata
+     */
+    protected AbstractComponentManager(BundleComponentActivator activator, ComponentMetadata metadata)
+    {
+        m_activator = activator;
+        m_componentMetadata = metadata;
+        
+        m_state = STATE_DISABLED;
+        m_dependencyManagers = new ArrayList();
+    }
+    
+    /**
+     * Enable this component
+     * 
+     * @return true if enabling was successful
+     */
+    public synchronized boolean enable() {
+    	
+        if (getState() == STATE_DESTROYED)
+        {
+            Activator.error( "Destroyed Component cannot be enabled", m_componentMetadata );
+            return false;
+        }
+        else if (getState() != STATE_DISABLED)
+        {
+            Activator.trace( "Component is already enabled", m_componentMetadata );
+            return true;
+        }
+        
+        Activator.trace("Enabling component", m_componentMetadata);
+    	
+    	try
+    	{
+	        // If this component has got dependencies, create dependency managers for each one of them.
+	        if (m_componentMetadata.getDependencies().size() != 0)
+	        {
+	            Iterator dependencyit = m_componentMetadata.getDependencies().iterator();
+	
+	            while(dependencyit.hasNext())
+	            {
+	                ReferenceMetadata currentdependency = (ReferenceMetadata)dependencyit.next();
+	
+	                DependencyManager depmanager = new DependencyManager(this, currentdependency);
+	
+	                m_dependencyManagers.add(depmanager);
+	            }
+	        }
+	
+            // enter enabled state before trying to activate
+	        setState(STATE_ENABLED);
+	        
+	        activate();
+	        
+	        return true;
+    	}
+    	catch(Exception ex)
+    	{
+    		Activator.exception( "Failed enabled Component", m_componentMetadata, ex );
+
+            // ensure we get back to DISABLED state 
+            disable();
+
+            return false;
+    	}
+    }
+
+    /**
+     * Activate this Instance manager.
+     * 
+     * 112.5.6 Activating a component configuration consists of the following steps
+     *   1. Load the component implementation class
+     *   2. Create the component instance and component context
+     *   3. Bind the target services
+     *   4. Call the activate method, if present
+     *   [5. Register provided services]
+     */
+     synchronized void activate()
+     {
+         // CONCURRENCY NOTE: This method is called either by the enable()
+         //     method or by the dependency managers or the reconfigure() method
+         if ( (getState() & (STATE_ENABLED|STATE_UNSATISFIED)) == 0)
+         {
+             // This state can only be entered from the ENABLED (in the enable()
+             // method) or UNSATISFIED (missing references) states
+             return;
+         }
+
+         // go to the activating state
+         setState(STATE_ACTIVATING);
+
+         // Before creating the implementation object, we are going to
+         // test if all the mandatory dependencies are satisfied
+         Iterator it = m_dependencyManagers.iterator();
+         while (it.hasNext())
+         {
+             DependencyManager dm = (DependencyManager)it.next();
+             if (!dm.isValid())
+             {
+                 // at least one dependency is not satisfied
+                 Activator.trace( "Dependency not satisfied: " + dm.getName(), m_componentMetadata );
+                 setState(STATE_UNSATISFIED);
+                 return;
+             }
+         }
+         
+         // 1. Load the component implementation class
+         // 2. Create the component instance and component context
+         // 3. Bind the target services
+         // 4. Call the activate method, if present
+         createComponent();
+         
+         // Validation occurs before the services are provided, otherwhise the
+         // service provider's service may be called by a service requester
+         // while it is still ACTIVATING
+         setState(getSatisfiedState());
+         
+         // 5. Register provided services
+         m_serviceRegistration = registerComponentService();
+     }
+
+     /**
+      * Method is called by {@link #activate()} in STATE_ACTIVATING or by
+      * {@link DelayedComponentManager#getService(Bundle, ServiceRegistration)}
+      * in STATE_REGISTERED.
+      */
+     protected abstract void createComponent();
+     
+     /**
+      * Method is called by {@link #deactivate()} in STATE_DEACTIVATING
+      *
+      */
+     protected abstract void deleteComponent();
+     
+     /**
+      * Returns the state value to set, when the component is satisfied. The
+      * return value depends on the kind of the component:
+      * <dl>
+      * <dt>Immediate</dt><dd><code>STATE_ACTIVE</code></dd>  
+      * <dt>Delayed</dt><dd><code>STATE_REGISTERED</code></dd>  
+      * <dt>Component Factory</dt><dd><code>STATE_FACTORY</code></dd>
+      * </dl>
+      *   
+      * @return
+      */
+     private int getSatisfiedState() {
+         if (m_componentMetadata.isFactory())
+         {
+             return STATE_FACTORY;
+         }
+         else if (m_componentMetadata.isImmediate())
+         {
+             return STATE_ACTIVE;
+         }
+         else
+         {
+             return STATE_REGISTERED;
+         }
+     }
+     
+     /**
+      * Returns the service object to be registered if the service element is
+      * specified.
+      * <p>
+      * Extensions of this class may overwrite this method to return a
+      * ServiceFactory to register in the case of a delayed or a service
+      * factory component. 
+      */
+     protected abstract Object getService();
+     
+
+     // 5. Register provided services
+     protected ServiceRegistration registerComponentService()
+     {
+         if ( getComponentMetadata().getServiceMetadata() != null )
+         {
+             Activator.trace( "registering services", getComponentMetadata() );
+
+             // get a copy of the component properties as service properties
+             Dictionary serviceProperties = copyTo( null, getProperties() );
+
+             return getActivator().getBundleContext().registerService(
+                 getComponentMetadata().getServiceMetadata().getProvides(), getService(), serviceProperties );
+         }
+         
+         return null;
+     }
+     
+     protected void unregisterComponentService()
+     {
+         if ( m_serviceRegistration != null )
+         {
+             m_serviceRegistration.unregister();
+             m_serviceRegistration = null;
+
+             Activator.trace( "unregistering the services", getComponentMetadata() );
+         }
+     }
+     
+    /**
+     * Reconfigures this component by deactivating and activating it. During
+     * activation the new configuration data is retrieved from the Configuration
+     * Admin Service.
+     */
+    public void reconfigure()
+    {
+        Activator.trace( "Deactivating and Activating to reconfigure", m_componentMetadata );
+        reactivate();
+    }
+    
+    /**
+     * Deactivates and activates this component instance.
+     */
+    void reactivate() {
+        deactivate();
+        Activator.trace( "Dependency Manager: RECREATING", m_componentMetadata ); 
+        activate();
+    }
+    
+    /**
+     * This method deactivates the manager, performing the following steps
+     * 
+     * [0. Remove published services from the registry]
+     * 1. Call the deactivate() method, if present
+     * 2. Unbind any bound services
+     * 3. Release references to the component instance and component context 
+    **/
+    synchronized void deactivate()
+    {
+        // CONCURRENCY NOTE: This method may be called either from application
+        // code or by the dependency managers or reconfiguration
+        if ((getState() & (STATE_ACTIVATING|STATE_ACTIVE|STATE_REGISTERED|STATE_FACTORY)) == 0)
+        {
+            // This state can only be entered from the ACTIVATING (if activation
+            // fails), ACTIVE, REGISTERED or FACTORY states
+            return;
+        }
+//        if (m_state != INSTANCE_VALID && m_state != INSTANCE_VALIDATING && m_state != INSTANCE_DESTROYING) {
+//            return;
+//        }
+
+        // start deactivation by resetting the state
+        setState( STATE_DEACTIVATING );
+        
+        // 0.- Remove published services from the registry
+        unregisterComponentService();
+
+        // 1.- Call the deactivate method, if present       
+        // 2. Unbind any bound services
+        // 3. Release references to the component instance and component context
+        deleteComponent();
+
+        //Activator.trace("InstanceManager from bundle ["+ m_activator.getBundleContext().getBundle().getBundleId() + "] was invalidated.");
+
+        // reset to state UNSATISFIED
+        setState( STATE_UNSATISFIED );
+    }
+
+    public synchronized void disable()
+    {
+        // CONCURRENCY NOTE: This method is only called from the BundleComponentActivator or by application logic
+        // but not by the dependency managers
+
+        // deactivate first, this does nothing if not active/registered/factory
+        deactivate();
+        
+        // close all service listeners now, they are recreated on enable
+        // Stop the dependency managers to listen to events...
+        Iterator it = m_dependencyManagers.iterator();
+        while (it.hasNext())
+        {
+            DependencyManager dm = (DependencyManager)it.next();
+            dm.close();
+        }
+        m_dependencyManagers.clear();
+
+        // we are now disabled, ready for re-enablement or complete destroyal
+        setState( STATE_DISABLED );
+    }
+    
+    /**
+     * 
+     */
+    public synchronized void dispose()
+    {
+        // CONCURRENCY NOTE: This method is only called from the BundleComponentActivator or by application logic
+    	// but not by the dependency managers
+
+        // disable first to clean up correctly
+        disable();
+        
+        // this component must not be used any more
+        setState( STATE_DISABLED );
+
+        // release references (except component metadata for logging purposes)
+        m_activator = null;
+        m_dependencyManagers = null;
+    }
+
+    //**********************************************************************************************************
+    
+    BundleComponentActivator getActivator() {
+        return m_activator;
+    }
+    
+    Iterator getDependencyManagers() {
+        return m_dependencyManagers.iterator();
+    }
+    
+    DependencyManager getDependencyManager( String name )
+    {
+        Iterator it = getDependencyManagers();
+        while ( it.hasNext() )
+        {
+            DependencyManager dm = ( DependencyManager ) it.next();
+            if ( name.equals( dm.getName() ) )
+            {
+                // only return the dm if it has service references 
+                return ( dm.size() > 0 ) ? dm : null;
+            }
+        }
+
+        // not found
+        return null;
+    }
+    
+    /**
+    * Get the object that is implementing this descriptor
+    *
+    * @return the object that implements the services
+    */
+    public abstract Object getInstance();
+    protected abstract Dictionary getProperties();
+
+    /**
+     * Copies the properties from the <code>source</code> <code>Dictionary</code>
+     * into the <code>target</code> <code>Dictionary</code>.
+     * 
+     * @param target The <code>Dictionary</code> into which to copy the
+     *      properties. If <code>null</code> a new <code>Hashtable</code> is
+     *      created.
+     * @param source The <code>Dictionary</code> providing the properties to
+     *      copy. If <code>null</code> or empty, nothing is copied.
+     *      
+     * @return The <code>target</code> is returned, which may be empty if
+     *      <code>source</code> is <code>null</code> or empty and
+     *      <code>target</code> was <code>null</code>.
+     */
+    protected Dictionary copyTo( Dictionary target, Dictionary source )
+    {
+        if ( target == null )
+        {
+            target = new Hashtable();
+        }
+
+        if ( source != null && !source.isEmpty() )
+        {
+            for ( Enumeration ce = source.keys(); ce.hasMoreElements(); )
+            {
+                Object key = ce.nextElement();
+                target.put( key, source.get( key ) );
+            }
+        }
+
+        return target;
+    }
+
+    ServiceReference getServiceReference() {
+        return ( m_serviceRegistration != null ) ? m_serviceRegistration.getReference() : null;
+    }
+    
+    /**
+     * 
+     */
+    public ComponentMetadata getComponentMetadata() {
+    	return m_componentMetadata;
+    }
+
+    int getState() {
+        return m_state;
+    }
+    
+    /**
+     * sets the state of the manager
+    **/
+    protected synchronized void setState(int newState) {
+        Activator.trace( "State transition : " + stateToString( m_state ) + " -> " + stateToString( newState ),
+            m_componentMetadata );
+    	
+        m_state = newState;
+    }
+
+    private String stateToString(int state) {
+        switch (state) {
+            case STATE_DESTROYED:
+                return "Destroyed";
+            case STATE_DISABLED:
+                return "Disabled";
+            case STATE_ENABLED:
+                return "Enabled";
+            case STATE_UNSATISFIED:
+                return "Unsatisfied";
+            case STATE_ACTIVATING:
+                return "Activating";
+            case STATE_ACTIVE:
+                return "Active";
+            case STATE_REGISTERED:
+                return "Registered";
+            case STATE_FACTORY:
+                return "Factory";
+            case STATE_DEACTIVATING:
+                return "Deactivating";
+            default:
+                return String.valueOf(state);
+        }
+    }
+    /**
+     * Finds the named public or protected method in the given class or any
+     * super class. If such a method is found, its accessibility is enfored by
+     * calling the <code>Method.setAccessible</code> method if required and
+     * the method is returned. Enforcing accessibility is required to support
+     * invocation of protected methods.
+     * 
+     * @param clazz The <code>Class</code> which provides the method.
+     * @param name The name of the method.
+     * @param parameterTypes The parameters to the method. Passing
+     *      <code>null</code> is equivalent to using an empty array.
+     *      
+     * @return The named method with enforced accessibility
+     * 
+     * @throws NoSuchMethodException If no public or protected method with
+     *      the given name can be found in the class or any of its super classes.
+     */
+    static Method getMethod(Class clazz, String name, Class[] parameterTypes)
+        throws NoSuchMethodException 
+    {
+        // try the default mechanism first, which only yields public methods
+        try
+        {
+            return clazz.getMethod(name, parameterTypes); 
+        }
+        catch (NoSuchMethodException nsme)
+        {
+            // it is ok to not find a public method, try to find a protected now
+        }
+        
+        // now use method declarations, requiring walking up the class
+        // hierarchy manually. this algorithm also returns protected methods
+        // which is, what we need here
+        for ( ; clazz != null; clazz = clazz.getSuperclass()) 
+        {
+            try 
+            {
+                Method method = clazz.getDeclaredMethod(name, parameterTypes);
+                
+                // only accept a protected method, a public method should
+                // have been found above and neither private nor package
+                // protected methods are acceptable here
+                if (Modifier.isProtected(method.getModifiers())) {
+                    method.setAccessible(true);
+                    return method;
+                }
+            }
+            catch (NoSuchMethodException nsme)
+            {
+                // ignore for now
+            }
+        }
+        
+        // walked up the complete super class hierarchy and still not found
+        // anything, sigh ...
+        throw new NoSuchMethodException(name);
+    }
+    
+}

Propchange: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/AbstractComponentManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/AbstractComponentManager.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Modified: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/Activator.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/Activator.java?view=diff&rev=523345&r1=523344&r2=523345
==============================================================================
--- incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/Activator.java (original)
+++ incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/Activator.java Wed Mar 28 07:34:01 2007
@@ -18,18 +18,28 @@
  */
 package org.apache.felix.scr;
 
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
-import java.util.*;
-
-import org.osgi.framework.*;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.logging.Logger;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.Constants;
+import org.osgi.framework.SynchronousBundleListener;
 import org.osgi.service.log.LogService;
+import org.osgi.util.tracker.ServiceTracker;
 
 /**
  * This activator is used to cover requirement described in section 112.8.1 @@ -27,14
  * 37,202 @@ in active bundles.
  * 
  */
-public class Activator implements BundleActivator, SynchronousBundleListener, ServiceListener
+public class Activator implements BundleActivator, SynchronousBundleListener
 {
     // name of the LogService class
     private static final String LOGSERVICE_CLASS = LogService.class.getName();
@@ -41,37 +51,20 @@
     private static boolean m_error = true;
 
     // A string containing the version number
-    private static String m_version = "1.0.0 (12012006)";
+    private static String m_version = "1.0.0 (20070320)";
 
     // this bundle's context
     private BundleContext m_context;
     
     // the log service to log messages to
-    private static /* TODO: not very good, is it ? */ LogService m_logService;
+    private static ServiceTracker m_logService;
     
     // map of BundleComponentActivator instances per Bundle indexed by Bundle symbolic
     // name
     private Map m_componentBundles;
 
-    // Static initializations based on system properties
-    static {
-        // Get system properties to see if traces or errors need to be displayed
-        String result = System.getProperty("ds.showtrace");
-        if(result != null && result.equals("true"))
-        {
-            m_trace = true;
-        }
-        result = System.getProperty("ds.showerrors");
-        if(result != null && result.equals("false"))
-        {
-            m_error = false;
-        }
-        result = System.getProperty("ds.showversion");
-        if(result != null && result.equals("true"))
-        {
-            System.out.println("[ Version = "+m_version+" ]\n");
-        }        
-    }
+    // registry of managed component
+    private ComponentRegistry m_componentRegistry;
 
     /**
      * Registers this instance as a (synchronous) bundle listener and loads the
@@ -84,15 +77,21 @@
     {
         m_context = context;
         m_componentBundles = new HashMap();
+        m_componentRegistry = new ComponentRegistry( m_context );
 
         // require the log service
-        ServiceReference logRef = context.getServiceReference(LOGSERVICE_CLASS);
-        if (logRef != null) {
-            m_logService = (LogService) context.getService(logRef);
-        }
-        context.addServiceListener(this,
-            "(" + Constants.OBJECTCLASS + "=" + LOGSERVICE_CLASS + ")");
+        m_logService = new ServiceTracker(context, LOGSERVICE_CLASS, null);
+        m_logService.open();
         
+        // configure logging from context properties
+        m_trace = "true".equalsIgnoreCase( context.getProperty( "ds.showtrace" ) );
+        m_error = !"false".equalsIgnoreCase( context.getProperty( "ds.showerrors" ) );
+        if ( "true".equalsIgnoreCase( context.getProperty( "ds.showversion" ) ) )
+        {
+            trace( context.getBundle().getSymbolicName() + "[ Version = "
+                + context.getBundle().getHeaders().get( Constants.BUNDLE_VERSION ) + " ]", null );
+        }
+
         // register for bundle updates
         context.addBundleListener(this);
 
@@ -115,6 +114,9 @@
 
         // 112.8.2 dispose off all active components
         disposeAllComponents();
+
+        // dispose off the component registry
+        m_componentRegistry.dispose();
     }
 
     // ---------- BundleListener Interface -------------------------------------
@@ -139,23 +141,7 @@
         }
     }
 
-    //---------- ServiceListener ----------------------------------------------
-
-    // TODO:
-    public void serviceChanged(ServiceEvent event)
-    {
-        if (event.getType() == ServiceEvent.REGISTERED)
-        {
-            m_logService = (LogService) m_context.getService(event.getServiceReference());
-        }
-        else if (event.getType() == ServiceEvent.UNREGISTERING)
-        {
-            m_logService = null;
-            m_context.ungetService(event.getServiceReference());
-        }
-    }
-    
-    // ---------- Component Management -----------------------------------------
+    //---------- Component Management -----------------------------------------
 
     // Loads the components of all bundles currently active.
     private void loadAllComponents(BundleContext context)
@@ -192,14 +178,13 @@
         BundleContext context = getBundleContext(bundle);
         if (context == null)
         {
-            error("Cannot get BundleContext of bundle "
-                + bundle.getSymbolicName());
+            error( "Cannot get BundleContext of bundle " + bundle.getSymbolicName(), null );
             return;
         }
 
         try
         {
-            BundleComponentActivator ga = new BundleComponentActivator(context);
+            BundleComponentActivator ga = new BundleComponentActivator( m_componentRegistry, context );
             m_componentBundles.put(bundle.getSymbolicName(), ga);
         }
         catch (Exception e)
@@ -267,15 +252,21 @@
      */
     private BundleContext getBundleContext(Bundle bundle)
     {
-        for (Class clazz = bundle.getClass(); clazz != null; clazz = clazz.getSuperclass())
+//        try {
+//            return bundle.getBundleContext();
+//        } catch (Throwable t) {
+//            // don't care, might be that the implementation is not yet updated
+//            // to OSGi Rev 4.1
+//        }
+        
+        BundleContext context = null;
+        for (Class clazz = bundle.getClass(); context == null && clazz != null; clazz = clazz.getSuperclass())
         {
             try
             {
-                Method m = clazz.getDeclaredMethod("getContext", null);
-                if (m.getReturnType().equals(BundleContext.class))
-                {
-                    m.setAccessible(true);
-                    return (BundleContext) m.invoke(bundle, null);
+                context = getBundleContext( clazz, bundle, "getBundleContext" );
+                if (context == null) {
+                    context = getBundleContext( clazz, bundle, "getContext" );
                 }
             }
             catch (NoSuchMethodException nsme)
@@ -289,10 +280,23 @@
             }
         }
 
-        // fall back to nothing
-        return null;
+        // return what we found
+        return context;
     }
     
+    private BundleContext getBundleContext( Class clazz, Bundle bundle, String methodName )
+        throws NoSuchMethodException, InvocationTargetException, IllegalAccessException
+    {
+        Method m = clazz.getDeclaredMethod( methodName, null );
+        if ( m.getReturnType().equals( BundleContext.class ) )
+        {
+            m.setAccessible( true );
+            return ( BundleContext ) m.invoke( bundle, null );
+        }
+        
+        // method exists but has wrong return type
+        return null;
+    }
     
     /**
      * Method to display traces
@@ -310,7 +314,7 @@
             }
             msg.append(message);
 
-            LogService log = m_logService;
+            LogService log = (LogService) m_logService.getService();
             if (log == null)
             {
                 System.out.println(msg);
@@ -326,14 +330,19 @@
      * Method to display errors
      *
      * @param message a string to be displayed
+     * @param metadata optional metadata providing more information to log
      **/
-    static void error(String message)
+    static void error(String message, ComponentMetadata metadata)
     {
         if(m_error)
         {
-            StringBuffer msg = new StringBuffer("### ").append(message);
+            StringBuffer msg = new StringBuffer("### ");
+            if(metadata != null) {
+                msg.append("[").append(metadata.getName()).append("] ");
+            }
+            msg.append(message);
 
-            LogService log = m_logService;
+            LogService log = (LogService) m_logService.getService();
             if (log == null)
             {
                 System.err.println(msg);
@@ -361,7 +370,7 @@
              msg.append("Exception with component : ");
              msg.append(message).append(" ---");
              
-             LogService log = m_logService;
+             LogService log = (LogService) m_logService.getService();
              if (log == null)
              {
                  System.err.println(msg);

Modified: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/BundleComponentActivator.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/BundleComponentActivator.java?view=diff&rev=523345&r1=523344&r2=523345
==============================================================================
--- incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/BundleComponentActivator.java (original)
+++ incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/BundleComponentActivator.java Wed Mar 28 07:34:01 2007
@@ -24,15 +24,21 @@
 import java.io.InputStreamReader;
 import java.net.URL;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.StringTokenizer;
 
+import javax.naming.ConfigurationException;
+
 import org.apache.felix.scr.parser.KXml2SAXParser;
 import org.osgi.framework.BundleContext;
+import org.osgi.service.cm.ConfigurationAdmin;
 import org.osgi.service.component.ComponentException;
+import org.osgi.util.tracker.ServiceTracker;
 
 /**
  * The BundleComponentActivator is helper class to load and unload Components of
@@ -41,27 +47,41 @@
  */
 class BundleComponentActivator
 {	
-	// The bundle context
+    // global component registration
+    private ComponentRegistry m_componentRegistry;
+    
+	// The bundle context owning the registered component
     private BundleContext m_context = null;
     
     // This is a list of component instance managers that belong to a particular bundle
     private List m_managers = new ArrayList();
 
-    // Global Registry of component names
-    private static Set m_componentNames = new HashSet();
+    // The Configuration Admin tracker providing configuration for components
+    private ServiceTracker m_configurationAdmin;
 
     /**
      * Called upon starting of the bundle. This method invokes initialize() which
      * parses the metadata and creates the instance managers
      *
-     * @param   context  The bundle context passed by the framework
-     * @exception   Exception any exception thrown from initialize
+     * @param componentRegistry The <code>ComponentRegistry</code> used to
+     *      register components with to ensure uniqueness of component names
+     *      and to ensure configuration updates.
+     * @param   context  The bundle context owning the components
+     * 
+     * @throws ComponentException if any error occurrs initializing this class
      */
-    BundleComponentActivator(BundleContext context) throws ComponentException
+    BundleComponentActivator(ComponentRegistry componentRegistry, BundleContext context) throws ComponentException
     {
+        // The global "Component" registry
+        this.m_componentRegistry = componentRegistry;
+        
     	// Stores the context
         m_context = context;
         
+        // have the Configuration Admin Service handy (if available)
+        m_configurationAdmin = new ServiceTracker(context, ConfigurationAdmin.class.getName(), null);
+        m_configurationAdmin.open();
+        
         // Get the Metadata-Location value from the manifest
         String descriptorLocations =
             (String) m_context.getBundle().getHeaders().get("Service-Component");
@@ -95,12 +115,13 @@
             {
                 // 112.4.1 If an XML document specified by the header cannot be located in the bundle and its attached
                 // fragments, SCR must log an error message with the Log Service, if present, and continue.
-                Activator.error("Component descriptor entry '" + descriptorLocation + "' not found");
+                Activator.error( "Component descriptor entry '" + descriptorLocation + "' not found", null );
                 continue;
             }
 
+            InputStream stream = null;
 			try {
-				InputStream stream = descriptorURL.openStream();
+				stream = descriptorURL.openStream();
 
 				BufferedReader in = new BufferedReader(new InputStreamReader(stream)); 
 	            XmlHandler handler = new XmlHandler(); 
@@ -121,16 +142,23 @@
     		            validate(metadata);
     		        	
     	                // Request creation of the component manager
-    	                ComponentManager manager = ManagerFactory.createManager(this,metadata);
+    	                ComponentManager 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 {
+                            manager = ManagerFactory.createManager( this, metadata, m_componentRegistry
+                            .createComponentId() );
+                        }
                 		
-                		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
-                		}
-                		else if(metadata.isEnabled())
+                        // register the component after validation
+                        m_componentRegistry.registerComponent( metadata.getName(), manager );
+                        
+                        // enable the component
+                		if(metadata.isEnabled())
                         {
-		                	// enable the component
 		                	manager.enable();
 		                }
 
@@ -144,9 +172,6 @@
                         Activator.exception("Cannot register Component", metadata, e);
 					} 
 		        }
-		        
-		        stream.close();
-
 			}
 			catch ( IOException ex )
             {
@@ -161,6 +186,19 @@
                 Activator.exception("General problem with descriptor entry '"
                     + descriptorLocation + "'", null, ex);
 			}
+            finally
+            {
+                if ( stream != null )
+                {
+                    try
+                    {
+                        stream.close();
+                    }
+                    catch ( IOException ignore )
+                    {
+                    }
+                }
+            }
 		}
     }
 
@@ -193,11 +231,16 @@
             }
             finally
             {
-            	m_componentNames.remove(manager.getComponentMetadata().getName());
+                m_componentRegistry.unregisterComponent( manager.getComponentMetadata().getName() );
             }
             
         }
 
+        // close the Configuration Admin tracker
+        if (m_configurationAdmin != null) {
+            m_configurationAdmin.close();
+        }
+        
         Activator.trace("BundleComponentActivator : Bundle ["
             + m_context.getBundle().getBundleId() + "] STOPPED", null);
 
@@ -225,6 +268,16 @@
     }
 
     /**
+     * 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.
@@ -255,8 +308,7 @@
                     }
                     catch (Throwable t) 
                     {
-                        Activator.exception("Cannot enable component",
-                            cm[i].getComponentMetadata(), t);
+                        Activator.exception( "Cannot enable component", cm[i].getComponentMetadata(), t );
                     }
                 }
             }
@@ -291,7 +343,7 @@
                 {
                     try
                     {
-                        cm[i].dispose();
+                        cm[i].disable();
                     }
                     catch (Throwable t)
                     {
@@ -326,7 +378,7 @@
             return (ComponentManager[]) m_managers.toArray(new ComponentManager[m_managers.size()]);
         }
         
-        if (m_componentNames.contains(name))
+        if ( m_componentRegistry.getComponent( name ) != null )
         {
             // otherwise just find it
             Iterator it = m_managers.iterator();
@@ -358,16 +410,19 @@
     void validate(ComponentMetadata component) throws ComponentException
     {
 
-    	if(m_componentNames.contains(component.getName()))
-    	{
-    		throw new ComponentException("The component name '"+component.getName()+"' has already been registered.");
-    	}
+        m_componentRegistry.checkComponentName( component.getName() );
     	
-        component.validate();
+        try
+        {
+            component.validate();
+        }
+        catch ( ComponentException ce )
+        {
+            // remove the reservation before leaving
+            m_componentRegistry.unregisterComponent( component.getName() );
+            throw ce;
+        }
 
-        // register the component after validation
-        m_componentNames.add(component.getName());
-    	
-        Activator.trace("Validated and registered component",component);
+        Activator.trace( "Validated and registered component", component );
     }
 }

Added: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentContextImpl.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentContextImpl.java?view=auto&rev=523345
==============================================================================
--- incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentContextImpl.java (added)
+++ incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentContextImpl.java Wed Mar 28 07:34:01 2007
@@ -0,0 +1,157 @@
+/* 
+ * 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;
+
+
+import java.util.Dictionary;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.ComponentInstance;
+
+
+/**
+ * Implementation for the ComponentContext interface
+ *
+ */
+class ComponentContextImpl implements ComponentContext
+{
+
+    private AbstractComponentManager m_componentManager;
+
+
+    ComponentContextImpl( AbstractComponentManager componentManager )
+    {
+        m_componentManager = componentManager;
+    }
+
+    
+    protected AbstractComponentManager getComponentManager()
+    {
+        return m_componentManager;
+    }
+
+    public Dictionary getProperties()
+    {
+        // 112.11.3.5 The Dictionary is read-only and cannot be modified
+        return new ReadOnlyDictionary( m_componentManager.getProperties() );
+    }
+
+
+    public Object locateService( String name )
+    {
+        DependencyManager dm = m_componentManager.getDependencyManager( name );
+        if ( dm == null )
+        {
+            return null;
+        }
+
+        ServiceReference selectedRef;
+        if ( dm.size() == 1 )
+        {
+            // short cut for single bound service
+            selectedRef = dm.getServiceReference();
+        }
+        else
+        {
+            // is it correct to assume an ordered bound services set ? 
+            int maxRanking = Integer.MIN_VALUE;
+            long minId = Long.MAX_VALUE;
+            selectedRef = null;
+
+            ServiceReference[] refs = dm.getServiceReferences();
+            for ( int i = 0; refs != null && i < refs.length; i++ )
+            {
+                ServiceReference ref = refs[i];
+                Integer rank = ( Integer ) ref.getProperty( Constants.SERVICE_RANKING );
+                int ranking = ( rank == null ) ? Integer.MIN_VALUE : rank.intValue();
+                long id = ( ( Long ) ref.getProperty( Constants.SERVICE_ID ) ).longValue();
+                if ( maxRanking < ranking || ( maxRanking == ranking && id < minId ) )
+                {
+                    maxRanking = ranking;
+                    minId = id;
+                    selectedRef = ref;
+                }
+            }
+        }
+
+        // this is not realistic, as at least one service is available
+        // whose service id is smaller than Long.MAX_VALUE, still be sure
+        if ( selectedRef == null )
+        {
+            return null;
+        }
+
+        // return the service for the selected reference
+        return dm.getService( selectedRef );
+    }
+
+
+    public Object locateService( String name, ServiceReference ref )
+    {
+        DependencyManager dm = m_componentManager.getDependencyManager( name );
+        return ( dm != null ) ? dm.getService( ref ) : null;
+    }
+
+
+    public Object[] locateServices( String name )
+    {
+        DependencyManager dm = m_componentManager.getDependencyManager( name );
+        return ( dm != null ) ? dm.getServices() : null;
+    }
+
+
+    public BundleContext getBundleContext()
+    {
+        return m_componentManager.getActivator().getBundleContext();
+    }
+
+
+    public Bundle getUsingBundle()
+    {
+        return null;
+    }
+
+
+    public ComponentInstance getComponentInstance()
+    {
+        return m_componentManager;
+    }
+
+
+    public void enableComponent( String name )
+    {
+        m_componentManager.getActivator().enableComponent( name );
+    }
+
+
+    public void disableComponent( String name )
+    {
+        m_componentManager.getActivator().disableComponent( name );
+    }
+
+
+    public ServiceReference getServiceReference()
+    {
+        return m_componentManager.getServiceReference();
+    }
+}

Propchange: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentContextImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentContextImpl.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentFactoryImpl.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentFactoryImpl.java?view=auto&rev=523345
==============================================================================
--- incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentFactoryImpl.java (added)
+++ incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentFactoryImpl.java Wed Mar 28 07:34:01 2007
@@ -0,0 +1,248 @@
+/* 
+ * 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;
+
+
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.IdentityHashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedServiceFactory;
+import org.osgi.service.component.ComponentConstants;
+import org.osgi.service.component.ComponentFactory;
+import org.osgi.service.component.ComponentInstance;
+
+
+/**
+ * The <code>ComponentFactoryImpl</code> TODO
+ *
+ * @author fmeschbe
+ */
+public class ComponentFactoryImpl extends AbstractComponentManager implements ComponentFactory, ManagedServiceFactory
+{
+
+    // The component registry used to retrieve component IDs
+    private ComponentRegistry m_componentRegistry;
+
+    // The map of components created from Configuration objects
+    // maps PID to ComponentManager for configuration updating
+    // this map is lazily created
+    private Map m_configuredServices;
+
+    // Actually we only use the identity key stuff, but there is
+    // no IdentityHashSet and HashSet internally uses a HashMap anyway
+    private Map m_createdComponents;
+
+    ComponentFactoryImpl( BundleComponentActivator activator, ComponentMetadata metadata,
+        ComponentRegistry componentRegistry )
+    {
+        super( activator, metadata );
+        m_componentRegistry = componentRegistry;
+        m_createdComponents = new IdentityHashMap();
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.osgi.service.component.ComponentFactory#newInstance(java.util.Dictionary)
+     */
+    public ComponentInstance newInstance( Dictionary dictionary )
+    {
+        return ( ComponentInstance ) createComponentManager( dictionary );
+    }
+
+
+    protected void createComponent()
+    {
+        // not component to create, newInstance must be used instead
+    }
+
+    public void reconfigure()
+    {
+        super.reconfigure();
+    }
+
+    protected void deleteComponent()
+    {
+        // nothing to delete
+    }
+
+
+    protected ServiceRegistration registerComponentService()
+    {
+        Activator.trace( "registering component factory", getComponentMetadata() );
+
+        Dictionary serviceProperties = getProperties();
+        return getActivator().getBundleContext().registerService( new String[]
+            { ComponentFactory.class.getName(), ManagedServiceFactory.class.getName() }, getService(),
+            serviceProperties );
+    }
+
+
+    public Object getInstance()
+    {
+        // this does not return the component instance actually
+        return null;
+    }
+
+
+    protected Dictionary getProperties()
+    {
+        Dictionary props = new Hashtable();
+        
+        // 112.5.5 The Component Factory service must register with the following properties
+        props.put( ComponentConstants.COMPONENT_NAME, getComponentMetadata().getName() );
+        props.put( ComponentConstants.COMPONENT_FACTORY, getComponentMetadata().getFactoryIdentifier() );
+        
+        // also register with the factory PID
+        props.put( Constants.SERVICE_PID, getComponentMetadata().getName() );
+        
+        return props;
+    }
+
+
+    protected Object getService()
+    {
+        return this;
+    }
+
+
+    //---------- ManagedServiceFactory interface ------------------------------
+
+    public void updated( String pid, Dictionary configuration )
+    {
+        ComponentManager cm;
+        if ( m_configuredServices != null )
+        {
+            cm = ( ComponentManager ) 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 );
+
+            // keep a reference for future updates
+            m_configuredServices.put( pid, cm );
+        }
+        else
+        {
+            if ( cm instanceof ImmediateComponentManager )
+            {
+                // inject current configuration before cycling
+                ( ( ImmediateComponentManager ) cm ).setFactoryProperties( configuration );
+            }
+
+            // reconfigure the component
+            cm.reconfigure();
+        }
+    }
+
+
+    public void deleted( String pid )
+    {
+        if ( m_configuredServices != null )
+        {
+            ComponentManager cm = ( ComponentManager ) m_configuredServices.remove( pid );
+            if ( cm != null )
+            {
+                disposeComponentManager( cm );
+            }
+        }
+
+    }
+
+
+    public String getName()
+    {
+        return "Component Factory " + getComponentMetadata().getName();
+    }
+
+
+    //---------- internal -----------------------------------------------------
+
+    /**
+     * ComponentManager instances created by this method are not registered
+     * with the ComponentRegistry. Therefore, any configuration update to these
+     * components must be effected by this class !
+     */
+    private ComponentManager createComponentManager( Dictionary configuration )
+    {
+        long componentId = m_componentRegistry.createComponentId();
+        ComponentManager cm = ManagerFactory.createManager( getActivator(), getComponentMetadata(), componentId );
+
+        // add the new component to the activators instances
+        getActivator().getInstanceReferences().add( cm );
+
+        // register with the internal set of created components
+        m_createdComponents.put(cm, cm);
+        
+        // inject configuration if possible
+        if ( cm instanceof ImmediateComponentManager )
+        {
+            ( ( ImmediateComponentManager ) cm ).setFactoryProperties( configuration );
+        }
+
+        // immediately enable this ComponentManager
+        cm.enable();
+        
+        return cm;
+    }
+    
+    private void disposeComponentManager(ComponentManager cm) {
+        // remove from created components
+        m_createdComponents.remove( cm );
+        
+        // remove from activators list
+        getActivator().getInstanceReferences().remove( cm );
+        
+        // finally dispose it
+        cm.dispose();
+    }
+    
+    private class ComponentInstanceWrapper implements ComponentInstance {
+        
+        private ComponentManager m_component;
+        
+        ComponentInstanceWrapper(ComponentManager component) {
+            m_component = component;
+        }
+        
+        public Object getInstance()
+        {
+            return ((ComponentInstance) m_component).getInstance();
+        }
+        
+        public void dispose()
+        {
+            disposeComponentManager( m_component );
+        }
+    }
+}

Propchange: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentFactoryImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentFactoryImpl.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Modified: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentManager.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentManager.java?view=diff&rev=523345&r1=523344&r2=523345
==============================================================================
--- incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentManager.java (original)
+++ incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentManager.java Wed Mar 28 07:34:01 2007
@@ -18,6 +18,8 @@
  */
 package org.apache.felix.scr;
 
+import java.util.Dictionary;
+
 /**
  * This interface is provided so that there can be multiple implementations of 
  * managers that are responsible for managing component's lifecycle.  
@@ -32,9 +34,21 @@
 	 */
 	public boolean enable();
 	
+    /**
+     * Reconfigure the component with configuration data newly retrieved from
+     * the Configuration Admin Service.
+     */
+    public void reconfigure();
+    
+    /**
+     * Disable the component. After disabling the component may be re-enabled
+     * by calling the {@link #enable()} method.
+     */
+    public void disable();
+    
 	/**
-	 * Dispose the component
-	 * 
+	 * Dispose the component. After disposing the component manager it must not
+     * be used anymore.
 	 */
 	public void dispose();
 

Added: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentRegistry.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentRegistry.java?view=auto&rev=523345
==============================================================================
--- incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentRegistry.java (added)
+++ incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentRegistry.java Wed Mar 28 07:34:01 2007
@@ -0,0 +1,141 @@
+/* 
+ * 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;
+
+
+import java.awt.Component;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.ConfigurationEvent;
+import org.osgi.service.cm.ConfigurationListener;
+import org.osgi.service.component.ComponentException;
+
+
+/**
+ * The <code>ComponentRegistry</code> TODO
+ *
+ * @author fmeschbe
+ */
+public class ComponentRegistry implements ConfigurationListener
+{
+
+    // Known and registered ComponentManager instances
+    private Map m_componentNames;
+
+    // component id counter
+    private long m_componentCounter;
+
+    // the service registration of the ConfigurationListener service
+    private ServiceRegistration registration;
+
+
+    ComponentRegistry( BundleContext context )
+    {
+        m_componentNames = new HashMap();
+        m_componentCounter = -1;
+
+        Dictionary props = new Hashtable();
+        props.put( Constants.SERVICE_DESCRIPTION, "Service Component Configuration Support" );
+        props.put( Constants.SERVICE_VENDOR, "Apache Software Foundation" );
+        registration = context.registerService( ConfigurationListener.class.getName(), this, props );
+    }
+
+
+    void dispose()
+    {
+        if ( registration != null )
+        {
+            registration.unregister();
+            registration = null;
+        }
+    }
+
+
+    //---------- ConfigurationListener ----------------------------------------
+
+    public void configurationEvent( ConfigurationEvent configEvent )
+    {
+        String pid = configEvent.getPid();
+        ComponentManager cm = getComponent( pid );
+        if ( cm != null )
+        {
+            cm.reconfigure();
+        }
+    }
+
+
+    //---------- ComponentManager registration support ------------------------
+
+    long createComponentId()
+    {
+        m_componentCounter++;
+        return m_componentCounter;
+    }
+
+
+    void checkComponentName( String name )
+    {
+        if ( m_componentNames.containsKey( name ) )
+        {
+            throw new ComponentException( "The component name '" + name + "' has already been registered." );
+        }
+
+        // reserve the name
+        m_componentNames.put( name, name );
+    }
+
+
+    void registerComponent( String name, ComponentManager component )
+    {
+        // only register the component if there is a registration for it !
+        if ( !name.equals( m_componentNames.get( name ) ) )
+        {
+            // this is not expected if all works ok
+            throw new ComponentException( "The component name '" + name + "' has already been registered." );
+        }
+
+        m_componentNames.put( name, component );
+    }
+
+
+    ComponentManager getComponent( String name )
+    {
+        Object entry = m_componentNames.get( name );
+
+        // only return the entry if non-null and not a reservation
+        if ( entry instanceof ComponentManager )
+        {
+            return ( ComponentManager ) entry;
+        }
+
+        return null;
+    }
+
+
+    void unregisterComponent( String name )
+    {
+        m_componentNames.remove( name );
+    }
+}

Propchange: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentRegistry.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/ComponentRegistry.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/DelayedComponentManager.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/DelayedComponentManager.java?view=auto&rev=523345
==============================================================================
--- incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/DelayedComponentManager.java (added)
+++ incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/DelayedComponentManager.java Wed Mar 28 07:34:01 2007
@@ -0,0 +1,84 @@
+/* 
+ * 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;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.component.ComponentContext;
+
+/**
+ * The <code>DelayedComponentManager</code> TODO
+ *
+ * @author fmeschbe
+ * @version $Rev$, $Date$
+ */
+public class DelayedComponentManager extends ImmediateComponentManager implements ServiceFactory
+{
+
+    /**
+     * @param activator
+     * @param metadata
+     * @param componentId
+     */
+    public DelayedComponentManager( BundleComponentActivator activator, ComponentMetadata metadata, long componentId )
+    {
+        super( activator, metadata, componentId );
+    }
+
+    protected void createComponent()
+    {
+        // nothing to do here for a delayed component, will be done in the
+        // getService method for the first bundle acquiring the component
+    }
+    
+    protected Object getService()
+    {
+        return this;
+    }
+    
+    //---------- ServiceFactory interface -------------------------------------
+    
+    public Object getService( Bundle arg0, ServiceRegistration arg1 )
+    {
+        Activator.trace("DelayedComponentServiceFactory.getService()", getComponentMetadata());
+        // When the getServiceMethod is called, the implementation object must be created
+        // unless another bundle has already retrievd it
+        
+        if (getInstance() == null) {
+            super.createComponent();
+            
+            // if component creation failed, we were deactivated and the state
+            // is not REGISTERED any more. Otherwise go to standard ACTIVE
+            // state now
+            if (getState() == STATE_REGISTERED)
+            {
+                setState( STATE_ACTIVE );
+            }
+        }
+        
+        return getInstance();
+    }
+    
+    public void ungetService( Bundle arg0, ServiceRegistration arg1, Object arg2 )
+    {
+        // nothing to do here
+    }
+    
+}

Propchange: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/DelayedComponentManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/felix/trunk/scr/src/main/java/org/apache/felix/scr/DelayedComponentManager.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url