public void execute()

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);
            }
        }
    }