package hudson.drools;
import hudson.model.AbstractModelObject;
import hudson.model.BooleanParameterValue;
import hudson.model.Hudson;
import hudson.model.Job;
import hudson.model.ParameterDefinition;
import hudson.model.ParameterValue;
import hudson.model.StringParameterValue;
import hudson.model.User;
import hudson.security.ACL;
import hudson.security.AccessControlled;
import hudson.security.Permission;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.acegisecurity.AccessDeniedException;
import org.kohsuke.stapler.HttpResponse;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.framework.io.IOException2;
public class HumanTask extends AbstractModelObject implements AccessControlled {
private final List<ParameterDefinition> parameterDefinitions = new ArrayList<ParameterDefinition>();
private final String displayName;
private String actorId;
private long workItemId;
private transient DroolsRun run;
private Status status = Status.NEW;
public Status getStatus() {
return status;
}
public enum Status {
NEW, COMPLETED, CANCELED
}
private List<ParameterValue> answers;
private boolean privateTask;
public boolean isPrivateTask() {
return privateTask;
}
public HumanTask(String displayName, boolean privateTask) {
this.displayName = displayName;
this.privateTask = privateTask;
}
public HttpResponse doSubmit(StaplerRequest req, StaplerResponse rsp)
throws IOException, ServletException {
List<ParameterValue> values = new ArrayList<ParameterValue>();
JSONObject formData = req.getSubmittedForm();
JSONArray a = JSONArray.fromObject(formData.get("parameter"));
for (Object o : a) {
JSONObject jo = (JSONObject) o;
String name = jo.getString("name");
ParameterDefinition d = getParameterDefinition(name);
values.add(d.createValue(req, jo));
}
Map<String, Object> results = new HashMap<String, Object>();
for (ParameterValue value : values) {
if (value instanceof StringParameterValue) {
results.put(value.getName(),
((StringParameterValue) value).value);
} else if (value instanceof BooleanParameterValue) {
results.put(value.getName(),
((BooleanParameterValue) value).value);
}
}
PrintWriter log = run.getLogWriter();
log.println("HumanTask " + displayName + " #" + workItemId + " submitted.");
log.println("\tUser: " + Hudson.getAuthentication().getName());
log.println("\tResults: " + results);
try {
run.getParent().run(
new CompleteWorkItemCallable(workItemId, results));
} catch (Exception e) {
throw new IOException2("Error while completing human task #"
+ workItemId, e);
}
this.answers = values;
status = Status.COMPLETED;
run.save();
return new ForwardToPreviousPage();
}
public void cancel() throws IOException {
status = Status.CANCELED;
run.save();
}
private ParameterDefinition getParameterDefinition(String name) {
for (ParameterDefinition pd : parameterDefinitions) {
if (name.equals(pd.getName())) {
return pd;
}
}
throw new IllegalArgumentException("Unknown parameter " + name);
}
public String getDisplayName() {
return displayName;
}
public String getSearchUrl() {
return null;
}
public boolean isCompleted() {
return status == Status.COMPLETED;
}
public boolean isCanceled() {
return status == Status.CANCELED;
}
public boolean isNew() {
return status == Status.NEW;
}
public long getWorkItemId() {
return workItemId;
}
public void setWorkItemId(long workItemId) {
this.workItemId = workItemId;
}
public List<ParameterDefinition> getParameterDefinitions() {
return parameterDefinitions;
}
public List<ParameterValue> getAnswers() {
return answers;
}
public DroolsRun getRun() {
return run;
}
public void setRun(DroolsRun run) {
this.run = run;
}
public String getUrl() {
return run.getUrl() + "scriptExecution/" + workItemId;
}
@Override
public String toString() {
if (answers != null) {
return String.format("HumanTask(%s) parameters: %s answers: %s",
displayName, parameterDefinitions, answers);
} else {
return String.format("HumanTask(%s) parameters: %s", displayName,
parameterDefinitions);
}
}
public String getActorId() {
return actorId;
}
public User getActor() {
return actorId != null ? User.get(actorId, false) : null;
}
public void setActorId(String actorId) {
this.actorId = actorId;
}
public boolean canRead() {
if (privateTask) {
return actorId == null || actorId.equals(User.current().getId());
} else {
return true;
}
}
public boolean canComplete() {
if (status != Status.NEW) {
return false;
}
// TODO should create a real ACL for this
if (actorId != null && User.current() != null) {
return /* hasPermission(Job.CONFIGURE) || */actorId.equals(User
.current().getId());
} else {
return hasPermission(Job.BUILD);
}
}
public void checkPermission(Permission permission)
throws AccessDeniedException {
getACL().checkPermission(permission);
}
public ACL getACL() {
return run.getACL();
}
public boolean hasPermission(Permission permission) {
return getACL().hasPermission(permission);
}
}