You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2010/09/12 12:15:10 UTC

svn commit: r996285 - in /sling/trunk/installer/osgi/installer/src: main/java/org/apache/sling/osgi/installer/impl/ main/java/org/apache/sling/osgi/installer/impl/config/ main/java/org/apache/sling/osgi/installer/impl/tasks/ test/java/org/apache/sling/...

Author: cziegeler
Date: Sun Sep 12 10:15:09 2010
New Revision: 996285

URL: http://svn.apache.org/viewvc?rev=996285&view=rev
Log:
SLING-1737 : Add state management for resources

Modified:
    sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/RegisteredResourceImpl.java
    sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/config/AbstractConfigTask.java
    sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/config/ConfigInstallTask.java
    sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/config/ConfigRemoveTask.java
    sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/config/ConfigurationPid.java
    sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleInstallTask.java
    sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleRemoveTask.java
    sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleUpdateTask.java
    sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/RegisteredResourceTest.java

Modified: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/RegisteredResourceImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/RegisteredResourceImpl.java?rev=996285&r1=996284&r2=996285&view=diff
==============================================================================
--- sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/RegisteredResourceImpl.java (original)
+++ sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/RegisteredResourceImpl.java Sun Sep 12 10:15:09 2010
@@ -160,10 +160,18 @@ public class RegisteredResourceImpl
             }
 		} else if ( resourceType.equals(InstallableResource.TYPE_CONFIG)) {
             this.dataFile = null;
-            final ConfigurationPid pid = new ConfigurationPid(scheme + ':' + id);
+            final ConfigurationPid pid = new ConfigurationPid(id);
             entity = ENTITY_CONFIG_PREFIX + pid.getCompositePid();
             attributes.put(CONFIG_PID_ATTRIBUTE, pid);
             this.digest = (digest != null && digest.length() > 0 ? digest : id + ":" + computeDigest(dict));
+            // Add pseudo-properties
+            this.dictionary.put(ConfigurationPid.CONFIG_PATH_KEY, this.getURL());
+
+            // Factory?
+            if (pid.getFactoryPid() != null) {
+                this.dictionary.put(ConfigurationPid.ALIAS_KEY, pid.getFactoryPid());
+            }
+
 		} else {
 		    throw new IOException("Unknown type " + resourceType);
 		}
@@ -461,7 +469,7 @@ public class RegisteredResourceImpl
     /**
      * Compute the extension
      */
-    private static String getExtension(String url) {
+    public static String getExtension(String url) {
         final int pos = url.lastIndexOf('.');
         return (pos < 0 ? "" : url.substring(pos+1));
     }
@@ -473,15 +481,22 @@ public class RegisteredResourceImpl
         if (extension.equals("jar")) {
             return InstallableResource.TYPE_BUNDLE;
         }
-        if ( extension.equals("cfg")
-             || extension.equals("config")
-             || extension.equals("xml")
-             || extension.equals("properties")) {
+        if ( isConfigExtension(extension) ) {
             return InstallableResource.TYPE_CONFIG;
         }
         return extension;
     }
 
+    public static boolean isConfigExtension(String extension) {
+        if ( extension.equals("cfg")
+                || extension.equals("config")
+                || extension.equals("xml")
+                || extension.equals("properties")) {
+            return true;
+        }
+        return false;
+    }
+
     /** convert digest to readable string (http://www.javalobby.org/java/forums/t84420.html) */
     private static String digestToString(MessageDigest d) {
         final BigInteger bigInt = new BigInteger(1, d.digest());

Modified: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/config/AbstractConfigTask.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/config/AbstractConfigTask.java?rev=996285&r1=996284&r2=996285&view=diff
==============================================================================
--- sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/config/AbstractConfigTask.java (original)
+++ sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/config/AbstractConfigTask.java Sun Sep 12 10:15:09 2010
@@ -19,6 +19,10 @@
 package org.apache.sling.osgi.installer.impl.config;
 
 import java.io.IOException;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Set;
 
 import org.apache.sling.osgi.installer.impl.OsgiInstallerTask;
 import org.apache.sling.osgi.installer.impl.RegisteredResource;
@@ -30,6 +34,13 @@ import org.osgi.util.tracker.ServiceTrac
 /** Base class for configuration-related tasks */
 abstract class AbstractConfigTask extends OsgiInstallerTask {
 
+    /** Configuration properties to ignore when comparing configs */
+    protected static final Set<String> ignoredProperties = new HashSet<String>();
+    static {
+        ignoredProperties.add("service.pid");
+        ignoredProperties.add(ConfigurationPid.CONFIG_PATH_KEY);
+    }
+
     protected final ConfigurationPid pid;
 
     /** Tracker for the configuration admin. */
@@ -59,7 +70,7 @@ abstract class AbstractConfigTask extend
             result = ca.getConfiguration(cp.getConfigPid(), null);
         } else {
             Configuration configs[] = ca.listConfigurations(
-                "(|(" + ConfigInstallTask.ALIAS_KEY
+                "(|(" + ConfigurationPid.ALIAS_KEY
                 + "=" + cp.getFactoryPid() + ")(.alias_factory_pid=" + cp.getFactoryPid()
                 + "))");
 
@@ -74,4 +85,34 @@ abstract class AbstractConfigTask extend
 
         return result;
     }
+
+    private Set<String> collectKeys(final Dictionary<String, Object>a) {
+        final Set<String> keys = new HashSet<String>();
+        final Enumeration<String> aI = a.keys();
+        while (aI.hasMoreElements() ) {
+            final String key = aI.nextElement();
+            if ( !ignoredProperties.contains(key) ) {
+                keys.add(key);
+            }
+        }
+        return keys;
+    }
+
+    /** True if a and b represent the same config data, ignoring "non-configuration" keys in the dictionaries */
+    protected boolean isSameData(Dictionary<String, Object>a, Dictionary<String, Object>b) {
+        boolean result = false;
+        if (a != null && b != null) {
+            final Set<String> keysA = collectKeys(a);
+            final Set<String> keysB = collectKeys(b);
+            if ( keysA.size() == keysB.size() && keysA.containsAll(keysB) ) {
+                for(final String key : keysA ) {
+                    if ( !a.get(key).equals(b.get(key)) ) {
+                        return result;
+                    }
+                }
+                result = true;
+            }
+        }
+        return result;
+    }
 }

Modified: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/config/ConfigInstallTask.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/config/ConfigInstallTask.java?rev=996285&r1=996284&r2=996285&view=diff
==============================================================================
--- sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/config/ConfigInstallTask.java (original)
+++ sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/config/ConfigInstallTask.java Sun Sep 12 10:15:09 2010
@@ -18,33 +18,19 @@
  */
 package org.apache.sling.osgi.installer.impl.config;
 
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Set;
-
 import org.apache.sling.osgi.installer.impl.OsgiInstallerContext;
 import org.apache.sling.osgi.installer.impl.RegisteredResource;
 import org.osgi.service.cm.Configuration;
 import org.osgi.service.cm.ConfigurationAdmin;
 import org.osgi.util.tracker.ServiceTracker;
 
-/** Install/remove task for configurations */
+/**
+ * Task to install a configuration
+ */
 public class ConfigInstallTask extends AbstractConfigTask {
 
     private static final String CONFIG_INSTALL_ORDER = "20-";
 
-    static final String ALIAS_KEY = "_alias_factory_pid";
-    static final String CONFIG_PATH_KEY = "_jcr_config_path";
-    public static final String [] CONFIG_EXTENSIONS = { ".cfg", ".properties" };
-
-    /** Configuration properties to ignore when comparing configs */
-    public static final Set<String> ignoredProperties = new HashSet<String>();
-    static {
-    	ignoredProperties.add("service.pid");
-    	ignoredProperties.add(CONFIG_PATH_KEY);
-    }
-
     public ConfigInstallTask(final RegisteredResource r, final ServiceTracker configAdminServiceTracker) {
         super(r, configAdminServiceTracker);
     }
@@ -59,22 +45,10 @@ public class ConfigInstallTask extends A
     public void execute(final OsgiInstallerContext ctx) {
         final ConfigurationAdmin ca = this.getConfigurationAdmin();
         if (ca == null) {
-            ctx.addTaskToNextCycle(this);
             this.getLogger().debug("ConfigurationAdmin not available, task will be retried later: {}", this);
             return;
         }
 
-        // Convert data to a configuration Dictionary
-        final Dictionary<String, Object> dict = getResource().getDictionary();
-
-        // Add pseudo-properties
-        dict.put(CONFIG_PATH_KEY, getResource().getURL());
-
-        // Factory?
-        if (pid.getFactoryPid() != null) {
-            dict.put(ALIAS_KEY, pid.getFactoryPid());
-        }
-
         // Get or create configuration, but do not
         // update if the new one has the same values.
         boolean created = false;
@@ -95,7 +69,7 @@ public class ConfigInstallTask extends A
                 if (config.getBundleLocation() != null) {
                     config.setBundleLocation(null);
                 }
-                config.update(dict);
+                config.update(getResource().getDictionary());
                 ctx.log("Installed configuration {} from resource {}", config.getPid(), getResource());
                 this.getResource().setState(RegisteredResource.State.INSTALLED);
                 this.getLogger().debug("Configuration " + config.getPid()
@@ -106,37 +80,6 @@ public class ConfigInstallTask extends A
             }
         } catch (Exception e) {
             this.getLogger().debug("Exception during installation of config " + this.getResource() + " : " + e.getMessage() + ". Retrying later.", e);
-            ctx.addTaskToNextCycle(this);
         }
     }
-
-    private Set<String> collectKeys(final Dictionary<String, Object>a) {
-        final Set<String> keys = new HashSet<String>();
-        final Enumeration<String> aI = a.keys();
-        while (aI.hasMoreElements() ) {
-            final String key = aI.nextElement();
-            if ( !ignoredProperties.contains(key) ) {
-                keys.add(key);
-            }
-        }
-        return keys;
-    }
-
-    /** True if a and b represent the same config data, ignoring "non-configuration" keys in the dictionaries */
-    boolean isSameData(Dictionary<String, Object>a, Dictionary<String, Object>b) {
-    	boolean result = false;
-    	if (a != null && b != null) {
-    	    final Set<String> keysA = collectKeys(a);
-            final Set<String> keysB = collectKeys(b);
-            if ( keysA.size() == keysB.size() && keysA.containsAll(keysB) ) {
-                for(final String key : keysA ) {
-                    if ( !a.get(key).equals(b.get(key)) ) {
-                        return result;
-                    }
-                }
-                result = true;
-            }
-    	}
-    	return result;
-    }
 }
\ No newline at end of file

Modified: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/config/ConfigRemoveTask.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/config/ConfigRemoveTask.java?rev=996285&r1=996284&r2=996285&view=diff
==============================================================================
--- sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/config/ConfigRemoveTask.java (original)
+++ sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/config/ConfigRemoveTask.java Sun Sep 12 10:15:09 2010
@@ -29,10 +29,6 @@ public class ConfigRemoveTask extends Ab
 
     private static final String CONFIG_REMOVE_ORDER = "10-";
 
-    static final String ALIAS_KEY = "_alias_factory_pid";
-    static final String CONFIG_PATH_KEY = "_jcr_config_path";
-    public static final String [] CONFIG_EXTENSIONS = { ".cfg", ".properties" };
-
     public ConfigRemoveTask(final RegisteredResource r,
             final ServiceTracker configAdminServiceTracker) {
         super(r, configAdminServiceTracker);
@@ -46,10 +42,10 @@ public class ConfigRemoveTask extends Ab
     /**
      * @see org.apache.sling.osgi.installer.impl.OsgiInstallerTask#execute(org.apache.sling.osgi.installer.impl.OsgiInstallerContext)
      */
+    @SuppressWarnings("unchecked")
     public void execute(final OsgiInstallerContext ctx) {
         final ConfigurationAdmin ca = this.getConfigurationAdmin();
         if (ca == null) {
-            ctx.addTaskToNextCycle(this);
             this.getLogger().debug("ConfigurationAdmin not available, task will be retried later: {}", this);
             return;
         }
@@ -60,14 +56,21 @@ public class ConfigRemoveTask extends Ab
                 this.getLogger().debug("Cannot delete config , pid={} not found, ignored ({})", pid, getResource());
                 this.getResource().setState(RegisteredResource.State.IGNORED);
             } else {
-                this.getLogger().debug("Deleting config {} ({})", pid, getResource());
-                cfg.delete();
-                ctx.log("Deleted configuration {} from resource {}", pid, getResource());
-                this.getResource().setState(RegisteredResource.State.UNINSTALLED);
+                if ( cfg.getProperties().get(ConfigurationPid.CONFIG_PATH_KEY) == null ) {
+                    this.getLogger().debug("Configuration has not been installed by this resource. Not removing!");
+                    this.getResource().setState(RegisteredResource.State.IGNORED);
+                } else if ( !isSameData(cfg.getProperties(), this.getResource().getDictionary()) ) {
+                    this.getLogger().debug("Configuration has changed after is has been installed. Not removing!");
+                    this.getResource().setState(RegisteredResource.State.IGNORED);
+                } else {
+                    this.getLogger().debug("Deleting config {} ({})", pid, getResource());
+                    cfg.delete();
+                    ctx.log("Deleted configuration {} from resource {}", pid, getResource());
+                    this.getResource().setState(RegisteredResource.State.UNINSTALLED);
+                }
             }
         } catch (Exception e) {
             this.getLogger().debug("Exception during removal of config " + this.getResource() + " : " + e.getMessage() + ". Retrying later.", e);
-            ctx.addTaskToNextCycle(this);
         }
     }
 }
\ No newline at end of file

Modified: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/config/ConfigurationPid.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/config/ConfigurationPid.java?rev=996285&r1=996284&r2=996285&view=diff
==============================================================================
--- sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/config/ConfigurationPid.java (original)
+++ sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/config/ConfigurationPid.java Sun Sep 12 10:15:09 2010
@@ -20,35 +20,33 @@ package org.apache.sling.osgi.installer.
 
 import java.io.Serializable;
 
+import org.apache.sling.osgi.installer.impl.RegisteredResourceImpl;
+
 
 /** Builds configration PIDs out of filenames, examples:
  *      o.a.s.foo.bar.cfg -> pid = o.a.s.foo.bar
- *      o.a.s.foo.bar-a.cfg -> pid = o.a.s.foo.bar, factory pid = a 
+ *      o.a.s.foo.bar-a.cfg -> pid = o.a.s.foo.bar, factory pid = a
  */
 public class ConfigurationPid implements Serializable {
+
+    public static final String ALIAS_KEY = "_alias_factory_pid";
+    public static final String CONFIG_PATH_KEY = "org.apache.sling.installer.osgi.path";
+
     private static final long serialVersionUID = 1L;
     private final String configPid;
     private final String factoryPid;
 
-    public ConfigurationPid(String path) {
-        // cut off path
-        String pid = path;
-        final int lastSlash = path.lastIndexOf('/');
-        if(lastSlash >= 0) {
-            pid = path.substring(lastSlash + 1);
+    public ConfigurationPid(String pid) {
+        // remove path
+        final int slashPos = pid.lastIndexOf('/');
+        if ( slashPos != -1 ) {
+            pid = pid.substring(slashPos + 1);
         }
-        
-        // cut off extension if it's one of our config extensions
-        for(String ext : ConfigInstallTask.CONFIG_EXTENSIONS) {
-            if(pid.endsWith(ext)) {
-                final int lastDot = pid.lastIndexOf('.');
-                if(lastDot >= 0) {
-                    pid = pid.substring(0, lastDot);
-                }
-                break;
-            }
+        // remove extension
+        if ( RegisteredResourceImpl.    isConfigExtension(RegisteredResourceImpl.getExtension(pid))) {
+            final int lastDot = pid.lastIndexOf('.');
+            pid = pid.substring(0, lastDot);
         }
-
         // split pid and factory pid alias
         int n = pid.indexOf('-');
         if (n > 0) {
@@ -59,7 +57,7 @@ public class ConfigurationPid implements
             configPid = pid;
         }
     }
-    
+
     @Override
     public String toString() {
         return "Configuration (configPid=" + configPid + ", factoryPid=" + factoryPid + ")";
@@ -72,7 +70,7 @@ public class ConfigurationPid implements
     public String getFactoryPid() {
         return factoryPid;
     }
-    
+
     public String getCompositePid() {
         return (factoryPid == null ? "" : factoryPid + ".") + configPid;
     }

Modified: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleInstallTask.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleInstallTask.java?rev=996285&r1=996284&r2=996285&view=diff
==============================================================================
--- sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleInstallTask.java (original)
+++ sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleInstallTask.java Sun Sep 12 10:15:09 2010
@@ -78,7 +78,6 @@ public class BundleInstallTask extends O
         } catch (Exception ex) {
             // if something goes wrong we simply try it again
             this.getLogger().debug("Exception during install of bundle " + this.getResource() + " : " + ex.getMessage() + ". Retrying later.", ex);
-            ctx.addTaskToNextCycle(this);
         }
     }
 

Modified: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleRemoveTask.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleRemoveTask.java?rev=996285&r1=996284&r2=996285&view=diff
==============================================================================
--- sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleRemoveTask.java (original)
+++ sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleRemoveTask.java Sun Sep 12 10:15:09 2010
@@ -63,7 +63,6 @@ public class BundleRemoveTask extends Os
             ctx.addTaskToCurrentCycle(new SynchronousRefreshPackagesTask(this.creator));
         } catch (final BundleException be) {
             this.getLogger().debug("Exception during removal of bundle " + this.getResource() + " : " + be.getMessage() + ". Retrying later.", be);
-            ctx.addTaskToNextCycle(this);
         }
     }
 

Modified: sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleUpdateTask.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleUpdateTask.java?rev=996285&r1=996284&r2=996285&view=diff
==============================================================================
--- sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleUpdateTask.java (original)
+++ sling/trunk/installer/osgi/installer/src/main/java/org/apache/sling/osgi/installer/impl/tasks/BundleUpdateTask.java Sun Sep 12 10:15:09 2010
@@ -18,8 +18,6 @@
  */
 package org.apache.sling.osgi.installer.impl.tasks;
 
-import java.io.InputStream;
-
 import org.apache.sling.osgi.installer.impl.OsgiInstallerContext;
 import org.apache.sling.osgi.installer.impl.OsgiInstallerTask;
 import org.apache.sling.osgi.installer.impl.RegisteredResource;
@@ -57,7 +55,6 @@ public class BundleUpdateTask extends Os
             return;
         }
 
-        this.getResource().setState(RegisteredResource.State.INSTALLED);
         final Version newVersion = new Version((String)getResource().getAttributes().get(Constants.BUNDLE_VERSION));
 
         // check for system bundle update
@@ -71,6 +68,7 @@ public class BundleUpdateTask extends Os
     	if (currentVersion.equals(newVersion) && !snapshot) {
     	    // TODO : Isn't this already checked in the task creator?
     	    this.getLogger().debug("Same version is already installed, and not a snapshot, ignoring update: {}", getResource());
+            this.getResource().setState(RegisteredResource.State.INSTALLED);
     		return;
     	}
 
@@ -82,37 +80,34 @@ public class BundleUpdateTask extends Os
                 final String oldDigest = this.creator.getBundleDigestStorage().getDigest(symbolicName);
                 if (getResource().getDigest().equals(oldDigest)) {
                     this.getLogger().debug("Snapshot digest did not change, ignoring update: {}", getResource());
+                    this.getResource().setState(RegisteredResource.State.INSTALLED);
                     return;
                 }
             }
 
-            if (b.getState() == Bundle.ACTIVE) {
-                // bundle was active before the update - restart it once updated, but
-                // in sequence, not right now
-                ctx.addTaskToCurrentCycle(new BundleStartTask(getResource(), b.getBundleId(), this.creator));
-            }
+            // If the bundle is active before the update - restart it once updated, but
+            // in sequence, not right now
+            final boolean reactivate = (b.getState() == Bundle.ACTIVE);
             b.stop();
-            final InputStream is = getResource().getInputStream();
-            if(is == null) {
-            	canRetry = false;
-                throw new IllegalStateException(
-                        "RegisteredResource provides null InputStream, cannot update bundle: "
-                        + getResource());
-            }
-            b.update(is);
+
+            b.update(getResource().getInputStream());
             ctx.log("Updated bundle {} from resource {}", b, getResource());
             this.creator.getBundleDigestStorage().putInfo(b.getSymbolicName(), getResource().getDigest(), newVersion.toString());
+
+            if (reactivate) {
+                this.getResource().getAttributes().put(BundleTaskCreator.ATTR_START, "true");
+                ctx.addTaskToCurrentCycle(new BundleStartTask(getResource(), b.getBundleId(), this.creator));
+            } else {
+                this.getResource().setState(RegisteredResource.State.INSTALLED);
+            }
+            ctx.addTaskToCurrentCycle(new SynchronousRefreshPackagesTask(this.creator));
+            this.getLogger().debug("Bundle updated: {}/{}", b.getBundleId(), b.getSymbolicName());
     	} catch (Exception e) {
-            if ( canRetry ) {
-                ctx.addTaskToNextCycle(this);
-                return;
+            if ( !canRetry ) {
+                this.getLogger().warn("Removing failing tasks - unable to retry: " + this, e);
+                this.getResource().setState(RegisteredResource.State.IGNORED);
             }
-            this.getLogger().warn("Removing failing tasks - unable to retry: " + this, e);
-            return;
     	}
-        ctx.addTaskToCurrentCycle(new SynchronousRefreshPackagesTask(this.creator));
-        this.getLogger().debug("Bundle updated: {}/{}", b.getBundleId(), b.getSymbolicName());
-        return;
     }
 
     @Override

Modified: sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/RegisteredResourceTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/RegisteredResourceTest.java?rev=996285&r1=996284&r2=996285&view=diff
==============================================================================
--- sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/RegisteredResourceTest.java (original)
+++ sling/trunk/installer/osgi/installer/src/test/java/org/apache/sling/osgi/installer/impl/RegisteredResourceTest.java Sun Sep 12 10:15:09 2010
@@ -71,7 +71,7 @@ public class RegisteredResourceTest {
             assertNull("CONFIG resource does not provide an InputStream", rs);
             final Dictionary<String, Object> d = r.getDictionary();
             assertNotNull("CONFIG resource provides a Dictionary", d);
-            assertEquals("CONFIG resource dictionary has two properties", 2, d.size());
+            assertEquals("CONFIG resource dictionary has three properties", 3, d.size());
             assertNotNull("CONFIG resource has a pid attribute", r.getAttributes().get(RegisteredResource.CONFIG_PID_ATTRIBUTE));
         }
     }