ScriptConfigImpl.java 7.38 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  org.apache.felix.scr.annotations.Activate
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.ConfigurationPolicy
 *  org.apache.felix.scr.annotations.Deactivate
 *  org.apache.felix.scr.annotations.Property
 *  org.apache.felix.scr.annotations.Reference
 *  org.apache.jackrabbit.util.Text
 *  org.apache.sling.commons.osgi.OsgiUtil
 *  org.osgi.framework.BundleContext
 *  org.osgi.framework.ServiceRegistration
 *  org.osgi.service.component.ComponentContext
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.granite.monitoring.impl;

import com.adobe.granite.monitoring.impl.ScriptConfig;
import com.adobe.granite.monitoring.impl.ScriptMBean;
import com.adobe.granite.monitoring.impl.ShellScriptExecutor;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.regex.Pattern;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.ConfigurationPolicy;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.jackrabbit.util.Text;
import org.apache.sling.commons.osgi.OsgiUtil;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(policy=ConfigurationPolicy.REQUIRE, label="%monitoring.name", description="%monitoring.description", configurationFactory=1, metatype=1, immediate=1)
public class ScriptConfigImpl {
    private static final Logger log = LoggerFactory.getLogger(ScriptConfigImpl.class);
    @Property
    static final String SCRIPT_FILE_NAME = "script.filename";
    @Property
    static final String SCRIPT_DISPLAY_NAME = "script.display";
    @Property
    static final String SCRIPT_PATH = "script.path";
    @Property(cardinality=Integer.MAX_VALUE)
    static final String PLATFORMS = "script.platform";
    @Property(intValue={0})
    static final String INTERVAL = "interval";
    @Property(value={"com.adobe.granite.monitoring"})
    static final String JMX_DOMAIN = "jmxdomain";
    private int interval = 0;
    private ExecutionThread intervalThread = null;
    private ScriptMBean mbean = null;
    private ServiceRegistration reg = null;
    @Reference
    private ShellScriptExecutor executor = null;

    @Activate
    private void activate(ComponentContext context) throws Exception {
        Dictionary props = context.getProperties();
        final String fileName = OsgiUtil.toString(props.get("script.filename"), (String)null);
        final String scriptPath = OsgiUtil.toString(props.get("script.path"), (String)null);
        String[] platforms = OsgiUtil.toStringArray(props.get("script.platform"));
        if (platforms != null && platforms.length > 0) {
            String os = System.getProperty("os.name").toLowerCase();
            boolean matches = false;
            for (String pf : platforms) {
                if (pf.length() <= 0) continue;
                pf = pf.toLowerCase();
                boolean allow = true;
                if (pf.charAt(0) == '-') {
                    allow = false;
                    pf = pf.substring(1);
                }
                if (!Pattern.matches(pf, os)) continue;
                matches = allow;
            }
            if (!matches) {
                log.info("Script {} not activated due to not-matching platform: {}", (Object)fileName, (Object)os);
                return;
            }
        }
        String domain = OsgiUtil.toString(props.get("jmxdomain"), (String)"com.adobe.granite.monitoring");
        this.interval = OsgiUtil.toInteger(props.get("interval"), (int)0);
        String displayName = OsgiUtil.toString(props.get("script.display"), (String)null);
        if (fileName == null || fileName.length() == 0) {
            log.error("Unable to create script bean. Filename missing.");
            return;
        }
        ScriptConfig cfg = new ScriptConfig(){

            public String getScriptFilename() {
                return fileName;
            }

            public String getScriptPath() {
                return scriptPath;
            }
        };
        if (displayName == null || displayName.length() == 0) {
            displayName = Text.getName((String)fileName);
            if (displayName.toLowerCase().endsWith(".sh")) {
                displayName = displayName.substring(0, displayName.length() - 3);
            } else if (displayName.toLowerCase().endsWith(".bat") || displayName.toLowerCase().endsWith(".exe") || displayName.toLowerCase().endsWith(".com")) {
                displayName = displayName.substring(0, displayName.length() - 4);
            }
        }
        this.mbean = new ScriptMBean(this.executor, cfg);
        Hashtable<String, String> mbeanProps = new Hashtable<String, String>();
        mbeanProps.put("jmx.objectname", domain + ":type=script,id=" + displayName);
        this.reg = context.getBundleContext().registerService("javax.management.DynamicMBean", (Object)this.mbean, mbeanProps);
        log.info("registered MBean for " + displayName);
        if (this.interval > 0) {
            log.info("setting automatic execution of " + displayName + " to " + this.interval + " seconds");
            this.intervalThread = new ExecutionThread(this.mbean, this.interval);
            Thread t = new Thread((Runnable)this.intervalThread, "Shell Script Executor Thread for " + cfg.getScriptFilename());
            t.setDaemon(true);
            t.start();
        }
    }

    @Deactivate
    private void deactivate() {
        if (this.intervalThread != null) {
            this.intervalThread.stopThread();
            this.interval = -1;
            this.intervalThread = null;
        }
        if (this.reg != null) {
            this.reg.unregister();
            this.reg = null;
        }
        this.mbean = null;
    }

    protected void bindExecutor(ShellScriptExecutor shellScriptExecutor) {
        this.executor = shellScriptExecutor;
    }

    protected void unbindExecutor(ShellScriptExecutor shellScriptExecutor) {
        if (this.executor == shellScriptExecutor) {
            this.executor = null;
        }
    }

    private class ExecutionThread
    implements Runnable {
        private volatile boolean running;
        private final ScriptMBean mbean;
        private final int interval;

        private ExecutionThread(ScriptMBean mbean, int interval) {
            this.running = true;
            this.mbean = mbean;
            this.interval = interval;
        }

        public void run() {
            String name = this.mbean.getCfg().getScriptFilename();
            while (this.running) {
                try {
                    log.debug("executing {}", (Object)name);
                    this.mbean.invoke("execute", null, null);
                }
                catch (Exception e) {
                    log.debug("couldn't execute MBean for script {}", (Object)name, (Object)e);
                }
                try {
                    Thread.sleep(this.interval * 1000);
                }
                catch (InterruptedException e) {}
            }
            log.info("interval thread for " + name + " finished");
        }

        public void stopThread() {
            this.running = false;
        }
    }

}