/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.activiti.rest.service.api.runtime.task;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.ActivitiIllegalArgumentException;
import org.activiti.engine.task.Task;
import org.activiti.rest.exception.ActivitiForbiddenException;
import org.activiti.rest.service.api.engine.variable.RestVariable;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Frederik Heremans
*/
@RestController
public class TaskResource extends TaskBaseResource {
@RequestMapping(value="/runtime/tasks/{taskId}", method = RequestMethod.GET, produces="application/json")
public TaskResponse getTask(@PathVariable String taskId, HttpServletRequest request) {
return restResponseFactory.createTaskResponse(getTaskFromRequest(taskId));
}
@RequestMapping(value="/runtime/tasks/{taskId}", method = RequestMethod.PUT, produces="application/json")
public TaskResponse updateTask(@PathVariable String taskId,
@RequestBody TaskRequest taskRequest, HttpServletRequest request) {
if (taskRequest == null) {
throw new ActivitiException("A request body was expected when updating the task.");
}
Task task = getTaskFromRequest(taskId);
// Populate the task properties based on the request
populateTaskFromRequest(task, taskRequest);
// Save the task and fetch agian, it's possible that an assignment-listener has updated
// fields after it was saved so we can't use the in-memory task
taskService.saveTask(task);
task = taskService.createTaskQuery().taskId(task.getId()).singleResult();
return restResponseFactory.createTaskResponse(task);
}
@RequestMapping(value="/runtime/tasks/{taskId}", method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
public void executeTaskAction(@PathVariable String taskId, @RequestBody TaskActionRequest actionRequest) {
if (actionRequest == null) {
throw new ActivitiException("A request body was expected when executing a task action.");
}
Task task = getTaskFromRequest(taskId);
if (TaskActionRequest.ACTION_COMPLETE.equals(actionRequest.getAction())) {
completeTask(task, actionRequest);
} else if (TaskActionRequest.ACTION_CLAIM.equals(actionRequest.getAction())) {
claimTask(task, actionRequest);
} else if (TaskActionRequest.ACTION_DELEGATE.equals(actionRequest.getAction())) {
delegateTask(task, actionRequest);
} else if (TaskActionRequest.ACTION_RESOLVE.equals(actionRequest.getAction())) {
resolveTask(task, actionRequest);
} else {
throw new ActivitiIllegalArgumentException("Invalid action: '" + actionRequest.getAction() + "'.");
}
}
@RequestMapping(value="/runtime/tasks/{taskId}", method = RequestMethod.DELETE)
public void deleteTask(@PathVariable String taskId, @RequestParam(value="cascadeHistory", required=false) Boolean cascadeHistory,
@RequestParam(value="deleteReason", required=false) String deleteReason, HttpServletResponse response) {
Task taskToDelete = getTaskFromRequest(taskId);
if (taskToDelete.getExecutionId() != null) {
// Can't delete a task that is part of a process instance
throw new ActivitiForbiddenException("Cannot delete a task that is part of a process-instance.");
}
if (cascadeHistory != null) {
// Ignore delete-reason since the task-history (where the reason is recorded) will be deleted anyway
taskService.deleteTask(taskToDelete.getId(), cascadeHistory);
} else {
// Delete with delete-reason
taskService.deleteTask(taskToDelete.getId(), deleteReason);
}
response.setStatus(HttpStatus.NO_CONTENT.value());
}
protected void completeTask(Task task, TaskActionRequest actionRequest) {
if(actionRequest.getVariables() != null) {
Map<String, Object> variablesToSet = new HashMap<String, Object>();
for(RestVariable var : actionRequest.getVariables()) {
if(var.getName() == null) {
throw new ActivitiIllegalArgumentException("Variable name is required");
}
Object actualVariableValue = restResponseFactory.getVariableValue(var);
variablesToSet.put(var.getName(), actualVariableValue);
}
taskService.complete(task.getId(), variablesToSet);
} else {
taskService.complete(task.getId());
}
}
protected void resolveTask(Task task, TaskActionRequest actionRequest) {
taskService.resolveTask(task.getId());
}
protected void delegateTask(Task task, TaskActionRequest actionRequest) {
if (actionRequest.getAssignee() == null) {
throw new ActivitiIllegalArgumentException("An assignee is required when delegating a task.");
}
taskService.delegateTask(task.getId(), actionRequest.getAssignee());
}
protected void claimTask(Task task, TaskActionRequest actionRequest) {
// In case the task is already claimed, a ActivitiTaskAlreadyClaimedException is thrown and converted to
// a CONFLICT response by the ExceptionHandlerAdvice
taskService.claim(task.getId(), actionRequest.getAssignee());
}
}