FELIX-1162 Setup the DependencyManagers when the component
helper instance is created and enable the DependencyManagers
separately when the component is enabled

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@778407 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/AbstractComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/AbstractComponentManager.java
index 2e6cd6e..6b0fe97 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/AbstractComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/AbstractComponentManager.java
@@ -72,7 +72,7 @@
         m_componentId = componentId;
 
         m_state = STATE_DISABLED;
-        m_dependencyManagers = new ArrayList();
+        loadDependencyManagers( metadata );
 
         log( LogService.LOG_DEBUG, "Component created", m_componentMetadata, null );
     }
@@ -341,20 +341,8 @@
 
         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 );
-                }
-            }
+            // enable the dependency managers of this component
+            enableDependencyManagers();
 
             // enter enabled state before trying to activate
             setState( STATE_ENABLED );
@@ -411,29 +399,11 @@
 
             // Before creating the implementation object, we are going to
             // test if all the mandatory dependencies are satisfied
-            Dictionary properties = getProperties();
-            Iterator it = m_dependencyManagers.iterator();
-            while ( it.hasNext() )
+            if ( !verifyDependencyManagers( getProperties() ) )
             {
-                DependencyManager dm = ( DependencyManager ) it.next();
-
-                // ensure the target filter is correctly set
-                dm.setTargetFilter( properties );
-
-                // check whether the service is satisfied
-                if ( !dm.isSatisfied() )
-                {
-                    // at least one dependency is not satisfied
-                    log( LogService.LOG_INFO, "Dependency not satisfied: " + dm.getName(), m_componentMetadata, null );
-                    setState( STATE_UNSATISFIED );
-                }
-
-                // if at least one dependency is missing, we cannot continue and
-                // have to return
-                if ( getState() == STATE_UNSATISFIED )
-                {
-                    return;
-                }
+                log( LogService.LOG_INFO, "Not all dependencies satisified, cannot activate", m_componentMetadata, null );
+                setState( STATE_UNSATISFIED );
+                return;
             }
 
             // 1. Load the component implementation class
@@ -547,15 +517,9 @@
 
         log( LogService.LOG_DEBUG, "Disabling component", m_componentMetadata, null );
 
-        // 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.dispose();
-        }
-        m_dependencyManagers.clear();
+        // dispose and recreate dependency managers
+        disposeDependencyManagers();
+        loadDependencyManagers( m_componentMetadata );
 
         // we are now disabled, ready for re-enablement or complete destroyal
         setState( STATE_DISABLED );
@@ -589,7 +553,7 @@
 
         // release references (except component metadata for logging purposes)
         m_activator = null;
-        m_dependencyManagers = null;
+        m_dependencyManagers.clear();
     }
 
 
@@ -817,6 +781,66 @@
     }
 
 
+    private void loadDependencyManagers( ComponentMetadata metadata )
+    {
+        List depMgrList = new ArrayList();
+
+        // If this component has got dependencies, create dependency managers for each one of them.
+        if ( metadata.getDependencies().size() != 0 )
+        {
+            Iterator dependencyit = metadata.getDependencies().iterator();
+
+            while ( dependencyit.hasNext() )
+            {
+                ReferenceMetadata currentdependency = ( ReferenceMetadata ) dependencyit.next();
+
+                DependencyManager depmanager = new DependencyManager( this, currentdependency );
+
+                depMgrList.add( depmanager );
+            }
+        }
+
+        m_dependencyManagers = depMgrList;
+    }
+
+
+    private void enableDependencyManagers() throws InvalidSyntaxException
+    {
+        Iterator it = getDependencyManagers();
+        while ( it.hasNext() )
+        {
+            DependencyManager dm = ( DependencyManager ) it.next();
+            dm.enable();
+        }
+    }
+
+
+    private boolean verifyDependencyManagers( Dictionary properties )
+    {
+        // indicates whether all dependencies are satisfied
+        boolean satisfied = true;
+
+        Iterator it = getDependencyManagers();
+        while ( it.hasNext() )
+        {
+            DependencyManager dm = ( DependencyManager ) it.next();
+
+            // ensure the target filter is correctly set
+            dm.setTargetFilter( properties );
+
+            // check whether the service is satisfied
+            if ( !dm.isSatisfied() )
+            {
+                // at least one dependency is not satisfied
+                log( LogService.LOG_INFO, "Dependency not satisfied: " + dm.getName(), m_componentMetadata, null );
+                satisfied = false;
+            }
+        }
+
+        return satisfied;
+    }
+
+
     Iterator getDependencyManagers()
     {
         return m_dependencyManagers.iterator();
@@ -840,11 +864,22 @@
     }
 
 
+    private void disposeDependencyManagers()
+    {
+        Iterator it = getDependencyManagers();
+        while ( it.hasNext() )
+        {
+            DependencyManager dm = ( DependencyManager ) it.next();
+            dm.dispose();
+        }
+    }
+
+
     /**
-    * Get the object that is implementing this descriptor
-    *
-    * @return the object that implements the services
-    */
+     * Get the object that is implementing this descriptor
+     *
+     * @return the object that implements the services
+     */
     public abstract Object getInstance();
 
 
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/DependencyManager.java b/scr/src/main/java/org/apache/felix/scr/impl/DependencyManager.java
index 0c17c5d..0b40681 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/DependencyManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/DependencyManager.java
@@ -98,7 +98,6 @@
      * @param dependency An object that contains data about the dependency
      */
     DependencyManager( AbstractComponentManager componentManager, ReferenceMetadata dependency )
-        throws InvalidSyntaxException
     {
         m_componentManager = componentManager;
         m_dependencyMetadata = dependency;
@@ -107,10 +106,6 @@
         // setup the target filter from component descriptor
         setTargetFilter( m_dependencyMetadata.getTarget() );
 
-        // register the service listener
-        String filterString = "(" + Constants.OBJECTCLASS + "=" + dependency.getInterface() + ")";
-        componentManager.getActivator().getBundleContext().addServiceListener( this, filterString );
-
         // get the current number of registered services available
         ServiceReference refs[] = getFrameworkServiceReferences();
         m_size = ( refs == null ) ? 0 : refs.length;
@@ -430,6 +425,18 @@
     //---------- Service tracking support -------------------------------------
 
     /**
+     * Enables this dependency manager by starting to listen for service
+     * events.
+     * @throws InvalidSyntaxException if the target filter is invalid
+     */
+    void enable() throws InvalidSyntaxException
+    {
+        // register the service listener
+        String filterString = "(" + Constants.OBJECTCLASS + "=" + m_dependencyMetadata.getInterface() + ")";
+        m_componentManager.getActivator().getBundleContext().addServiceListener( this, filterString );
+    }
+    
+    /**
      * Disposes off this dependency manager by removing as a service listener
      * and ungetting all services, which are still kept in the list of our
      * bound services. This list will not be empty if the service lookup