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/08/04 14:24:46 UTC
svn commit: r1153861 - in
/sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl:
BootstrapInstaller.java bootstrapcommands/BootstrapCommandFile.java
bootstrapcommands/Command.java bootstrapcommands/UninstallBundleCommand.java
Author: cziegeler
Date: Thu Aug 4 12:24:45 2011
New Revision: 1153861
URL: http://svn.apache.org/viewvc?rev=1153861&view=rev
Log:
SLING-2168 : If a system fragment is uninstalled during bootstrapping, the framework should be restarted
Modified:
sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/BootstrapInstaller.java
sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/BootstrapCommandFile.java
sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/Command.java
sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/UninstallBundleCommand.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=1153861&r1=1153860&r2=1153861&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 Aug 4 12:24:45 2011
@@ -203,7 +203,7 @@ class BootstrapInstaller implements Bund
// execute bootstrap commands, if needed
final BootstrapCommandFile cmd = new BootstrapCommandFile(logger, new File(slingHome, BOOTSTRAP_CMD_FILENAME));
- cmd.execute(context);
+ boolean requireRestart = cmd.execute(context);
boolean shouldInstall = false;
@@ -263,24 +263,24 @@ class BootstrapInstaller implements Bund
List<Bundle> installed = new LinkedList<Bundle>();
// get all bundles from the startup location and install them
- boolean requireRestart = installBundles(slingStartupDir, context, bySymbolicName, installed);
+ requireRestart |= installBundles(slingStartupDir, context, bySymbolicName, installed);
// start all the newly installed bundles (existing bundles are not started if they are stopped)
startBundles(installed);
// mark everything installed
markInstalled(context, slingStartupDir);
+ }
- // due to the upgrade of a framework extension bundle, the framework
- // has to be restarted. For this reason, set the target start level
- // to a negative value.
- if (requireRestart) {
- logger.log(
- Logger.LOG_INFO,
- "Framework extension(s) have been updated, restarting framework after startup has completed");
+ // due to the upgrade of a framework extension bundle, the framework
+ // has to be restarted. For this reason, set the target start level
+ // to a negative value.
+ if (requireRestart) {
+ logger.log(
+ Logger.LOG_INFO,
+ "Framework extension(s) have been updated, restarting framework after startup has completed");
- targetStartLevel = -1;
- }
+ targetStartLevel = -1;
}
}
Modified: sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/BootstrapCommandFile.java
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/BootstrapCommandFile.java?rev=1153861&r1=1153860&r2=1153861&view=diff
==============================================================================
--- sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/BootstrapCommandFile.java (original)
+++ sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/BootstrapCommandFile.java Thu Aug 4 12:24:45 2011
@@ -80,11 +80,13 @@ public class BootstrapCommandFile {
return result;
}
- /** Execute commands if needed, and store execution timestamp
- * @return number of commands executed */
- public int execute(BundleContext ctx) throws IOException {
- int count = 0;
- if(anythingToExecute(ctx)) {
+ /**
+ * Execute commands if needed, and store execution timestamp
+ * @return If system bundle needs a restart.
+ */
+ public boolean execute(BundleContext ctx) throws IOException {
+ boolean needsRestart = false;
+ if (anythingToExecute(ctx)) {
InputStream is = null;
try {
is = new FileInputStream(commandFile);
@@ -92,8 +94,7 @@ public class BootstrapCommandFile {
for(Command cmd : cmds) {
try {
logger.log(Logger.LOG_DEBUG, "Executing command: " + cmd);
- cmd.execute(logger, ctx);
- count++;
+ needsRestart |= cmd.execute(logger, ctx);
} catch(Exception e) {
logger.log(Logger.LOG_WARNING, "Exception in command execution (" + cmd + ") :" + e);
}
@@ -114,7 +115,7 @@ public class BootstrapCommandFile {
logger.log(Logger.LOG_WARNING, "IOException while storing timestamp", ioe);
}
}
- return count;
+ return needsRestart;
}
/** Parse commands from supplied input stream.
Modified: sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/Command.java
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/Command.java?rev=1153861&r1=1153860&r2=1153861&view=diff
==============================================================================
--- sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/Command.java (original)
+++ sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/Command.java Thu Aug 4 12:24:45 2011
@@ -24,6 +24,7 @@ import org.apache.felix.framework.Logger
import org.osgi.framework.BundleContext;
interface Command {
+
@SuppressWarnings("serial")
static class ParseException extends IOException {
ParseException(String reason) {
@@ -36,7 +37,10 @@ interface Command {
* @throws ParseException if we know the command but syntax is wrong
*/
Command parse(String commandLine) throws ParseException;
-
- /** Execute this command */
- void execute(Logger logger, BundleContext ctx) throws Exception;
+
+ /**
+ * Execute this command.
+ * @return Return true if system bundle needs a restart.
+ */
+ boolean execute(Logger logger, BundleContext ctx) throws Exception;
}
Modified: sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/UninstallBundleCommand.java
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/UninstallBundleCommand.java?rev=1153861&r1=1153860&r2=1153861&view=diff
==============================================================================
--- sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/UninstallBundleCommand.java (original)
+++ sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/base/impl/bootstrapcommands/UninstallBundleCommand.java Thu Aug 4 12:24:45 2011
@@ -18,17 +18,26 @@
*/
package org.apache.sling.launchpad.base.impl.bootstrapcommands;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
import org.apache.felix.framework.Logger;
import org.apache.felix.framework.util.VersionRange;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
-
-/** A Command that uninstalls a bundle, see
- * {@link UninstallBundleCommandTest} for examples
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+/**
+ * A Command that uninstalls a bundle, see
+ * {@link UninstallBundleCommandTest} for examples
*/
class UninstallBundleCommand implements Command {
- public static String CMD_PREFIX = "uninstall ";
+ private static String CMD_PREFIX = "uninstall ";
private final String bundleSymbolicName;
private final VersionRange versionRange;
@@ -38,24 +47,64 @@ class UninstallBundleCommand implements
versionRange = null;
}
- /** Used to create an actual command */
- private UninstallBundleCommand(String bundleSymbolicName, String versionRangeStr) {
+ /**
+ * Used to create an uninstall command with symbolic name and version range
+ */
+ private UninstallBundleCommand(final String bundleSymbolicName, String versionRangeStr) {
this.bundleSymbolicName = bundleSymbolicName;
// If versionRangeStr is not a range, make it strict
- if(!versionRangeStr.contains(",")) {
+ if (!versionRangeStr.contains(",")) {
versionRangeStr = "[" + versionRangeStr + "," + versionRangeStr + "]";
}
this.versionRange = VersionRange.parse(versionRangeStr);
}
- public void execute(Logger logger, BundleContext ctx) throws Exception {
+ /**
+ * Used to create an uninstall command with symbolic name
+ */
+ private UninstallBundleCommand(String bundleSymbolicName) {
+ this.bundleSymbolicName = bundleSymbolicName;
+ this.versionRange = null;
+ }
+
+ /**
+ * Gets the bundle's Fragment-Host header.
+ */
+ private static String getFragmentHostHeader(final Bundle b) {
+ return (String) b.getHeaders().get( Constants.FRAGMENT_HOST );
+ }
+
+ private boolean isSystemBundleFragment(final Bundle installedBundle) {
+ final String fragmentHeader = (String) installedBundle.getHeaders().get(
+ Constants.FRAGMENT_HOST);
+ return fragmentHeader != null
+ && fragmentHeader.indexOf(Constants.EXTENSION_DIRECTIVE) > 0;
+ }
+
+ /**
+ * @see org.apache.sling.launchpad.base.impl.bootstrapcommands.Command#execute(org.apache.felix.framework.Logger, org.osgi.framework.BundleContext)
+ */
+ public boolean execute(final Logger logger, final BundleContext ctx) throws Exception {
+ final Set<String> refreshBundles = new HashSet<String>();
// Uninstall all instances of our bundle within our version range
- for(Bundle b : ctx.getBundles()) {
- if(b.getSymbolicName().equals(bundleSymbolicName)) {
- if(versionRange.isInRange(b.getVersion())) {
+ boolean refreshSystemBundle = false;
+ for(final Bundle b : ctx.getBundles()) {
+ if (b.getSymbolicName().equals(bundleSymbolicName)) {
+ if (versionRange == null || versionRange.isInRange(b.getVersion())) {
logger.log(Logger.LOG_INFO,
this + ": uninstalling bundle version " + b.getVersion());
+ final String fragmentHostHeader = getFragmentHostHeader(b);
+ if (fragmentHostHeader != null) {
+ if ( isSystemBundleFragment(b) ) {
+ logger.log(Logger.LOG_INFO, this + ": Need to do a system bundle refresh");
+ refreshSystemBundle = true;
+ } else {
+ logger.log(Logger.LOG_INFO, this + ": Need to do a refresh of the bundle's host: " + fragmentHostHeader);
+ refreshBundles.add(fragmentHostHeader);
+ }
+ }
+
b.uninstall();
} else {
logger.log(Logger.LOG_INFO,
@@ -63,13 +112,38 @@ class UninstallBundleCommand implements
}
}
}
+ if ( refreshBundles.size() > 0 ) {
+ final List<Bundle> bundles = new ArrayList<Bundle>();
+ for(final Bundle b : ctx.getBundles() ) {
+ if ( refreshBundles.contains(b.getSymbolicName()) ) {
+ logger.log(Logger.LOG_INFO, this + ": Found host bundle to refresh " + b.getBundleId());
+ bundles.add(b);
+ }
+ }
+ if ( bundles.size() > 0 ) {
+ final ServiceReference paRef = ctx.getServiceReference(PackageAdmin.class.getName());
+ if ( paRef != null ) {
+ try {
+ final PackageAdmin pa = (PackageAdmin)ctx.getService(paRef);
+ if ( pa != null ) {
+ pa.refreshPackages(bundles.toArray(new Bundle[bundles.size()]));
+ }
+ } finally {
+ ctx.ungetService(paRef);
+ }
+ }
+ }
+ }
+ return refreshSystemBundle;
}
public Command parse(String commandLine) throws ParseException {
if(commandLine.startsWith(CMD_PREFIX)) {
final String [] s = commandLine.split(" ");
- if(s.length == 3) {
+ if (s.length == 3) {
return new UninstallBundleCommand(s[1].trim(), s[2].trim());
+ } else if ( s.length == 2 ) {
+ return new UninstallBundleCommand(s[1].trim());
}
throw new Command.ParseException("Syntax error: '" + commandLine + "'");
}
@@ -78,6 +152,6 @@ class UninstallBundleCommand implements
@Override
public String toString() {
- return getClass().getSimpleName() + " " + bundleSymbolicName + " " + versionRange;
+ return getClass().getSimpleName() + " " + bundleSymbolicName + " " + (versionRange != null ? versionRange : "");
}
}
\ No newline at end of file