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 2011/11/22 15:27:42 UTC

svn commit: r1205016 - /sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/

Author: cziegeler
Date: Tue Nov 22 14:27:39 2011
New Revision: 1205016

URL: http://svn.apache.org/viewvc?rev=1205016&view=rev
Log:
SLING-2290 : Updating a fragment with a different version but the same content does not work

Added:
    sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/AbstractBundleTask.java   (with props)
    sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleInfo.java   (with props)
Modified:
    sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleInstallTask.java
    sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleRemoveTask.java
    sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleStartTask.java
    sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleTaskCreator.java
    sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleUpdateTask.java
    sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/RefreshOptionalPackagesTask.java
    sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/SynchronousRefreshPackagesTask.java

Added: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/AbstractBundleTask.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/AbstractBundleTask.java?rev=1205016&view=auto
==============================================================================
--- sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/AbstractBundleTask.java (added)
+++ sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/AbstractBundleTask.java Tue Nov 22 14:27:39 2011
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.installer.core.impl.tasks;
+
+import org.apache.sling.installer.api.tasks.TaskResourceGroup;
+import org.apache.sling.installer.core.impl.AbstractInstallTask;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.service.startlevel.StartLevel;
+
+/**
+ * Abstract base class for bundle related tasks.
+ */
+public abstract class AbstractBundleTask extends AbstractInstallTask {
+
+    private final BundleTaskCreator creator;
+
+    public AbstractBundleTask(final TaskResourceGroup erl, final BundleTaskCreator creator) {
+        super(erl);
+        this.creator = creator;
+    }
+
+    protected PackageAdmin getPackageAdmin() {
+        return this.creator.getPackageAdmin();
+    }
+
+    protected BundleContext getBundleContext() {
+        return this.creator.getBundleContext();
+    }
+
+    protected StartLevel getStartLevel() {
+        return this.creator.getStartLevel();
+    }
+
+    protected BundleTaskCreator getCreator() {
+        return this.creator;
+    }
+
+    /**
+     * Check if the bundle is active.
+     * This is true if the bundle has the active state or of the bundle
+     * is in the starting state and has the lazy activation policy.
+     * Or if the bundle is a fragment, it's considered active as well
+     */
+    protected boolean isBundleActive(final Bundle b) {
+        if ( b.getState() == Bundle.ACTIVE ) {
+            return true;
+        }
+        if ( b.getState() == Bundle.STARTING && isLazyActivatian(b) ) {
+            return true;
+        }
+        return ( getFragmentHostHeader(b) != null );
+    }
+
+    /**
+     * Gets the bundle's Fragment-Host header.
+     */
+    protected String getFragmentHostHeader(final Bundle b) {
+        return (String) b.getHeaders().get( Constants.FRAGMENT_HOST );
+    }
+
+    /**
+     * Check if the bundle has the lazy activation policy
+     */
+    private boolean isLazyActivatian(final Bundle b) {
+        return Constants.ACTIVATION_LAZY.equals(b.getHeaders().get(Constants.BUNDLE_ACTIVATIONPOLICY));
+    }
+
+    /**
+     * Refresh host bundle
+     */
+    protected void refreshHostBundle(final Bundle b) {
+        final String fragmentHostHeader = getFragmentHostHeader(b);
+        if (fragmentHostHeader != null) {
+            this.getLogger().debug("Need to do a refresh of the bundle's host");
+            for (final Bundle bundle : this.getBundleContext().getBundles()) {
+                if (fragmentHostHeader.equals(bundle.getSymbolicName())) {
+                    this.getLogger().debug("Found host bundle to refresh {}", bundle.getBundleId());
+                    this.getPackageAdmin().refreshPackages(new Bundle[] { bundle });
+                    break;
+                }
+            }
+        }
+    }
+}

Propchange: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/AbstractBundleTask.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/AbstractBundleTask.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Propchange: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/AbstractBundleTask.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleInfo.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleInfo.java?rev=1205016&view=auto
==============================================================================
--- sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleInfo.java (added)
+++ sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleInfo.java Tue Nov 22 14:27:39 2011
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.installer.core.impl.tasks;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+
+/**
+ * Holds the bundle info that we need, makes it easier to test
+ * without an OSGi framework.
+ */
+public class BundleInfo {
+
+    private static final String MAVEN_SNAPSHOT_MARKER = "SNAPSHOT";
+
+    final public String symbolicName;
+    final public Version version;
+    final public int state;
+    final public long id;
+
+    public BundleInfo(String symbolicName, Version version, int state, long id) {
+        this.symbolicName = symbolicName;
+        this.version = version;
+        this.state = state;
+        this.id = id;
+    }
+
+    private BundleInfo(Bundle b) {
+        this.symbolicName = b.getSymbolicName();
+        this.version = new Version((String)b.getHeaders().get(Constants.BUNDLE_VERSION));
+        this.state = b.getState();
+        this.id = b.getBundleId();
+    }
+
+    public static BundleInfo getBundleInfo(final BundleContext bundleContext,
+            final String symbolicName, final String version) {
+        final Bundle b = getMatchingBundle(bundleContext, symbolicName, version);
+        if (b == null) {
+            return null;
+        }
+        return new BundleInfo(b);
+    }
+
+    /**
+     * Finds the bundle with given symbolic name in our bundle context.
+     */
+    public static Bundle getMatchingBundle(final BundleContext bundleContext,
+            final String bundleSymbolicName, final String version) {
+        Bundle match = null;
+        if (bundleSymbolicName != null) {
+            // check if this is the system bundle
+            if ( Constants.SYSTEM_BUNDLE_SYMBOLICNAME.equals(bundleSymbolicName) ) {
+                return bundleContext.getBundle(0);
+            }
+            final List<Bundle> matchingBundles = new ArrayList<Bundle>();
+            final Bundle[] bundles = bundleContext.getBundles();
+            for (Bundle bundle : bundles) {
+                if (bundleSymbolicName.equals(bundle.getSymbolicName())) {
+                    matchingBundles.add(bundle);
+                }
+            }
+            if ( matchingBundles.size() > 0 ) {
+                final Version searchVersion = (version == null ? null : new Version(version));
+                if ( searchVersion == null || searchVersion.compareTo(getBundleVersion(matchingBundles.get(0))) == 0 ) {
+                    match = matchingBundles.get(0);
+                }
+                for(int i=1; i<matchingBundles.size(); i++) {
+                    final Bundle current = matchingBundles.get(i);
+                    if ( searchVersion == null ) {
+                        if ( getBundleVersion(match).compareTo(getBundleVersion(current)) < 0 ) {
+                            match = current;
+                        }
+                    } else {
+                        if ( searchVersion.compareTo(getBundleVersion(current)) == 0 ) {
+                            match = current;
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+        return match;
+    }
+
+    private static Version getBundleVersion(final Bundle b) {
+        return new Version((String)b.getHeaders().get(Constants.BUNDLE_VERSION));
+    }
+
+    /**
+     * Check if the version is a snapshot version
+     */
+    public static boolean isSnapshot(final Version v) {
+        return v.toString().indexOf(MAVEN_SNAPSHOT_MARKER) >= 0;
+    }
+}

Propchange: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleInfo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleInfo.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Propchange: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleInfo.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleInstallTask.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleInstallTask.java?rev=1205016&r1=1205015&r2=1205016&view=diff
==============================================================================
--- sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleInstallTask.java (original)
+++ sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleInstallTask.java Tue Nov 22 14:27:39 2011
@@ -21,22 +21,20 @@ package org.apache.sling.installer.core.
 import org.apache.sling.installer.api.InstallableResource;
 import org.apache.sling.installer.api.tasks.InstallationContext;
 import org.apache.sling.installer.api.tasks.TaskResourceGroup;
-import org.apache.sling.installer.core.impl.AbstractInstallTask;
 import org.osgi.framework.Bundle;
 import org.osgi.service.startlevel.StartLevel;
 
-/** Install a bundle supplied as a RegisteredResource.
- *  Creates a BundleStartTask to start the bundle */
-public class BundleInstallTask extends AbstractInstallTask {
+/**
+ * Install a bundle supplied as a RegisteredResource.
+ * Creates a BundleStartTask to start the bundle.
+ */
+public class BundleInstallTask extends AbstractBundleTask {
 
     private static final String BUNDLE_INSTALL_ORDER = "50-";
 
-    private final BundleTaskCreator creator;
-
     public BundleInstallTask(final TaskResourceGroup r,
             final BundleTaskCreator creator) {
-        super(r);
-        this.creator = creator;
+        super(r, creator);
     }
 
     /**
@@ -67,9 +65,9 @@ public class BundleInstallTask extends A
             }
         }
         // get the start level service (if possible) so we can set the initial start level
-        final StartLevel startLevelService = this.creator.getStartLevel();
+        final StartLevel startLevelService = this.getStartLevel();
         try {
-            final Bundle b = this.creator.getBundleContext().installBundle(getResource().getURL(), getResource().getInputStream());
+            final Bundle b = this.getBundleContext().installBundle(getResource().getURL(), getResource().getInputStream());
             ctx.log("Installed bundle {} from resource {}", b, getResource());
             // optionally set the start level
             if ( startLevel > 0 ) {
@@ -83,8 +81,7 @@ public class BundleInstallTask extends A
 
             // mark this resource as installed and to be started
             this.getResource().setAttribute(BundleTaskCreator.ATTR_START, "true");
-            ctx.addTaskToCurrentCycle(new BundleStartTask(getResourceGroup(), b.getBundleId(), this.creator));
-            ctx.addTaskToNextCycle(new RefreshOptionalPackagesTask(this.creator));
+            ctx.addTaskToCurrentCycle(new BundleStartTask(getResourceGroup(), b.getBundleId(), this.getCreator()));
         } 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);

Modified: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleRemoveTask.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleRemoveTask.java?rev=1205016&r1=1205015&r2=1205016&view=diff
==============================================================================
--- sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleRemoveTask.java (original)
+++ sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleRemoveTask.java Tue Nov 22 14:27:39 2011
@@ -21,7 +21,6 @@ package org.apache.sling.installer.core.
 import org.apache.sling.installer.api.tasks.InstallationContext;
 import org.apache.sling.installer.api.tasks.ResourceState;
 import org.apache.sling.installer.api.tasks.TaskResourceGroup;
-import org.apache.sling.installer.core.impl.AbstractInstallTask;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleException;
 import org.osgi.framework.Constants;
@@ -30,16 +29,13 @@ import org.osgi.framework.Constants;
  *  Creates a SynchronousRefreshPackagesTask when
  *  executed.
  */
-public class BundleRemoveTask extends AbstractInstallTask {
+public class BundleRemoveTask extends AbstractBundleTask {
 
     private static final String BUNDLE_REMOVE_ORDER = "30-";
 
-    private final BundleTaskCreator creator;
-
     public BundleRemoveTask(final TaskResourceGroup r,
                             final BundleTaskCreator creator) {
-        super(r);
-        this.creator = creator;
+        super(r, creator);
     }
 
     /**
@@ -48,7 +44,7 @@ public class BundleRemoveTask extends Ab
     public void execute(InstallationContext ctx) {
         final String symbolicName = (String)getResource().getAttribute(Constants.BUNDLE_SYMBOLICNAME);
         final String version = (String)getResource().getAttribute(Constants.BUNDLE_VERSION);
-        final Bundle b = this.creator.getMatchingBundle(symbolicName, version);
+        final Bundle b = BundleInfo.getMatchingBundle(this.getBundleContext(), symbolicName, version);
         if (b == null) {
             // nothing to do, so just stop
             this.setFinishedState(ResourceState.IGNORED);
@@ -62,7 +58,7 @@ public class BundleRemoveTask extends Ab
             b.uninstall();
             ctx.log("Uninstalled bundle {} from resource {}", b, getResource());
             this.setFinishedState(ResourceState.UNINSTALLED);
-            ctx.addTaskToCurrentCycle(new SynchronousRefreshPackagesTask(this.creator));
+            ctx.addTaskToCurrentCycle(new SynchronousRefreshPackagesTask(this.getCreator()));
         } catch (final BundleException be) {
             this.getLogger().debug("Exception during removal of bundle " + this.getResource() + " : " + be.getMessage() + ". Retrying later.", be);
         }

Modified: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleStartTask.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleStartTask.java?rev=1205016&r1=1205015&r2=1205016&view=diff
==============================================================================
--- sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleStartTask.java (original)
+++ sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleStartTask.java Tue Nov 22 14:27:39 2011
@@ -24,18 +24,16 @@ import org.apache.sling.installer.api.ta
 import org.apache.sling.installer.api.tasks.ResourceState;
 import org.apache.sling.installer.api.tasks.TaskResource;
 import org.apache.sling.installer.api.tasks.TaskResourceGroup;
-import org.apache.sling.installer.core.impl.AbstractInstallTask;
 import org.apache.sling.installer.core.impl.OsgiInstallerImpl;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleException;
-import org.osgi.framework.Constants;
 
 /** Start a bundle given its bundle ID
  *  Restarts if the bundle does not start on the first try,
  *  but only after receiving a bundle or framework event,
  *  indicating that it's worth retrying
  */
-public class BundleStartTask extends AbstractInstallTask {
+public class BundleStartTask extends AbstractBundleTask {
 
     private static final String BUNDLE_START_ORDER = "70-";
 
@@ -47,12 +45,9 @@ public class BundleStartTask extends Abs
 	private long eventsCountForRetrying;
 	private int retryCount = 0;
 
-	private final BundleTaskCreator creator;
-
-	public BundleStartTask(final TaskResourceGroup r, final long bundleId, final BundleTaskCreator btc) {
-	    super(r);
+		public BundleStartTask(final TaskResourceGroup r, final long bundleId, final BundleTaskCreator btc) {
+	    super(r, btc);
         this.bundleId = bundleId;
-        this.creator = btc;
         this.sortKey = BUNDLE_START_ORDER + new DecimalFormat("00000").format(bundleId);
         final TaskResource rr = this.getResource();
 	    if ( rr != null && rr.getTemporaryAttribute(ATTR_RC) != null ) {
@@ -72,36 +67,6 @@ public class BundleStartTask extends Abs
 	}
 
 	/**
-	 * Check if the bundle is active.
-	 * This is true if the bundle has the active state or of the bundle
-	 * is in the starting state and has the lazy activation policy.
-	 * Or if the bundle is a fragment, it's considered active as well
-	 */
-	public static boolean isBundleActive(final Bundle b) {
-	    if ( b.getState() == Bundle.ACTIVE ) {
-	        return true;
-	    }
-	    if ( b.getState() == Bundle.STARTING && isLazyActivatian(b) ) {
-	        return true;
-	    }
-	    return ( getFragmentHostHeader(b) != null );
-	}
-
-	/**
-         * Gets the bundle's Fragment-Host header.
-         */
-	public static String getFragmentHostHeader(final Bundle b) {
-	    return (String) b.getHeaders().get( Constants.FRAGMENT_HOST );
-	}
-
-	/**
-	 * Check if the bundle has the lazy activation policy
-	 */
-	private static boolean isLazyActivatian(final Bundle b) {
-        return Constants.ACTIVATION_LAZY.equals(b.getHeaders().get(Constants.BUNDLE_ACTIVATIONPOLICY));
-	}
-
-	/**
 	 * @see org.apache.sling.installer.api.tasks.InstallTask#execute(org.apache.sling.installer.api.tasks.InstallationContext)
 	 */
 	public void execute(final InstallationContext ctx) {
@@ -125,7 +90,7 @@ public class BundleStartTask extends Abs
             return;
         }
 
-        final Bundle b = this.creator.getBundleContext().getBundle(bundleId);
+        final Bundle b = this.getBundleContext().getBundle(bundleId);
 		if (b == null) {
 		    this.getLogger().info("Cannot start bundle, id not found: {}", bundleId);
 			return;
@@ -134,10 +99,10 @@ public class BundleStartTask extends Abs
         final String fragmentHostHeader = getFragmentHostHeader(b);
         if (fragmentHostHeader != null) {
             this.getLogger().debug("Need to do a refresh of the bundle's host");
-            for (final Bundle bundle : this.creator.getBundleContext().getBundles()) {
+            for (final Bundle bundle : this.getBundleContext().getBundles()) {
                 if (fragmentHostHeader.equals(bundle.getSymbolicName())) {
                     this.getLogger().debug("Found host bundle to refresh {}", bundle.getBundleId());
-                    this.creator.getPackageAdmin().refreshPackages(new Bundle[] { bundle });
+                    this.getPackageAdmin().refreshPackages(new Bundle[] { bundle });
                     break;
                 }
             }

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=1205016&r1=1205015&r2=1205016&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 Tue Nov 22 14:27:39 2011
@@ -18,9 +18,6 @@
  */
 package org.apache.sling.installer.core.impl.tasks;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import org.apache.sling.installer.api.InstallableResource;
 import org.apache.sling.installer.api.ResourceChangeListener;
 import org.apache.sling.installer.api.tasks.InstallTask;
@@ -30,7 +27,6 @@ import org.apache.sling.installer.api.ta
 import org.apache.sling.installer.api.tasks.TaskResourceGroup;
 import org.apache.sling.installer.core.impl.InternalService;
 import org.apache.sling.installer.core.impl.Util;
-import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
 import org.osgi.framework.Version;
@@ -63,8 +59,6 @@ public class BundleTaskCreator implement
     /** Interface of the start level */
     private static String START_LEVEL_NAME = StartLevel.class.getName();
 
-    private static final String MAVEN_SNAPSHOT_MARKER = "SNAPSHOT";
-
     /** Tracker for the package admin. */
     private ServiceTracker packageAdminTracker;
 
@@ -119,29 +113,6 @@ public class BundleTaskCreator implement
         return (PackageAdmin)this.packageAdminTracker.getService();
     }
 
-    /** Holds the bundle info that we need, makes it easier to test
-     *  without an OSGi framework */
-    static class BundleInfo {
-        final String symbolicName;
-        final Version version;
-        final int state;
-        final long id;
-
-        BundleInfo(String symbolicName, Version version, int state, long id) {
-            this.symbolicName = symbolicName;
-            this.version = version;
-            this.state = state;
-            this.id = id;
-        }
-
-        BundleInfo(Bundle b) {
-            this.symbolicName = b.getSymbolicName();
-            this.version = new Version((String)b.getHeaders().get(Constants.BUNDLE_VERSION));
-            this.state = b.getState();
-            this.id = b.getBundleId();
-        }
-    }
-
 	/**
      * Create a bundle task - install, update or remove
      *
@@ -174,7 +145,8 @@ public class BundleTaskCreator implement
         final InstallTask result;
 		if (toActivate.getState() == ResourceState.UNINSTALL) {
             // find the info with the exact version
-            final BundleInfo info = this.getBundleInfo(symbolicName,
+            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 ) {
@@ -227,7 +199,7 @@ public class BundleTaskCreator implement
                         logger.debug("Bundle " + info.symbolicName + " " + newVersion
                                     + " is not installed, bundle with higher version is already installed.");
                     }
-			    } else if (compare == 0 && this.isSnapshot(newVersion)) {
+			    } else if (compare == 0 && BundleInfo.isSnapshot(newVersion)) {
 			        // check if system bundle or installer bundle
 			        if ( isInstallerCoreBundle || Constants.SYSTEM_BUNDLE_SYMBOLICNAME.equals(symbolicName) ) {
 			            if ( toActivate.getAttribute(SPECIAL_ATTR) != null ) {
@@ -265,62 +237,7 @@ public class BundleTaskCreator implement
 		return result;
 	}
 
-	protected BundleInfo getBundleInfo(final String symbolicName, final String version) {
-		final Bundle b = this.getMatchingBundle(symbolicName, version);
-		if (b == null) {
-		    return null;
-        }
-		return new BundleInfo(b);
-	}
-
-    /**
-     * Finds the bundle with given symbolic name in our bundle context.
-     */
-    public Bundle getMatchingBundle(final String bundleSymbolicName, final String version) {
-        Bundle match = null;
-        if (bundleSymbolicName != null) {
-            // check if this is the system bundle
-            if ( Constants.SYSTEM_BUNDLE_SYMBOLICNAME.equals(bundleSymbolicName) ) {
-                return bundleContext.getBundle(0);
-            }
-            final List<Bundle> matchingBundles = new ArrayList<Bundle>();
-            final Bundle[] bundles = bundleContext.getBundles();
-            for (Bundle bundle : bundles) {
-                if (bundleSymbolicName.equals(bundle.getSymbolicName())) {
-                    matchingBundles.add(bundle);
-                }
-            }
-            if ( matchingBundles.size() > 0 ) {
-                final Version searchVersion = (version == null ? null : new Version(version));
-                if ( searchVersion == null || searchVersion.compareTo(getBundleVersion(matchingBundles.get(0))) == 0 ) {
-                    match = matchingBundles.get(0);
-                }
-                for(int i=1; i<matchingBundles.size(); i++) {
-                    final Bundle current = matchingBundles.get(i);
-                    if ( searchVersion == null ) {
-                        if ( getBundleVersion(match).compareTo(getBundleVersion(current)) < 0 ) {
-                            match = current;
-                        }
-                    } else {
-                        if ( searchVersion.compareTo(getBundleVersion(current)) == 0 ) {
-                            match = current;
-                            break;
-                        }
-                    }
-                }
-            }
-        }
-        return match;
-    }
-
-    private Version getBundleVersion(final Bundle b) {
-        return new Version((String)b.getHeaders().get(Constants.BUNDLE_VERSION));
-    }
-
-    /**
-     * Check if the version is a snapshot version
-     */
-    public boolean isSnapshot(Version v) {
-        return v.toString().indexOf(MAVEN_SNAPSHOT_MARKER) >= 0;
+    protected BundleInfo getBundleInfo(final String symbolicName, final String version) {
+        return BundleInfo.getBundleInfo(this.getBundleContext(), symbolicName, version);
     }
 }

Modified: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleUpdateTask.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleUpdateTask.java?rev=1205016&r1=1205015&r2=1205016&view=diff
==============================================================================
--- sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleUpdateTask.java (original)
+++ sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/BundleUpdateTask.java Tue Nov 22 14:27:39 2011
@@ -21,7 +21,6 @@ package org.apache.sling.installer.core.
 import org.apache.sling.installer.api.tasks.InstallationContext;
 import org.apache.sling.installer.api.tasks.ResourceState;
 import org.apache.sling.installer.api.tasks.TaskResourceGroup;
-import org.apache.sling.installer.core.impl.AbstractInstallTask;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.Constants;
 import org.osgi.framework.Version;
@@ -31,18 +30,15 @@ import org.osgi.service.startlevel.Start
  *  a bundleStartTask to restart the bundle if it was
  *   active before the update.
  */
-public class BundleUpdateTask extends AbstractInstallTask {
+public class BundleUpdateTask extends AbstractBundleTask {
 
     private static final String BUNDLE_UPDATE_ORDER = "40-";
 
     private boolean canRetry = true;
 
-    private final BundleTaskCreator creator;
-
     public BundleUpdateTask(final TaskResourceGroup r,
                             final BundleTaskCreator creator) {
-        super(r);
-        this.creator = creator;
+        super(r, creator);
     }
 
     /**
@@ -52,10 +48,10 @@ public class BundleUpdateTask extends Ab
      * Or if the bundle is a fragment, it's considered active as well
      */
     protected boolean isBundleActive(final Bundle b) {
-        if ( BundleStartTask.isBundleActive(b) ) {
+        if ( super.isBundleActive(b) ) {
             return true;
         }
-        final StartLevel startLevelService = this.creator.getStartLevel();
+        final StartLevel startLevelService = this.getStartLevel();
         return startLevelService.isBundlePersistentlyStarted(b);
     }
 
@@ -64,7 +60,7 @@ public class BundleUpdateTask extends Ab
      */
     public void execute(InstallationContext ctx) {
         final String symbolicName = (String)getResource().getAttribute(Constants.BUNDLE_SYMBOLICNAME);
-        final Bundle b = this.creator.getMatchingBundle(symbolicName, null);
+        final Bundle b = BundleInfo.getMatchingBundle(this.getBundleContext(), symbolicName, null);
         if (b == null) {
             this.getLogger().debug("Bundle to update ({}) not found", symbolicName);
             this.setFinishedState(ResourceState.IGNORED);
@@ -76,7 +72,7 @@ public class BundleUpdateTask extends Ab
         // Do not update if same version, unless snapshot
         boolean snapshot = false;
     	final Version currentVersion = new Version((String)b.getHeaders().get(Constants.BUNDLE_VERSION));
-    	snapshot = this.creator.isSnapshot(newVersion);
+    	snapshot = BundleInfo.isSnapshot(newVersion);
     	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());
@@ -88,7 +84,11 @@ public class BundleUpdateTask extends Ab
             // If the bundle is active before the update - restart it once updated, but
             // in sequence, not right now
             final boolean reactivate = this.isBundleActive(b);
-            b.stop();
+            // if this is not a fragment, stop the bundle
+            final int state = b.getState();
+            if (state == Bundle.ACTIVE || state == Bundle.STARTING) {
+                b.stop();
+            }
 
             b.update(getResource().getInputStream());
             ctx.log("Updated bundle {} from resource {}", b, getResource());
@@ -96,16 +96,18 @@ public class BundleUpdateTask extends Ab
             if (reactivate) {
                 if ( isSystemBundleFragment(b) ) {
                     this.setFinishedState(ResourceState.INSTALLED);
-                    ctx.addTaskToCurrentCycle(new SystemBundleUpdateTask(null, creator));
+                    ctx.addTaskToCurrentCycle(new SystemBundleUpdateTask(null, this.getCreator()));
+                } else if ( this.getFragmentHostHeader(b) != null ) {
+                    // if this is a fragment, we're done after a refresh
+                    this.getPackageAdmin().refreshPackages(new Bundle[] {b});
+                    this.setFinishedState(ResourceState.INSTALLED);
                 } else {
                     this.getResource().setAttribute(BundleTaskCreator.ATTR_START, "true");
-                    ctx.addTaskToCurrentCycle(new BundleStartTask(this.getResourceGroup(), b.getBundleId(), this.creator));
+                    ctx.addTaskToCurrentCycle(new BundleStartTask(this.getResourceGroup(), b.getBundleId(), this.getCreator()));
                 }
             } else {
                 this.setFinishedState(ResourceState.INSTALLED);
             }
-            ctx.addTaskToNextCycle(new SynchronousRefreshPackagesTask(this.creator));
-            ctx.addTaskToCurrentCycle(new RefreshOptionalPackagesTask(this.creator));
             this.getLogger().debug("Bundle updated: {}/{}", b.getBundleId(), b.getSymbolicName());
     	} catch (Exception e) {
             if ( !canRetry ) {
@@ -121,8 +123,7 @@ public class BundleUpdateTask extends Ab
     }
 
     private boolean isSystemBundleFragment(final Bundle installedBundle) {
-        final String fragmentHeader = (String) installedBundle.getHeaders().get(
-            Constants.FRAGMENT_HOST);
+        final String fragmentHeader = this.getFragmentHostHeader(installedBundle);
         return fragmentHeader != null
             && fragmentHeader.indexOf(Constants.EXTENSION_DIRECTIVE) > 0;
     }

Modified: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/RefreshOptionalPackagesTask.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/RefreshOptionalPackagesTask.java?rev=1205016&r1=1205015&r2=1205016&view=diff
==============================================================================
--- sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/RefreshOptionalPackagesTask.java (original)
+++ sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/RefreshOptionalPackagesTask.java Tue Nov 22 14:27:39 2011
@@ -66,9 +66,6 @@ public class RefreshOptionalPackagesTask
      * @see org.apache.sling.installer.api.tasks.InstallTask#execute(org.apache.sling.installer.api.tasks.InstallationContext)
      */
     public void execute(final InstallationContext ctx) {
-        if ( true ) {
-            return;
-        }
         getLogger().info("** Invoking refresh optional packages!");
         final PackageAdmin packageAdmin = this.getPackageAdmin();
 

Modified: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/SynchronousRefreshPackagesTask.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/SynchronousRefreshPackagesTask.java?rev=1205016&r1=1205015&r2=1205016&view=diff
==============================================================================
--- sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/SynchronousRefreshPackagesTask.java (original)
+++ sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/SynchronousRefreshPackagesTask.java Tue Nov 22 14:27:39 2011
@@ -20,7 +20,6 @@ package org.apache.sling.installer.core.
 
 import org.apache.sling.installer.api.tasks.InstallTask;
 import org.apache.sling.installer.api.tasks.InstallationContext;
-import org.apache.sling.installer.core.impl.AbstractInstallTask;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.FrameworkEvent;
 import org.osgi.framework.FrameworkListener;
@@ -29,10 +28,8 @@ import org.osgi.framework.FrameworkListe
  * Execute an OSGi "refresh packages" operation, synchronously
  * by waiting until a package refresh event occurs.
  */
-public class SynchronousRefreshPackagesTask extends AbstractInstallTask implements FrameworkListener {
-
-    /** Tracker for the package admin. */
-    private final BundleTaskCreator bundleTaskCreator;
+public class SynchronousRefreshPackagesTask extends AbstractBundleTask
+    implements FrameworkListener {
 
     private static final String REFRESH_PACKAGES_ORDER = "60-";
 
@@ -46,8 +43,7 @@ public class SynchronousRefreshPackagesT
     private volatile int packageRefreshEventsCount;
 
 	public SynchronousRefreshPackagesTask(final BundleTaskCreator btc) {
-	    super(null);
-	    this.bundleTaskCreator = btc;
+	    super(null, btc);
 	}
 
     /**
@@ -86,9 +82,9 @@ public class SynchronousRefreshPackagesT
         // make sure all currently active ones are restarted after
         // this task has executed
         // we don't check for fragments!
-    	for(final Bundle b : this.bundleTaskCreator.getBundleContext().getBundles()) {
-    	    if ( BundleStartTask.isBundleActive(b) && BundleStartTask.getFragmentHostHeader(b) == null ) {
-    	        final InstallTask t = new BundleStartTask(null, b.getBundleId(), this.bundleTaskCreator);
+    	for(final Bundle b : this.getBundleContext().getBundles()) {
+    	    if ( this.isBundleActive(b) && this.getFragmentHostHeader(b) == null ) {
+    	        final InstallTask t = new BundleStartTask(null, b.getBundleId(), this.getCreator());
     			ctx.addTaskToCurrentCycle(t);
     			this.getLogger().debug("Added {} to restart bundle if needed after refreshing packages", t);
     		}
@@ -96,9 +92,9 @@ public class SynchronousRefreshPackagesT
 
         // It seems like (at least with Felix 1.0.4) we won't get a FrameworkEvent.PACKAGES_REFRESHED
         // if one happened very recently and there's nothing to refresh
-        this.bundleTaskCreator.getBundleContext().addFrameworkListener(this);
+        this.getBundleContext().addFrameworkListener(this);
         try {
-            this.bundleTaskCreator.getPackageAdmin().refreshPackages(null);
+            this.getPackageAdmin().refreshPackages(null);
             while (true) {
                 if (System.currentTimeMillis() > timeout) {
                     this.getLogger().warn("No FrameworkEvent.PACKAGES_REFRESHED event received within {}"
@@ -118,7 +114,7 @@ public class SynchronousRefreshPackagesT
                 }
             }
         } finally {
-        	this.bundleTaskCreator.getBundleContext().removeFrameworkListener(this);
+        	this.getBundleContext().removeFrameworkListener(this);
         }
 	}
 }