FELIX-3915 Avoid possible double update of component on startup

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1449401 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/config/ComponentHolder.java b/scr/src/main/java/org/apache/felix/scr/impl/config/ComponentHolder.java
index 21cbf0a..4fcee90 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/config/ComponentHolder.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/config/ComponentHolder.java
@@ -69,6 +69,12 @@
      * @param pid The PID of the configuration used to configure the component
      */
     void configurationUpdated( String pid, Dictionary<String, Object> props );
+    
+    /**
+     * Has this component holder ever been configured?  Used to avoid double update during startup
+     * @return true if configurationUpdated has ever been called on this holder.
+     */
+    boolean isConfigured();
 
     /**
      * Returns all <code>Component</code> instances held by this holder.
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurationSupport.java b/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurationSupport.java
index ea3d43c..4dd6e5b 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurationSupport.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurationSupport.java
@@ -74,7 +74,7 @@
     {
 
         // 112.7 configure unless configuration not required
-        if (!holder.getComponentMetadata().isConfigurationIgnored())
+        if (!holder.isConfigured() && !holder.getComponentMetadata().isConfigurationIgnored())
         {
             final BundleContext bundleContext = holder.getActivator().getBundleContext();
             final String bundleLocation = bundleContext.getBundle().getLocation();
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/config/ImmediateComponentHolder.java b/scr/src/main/java/org/apache/felix/scr/impl/config/ImmediateComponentHolder.java
index 11fa58e..7c452b7 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/config/ImmediateComponentHolder.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/config/ImmediateComponentHolder.java
@@ -105,6 +105,8 @@
      */
     private volatile boolean m_enabled;
     private final ComponentMethods m_componentMethods;
+    
+    private volatile boolean m_configured;
 
 
     public ImmediateComponentHolder( final BundleComponentActivator activator, final ComponentMetadata metadata )
@@ -268,11 +270,12 @@
      * this case a new component is created, configured and stored in the map</li>
      * </ul>
      */
-    public void configurationUpdated( final String pid, final Dictionary props )
+    public void configurationUpdated( final String pid, final Dictionary<String, Object> props )
     {
         log( LogService.LOG_DEBUG, "ImmediateComponentHolder configuration updated for pid {0} with properties {1}",
                 new Object[] {pid, props}, null);
 
+        m_configured = true;
         // component to update or create
         final ImmediateComponentManager icm;
         final String message;
@@ -356,6 +359,10 @@
         }
     }
 
+    public boolean isConfigured()
+    {
+        return m_configured;
+    }
 
     public Component[] getComponents()
     {
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 40b6c5b..6cb1b56 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
@@ -78,11 +78,16 @@
     private volatile Dictionary<String, Object> m_configuration;
     
     /**
-     * Flag telling if our component factory is configured from config admin.
+     * Flag telling if our component factory is currently configured from config admin.
      * We are configured when configuration policy is required and we have received the
      * config admin properties, or when configuration policy is optional or ignored.
      */
-    public volatile boolean m_isConfigured;
+    private volatile boolean m_hasConfiguration;
+    
+    /**
+     * whether this holder has ever been configured.
+     */
+    private volatile boolean m_isConfigured;
 
     public ComponentFactoryImpl( BundleComponentActivator activator, ComponentMetadata metadata )
     {
@@ -202,7 +207,7 @@
 
     public boolean hasConfiguration()
     {
-        return m_isConfigured;
+        return m_hasConfiguration;
     }
 
 
@@ -314,14 +319,14 @@
             log( LogService.LOG_DEBUG, "Handling configuration removal", null );
 
             // nothing to do if there is no configuration currently known.
-            if ( !m_isConfigured )
+            if ( !m_hasConfiguration )
             {
                 log( LogService.LOG_DEBUG, "ignoring configuration removal: not currently configured", null );
                 return;
             }
 
             // So far, we were configured: clear the current configuration.
-            m_isConfigured = false;
+            m_hasConfiguration = false;
             m_configuration = new Hashtable();
 
             log( LogService.LOG_DEBUG, "Current component factory state={0}", new Object[] {getState()}, null );
@@ -343,6 +348,7 @@
 
     public void configurationUpdated( String pid, Dictionary<String, Object> configuration )
     {
+        m_isConfigured = true;
         if ( pid.equals( getComponentMetadata().getConfigurationPid() ) )
         {
             log( LogService.LOG_INFO, "Configuration PID updated for Component Factory", null );
@@ -357,7 +363,7 @@
             m_configuration = configuration;
 
             // We are now configured from config admin.
-            m_isConfigured = true;
+            m_hasConfiguration = true;
 
             log( LogService.LOG_INFO, "Current ComponentFactory state={0}", new Object[]
                     {getState()}, null );
@@ -398,6 +404,11 @@
     }
 
 
+    public boolean isConfigured()
+    {
+        return m_isConfigured;
+    }
+    
     public Component[] getComponents()
     {
         List<AbstractComponentManager> cms = getComponentList();