FELIX-301 Factory Configurations not unbound on bundle uninstall

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@544741 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/configadmin/src/main/java/org/apache/felix/cm/file/FilePersistenceManager.java b/configadmin/src/main/java/org/apache/felix/cm/file/FilePersistenceManager.java
index 8b99b0b..f9c0c12 100644
--- a/configadmin/src/main/java/org/apache/felix/cm/file/FilePersistenceManager.java
+++ b/configadmin/src/main/java/org/apache/felix/cm/file/FilePersistenceManager.java
@@ -65,7 +65,7 @@
  * <tr><th>PID</th><th>Configuration File Name</th></tr>
  * <tr><td><code>sample</code><td><code>sample.config</code></tr>
  * <tr><td><code>org.apache.felix.log.LogService</code><td><code>org/apache/felix/log/LogService.config</code></tr>
- * <tr><td><code>sample.flèche</code><td><code>sample/fl%00e8che.config</code></tr>
+ * <tr><td><code>sample.fl�che</code><td><code>sample/fl%00e8che.config</code></tr>
  * </table>
  *
  * @author fmeschbe
@@ -409,10 +409,10 @@
                         {
                             Dictionary dict =  load( cfgFile );
                             
-                            // use the dictionary if it has a PID and the PID
+                            // use the dictionary if it has no PID or the PID
                             // derived file name matches the source file name 
-                            if ( dict.get( Constants.SERVICE_PID ) != null
-                                && cfgFile.equals( getFile( ( String ) dict.get( Constants.SERVICE_PID ) ) ) )
+                            if ( dict.get( Constants.SERVICE_PID ) == null
+                                || cfgFile.equals( getFile( ( String ) dict.get( Constants.SERVICE_PID ) ) ) )
                             {
                                 return dict;
                             }
diff --git a/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java b/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java
index d6b2190..4ff5d97 100644
--- a/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java
+++ b/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java
@@ -448,45 +448,57 @@
         if ( event.getType() == BundleEvent.UNINSTALLED )
         {
             String location = event.getBundle().getLocation();
-            String filter = "(service.bundleLocation=" + location + ")";
 
             try
             {
-                ConfigurationImpl[] configs = listConfigurations( null, filter );
-                if ( configs != null && configs.length > 0 )
+                PersistenceManager[] pmList = getPersistenceManagers();
+                for ( int i = 0; i < pmList.length; i++ )
                 {
-                    for ( int i = 0; i < configs.length; i++ )
+                    Enumeration configs = pmList[i].getDictionaries();
+                    while ( configs.hasMoreElements() )
                     {
-                        configs[i].setBundleLocation( null );
-                        try
+                        Dictionary config = ( Dictionary ) configs.nextElement();
+
+                        String pid = ( String ) config.get( Constants.SERVICE_PID );
+                        if ( pid != null )
                         {
-                            configs[i].store();
+                            ConfigurationImpl cfg = getCachedConfiguration( pid );
+                            if ( cfg == null )
+                            {
+                                cfg = new ConfigurationImpl( this, pmList[i], config );
+                            }
+
+                            if ( location.equals( cfg.getBundleLocation() ) )
+                            {
+                                cfg.setBundleLocation( null );
+                            }
                         }
-                        catch ( IOException ioe )
+                        else
                         {
-                            log( LogService.LOG_WARNING,
-                                "Problem storing unbound configuration " + configs[i].getPid(), ioe );
+
+                            Factory factory = Factory.getFactory( pmList[i], config );
+                            if ( factory != null )
+                            {
+                                Factory cachedFactory = ( Factory ) factories.get( factory.getFactoryPid() );
+                                if ( cachedFactory != null )
+                                {
+                                    factory = cachedFactory;
+                                }
+
+                                if ( location.equals( factory.getBundleLocation() ) )
+                                {
+                                    factory.setBundleLocation( null );
+                                }
+                            }
                         }
                     }
                 }
+
             }
             catch ( Exception e )
             {
                 log( LogService.LOG_WARNING, "Problem unbinding configurations for bundle " + location, e );
             }
-
-            // unbind cached configurations
-            Iterator configurations = getCachedConfigurations();
-            while ( configurations.hasNext() )
-            {
-                ConfigurationImpl cfg = ( ConfigurationImpl ) configurations.next();
-                if ( location.equals( cfg.getBundleLocation() ) )
-                {
-                    cfg.setBundleLocation( null );
-                }
-            }
-
-            // TODO: find factories to unbind !!
         }
     }
 
diff --git a/configadmin/src/main/java/org/apache/felix/cm/impl/Factory.java b/configadmin/src/main/java/org/apache/felix/cm/impl/Factory.java
index 12f7ab1..0c18b7e 100644
--- a/configadmin/src/main/java/org/apache/felix/cm/impl/Factory.java
+++ b/configadmin/src/main/java/org/apache/felix/cm/impl/Factory.java
@@ -31,25 +31,27 @@
 
 
 /**
- * The <code>Factory</code> class is used to manage mappings between factory PIDs
- * the configuration PID belonging to it.
- *
+ * The <code>Factory</code> class is used to manage mappings between factory
+ * PIDs the configuration PID belonging to it.
+ * 
  * @author fmeschbe
  */
 class Factory
 {
 
+    public static final String FACTORY_PID = "factory.pid";
+
     public static final String FACTORY_PID_LIST = "factory.pidList";
 
     // the persistence manager storing this factory mapping
     private PersistenceManager persistenceManager;
-    
+
     // the factory PID of this factory
     private String factoryPid;
-    
-    // the bundle location to which factory PID mapping is bound 
+
+    // the bundle location to which factory PID mapping is bound
     private String bundleLocation;
-    
+
     // the set of configuration PIDs belonging to this factory
     private Set pids;
 
@@ -67,6 +69,19 @@
     }
 
 
+    static Factory getFactory( PersistenceManager persistenceManager, Dictionary props )
+    {
+        // ignore non-Configuration dictionaries
+        String factoryPid = ( String ) props.get( Factory.FACTORY_PID );
+        if ( factoryPid == null )
+        {
+            return null;
+        }
+
+        return new Factory( persistenceManager, factoryPid, props );
+    }
+
+
     private static String factoryPidToIdentifier( String factoryPid )
     {
         return factoryPid + ".factory";
@@ -121,7 +136,7 @@
     void setBundleLocation( String bundleLocation )
     {
         this.bundleLocation = bundleLocation;
-        
+
         // 104.15.2.8 The bundle location will be set persistently
         storeSilently();
     }
@@ -166,10 +181,12 @@
         }
         else
         {
+            props.put( FACTORY_PID, getFactoryPid() );
             persistenceManager.store( id, props );
         }
     }
-    
+
+
     void storeSilently()
     {
         try
@@ -179,7 +196,8 @@
         catch ( IOException ioe )
         {
             // should actually log this problem
-            // configurationManager.log( LogService.LOG_ERROR, "Persisting new bundle location failed", ioe );
+            // configurationManager.log( LogService.LOG_ERROR, "Persisting new
+            // bundle location failed", ioe );
         }
     }
 }