package org.jenkinsci.plugins.parameterizedschedular; import hudson.model.ParameterValue; import hudson.model.AbstractProject; import hudson.model.ParameterDefinition; import hudson.model.ParametersAction; import hudson.model.ParametersDefinitionProperty; import hudson.scheduler.Hash; import hudson.triggers.Trigger; import java.util.ArrayList; import java.util.Calendar; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import org.kohsuke.stapler.DataBoundConstructor; import antlr.ANTLRException; /** * {@link Trigger} that runs a job periodically with support for parameters. * * @author jameswilson * */ @SuppressWarnings("rawtypes") public class ParameterizedTimerTrigger extends Trigger<AbstractProject> { private static final Logger LOGGER = Logger.getLogger(ParameterizedTimerTrigger.class.getName()); private transient ParameterizedCronTabList cronTabList; private final String parameterizedSpecification; @DataBoundConstructor public ParameterizedTimerTrigger(String parameterizedSpecification) throws ANTLRException { this.parameterizedSpecification = parameterizedSpecification; this.cronTabList = ParameterizedCronTabList.create(parameterizedSpecification); } @Override public void run() { LOGGER.fine("tried to run from base Trigger, nothing will happen"); } /** * this method started out as hudson.model.AbstractProject.getDefaultParametersValues() * @param parameterValues * @return the ParameterValues as set from the crontab row or their defaults */ @SuppressWarnings("unchecked") private List<ParameterValue> configurePropertyValues(Map<String, String> parameterValues) { assert job != null : "job must not be null if this was 'started'"; ParametersDefinitionProperty paramDefProp = (ParametersDefinitionProperty) job .getProperty(ParametersDefinitionProperty.class); ArrayList<ParameterValue> defValues = new ArrayList<ParameterValue>(); /* Scan for all parameter with an associated default values */ for (ParameterDefinition paramDefinition : paramDefProp.getParameterDefinitions()) { ParameterValue defaultValue = paramDefinition.getDefaultParameterValue(); if (parameterValues.containsKey(paramDefinition.getName())) { ParameterizedStaplerRequest request = new ParameterizedStaplerRequest( parameterValues.get(paramDefinition.getName())); defValues.add(paramDefinition.createValue(request)); } else if (defaultValue != null) defValues.add(defaultValue); } return defValues; } public void checkCronTabsAndRun(Calendar calendar) { LOGGER.fine("checking and maybe running at " + calendar); ParameterizedCronTab cronTab = cronTabList.check(calendar); if (cronTab != null) { Map<String, String> parameterValues = cronTab.getParameterValues(); ParametersAction parametersAction = new ParametersAction(configurePropertyValues(parameterValues)); assert job != null : "job must not be null, if this was 'started'"; job.scheduleBuild2(0, new ParameterizedTimerTriggerCause(parameterValues), parametersAction); } } @Override public void start(AbstractProject project, boolean newInstance) { this.job = project; try {// reparse the tabs with the job as the hash cronTabList = ParameterizedCronTabList.create(parameterizedSpecification, Hash.from(project.getFullName())); } catch (ANTLRException e) { // this shouldn't fail because we've already parsed stuff in the constructor, // so if it fails, use whatever 'tabs' that we already have. LOGGER.log(Level.FINE, "Failed to parse crontab spec: " + spec, e); } } /** * for the config.jelly to populate * * @return the raw specification */ public String getParameterizedSpecification() { return parameterizedSpecification; } }