/**
*
*/
package hudson.drools;
import hudson.model.AbstractProject;
import hudson.model.Action;
import hudson.model.Hudson;
import hudson.model.Job;
import hudson.model.ParameterValue;
import hudson.model.ParametersAction;
import hudson.model.Result;
import hudson.model.Run;
import java.io.IOException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import org.kohsuke.stapler.HttpResponse;
public class WorkItemAction extends ParametersAction {
private final static Logger logger = Logger.getLogger(WorkItemAction.class
.getName());
private final long workItemId;
private final String projectName;
// backward compatibility
private final long processInstanceId;
private Run<?, ?> run;
private final boolean completeWhenUnstable;
private final boolean completeWhenFailed;
private final String droolsProjectName;
private boolean completed = false;
public WorkItemAction(String droolsProjectName, long workItemId,
long processInstanceId, String projectName,
boolean completeWhenFailed, boolean completeWhenUnstable,
List<ParameterValue> parameters) {
super(parameters);
this.droolsProjectName = droolsProjectName;
this.workItemId = workItemId;
this.processInstanceId = processInstanceId;
this.projectName = projectName;
this.completeWhenUnstable = completeWhenUnstable;
this.completeWhenFailed = completeWhenFailed;
}
public long getWorkItemId() {
return workItemId;
}
public long getProcessInstanceId() {
return processInstanceId;
}
public String getProjectName() {
return projectName;
}
public void scheduleBuild() {
Job project = (Job) Hudson.getInstance().getItem(projectName);
if (project == null) {
throw new IllegalArgumentException("project " + projectName
+ " does not exist (work item " + workItemId + ")");
}
if (project instanceof AbstractProject) {
((AbstractProject) project).scheduleBuild(0, new DroolsCause("Started by workflow"), this);
} else if (project instanceof DroolsProject) {
((DroolsProject) project).scheduleBuild(new DroolsCause("Started by workflow"), this);
} else {
throw new IllegalArgumentException("project " + projectName + " has an unsupported type: " + project.getClass());
}
}
public void buildComplete(Run r) {
run = r;
save();
try {
DroolsProject p = (DroolsProject) Hudson.getInstance().getItem(
droolsProjectName);
p.removePendingWorkItemBuild(this);
} catch (IOException e) {
e.printStackTrace();
}
// TODO add logging when this happens
if (!completeWhenUnstable && r.getResult() == Result.UNSTABLE) {
return;
}
if (!completeWhenFailed
&& r.getResult().isWorseOrEqualTo(Result.FAILURE)) {
return;
}
complete();
}
private void complete() {
DroolsProject p = (DroolsProject) Hudson.getInstance().getItem(
droolsProjectName);
try {
p.run(new CompleteWorkItemCallable(workItemId, run));
completed = true;
save();
} catch (Exception e) {
logger.log(Level.WARNING, "Error while finalizing "
+ run.getDisplayName() + " and completing WorkItem "
+ workItemId, e);
}
}
private void save() {
try {
run.save();
} catch (IOException e) {
logger.log(Level.WARNING, "error while saving run", e);
}
}
public HttpResponse doRestart() throws ServletException, IOException {
if (run != null && run.getResult().isWorseOrEqualTo(Result.UNSTABLE)) {
run.checkPermission(Job.BUILD);
new WorkItemAction(droolsProjectName, workItemId,
processInstanceId, projectName, completeWhenFailed,
completeWhenUnstable, getParameters()).scheduleBuild();
return new ForwardToPreviousPage();
} else {
throw new IllegalArgumentException(
"Cannot restart a build that did not fail.");
}
}
public HttpResponse doComplete() throws ServletException, IOException {
if (run == null) {
throw new IllegalArgumentException(
"Cannot complete before the build is done");
}
run.checkPermission(Job.BUILD);
complete();
return new ForwardToPreviousPage();
}
@Override
public String getDisplayName() {
return "Work Item";
}
@Override
public String getIconFileName() {
return null;
}
@Override
public String getUrlName() {
return "workItem";
}
public Run<?, ?> getRun() {
return run;
}
public boolean isAllowRestart() {
DroolsRun droolsRun = getDroolsRun();
if (droolsRun == null || !droolsRun.isRunning()) {
return false;
}
if (run == null) {
return false;
}
if (run.getResult() == Result.UNSTABLE) {
return !completeWhenUnstable;
}
if (run.getResult().isWorseOrEqualTo(Result.FAILURE)) {
return !completeWhenFailed;
}
return false;
}
public boolean isAllowComplete() {
if (completed) {
return false;
}
DroolsRun droolsRun = getDroolsRun();
if (droolsRun == null || !droolsRun.isRunning()) {
return false;
}
if (run == null) {
return false;
}
return true;
}
public DroolsRun getDroolsRun() {
DroolsProject p = (DroolsProject) Hudson.getInstance().getItem(
droolsProjectName);
return p != null ? p.getFromProcessInstance(processInstanceId) : null;
}
public static Run findRun(Job<?, ?> project, long processInstanceId) {
for (Run run : project.getBuilds()) {
WorkItemAction w = run.getAction(WorkItemAction.class);
if (w != null && w.processInstanceId == processInstanceId) {
return run;
}
}
return null;
}
public String getUrl() {
return getRun().getUrl() + "/workItem";
}
public boolean shouldSchedule(List<Action> actions) {
return true;
}
}