FELIX-3729 fix factory setup order, don't respond to added events while tracker is opening

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1424300 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
index 3960e61..d9d126e 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
@@ -26,7 +26,6 @@
 import java.util.Enumeration;
 import java.util.Hashtable;
 import java.util.List;
-import java.util.Map;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicLong;
@@ -917,7 +916,7 @@
         }
     }
 
-    protected boolean verifyDependencyManagers( Dictionary properties )
+    protected boolean verifyDependencyManagers()
     {
         // indicates whether all dependencies are satisfied
         boolean satisfied = true;
@@ -1389,7 +1388,7 @@
 
             // Before creating the implementation object, we are going to
             // test if all the mandatory dependencies are satisfied
-            if ( !acm.verifyDependencyManagers( acm.getProperties() ) )
+            if ( !acm.verifyDependencyManagers() )
             {
                 acm.log( LogService.LOG_DEBUG, "Not all dependencies satisfied, cannot activate", null );
                 return true;
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
index b3c27d8..c11008d 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
@@ -109,10 +109,10 @@
 
         ComponentInstance instance;
         cm.setFactoryProperties( dictionary );
-        // enable
-        cm.enableInternal();
         //configure the properties
         cm.reconfigure( m_configuration );
+        // enable
+        cm.enableInternal();
         //activate immediately
         cm.activateInternal();
 
@@ -373,7 +373,7 @@
                 super.updateTargets( getProperties() );
 
                 // Next, verify dependencies
-                if ( !verifyDependencyManagers( m_configuration ) )
+                if ( !verifyDependencyManagers() )
                 {
                     log( LogService.LOG_DEBUG,
                             "Component Factory target filters not satisfied anymore: deactivating", null );
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
index f273a36..3d5c070 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
@@ -114,23 +114,54 @@
         void close();
 
         Collection<RefPair<T>> getRefs();
+
+        boolean isSatisfied();
         
         void setTracker( ServiceTracker<T, RefPair<T>> tracker );
+
+        void setTrackerOpened();
     }
 
     private abstract class AbstractCustomizer implements Customizer<T>
     {
         private ServiceTracker<T, RefPair<T>> tracker;
 
+        private volatile boolean trackerOpened;
+
         public void setTracker( ServiceTracker<T, RefPair<T>> tracker )
         {
             this.tracker = tracker;
         }
 
+        public boolean isSatisfied()
+        {
+            return isOptional() || !tracker.isEmpty();
+        }
+
         protected ServiceTracker<T, RefPair<T>> getTracker()
         {
             return tracker;
         }
+
+        /**
+         *
+         * @return whether the tracker
+         */
+        protected boolean isActive()
+        {
+            return tracker.isActive();
+        }
+
+        protected boolean isTrackerOpened()
+        {
+            return trackerOpened;
+        }
+
+        public void setTrackerOpened()
+        {
+            trackerOpened = true;
+        }
+
     }
 
 
@@ -201,7 +232,7 @@
             {
                 m_componentManager.invokeBindMethod( DependencyManager.this, refPair );
             }
-            else if ( !isOptional() )
+            else if ( isTrackerOpened() && !isOptional() )
             {
                 m_componentManager.activateInternal();
             }
@@ -296,9 +327,13 @@
                     "Dependency Manager: Static dependency on {0}/{1} is broken", new Object[]
                         { m_dependencyMetadata.getName(), m_dependencyMetadata.getInterface() }, null );
                 m_componentManager.deactivateInternal( ComponentConstants.DEACTIVATION_REASON_REFERENCE, false );
+                m_componentManager.activateInternal();
 
             }
-            m_componentManager.activateInternal();
+            else if ( isTrackerOpened() &&  !isOptional() )
+            {
+                m_componentManager.activateInternal();
+            }
         }
 
         public void modifiedService( ServiceReference<T> serviceReference, RefPair<T> refPair )
@@ -367,7 +402,7 @@
 
         public void addedService( ServiceReference<T> serviceReference, RefPair<T> refPair )
         {
-            if (!isActive())
+            if ( isTrackerOpened() && !isOptional() && !isActive())
             {
                 m_componentManager.activateInternal();
             }
@@ -470,7 +505,7 @@
                     this.refPair = refPair;
                 }
             }
-            else if ( !isOptional() )
+            else if ( isTrackerOpened() && !isOptional() )
             {
                 m_componentManager.activateInternal();
             }
@@ -581,7 +616,7 @@
                     m_componentManager.activateInternal();
                 }
             }
-            else
+            else if (isTrackerOpened() && !isOptional() )
             {
                 m_componentManager.activateInternal();
             }
@@ -1507,7 +1542,7 @@
      */
     public boolean isSatisfied()
     {
-        return size() > 0 || m_dependencyMetadata.isOptional();
+        return customizerRef.get().isSatisfied();
     }
 
 
@@ -2167,9 +2202,10 @@
         Customizer<T> customizer = newCustomizer();
         ServiceTracker<T, RefPair<T>> tracker = new ServiceTracker<T, RefPair<T>>( m_componentManager.getActivator().getBundleContext(), m_targetFilter, customizer );
         customizer.setTracker( tracker );
-        tracker.open();
         trackerRef.set( tracker );
         registered = true;
+        tracker.open();
+        customizer.setTrackerOpened();
         m_componentManager.log( LogService.LOG_DEBUG, "registering service listener for dependency {0}", new Object[]
                 {m_dependencyMetadata.getName()}, null );
     }
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
index 9748f0d..7b25398 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
@@ -21,7 +21,6 @@
 
 import java.util.Dictionary;
 import java.util.Hashtable;
-import java.util.Map;
 
 import org.apache.felix.scr.impl.BundleComponentActivator;
 import org.apache.felix.scr.impl.config.ComponentHolder;
@@ -32,7 +31,6 @@
 import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.ServiceFactory;
-import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.component.ComponentConstants;
 import org.osgi.service.component.ComponentContext;
@@ -612,7 +610,7 @@
         // 5. update the target filter on the services now, this may still
         // result in unsatisfied dependencies, in which case we abort
         // this dynamic update and have the component be deactivated
-        if ( !verifyDependencyManagers( props ) )
+        if ( !verifyDependencyManagers() )
         {
             log(
                     LogService.LOG_ERROR,