Author: fmeschbe
Date: Thu Nov 26 07:09:00 2009
New Revision: 884426

URL: http://svn.apache.org/viewvc?rev=884426&view=rev
Log:
SLING-1189 apply patch by Justin Edelson (thanks) to support more fine grained 
bundle update decision based on optional (non-standard) Bnd-LastModified header

Modified:
    
sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/BootstrapInstaller.java

Modified: 
sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/BootstrapInstaller.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/BootstrapInstaller.java?rev=884426&r1=884425&r2=884426&view=diff
==============================================================================
--- 
sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/BootstrapInstaller.java
 (original)
+++ 
sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/BootstrapInstaller.java
 Thu Nov 26 07:09:00 2009
@@ -101,6 +101,11 @@
     private static final String[] BUNDLE_EXTENSIONS = { ".jar", ".war" };
 
     /**
+     * The header which contains the bundle's last modified date.
+     */
+    static final String BND_LAST_MODIFIED_HEADER = "Bnd-LastModified";
+
+    /**
      * The start level to be assigned to bundles found in the (old style)
      * {...@link #PATH_CORE_BUNDLES resources/corebundles} location (value is 
1).
      */
@@ -760,7 +765,8 @@
         // if the new version and the current version are the same, reinstall 
if
         // the version is a snapshot
         if (newVersion.equals(installedVersion)
-            && installedVersionProp.endsWith("SNAPSHOT")) {
+            && installedVersionProp.endsWith("SNAPSHOT")
+            && isNewerSnapshot(installedBundle, manifest)) {
             logger.log(Logger.LOG_INFO, "Forcing upgrade of SNAPSHOT bundle: "
                 + installedBundle.getSymbolicName());
             return false;
@@ -769,6 +775,55 @@
         return newVersion.compareTo(installedVersion) <= 0;
     }
 
+    /**
+     * Determine if the bundle containing the passed manfiest is a newer
+     * SNAPSHOT than the already-installed bundle.
+     *
+     * @param installedBundle the already-installed bundle
+     * @param manifest the manifest of the to-be-installed bundle
+     * @return true if the to-be-installed bundle is newer or if the comparison
+     *         fails for some reason
+     */
+    private boolean isNewerSnapshot(Bundle installedBundle, Manifest manifest) 
{
+        String installedDate = (String) installedBundle.getHeaders().get(
+            BND_LAST_MODIFIED_HEADER);
+        String toBeInstalledDate = manifest.getMainAttributes().getValue(
+            BND_LAST_MODIFIED_HEADER);
+        if (installedDate == null) {
+            logger.log(Logger.LOG_DEBUG, String.format(
+                "Currently installed bundle %s doesn't have a %s header",
+                installedBundle.getSymbolicName(), BND_LAST_MODIFIED_HEADER));
+            return true;
+        }
+        if (toBeInstalledDate == null) {
+            logger.log(Logger.LOG_DEBUG, String.format(
+                "Candidate bundle %s doesn't have a %s header",
+                installedBundle.getSymbolicName(), BND_LAST_MODIFIED_HEADER));
+            return true;
+        }
+
+        long installedTime, toBeInstalledTime = 0;
+        try {
+            installedTime = Long.valueOf(installedDate);
+        } catch (NumberFormatException e) {
+            logger.log(Logger.LOG_DEBUG, String.format(
+                "%s header of currently installed bundle %s isn't parseable.",
+                BND_LAST_MODIFIED_HEADER, installedBundle.getSymbolicName()));
+            return true;
+        }
+        try {
+            toBeInstalledTime = Long.valueOf(toBeInstalledDate);
+        } catch (NumberFormatException e) {
+            logger.log(Logger.LOG_DEBUG, String.format(
+                "%s header of candidate bundle %s isn't parseable.",
+                BND_LAST_MODIFIED_HEADER, installedBundle.getSymbolicName()));
+            return true;
+        }
+
+        return toBeInstalledTime > installedTime;
+
+    }
+
     // ---------- Bundle Installation marker file
 
     private boolean isAlreadyInstalled(BundleContext context,


Reply via email to