/*
* Created on Apr 22, 2007
*/
package hudson.plugins.im.bot;
import hudson.model.AbstractProject;
import hudson.model.BooleanParameterValue;
import hudson.model.Cause;
import hudson.model.ParameterValue;
import hudson.model.ParametersAction;
import hudson.model.Queue;
import hudson.model.StringParameterValue;
import hudson.plugins.im.IMCause;
import hudson.plugins.im.Sender;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Build command for the instant messaging bot.
*
* @author Pascal Bleser
* @author kutzi
*/
public class BuildCommand extends AbstractTextSendingCommand {
private static final Pattern NUMERIC_EXTRACTION_REGEX = Pattern.compile("^(\\d+)");
private static final String SYNTAX = " <job> [now|<delay>[s|m|h]] [<parameterkey>=<value>]*";
private static final String HELP = SYNTAX + " - schedule a job build, with standard, custom or no quiet period";
private final String imId;
/**
*
* @param imId An identifier describing the Im account used to send the build command.
* E.g. the Jabber ID of the Bot.
*/
public BuildCommand(final String imId) {
this.imId = imId;
}
private boolean scheduleBuild(AbstractProject<?, ?> project, int delaySeconds, Sender sender, List<ParameterValue> parameters) {
String senderId = sender.getId();
if (senderId == null) {
senderId = sender.getNickname();
}
Cause cause = new IMCause("Started by " + this.imId + " on request of '" + senderId + "'");
if (parameters.isEmpty()) {
return project.scheduleBuild(delaySeconds, cause);
} else {
return project.scheduleBuild(delaySeconds, cause, new ParametersAction(parameters));
}
}
@Override
public String getReply(Sender sender, String args[]) {
if (args.length >= 2) {
String jobName = args[1];
jobName = jobName.replaceAll("\"", "");
AbstractProject<?, ?> project = getJobProvider().getJobByName(jobName);
if (project != null) {
String msg = "";
if (project.isInQueue()) {
Queue.Item queueItem = project.getQueueItem();
return sender.getNickname() + ": job " + jobName + " is already in the build queue (" + queueItem.getWhy() + ")";
} else if (project.isDisabled()) {
return sender.getNickname() + ": job " + jobName + " is disabled";
} else {
int delay = project.getQuietPeriod();
List<ParameterValue> parameters = new ArrayList<ParameterValue>();
if (args.length >= 3) {
int parametersStartIndex = 2;
if (!args[2].contains("=")) { // otherwise looks like a parameter
parametersStartIndex = 3;
String delayStr = args[2].trim();
if ("now".equalsIgnoreCase(delayStr)) {
delay = 0;
} else {
int multiplicator = 1;
if (delayStr.endsWith("m") || delayStr.endsWith("min")) {
multiplicator = 60;
} else if (delayStr.endsWith("h")) {
multiplicator = 3600;
} else {
char c = delayStr.charAt(delayStr.length() - 1);
if (! (c == 's' || Character.isDigit(c))) {
return giveSyntax(sender.getNickname(), args[0]);
}
}
Matcher matcher = NUMERIC_EXTRACTION_REGEX.matcher(delayStr);
if (matcher.find()) {
int value = Integer.parseInt(matcher.group(1));
delay = multiplicator * value;
} else {
return giveSyntax(sender.getNickname(), args[0]);
}
}
}
// parse possible parameters:
for (int i=parametersStartIndex; i < args.length; i++) {
String[] split = args[i].split("=");
// TODO: guess ParameterValue type from ParametersDefintion of job?
if (split.length == 2) {
String value = split[1];
if ("true".equals(value) || "false".equals(value)) {
parameters.add(new BooleanParameterValue(split[0], Boolean.parseBoolean(split[1])));
} else {
parameters.add(new StringParameterValue(split[0], split[1]));
}
} else {
msg += "Unparseable parameter: " + args[i];
}
}
}
if (!parameters.isEmpty() && !project.isParameterized()) {
msg += "Ignoring parameters as project is not parametrized!\n";
}
if (scheduleBuild(project, delay, sender, parameters)) {
if (delay == 0) {
return msg + sender.getNickname() + ": job " + jobName + " build scheduled now";
} else {
return msg + sender.getNickname() + ": job " + jobName + " build scheduled with a quiet period of " +
delay + " seconds";
}
} else {
return sender.getNickname() + ": job " + jobName + " scheduling failed or already in build queue";
}
}
} else {
return giveSyntax(sender.getNickname(), args[0]);
}
} else {
return sender.getNickname() + ": Error, syntax is: '" + args[0] + SYNTAX + "'";
}
}
private String giveSyntax(String sender, String cmd) {
return sender + ": syntax is: '" + cmd + SYNTAX + "'";
}
public String getHelp() {
return HELP;
}
}