package org.jenkinsci.plugins.activemq; import hudson.Extension; import hudson.model.AbstractProject; import hudson.model.BooleanParameterValue; import hudson.model.BuildableItem; import hudson.model.Item; import hudson.model.ParameterValue; import hudson.model.StringParameterValue; import hudson.triggers.Trigger; import hudson.triggers.TriggerDescriptor; import hudson.util.FormValidation; import jenkins.model.Jenkins; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; import org.slf4j.Logger; import javax.script.Invocable; import javax.script.ScriptEngine; import javax.script.ScriptException; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.TreeMap; import static java.lang.Boolean.TRUE; import static java.util.Collections.singletonMap; import static org.apache.commons.lang.StringUtils.trimToEmpty; import static org.apache.commons.lang.StringUtils.trimToNull; import static org.jenkinsci.plugins.activemq.ActiveMqClient.BuildRequest; import static org.slf4j.LoggerFactory.getLogger; public class ActiveMqBuildTrigger extends Trigger { private static final Logger log = getLogger(ActiveMqBuildTrigger.class); public static final String FUNCTION_NAME = "match"; private String expression; private transient ActiveMqPlugin plugin; private transient ScriptEngine engine; @DataBoundConstructor public ActiveMqBuildTrigger(String expression) { log.info("ActiveMqBuildTrigger.ActiveMqBuildTrigger"); log.info("expression = " + expression); this.expression = expression; } @Override public void start(AbstractProject project, boolean newInstance) { super.start(project, newInstance); plugin = Jenkins.getInstance().getPlugin(ActiveMqPlugin.class); log.info("ActiveMqBuildTrigger.start"); compileExpression(); } public String getExpression() { log.info("ActiveMqBuildTrigger.getExpression"); return expression; } public void setExpression(String expression) { this.expression = expression; } private void compileExpression() { log.info("ActiveMqBuildTrigger.compileExpression: expression={}", expression); if (expression == null) { return; } try { engine = plugin.createEngine(); engine.eval(expression); if (!checkEngine(engine)) { log.warn("Invalid expression: {}", expression); } } catch (Exception e) { log.warn("Unable to compile expression", e); } } public DoBuildResponse matches(BuildRequest req) { if (engine == null) { return new DoBuildResponse.NoBuild(); } Map parameters = new TreeMap(req.parameters); Map> context = singletonMap("parameters", parameters); try { Object o = ((Invocable) engine).invokeFunction(FUNCTION_NAME, parameters); log.info("o = " + o); if (o != null) { log.info("o.getClass() = " + o.getClass()); } if (o instanceof Boolean) { Boolean b = (Boolean) o; if (b) { return new DoBuildResponse.Build(); } } else if (o instanceof Map) { Map map = (Map) o; List buildParameters = new ArrayList(); for (Map.Entry e : map.entrySet()) { Object key = e.getKey(); if (key == null || !(key instanceof String)) { continue; } String k = trimToNull(key.toString()); if (k == null) { continue; } Object value = e.getValue(); if (value instanceof Boolean) { Boolean b = (Boolean) value; buildParameters.add(new BooleanParameterValue(k, b)); } else if (value instanceof String) { String v = trimToEmpty(value.toString()); buildParameters.add(new StringParameterValue(k, v)); } } return new DoBuildResponse.BuildWithParameters(buildParameters); } return new DoBuildResponse.NoBuild(); } catch (Exception e) { log.warn("Could not evaluate expression:"); log.warn(expression); log.warn("Context:"); for (Map.Entry> entry : context.entrySet()) { log.warn("{} = {}", entry.getKey(), entry.getValue()); } log.warn("Exception", e); return new DoBuildResponse.NoBuild(); } } @Extension public static class DescriptorImpl extends TriggerDescriptor { @Override public boolean isApplicable(Item item) { return item instanceof BuildableItem; } @Override public String getDisplayName() { return "ActiveMQ Trigger"; } public FormValidation doCheckExpression(@QueryParameter String expression) { log.info("ActiveMqBuildTrigger.doCheckExpression"); expression = trimToNull(expression); if (expression == null) { return FormValidation.ok(); } try { ActiveMqPlugin plugin = Jenkins.getInstance().getPlugin(ActiveMqPlugin.class); ScriptEngine engine = plugin.createEngine(); engine.eval(expression); if (checkEngine(engine)) { return FormValidation.ok(); } return FormValidation.warning("The expression must define a function named '" + FUNCTION_NAME + "'"); } catch (ScriptException e) { return FormValidation.error("Could not evaluate expression: " + e.getMessage()); } catch (Exception e) { return FormValidation.error(e, "Could not evaluate expression"); } } } private static boolean checkEngine(ScriptEngine engine) throws ScriptException { Object o = engine.eval("typeof " + FUNCTION_NAME + " === 'function'"); return TRUE.equals(o); } }