Author: cziegeler
Date: Thu Mar  3 09:02:06 2011
New Revision: 1076562

URL: http://svn.apache.org/viewvc?rev=1076562&view=rev
Log:
SLING-2000 : Bundle downgrade will uninstall newer version instead of actually 
"update" to the old version

Modified:
    
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/api/tasks/TaskResourceGroup.java
    
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/EntityResourceList.java
    
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleTaskCreator.java

Modified: 
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/api/tasks/TaskResourceGroup.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/api/tasks/TaskResourceGroup.java?rev=1076562&r1=1076561&r2=1076562&view=diff
==============================================================================
--- 
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/api/tasks/TaskResourceGroup.java
 (original)
+++ 
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/api/tasks/TaskResourceGroup.java
 Thu Mar  3 09:02:06 2011
@@ -18,7 +18,6 @@
  */
 package org.apache.sling.installer.api.tasks;
 
-
 /**
  * This is a group of resources all pointing to the same artifact,
  * but maybe in different versions or locations.
@@ -31,6 +30,12 @@ public interface TaskResourceGroup {
      */
     TaskResource getActiveResource();
 
+    /**
+     * If there is more than the active resource in the group, return the 
second
+     * resource from the group.
+     * @since 1.1
+     */
+    TaskResource getNextActiveResource();
 
     /**
      * Set the finish state for the active resource.

Modified: 
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/EntityResourceList.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/EntityResourceList.java?rev=1076562&r1=1076561&r2=1076562&view=diff
==============================================================================
--- 
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/EntityResourceList.java
 (original)
+++ 
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/EntityResourceList.java
 Thu Mar  3 09:02:06 2011
@@ -110,7 +110,7 @@ public class EntityResourceList implemen
     }
 
     /**
-     * Return the first resource if it either needs to be installed or 
uninstalled.
+     * @see 
org.apache.sling.installer.api.tasks.TaskResourceGroup#getActiveResource()
      */
     public TaskResource getActiveResource() {
         if ( !resources.isEmpty() ) {
@@ -124,6 +124,20 @@ public class EntityResourceList implemen
     }
 
     /**
+     * @see 
org.apache.sling.installer.api.tasks.TaskResourceGroup#getNextActiveResource()
+     */
+    public TaskResource getNextActiveResource() {
+        if ( this.getActiveResource() != null ) {
+            if ( this.resources.size() > 1 ) {
+                // to get the second item in the set we have to use an 
iterator!
+                final Iterator<TaskResource> i = this.resources.iterator();
+                i.next(); // skip first
+                return i.next();
+            }
+        }
+        return null;
+    }
+    /**
      * Return the first resource or null
      */
     public TaskResource getFirstResource() {
@@ -174,10 +188,7 @@ public class EntityResourceList implemen
             if ( toActivate.getState() == ResourceState.UNINSTALL
                  && this.resources.size() > 1 ) {
 
-                // to get the second item in the set we have to use an 
iterator!
-                final Iterator<TaskResource> i = this.resources.iterator();
-                i.next(); // skip first
-                final TaskResource second = i.next();
+                final TaskResource second = this.getNextActiveResource();
                 if ( state == ResourceState.UNINSTALLED ) {
                     // first resource got uninstalled, go back to second
                     if (second.getState() == ResourceState.IGNORED || 
second.getState() == ResourceState.INSTALLED) {

Modified: 
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleTaskCreator.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleTaskCreator.java?rev=1076562&r1=1076561&r2=1076562&view=diff
==============================================================================
--- 
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleTaskCreator.java
 (original)
+++ 
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleTaskCreator.java
 Thu Mar  3 09:02:06 2011
@@ -45,6 +45,11 @@ import org.slf4j.LoggerFactory;
  */
 public class BundleTaskCreator implements InternalService, InstallTaskFactory {
 
+    /** If this property is set, the bundle is installed if the currently 
installed version
+     * is the version specified by the property.
+     */
+    private final static String FORCE_INSTALL_VERSION = 
"force.install.version";
+
     /** The logger */
     private final Logger logger =  LoggerFactory.getLogger(this.getClass());
 
@@ -165,12 +170,22 @@ public class BundleTaskCreator implement
                // Uninstall
         final InstallTask result;
                if (toActivate.getState() == ResourceState.UNINSTALL) {
-                   // find the info with the exact version
+            // find the info with the exact version
             final BundleInfo info = this.getBundleInfo(symbolicName,
                     (String)toActivate.getAttribute(Constants.BUNDLE_VERSION));
                    // Remove corresponding bundle if present and if we 
installed it
                    if ( info != null ) {
-                       result = new BundleRemoveTask(resourceList, this);
+                   // if this is an uninstall, check if we have to install an 
older version
+                   // in this case we should do an update instead of 
uninstall/install (!)
+                   final TaskResource second = 
resourceList.getNextActiveResource();
+                   if ( second != null &&
+                       ( second.getState() == ResourceState.IGNORED || 
second.getState() == ResourceState.INSTALLED || second.getState() == 
ResourceState.INSTALL ) ) {
+                    second.setAttribute(FORCE_INSTALL_VERSION, 
info.version.toString());
+                    logger.debug("Detected downgrad of bundle {}", 
symbolicName);
+                    result = new ChangeStateTask(resourceList, 
ResourceState.UNINSTALLED);
+                   } else {
+                       result = new BundleRemoveTask(resourceList, this);
+                   }
                    } else {
                    logger.debug("Bundle {}:{} is not installed anymore - 
nothing to remove.", symbolicName,
                            toActivate.getAttribute(Constants.BUNDLE_VERSION));
@@ -196,8 +211,13 @@ public class BundleTaskCreator implement
                     // installed version is lower -> update
                     doUpdate = true;
                 } else if (compare > 0) {
-                    logger.debug("Bundle " + info.symbolicName + " " + 
newVersion
-                                + " is not installed, bundle with higher 
version is already installed.");
+                    final String forceVersion = (String) 
toActivate.getAttribute(FORCE_INSTALL_VERSION);
+                    if ( forceVersion != null && info.version.compareTo(new 
Version(forceVersion)) == 0 ) {
+                        doUpdate = true;
+                    } else {
+                        logger.debug("Bundle " + info.symbolicName + " " + 
newVersion
+                                    + " is not installed, bundle with higher 
version is already installed.");
+                    }
                            } else if (compare == 0 && 
this.isSnapshot(newVersion)) {
                                // installed, same version but SNAPSHOT
                                doUpdate = true;
@@ -215,6 +235,7 @@ public class BundleTaskCreator implement
                     result = new ChangeStateTask(resourceList, 
ResourceState.IGNORED);
                 }
                        }
+                   toActivate.setAttribute(FORCE_INSTALL_VERSION, null);
                }
                return result;
        }


Reply via email to