Author: gnodet
Date: Mon Oct 12 09:18:33 2009
New Revision: 824270

URL: http://svn.apache.org/viewvc?rev=824270&view=rev
Log:
FELIX-1628: fileinstall should load configurations as soon as config admin is 
available

Modified:
    
felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/DirectoryWatcher.java
    
felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/FileInstall.java
    
felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/Scanner.java

Modified: 
felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/DirectoryWatcher.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/DirectoryWatcher.java?rev=824270&r1=824269&r2=824270&view=diff
==============================================================================
--- 
felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/DirectoryWatcher.java
 (original)
+++ 
felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/DirectoryWatcher.java
 Mon Oct 12 09:18:33 2009
@@ -77,6 +77,7 @@
     public final static String TMPDIR = "felix.fileinstall.tmpdir";
     public final static String FILTER = "felix.fileinstall.filter";
     public final static String START_NEW_BUNDLES = 
"felix.fileinstall.bundles.new.start";
+    public final static String NO_INITIAL_DELAY = 
"felix.fileinstall.noInitialDelay";
 
     File watchedDirectory;
     File tmpDir;
@@ -86,6 +87,7 @@
     String filter;
     BundleContext context;
     String originatingFileName;
+    boolean noInitialDelay;
 
     // Map of all installed artifacts
     Map/* <File, Artifact> */ currentManagedArtifacts = new HashMap/* <File, 
Artifact> */();
@@ -111,6 +113,7 @@
         tmpDir = getFile(properties, TMPDIR, new File("./tmp"));
         startBundles = getBoolean(properties, START_NEW_BUNDLES, true);  // by 
default, we start bundles.
         filter = (String) properties.get(FILTER);
+        noInitialDelay = getBoolean(properties, NO_INITIAL_DELAY, false);
 
         FilenameFilter flt;
         if (filter != null && filter.length() > 0)
@@ -127,6 +130,18 @@
             flt = null;
         }
         scanner = new Scanner(watchedDirectory, flt);
+
+        if (noInitialDelay)
+        {
+            log("Starting initial scan", null);
+            initializeCurrentManagedBundles();
+            scanner.initialize(currentManagedArtifacts.keySet());
+            Set/*<File>*/ files = scanner.scan(true);
+            if (files != null)
+            {
+                process(files);
+            }
+        }
     }
 
     /**
@@ -143,175 +158,187 @@
                 + TMPDIR + " = " + tmpDir + ", "
                 + FILTER + " = " + filter + "}", null);
 
-        initializeCurrentManagedBundles();
-
-        scanner.initialize(currentManagedArtifacts.keySet());
+        if (!noInitialDelay)
+        {
+            initializeCurrentManagedBundles();
+            scanner.initialize(currentManagedArtifacts.keySet());
+        }
 
         while (!interrupted())
         {
             try
             {
-                Set/*<File>*/ files = scanner.scan();
+                Set/*<File>*/ files = scanner.scan(false);
                 // Check that there is a result.  If not, this means that the 
directory can not be listed,
                 // so it's presumably not a valid directory (it may have been 
deleted by someone).
                 // In such case, just sleep
                 if (files == null)
                 {
-                    Thread.sleep(poll);
+                    synchronized (this)
+                    {
+                        wait(poll);
+                    }
                     continue;
                 }
 
-                List/*<ArtifactListener>*/ listeners = 
FileInstall.getListeners();
-                List/*<Artifact>*/ deleted = new ArrayList/*<Artifact>*/();
-                List/*<Artifact>*/ modified = new ArrayList/*<Artifact>*/();
-                List/*<Artifact>*/ created = new ArrayList/*<Artifact>*/();
-
-                // Try to process again files that could not be processed
-                files.addAll(processingFailures);
-                processingFailures.clear();
-
-                for (Iterator it = files.iterator(); it.hasNext();)
-                {
-                    File file = (File) it.next();
-                    boolean exists = file.exists();
-                    Artifact artifact = (Artifact) 
currentManagedArtifacts.get(file);
-                    // File has been deleted
-                    if (!exists && artifact != null)
+                process(files);
+
+                synchronized (this)
+                {
+                    wait(poll);
+                }
+            }
+            catch (InterruptedException e)
+            {
+                return;
+            }
+            catch (Throwable e)
+            {
+                log("In main loop, we have serious trouble", e);
+            }
+        }
+    }
+
+    private void process(Set files) {
+        List/*<ArtifactListener>*/ listeners = FileInstall.getListeners();
+        List/*<Artifact>*/ deleted = new ArrayList/*<Artifact>*/();
+        List/*<Artifact>*/ modified = new ArrayList/*<Artifact>*/();
+        List/*<Artifact>*/ created = new ArrayList/*<Artifact>*/();
+
+        // Try to process again files that could not be processed
+        files.addAll(processingFailures);
+        processingFailures.clear();
+
+        for (Iterator it = files.iterator(); it.hasNext();)
+        {
+            File file = (File) it.next();
+            boolean exists = file.exists();
+            Artifact artifact = (Artifact) currentManagedArtifacts.get(file);
+            // File has been deleted
+            if (!exists && artifact != null)
+            {
+                deleteJaredDirectory(artifact);
+                deleteTransformedFile(artifact);
+                deleted.add(artifact);
+            }
+            else
+            {
+                File jar  = file;
+                // Jar up the directory if needed
+                if (file.isDirectory())
+                {
+                    prepareDir(tmpDir);
+                    try
                     {
-                        deleteJaredDirectory(artifact);
-                        deleteTransformedFile(artifact);
-                        deleted.add(artifact);
+                        jar = new File(tmpDir, file.getName() + ".jar");
+                        Util.jarDir(file, jar);
+
                     }
-                    else
+                    catch (IOException e)
                     {
-                        File jar  = file;
-                        // Jar up the directory if needed
-                        if (file.isDirectory())
+                        log("Unable to create jar for: " + 
file.getAbsolutePath(), e);
+                        continue;
+                    }
+                }
+                // File has been modified
+                if (exists && artifact != null)
+                {
+                    // Check the last modified date against
+                    // the artifact last modified date if available.  This 
will loose
+                    // the possibility of the jar being replaced by an older 
one
+                    // or the content changed without the date being modified, 
but
+                    // else, we'd have to reinstall all the deployed bundles 
on restart.
+                    if (artifact.getLastModified() > 
Util.getLastModified(file))
+                    {
+                        continue;
+                    }
+                    // If there's no listener, this is because this artifact 
has been installed before
+                    // fileinstall has been restarted.  In this case, try to 
find a listener.
+                    if (artifact.getListener() == null)
+                    {
+                        ArtifactListener listener = findListener(jar, 
listeners);
+                        // If no listener can handle this artifact, we need to 
defer the
+                        // processing for this artifact until one is found
+                        if (listener == null)
                         {
-                            prepareDir(tmpDir);
-                            try
-                            {
-                                jar = new File(tmpDir, file.getName() + 
".jar");
-                                Util.jarDir(file, jar);
-
-                            }
-                            catch (IOException e)
-                            {
-                                log("Unable to create jar for: " + 
file.getAbsolutePath(), e);
-                                continue;
-                            }
+                            processingFailures.add(file);
+                            continue;
                         }
-                        // File has been modified
-                        if (exists && artifact != null)
+                        artifact.setListener(listener);
+                    }
+                    // If the listener can not handle this file anymore,
+                    // uninstall the artifact and try as if is was new
+                    if (!listeners.contains(artifact.getListener()) || 
!artifact.getListener().canHandle(jar))
+                    {
+                        deleted.add(artifact);
+                        artifact = null;
+                    }
+                    // The listener is still ok
+                    else
+                    {
+                        deleteTransformedFile(artifact);
+                        artifact.setJaredDirectory(jar);
+                        if (transformArtifact(artifact))
                         {
-                            // Check the last modified date against
-                            // the artifact last modified date if available.  
This will loose
-                            // the possibility of the jar being replaced by an 
older one
-                            // or the content changed without the date being 
modified, but
-                            // else, we'd have to reinstall all the deployed 
bundles on restart.
-                            if (artifact.getLastModified() > 
Util.getLastModified(file))
-                            {
-                                continue;
-                            }
-                            // If there's no listener, this is because this 
artifact has been installed before
-                            // fileinstall has been restarted.  In this case, 
try to find a listener.
-                            if (artifact.getListener() == null)
-                            {
-                                ArtifactListener listener = findListener(jar, 
listeners);
-                                // If no listener can handle this artifact, we 
need to defer the
-                                // processing for this artifact until one is 
found
-                                if (listener == null)
-                                {
-                                    processingFailures.add(file);
-                                    continue;
-                                }
-                                artifact.setListener(listener);
-                            }
-                            // If the listener can not handle this file 
anymore,
-                            // uninstall the artifact and try as if is was new
-                            if (!listeners.contains(artifact.getListener()) || 
!artifact.getListener().canHandle(jar))
-                            {
-                                deleted.add(artifact);
-                                artifact = null;
-                            }
-                            // The listener is still ok
-                            else
-                            {
-                                deleteTransformedFile(artifact);
-                                artifact.setJaredDirectory(jar);
-                                if (transformArtifact(artifact))
-                                {
-                                    modified.add(artifact);
-                                }
-                                else
-                                {
-                                    deleteJaredDirectory(artifact);
-                                    deleted.add(artifact);
-                                }
-                                continue;
-                            }
+                            modified.add(artifact);
                         }
-                        // File has been added
-                        if (exists && artifact == null)
+                        else
                         {
-                            // Find the listener
-                            ArtifactListener listener = findListener(jar, 
listeners);
-                            // If no listener can handle this artifact, we 
need to defer the
-                            // processing for this artifact until one is found
-                            if (listener == null)
-                            {
-                                processingFailures.add(file);
-                                continue;
-                            }
-                            // Create the artifact
-                            artifact = new Artifact();
-                            artifact.setPath(file);
-                            artifact.setJaredDirectory(jar);
-                            artifact.setListener(listener);
-                            if (transformArtifact(artifact))
-                            {
-                                created.add(artifact);
-                            }
-                            else
-                            {
-                                deleteJaredDirectory(artifact);
-                            }
+                            deleteJaredDirectory(artifact);
+                            deleted.add(artifact);
                         }
+                        continue;
                     }
                 }
-                // Handle deleted artifacts
-                // We do the operations in the following order:
-                // uninstall, update, install, refresh & start.
-                Collection uninstalledBundles = uninstall(deleted);
-                Collection updatedBundles = update(modified);
-                Collection installedBundles = install(created);
-                if (uninstalledBundles.size() > 0 || updatedBundles.size() > 0)
-                {
-                    // Refresh if any bundle got uninstalled or updated.
-                    // This can lead to restart of recently updated bundles, 
but
-                    // don't worry about that at this point of time.
-                    refresh();
-                }
-
-                if (startBundles)
+                // File has been added
+                if (exists && artifact == null)
                 {
-                    // Try to start all the bundles that are not persistently 
stopped
-                    startAllBundles();
-                    // Try to start newly installed bundles
-                    start(installedBundles);
+                    // Find the listener
+                    ArtifactListener listener = findListener(jar, listeners);
+                    // If no listener can handle this artifact, we need to 
defer the
+                    // processing for this artifact until one is found
+                    if (listener == null)
+                    {
+                        processingFailures.add(file);
+                        continue;
+                    }
+                    // Create the artifact
+                    artifact = new Artifact();
+                    artifact.setPath(file);
+                    artifact.setJaredDirectory(jar);
+                    artifact.setListener(listener);
+                    if (transformArtifact(artifact))
+                    {
+                        created.add(artifact);
+                    }
+                    else
+                    {
+                        deleteJaredDirectory(artifact);
+                    }
                 }
-
-                Thread.sleep(poll);
-            }
-            catch (InterruptedException e)
-            {
-                return;
-            }
-            catch (Throwable e)
-            {
-                log("In main loop, we have serious trouble", e);
             }
         }
+        // Handle deleted artifacts
+        // We do the operations in the following order:
+        // uninstall, update, install, refresh & start.
+        Collection uninstalledBundles = uninstall(deleted);
+        Collection updatedBundles = update(modified);
+        Collection installedBundles = install(created);
+        if (uninstalledBundles.size() > 0 || updatedBundles.size() > 0)
+        {
+            // Refresh if any bundle got uninstalled or updated.
+            // This can lead to restart of recently updated bundles, but
+            // don't worry about that at this point of time.
+            refresh();
+        }
+
+        if (startBundles)
+        {
+            // Try to start all the bundles that are not persistently stopped
+            startAllBundles();
+            // Try to start newly installed bundles
+            start(installedBundles);
+        }
     }
 
     ArtifactListener findListener(File artifact, List/* <ArtifactListener> */ 
listeners)

Modified: 
felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/FileInstall.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/FileInstall.java?rev=824270&r1=824269&r2=824270&view=diff
==============================================================================
--- 
felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/FileInstall.java
 (original)
+++ 
felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/FileInstall.java
 Mon Oct 12 09:18:33 2009
@@ -115,6 +115,7 @@
         set(ht, DirectoryWatcher.FILTER);
         set(ht, DirectoryWatcher.TMPDIR);
         set(ht, DirectoryWatcher.START_NEW_BUNDLES);
+        set(ht, DirectoryWatcher.NO_INITIAL_DELAY);
         updated("initial", ht);
     }
 
@@ -135,12 +136,17 @@
 
     public void stop(BundleContext context) throws Exception
     {
-        for (Iterator w = watchers.values().iterator(); w.hasNext();)
+        List /*<DirectoryWatcher>*/ toClose = new ArrayList 
/*<DirectoryWatcher>*/();
+        synchronized (watchers)
+        {
+            toClose.addAll(watchers.values());
+            watchers.clear();
+        }
+        for (Iterator w = toClose.iterator(); w.hasNext();)
         {
             try
             {
                 DirectoryWatcher dir = (DirectoryWatcher) w.next();
-                w.remove();
                 dir.close();
             }
             catch (Exception e)
@@ -155,7 +161,11 @@
 
     public void deleted(String pid)
     {
-        DirectoryWatcher watcher = (DirectoryWatcher) watchers.remove(pid);
+        DirectoryWatcher watcher;
+        synchronized (watchers)
+        {
+            watcher = (DirectoryWatcher) watchers.remove(pid);
+        }
         if (watcher != null)
         {
             watcher.close();
@@ -184,6 +194,7 @@
         {
             listeners.add(listener);
         }
+        notifyWatchers();
     }
 
     private void removeListener(ArtifactListener listener)
@@ -192,6 +203,24 @@
         {
             listeners.remove(listener);
         }
+        notifyWatchers();
+    }
+
+    private void notifyWatchers()
+    {
+        List /*<DirectoryWatcher>*/ toNotify = new ArrayList 
/*<DirectoryWatcher>*/();
+        synchronized (watchers)
+        {
+            toNotify.addAll(watchers.values());
+        }
+        for (Iterator w = toNotify.iterator(); w.hasNext();)
+        {
+            DirectoryWatcher dir = (DirectoryWatcher) w.next();
+            synchronized (dir)
+            {
+                dir.notifyAll();
+            }
+        }
     }
 
     static List getListeners()

Modified: 
felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/Scanner.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/Scanner.java?rev=824270&r1=824269&r2=824270&view=diff
==============================================================================
--- 
felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/Scanner.java
 (original)
+++ 
felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/Scanner.java
 Mon Oct 12 09:18:33 2009
@@ -95,9 +95,10 @@
      * Upon restart, such checksums are not known so that all files will
      * be reported as modified. 
      *
+     * @param reportImmediately report all files immediately without waiting 
for the checksum to be stable
      * @return a list of changes on the files included in the directory
      */
-    public Set/*<File>*/ scan()
+    public Set/*<File>*/ scan(boolean reportImmediately)
     {
         File[] list = directory.listFiles(filter);
         if (list == null)
@@ -114,7 +115,7 @@
             long newChecksum = checksum(file);
             lastChecksums.put(file, Long.valueOf(newChecksum));
             // Only handle file when it does not change anymore and it has 
changed since last reported
-            if (newChecksum == lastChecksum && newChecksum != storedChecksum)
+            if ((newChecksum == lastChecksum || reportImmediately) && 
newChecksum != storedChecksum)
             {
                 storedChecksums.put(file, Long.valueOf(newChecksum));
                 files.add(file);


Reply via email to