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 2012/08/08 18:54:25 UTC

svn commit: r1370837 - in /sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl: console/ tasks/ util/

Author: cziegeler
Date: Wed Aug  8 16:54:24 2012
New Revision: 1370837

URL: http://svn.apache.org/viewvc?rev=1370837&view=rev
Log:
SLING-2556 : Installer should detect if installer bundle is refreshed by another bundle update (WiP)

Modified:
    sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/console/OsgiInstallerWebConsolePlugin.java
    sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/InstallerBundleUpdateTask.java
    sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/RefreshBundlesTask.java
    sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/util/BundleRefresher.java
    sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/util/PABundleRefresher.java

Modified: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/console/OsgiInstallerWebConsolePlugin.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/console/OsgiInstallerWebConsolePlugin.java?rev=1370837&r1=1370836&r2=1370837&view=diff
==============================================================================
--- sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/console/OsgiInstallerWebConsolePlugin.java (original)
+++ sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/console/OsgiInstallerWebConsolePlugin.java Wed Aug  8 16:54:24 2012
@@ -96,9 +96,8 @@ public class OsgiInstallerWebConsolePlug
     }
 
     @Override
-    public void service(ServletRequest req, ServletResponse res)
+    public void service(final ServletRequest req, final ServletResponse res)
     throws IOException {
-
         final PrintWriter pw = res.getWriter();
 
         pw.print("<p class='statline ui-state-highlight'>Apache Sling OSGi Installer</p>");

Modified: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/InstallerBundleUpdateTask.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/InstallerBundleUpdateTask.java?rev=1370837&r1=1370836&r2=1370837&view=diff
==============================================================================
--- sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/InstallerBundleUpdateTask.java (original)
+++ sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/InstallerBundleUpdateTask.java Wed Aug  8 16:54:24 2012
@@ -18,8 +18,7 @@
  */
 package org.apache.sling.installer.core.impl.tasks;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Collections;
 
 import org.apache.sling.installer.api.tasks.InstallTask;
 import org.apache.sling.installer.api.tasks.InstallationContext;
@@ -61,9 +60,7 @@ public class InstallerBundleUpdateTask e
             }
         } else if ( this.count == 1 ) {
             // second step: refresh
-            final List<Bundle> bundles = new ArrayList<Bundle>();
-            bundles.add(b);
-            this.getBundleRefresher().refreshBundles(ctx, bundles, false);
+            this.getBundleRefresher().refreshBundles(ctx, Collections.singletonList(b), false);
         } else {
             // finished
             this.getResource().setAttribute(ASYNC_ATTR_NAME, null);

Modified: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/RefreshBundlesTask.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/RefreshBundlesTask.java?rev=1370837&r1=1370836&r2=1370837&view=diff
==============================================================================
--- sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/RefreshBundlesTask.java (original)
+++ sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/tasks/RefreshBundlesTask.java Wed Aug  8 16:54:24 2012
@@ -78,7 +78,38 @@ public class RefreshBundlesTask
             BUNDLE_IDS.clear();
         }
         if ( bundles.size() > 0 ) {
-            this.getBundleRefresher().refreshBundles(ctx, bundles, true);
+            // check if the installer bundle is affected
+            if ( !this.getBundleRefresher().isInstallerBundleAffected(bundles) ) {
+                this.getBundleRefresher().refreshBundles(ctx, bundles, true);
+            } else {
+                ctx.log("Installer bundle is affected by bundle refresh, initiating asynchronous refresh");
+                ctx.addTaskToCurrentCycle(new AsyncRefreshBundlesTask(this.getTaskSupport(), bundles));
+            }
         }
 	}
+
+    private final class AsyncRefreshBundlesTask extends AbstractBundleTask {
+
+        private final List<Bundle> bundles;
+
+        public AsyncRefreshBundlesTask(final TaskSupport btc, final List<Bundle> bundles) {
+            super(null, btc);
+            this.bundles = bundles;
+        }
+
+        @Override
+        public void execute(final InstallationContext ctx) {
+            this.getBundleRefresher().refreshBundles(ctx, bundles, false);
+        }
+
+        @Override
+        public String getSortKey() {
+            return "07-";
+        }
+
+        @Override
+        public boolean isAsynchronousTask() {
+            return true;
+        }
+    }
 }

Modified: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/util/BundleRefresher.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/util/BundleRefresher.java?rev=1370837&r1=1370836&r2=1370837&view=diff
==============================================================================
--- sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/util/BundleRefresher.java (original)
+++ sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/util/BundleRefresher.java Wed Aug  8 16:54:24 2012
@@ -23,7 +23,12 @@ import java.util.List;
 import org.apache.sling.installer.api.tasks.InstallationContext;
 import org.osgi.framework.Bundle;
 
+/**
+ * Service for refreshing bundles.
+ */
 public interface BundleRefresher {
 
     void refreshBundles(final InstallationContext ctx, final List<Bundle> bundles, boolean wait);
+
+    boolean isInstallerBundleAffected(final List<Bundle> bundles);
 }

Modified: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/util/PABundleRefresher.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/util/PABundleRefresher.java?rev=1370837&r1=1370836&r2=1370837&view=diff
==============================================================================
--- sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/util/PABundleRefresher.java (original)
+++ sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/util/PABundleRefresher.java Wed Aug  8 16:54:24 2012
@@ -18,17 +18,26 @@
  */
 package org.apache.sling.installer.core.impl.util;
 
+import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
+import org.apache.sling.commons.osgi.ManifestHeader;
 import org.apache.sling.installer.api.tasks.InstallationContext;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
 import org.osgi.framework.FrameworkEvent;
 import org.osgi.framework.FrameworkListener;
+import org.osgi.service.packageadmin.ExportedPackage;
 import org.osgi.service.packageadmin.PackageAdmin;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+/**
+ * Implementation using the package admin
+ */
 public class PABundleRefresher implements BundleRefresher, FrameworkListener {
 
     private final Logger logger = LoggerFactory.getLogger(this.getClass());
@@ -51,6 +60,15 @@ public class PABundleRefresher implement
         this.bundleContext = bundleContext;
     }
 
+    private Set<String> getImportPackages(final Bundle bundle) {
+        final ManifestHeader header = ManifestHeader.parse(bundle.getHeaders().get(Constants.IMPORT_PACKAGE).toString());
+        final Set<String> packages = new HashSet<String>();
+        for(final ManifestHeader.Entry entry : header.getEntries()) {
+            packages.add(entry.getValue());
+        }
+        return packages;
+    }
+
     /**
      * @see org.apache.sling.installer.core.impl.util.BundleRefresher#refreshBundles(org.apache.sling.installer.api.tasks.InstallationContext, java.util.List, boolean)
      */
@@ -96,6 +114,53 @@ public class PABundleRefresher implement
     }
 
     /**
+     * Check whether a bundle refresh would affect the installer bundle
+     * @see org.apache.sling.installer.core.impl.util.BundleRefresher#isInstallerBundleAffected(java.util.List)
+     */
+    public boolean isInstallerBundleAffected(final List<Bundle> bundles) {
+        // we put all bundle ids into a set
+        final Set<Long> ids = new HashSet<Long>();
+        for(final Bundle b : bundles) {
+            ids.add(b.getBundleId());
+        }
+
+        final Set<Long> processed = new HashSet<Long>();
+        final List<Bundle> toProcess = new ArrayList<Bundle>();
+        toProcess.add(this.bundleContext.getBundle());
+        processed.add(this.bundleContext.getBundle().getBundleId());
+
+        while ( !toProcess.isEmpty() ) {
+            final Bundle bundle = toProcess.remove(0);
+
+            if ( ids.contains(bundle.getBundleId()) ) {
+                return true;
+            }
+
+            for(final String name : this.getImportPackages(bundle) ) {
+
+                final ExportedPackage[] pcks = this.pckAdmin.getExportedPackages(name);
+                if ( pcks != null ) {
+                    for(final ExportedPackage pck : pcks) {
+                        final Bundle exportingBundle = pck.getExportingBundle();
+                        if ( exportingBundle.getBundleId() == 0 || exportingBundle.getBundleId() == this.bundleContext.getBundle().getBundleId() ) {
+                            continue;
+                        }
+                        if ( ids.contains(exportingBundle.getBundleId()) ) {
+                            return true;
+                        }
+                        if ( !processed.contains(exportingBundle.getBundleId())) {
+                            processed.add(exportingBundle.getBundleId());
+                            toProcess.add(exportingBundle);
+                        }
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
+    /**
      * @see org.osgi.framework.FrameworkListener#frameworkEvent(org.osgi.framework.FrameworkEvent)
      */
     public void frameworkEvent(final FrameworkEvent event) {