in src/main/java/org/apache/sling/installer/core/impl/tasks/BundleUpdateTask.java [67:158]
public void execute(final InstallationContext ctx) {
final String symbolicName = (String)getResource().getAttribute(Constants.BUNDLE_SYMBOLICNAME);
final Bundle b = BundleInfo.getMatchingBundle(this.getBundleContext(), symbolicName, null);
if (b == null) {
String message = MessageFormat.format("Bundle to update ({0}) not found", symbolicName);
this.getLogger().debug(message);
this.setFinishedState(ResourceState.IGNORED, null, message);
return;
}
final Version newVersion = new Version((String)getResource().getAttribute(Constants.BUNDLE_VERSION));
// Do not update if same version, unless snapshot
boolean snapshot = false;
final Version currentVersion = b.getVersion();
snapshot = BundleInfo.isSnapshot(newVersion);
if (currentVersion.equals(newVersion) && !snapshot) {
// TODO : Isn't this already checked in the task creator?
String message = MessageFormat.format("Same version is already installed, and not a snapshot, ignoring update: {0}", getResource());
this.getLogger().debug(message);
this.setFinishedState(ResourceState.INSTALLED, null, message);
return;
}
try {
// If the bundle is active before the update - restart it once updated, but
// in sequence, not right now
final boolean reactivate = this.isBundleActive(b);
// if this is not a fragment, stop the bundle
final int state = b.getState();
if (state == Bundle.ACTIVE || state == Bundle.STARTING) {
b.stop();
}
// update bundle
b.update(getResource().getInputStream());
ctx.log("Updated bundle {} from resource {}", b, getResource());
setBundleLocation(getResource(), b.getLocation());
// start level handling - after update to avoid starting the bundle
// just before the update
final BundleStartLevel startLevelService = b.adapt(BundleStartLevel.class);
final int newStartLevel = this.getBundleStartLevel();
final int oldStartLevel = startLevelService.getStartLevel();
if ( newStartLevel != oldStartLevel && newStartLevel != 0 ) {
startLevelService.setStartLevel(newStartLevel);
ctx.log("Set start level for bundle {} to {}", b, newStartLevel);
}
if (reactivate) {
if ( BundleUtil.isSystemBundleFragment(b) ) {
this.setFinishedState(ResourceState.INSTALLED);
ctx.addTaskToCurrentCycle(new SystemBundleUpdateTask(null, this.getTaskSupport()));
} else if ( BundleUtil.getFragmentHostHeader(b) != null ) {
// if this is a fragment, we're done after a refresh of the host
final String fragmentHostHeader = BundleUtil.getFragmentHostHeader(b);
this.getLogger().debug("Need to do a refresh of the bundle's {} host", b);
for (final Bundle bundle : this.getBundleContext().getBundles()) {
if (fragmentHostHeader.equals(bundle.getSymbolicName())) {
this.getLogger().debug("Found host bundle for {} to refresh: {}", b, bundle);
RefreshBundlesTask.markBundleForRefresh(ctx, this.getTaskSupport(), bundle);
break;
}
}
this.setFinishedState(ResourceState.INSTALLED);
} else {
BundleUtil.markBundleStart(this.getResource());
RefreshBundlesTask.markBundleForRefresh(ctx, this.getTaskSupport(), b);
ctx.addTaskToCurrentCycle(new BundleStartTask(this.getResourceGroup(), b.getBundleId(), this.getTaskSupport()));
}
} else {
this.setFinishedState(ResourceState.INSTALLED);
}
} catch (final Exception e) {
int retries = 0;
Object obj = getResource().getTemporaryAttribute(ATTR_UPDATE_RETRY);
if (obj instanceof Integer) {
retries = (Integer) obj;
}
getResource().setTemporaryAttribute(ATTR_UPDATE_RETRY, Integer.valueOf(++retries));
if (retries > MAX_RETRIES) {
String message = MessageFormat.format("Removing failing update task due to {0} - unable to retry: {1}",
e.getLocalizedMessage(), this);
this.getLogger().error(message, e);
this.setFinishedState(ResourceState.IGNORED, null, message);
} else {
String message = MessageFormat.format("Failing update task due to {0} - will retry up to {1} more time(s) for {2} later",
e.getLocalizedMessage(), MAX_RETRIES - (retries - 1) , this);
this.getLogger().warn(message, e);
}
}
}