[FELIX-2852] Infinite reloading of config file ending with .config

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1301088 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/ConfigInstaller.java b/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/ConfigInstaller.java
index f7270f6..c00c745 100644
--- a/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/ConfigInstaller.java
+++ b/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/ConfigInstaller.java
@@ -39,12 +39,14 @@
 {
     private final BundleContext context;
     private final ConfigurationAdmin configAdmin;
+    private final FileInstall fileInstall;
     private ServiceRegistration registration;
 
-    ConfigInstaller(BundleContext context, ConfigurationAdmin configAdmin)
+    ConfigInstaller(BundleContext context, ConfigurationAdmin configAdmin, FileInstall fileInstall)
     {
         this.context = context;
         this.configAdmin = configAdmin;
+        this.fileInstall = fileInstall;
     }
 
     public void init()
@@ -156,6 +158,9 @@
                             fos.close();
                         }
                     }
+                    // we're just writing out what's already loaded into ConfigAdmin, so
+                    // update file checksum since lastModified gets updated when writing
+                    fileInstall.updateChecksum(file);
                 }
             }
             catch (Exception e)
diff --git a/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/FileInstall.java b/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/FileInstall.java
index 4336da3..d33308e 100644
--- a/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/FileInstall.java
+++ b/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/FileInstall.java
@@ -18,14 +18,33 @@
  */
 package org.apache.felix.fileinstall.internal;
 
-import java.util.*;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.TreeMap;
 
-import org.apache.felix.fileinstall.*;
+import org.apache.felix.fileinstall.ArtifactInstaller;
+import org.apache.felix.fileinstall.ArtifactListener;
+import org.apache.felix.fileinstall.ArtifactTransformer;
+import org.apache.felix.fileinstall.ArtifactUrlTransformer;
 import org.apache.felix.fileinstall.internal.Util.Logger;
 import org.apache.felix.utils.collections.DictionaryAsMap;
 import org.apache.felix.utils.properties.InterpolationHelper;
-import org.osgi.framework.*;
-import org.osgi.service.cm.*;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedServiceFactory;
 import org.osgi.service.packageadmin.PackageAdmin;
 import org.osgi.service.startlevel.StartLevel;
 import org.osgi.util.tracker.ServiceTracker;
@@ -227,6 +246,20 @@
         watcher.start();
     }
 
+    public void updateChecksum(File file)
+    {
+        List /*<DirectoryWatcher>*/ toUpdate = new ArrayList /*<DirectoryWatcher>*/();
+        synchronized (watchers)
+        {
+            toUpdate.addAll(watchers.values());
+        }
+        for (Iterator w = toUpdate.iterator(); w.hasNext();)
+        {
+            DirectoryWatcher watcher = (DirectoryWatcher) w.next();
+            watcher.scanner.updateChecksum(file);
+        }
+    }
+
     private void addListener(ServiceReference reference, ArtifactListener listener)
     {
         synchronized (listeners)
@@ -356,7 +389,7 @@
             public Object addingService(ServiceReference serviceReference)
             {
                 ConfigurationAdmin cm = (ConfigurationAdmin) super.addingService(serviceReference);
-                configInstaller = new ConfigInstaller(context, cm);
+                configInstaller = new ConfigInstaller(context, cm, fileInstall);
                 configInstaller.init();
                 return cm;
             }
diff --git a/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/Scanner.java b/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/Scanner.java
index ff9f023..d3141c4 100644
--- a/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/Scanner.java
+++ b/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/Scanner.java
@@ -21,7 +21,6 @@
 import java.io.File;
 import java.io.FilenameFilter;
 import java.io.IOException;
-import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -157,6 +156,20 @@
     }
 
     /**
+      * Update the checksum of a file if that file is already known locally.
+      *
+      * @param file
+      */
+    public void updateChecksum(File file)
+    {
+        if (file != null && storedChecksums.containsKey(file))
+        {
+            long newChecksum = checksum(file);
+            storedChecksums.put(file, new Long(newChecksum));
+        }
+    }
+
+    /**
      * Compute a cheksum for the file or directory that consists of the name, length and the last modified date
      * for a file and its children in case of a directory
      *
diff --git a/fileinstall/src/test/java/org/apache/felix/fileinstall/internal/ConfigInstallerTest.java b/fileinstall/src/test/java/org/apache/felix/fileinstall/internal/ConfigInstallerTest.java
index e1c5de5..f457955 100644
--- a/fileinstall/src/test/java/org/apache/felix/fileinstall/internal/ConfigInstallerTest.java
+++ b/fileinstall/src/test/java/org/apache/felix/fileinstall/internal/ConfigInstallerTest.java
@@ -19,18 +19,16 @@
 package org.apache.felix.fileinstall.internal;
 
 import java.io.File;
-import java.util.Hashtable;
 import java.util.Dictionary;
+import java.util.Hashtable;
 
 import junit.framework.TestCase;
-import org.easymock.MockControl;
 import org.easymock.ArgumentsMatcher;
-import org.osgi.framework.BundleContext;
+import org.easymock.MockControl;
 import org.osgi.framework.Bundle;
-import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.framework.BundleContext;
 import org.osgi.service.cm.Configuration;
-import org.apache.felix.fileinstall.internal.ConfigInstaller;
-import org.apache.felix.fileinstall.internal.FileInstall;
+import org.osgi.service.cm.ConfigurationAdmin;
 
 /**
  * Tests for ConfigInstaller
@@ -63,7 +61,7 @@
     public void testParsePidWithoutFactoryPid()
     {
         mockBundleContextControl.replay();
-        ConfigInstaller ci = new ConfigInstaller(null, null);
+        ConfigInstaller ci = new ConfigInstaller(null, null, null);
 
         String path = "pid.cfg";
         assertEquals( "Pid without Factory Pid calculated", "pid", ci.parsePid( path )[0] );
@@ -74,7 +72,7 @@
     public void testParsePidWithFactoryPid()
     {
         mockBundleContextControl.replay();
-        ConfigInstaller ci = new ConfigInstaller(null, null);
+        ConfigInstaller ci = new ConfigInstaller(null, null, null);
 
         String path = "factory-pid.cfg";
         assertEquals( "Pid with Factory Pid calculated", "factory", ci.parsePid( path )[0] );
@@ -92,7 +90,7 @@
         mockConfigurationAdminControl.replay();
         mockBundleContextControl.replay();
 
-        ConfigInstaller ci = new ConfigInstaller( mockBundleContext, mockConfigurationAdmin );
+        ConfigInstaller ci = new ConfigInstaller( mockBundleContext, mockConfigurationAdmin, new FileInstall() );
 
         assertEquals( "Factory configuration retrieved", mockConfiguration, ci.getConfiguration( "pid-factoryPid.cfg", "pid", "factoryPid" ) );
 
@@ -113,7 +111,7 @@
         mockConfigurationAdminControl.replay();
         mockBundleContextControl.replay();
 
-        ConfigInstaller ci = new ConfigInstaller( mockBundleContext, mockConfigurationAdmin );
+        ConfigInstaller ci = new ConfigInstaller( mockBundleContext, mockConfigurationAdmin, new FileInstall() );
 
         assertEquals( "Factory configuration retrieved", mockConfiguration, ci.getConfiguration( "pid-factoryPid.cfg","pid", "factoryPid" ) );
 
@@ -134,7 +132,7 @@
         mockConfigurationAdminControl.replay();
         mockBundleContextControl.replay();
 
-        ConfigInstaller ci = new ConfigInstaller( mockBundleContext, mockConfigurationAdmin );
+        ConfigInstaller ci = new ConfigInstaller( mockBundleContext, mockConfigurationAdmin, new FileInstall() );
 
         assertEquals( "Factory configuration retrieved", mockConfiguration, ci.getConfiguration( "pid.cfg", "pid", null ) );
 
@@ -156,7 +154,7 @@
         mockConfigurationAdminControl.replay();
         mockBundleContextControl.replay();
 
-        ConfigInstaller ci = new ConfigInstaller( mockBundleContext, mockConfigurationAdmin );
+        ConfigInstaller ci = new ConfigInstaller( mockBundleContext, mockConfigurationAdmin, new FileInstall() );
 
         assertTrue( ci.deleteConfig( new File( "pid.cfg" ) ) );
 
@@ -195,7 +193,7 @@
         mockConfigurationAdminControl.replay();
         mockBundleContextControl.replay();
 
-        ConfigInstaller ci = new ConfigInstaller( mockBundleContext, mockConfigurationAdmin );
+        ConfigInstaller ci = new ConfigInstaller( mockBundleContext, mockConfigurationAdmin, new FileInstall() );
 
         assertTrue( ci.setConfig( new File( "src/test/resources/watched/firstcfg.cfg" ) ) );