Activator.java 6.28 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.day.cq.compat.codeupgrade.CodeUpgradeTask
 *  javax.jcr.Item
 *  javax.jcr.Property
 *  javax.jcr.Session
 *  org.apache.sling.jcr.api.SlingRepository
 *  org.apache.sling.launchpad.api.StartupHandler
 *  org.apache.sling.launchpad.api.StartupMode
 *  org.apache.sling.startupfilter.StartupInfoProvider
 *  org.osgi.framework.BundleActivator
 *  org.osgi.framework.BundleContext
 *  org.osgi.framework.InvalidSyntaxException
 *  org.osgi.framework.ServiceReference
 *  org.osgi.framework.ServiceRegistration
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.cq.upgradesexecutor;

import com.day.cq.compat.codeupgrade.CodeUpgradeTask;
import org.apache.sling.jcr.api.SlingRepository;
import org.apache.sling.launchpad.api.StartupHandler;
import org.apache.sling.launchpad.api.StartupMode;
import org.apache.sling.startupfilter.StartupInfoProvider;
import org.osgi.framework.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.jcr.Item;
import javax.jcr.Session;
import java.util.ArrayList;
import java.util.Arrays;

public class Activator
implements BundleActivator {
    private final Logger log;
    public static final String FORCE_UPGRADES_PATH = "/var/upgrade/status/upgradesExecutor.forceUpgrades";

    public Activator() {
        this.log = LoggerFactory.getLogger(this.getClass());
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    public void start(BundleContext context) throws Exception {
        ServiceReference ref = context.getServiceReference(StartupHandler.class.getName());
        if (ref == null) {
            throw new IllegalStateException("StartupHandler not found, cannot decide whether to run upgrade code or not");
        }
        StartupHandler sh = (StartupHandler)context.getService(ref);
        StartupMode sm = sh.getMode();
        if (sm != StartupMode.UPDATE) {
            boolean force;
            force = false;
            ServiceReference repoRef = context.getServiceReference(SlingRepository.class.getName());
            if (repoRef != null) {
                SlingRepository repo = (SlingRepository)context.getService(repoRef);
                Session s = repo.loginAdministrative(repo.getDefaultWorkspace());
                try {
                    Item it;
                    if (s.itemExists("/var/upgrade/status/upgradesExecutor.forceUpgrades") && !(it = s.getItem("/var/upgrade/status/upgradesExecutor.forceUpgrades")).isNode()) {
                        force = s.getProperty("/var/upgrade/status/upgradesExecutor.forceUpgrades").getBoolean();
                        this.log.warn("{}=true will force upgrade code to run every time this bundle is started -  if this is not desired, remove that property", (Object)"/var/upgrade/status/upgradesExecutor.forceUpgrades");
                    }
                }
                finally {
                    s.logout();
                }
            }
            if (force) {
                this.log.info("StartupMode is {} but {} is true, executing upgrade tasks", (Object)sm, (Object)"/var/upgrade/status/upgradesExecutor.forceUpgrades");
            } else {
                this.log.info("UPGRADE NOT NEEDED - StartupMode is {}", (Object)sm);
                return;
            }
        }
        this.log.info("UPGRADE STARTS - StartupMode is {}", (Object)sm);
        InfoProvider ip = new InfoProvider();
        ServiceRegistration reg = null;
        try {
            reg = context.registerService(StartupInfoProvider.class.getName(), (Object)ip, null);
            this.runUpgradeTasks(context, ip);
        }
        finally {
            reg.unregister();
        }
    }

    public void stop(BundleContext context) throws Exception {
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    private void runUpgradeTasks(BundleContext context, InfoProvider ip) throws InvalidSyntaxException {
        ip.say("Collecting CodeUpgradeTasks");
        Object[] refs = context.getServiceReferences(CodeUpgradeTask.class.getName(), null);
        if (refs == null || refs.length < 1) {
            this.log.info("NO UPGRADE TASKS - no {} services found, nothing to do", (Object)CodeUpgradeTask.class.getName());
            return;
        }
        Arrays.sort(refs);
        ArrayList<CodeUpgradeTask> tasks = new ArrayList<CodeUpgradeTask>();
        for (Object ref : refs) {
            tasks.add((CodeUpgradeTask)context.getService((ServiceReference)ref));
        }
        long startTime = System.currentTimeMillis();
        ip.say("Checking " + refs.length + " candidate CodeUpgradeTasks: " + tasks);
        int executed = 0;
        for (CodeUpgradeTask t : tasks) {
            if (t.upgradeNeeded()) {
                try {
                    ip.say("UPGRADE TASK STARTING: " + (Object)t);
                    ip.setTask(t);
                    t.run();
                    ip.setTask(null);
                    ip.say("UPGRADE TASK DONE: " + (Object)t);
                    ++executed;
                    continue;
                }
                finally {
                    ip.setTask(null);
                    continue;
                }
            }
            ip.say("UPGRADE TASK SKIPPED: " + (Object)t);
        }
        long elapsed = System.currentTimeMillis() - startTime;
        this.log.info("UPGRADE FINISHED: {} CodeUpgradeTasks executed (out of {}), total time about {} seconds", new Object[]{executed, refs.length, elapsed / 1000});
    }

    class InfoProvider
    implements StartupInfoProvider {
        private String progressInfo;
        private volatile CodeUpgradeTask task;

        InfoProvider() {
            this.progressInfo = "Initializing";
        }

        public String getProgressInfo() {
            if (this.task != null) {
                String info = this.task.getProgressInfo();
                if (info == null) {
                    info = "No info yet";
                }
                return "Running " + (Object)this.task + ": " + info;
            }
            return this.progressInfo;
        }

        void say(String info) {
            Activator.this.log.info(info);
            this.progressInfo = info;
        }

        void setTask(CodeUpgradeTask t) {
            this.task = t;
        }
    }

}