/** * Copyright 2010 JBoss Inc * * 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.drools.jpdl.instance.node; import java.util.Date; import java.util.List; import java.util.Map; import org.drools.jpdl.instance.node.JpdlNodeInstance.JpdlExecutionContext; import org.drools.process.core.context.swimlane.SwimlaneContext; import org.drools.process.core.context.variable.VariableScope; import org.drools.process.instance.WorkItem; import org.drools.process.instance.context.swimlane.SwimlaneContextInstance; import org.drools.process.instance.context.variable.VariableScopeInstance; import org.drools.process.instance.impl.WorkItemImpl; import org.jbpm.JbpmException; import org.jbpm.calendar.BusinessCalendar; import org.jbpm.calendar.Duration; import org.jbpm.context.def.VariableAccess; import org.jbpm.graph.def.Event; import org.jbpm.instantiation.Delegation; import org.jbpm.jpdl.el.impl.JbpmExpressionEvaluator; import org.jbpm.taskmgmt.def.Task; import org.jbpm.taskmgmt.def.TaskController; public final class TaskUtils { private TaskUtils() { } public static WorkItem createWorkItem(Task task, JpdlNodeInstance nodeInstance) { WorkItemImpl workItem = new WorkItemImpl(); workItem.setName("JpdlTask"); workItem.setProcessInstanceId(nodeInstance.getProcessInstance().getId()); workItem.setParameter("name", task.getName()); String description = task.getDescription(); workItem.setParameter("signalling", task.isSignalling()); workItem.setParameter("blocking", task.isBlocking()); if ((description != null) && (description.indexOf("#{") != -1)) { Object result = JbpmExpressionEvaluator.evaluate( description, nodeInstance.new JpdlExecutionContext()); if (result != null) { description = result.toString(); } } workItem.setParameter("Description", description); initializeVariables(workItem, task, nodeInstance); if (task.getDueDate() != null) { BusinessCalendar businessCalendar = new BusinessCalendar(); workItem.setParameter("dueDate", businessCalendar.add(new Date(), new Duration(task.getDueDate()))); } if (task.getSwimlane() != null) { String swimlaneName = task.getSwimlane().getName(); SwimlaneContextInstance swimlaneContextInstance = (SwimlaneContextInstance) nodeInstance.resolveContextInstance(SwimlaneContext.SWIMLANE_SCOPE, swimlaneName); String actorId = swimlaneContextInstance.getActorId(swimlaneName); if (actorId == null) { actorId = assignTask(task, nodeInstance); } workItem.setParameter("ActorId", actorId); } Event event = task.getEvent(Event.EVENTTYPE_TASK_CREATE); if (event != null) { // TODO this doesn't take event handlers of task itself // into account JpdlExecutionContext context = nodeInstance.new JpdlExecutionContext(); context.setTask(task); nodeInstance.executeActions(event.getActions(), context); } return workItem; } private static void initializeVariables(WorkItemImpl workItem, Task task, JpdlNodeInstance nodeInstance) { TaskController taskController = task.getTaskController(); if (taskController != null) { Delegation taskControllerDelegation = taskController.getTaskControllerDelegation(); if (taskControllerDelegation != null) { // TODO: delegation (API mismatch!) } else { List<VariableAccess> variableAccesses = taskController.getVariableAccesses(); if (variableAccesses != null) { for (VariableAccess variableAccess: variableAccesses) { String mappedName = variableAccess.getMappedName(); if (variableAccess.isReadable()) { String variableName = variableAccess.getVariableName(); VariableScopeInstance variableScopeInstance = (VariableScopeInstance) nodeInstance.resolveContextInstance(VariableScope.VARIABLE_SCOPE, variableName); Object value = variableScopeInstance.getVariable(variableName); workItem.setParameter(mappedName, value); } } } } } } private static String assignTask(Task task, JpdlNodeInstance nodeInstance) { Event event = task.getEvent(Event.EVENTTYPE_TASK_ASSIGN); if (event != null) { JpdlExecutionContext context = nodeInstance.new JpdlExecutionContext(); context.setTask(task); nodeInstance.executeActions(event.getActions(), context); } if (task.getActorIdExpression() != null) { return resolveActor(task.getActorIdExpression(), nodeInstance); } else if (task.getSwimlane().getActorIdExpression() != null) { return resolveActor(task.getSwimlane().getActorIdExpression(), nodeInstance); } // TODO support other assignment types return null; } private static String resolveActor(String expression, JpdlNodeInstance nodeInstance) { Object result = JbpmExpressionEvaluator.evaluate(expression, nodeInstance.new JpdlExecutionContext()); if (result == null) { throw new JbpmException("actor-id expression '" + expression + "' returned null"); } if (result instanceof String) { return (String) result; } else { throw new JbpmException( "actor-id expression '" + expression + "' didn't resolve to a java.lang.String: '" + result + "' (" + result.getClass().getName() + ")"); } } public static void restoreVariables(WorkItemImpl workItem, Task task, JpdlNodeInstance nodeInstance) { TaskController taskController = task.getTaskController(); if (taskController != null) { Delegation taskControllerDelegation = taskController.getTaskControllerDelegation(); if (taskControllerDelegation != null) { // TODO: delegation (API mismatch!) } else { List<VariableAccess> variableAccesses = taskController.getVariableAccesses(); if (variableAccesses != null) { String missingTaskVariables = null; for (VariableAccess variableAccess: variableAccesses) { String mappedName = variableAccess.getMappedName(); Object value = workItem.getParameter(mappedName); if (variableAccess.isRequired() && (value != null)) { if (missingTaskVariables == null) { missingTaskVariables = mappedName; } else { missingTaskVariables += ", "+mappedName; } } } if (missingTaskVariables != null) { throw new IllegalArgumentException( "missing task variables: " + missingTaskVariables); } for (VariableAccess variableAccess: variableAccesses) { String mappedName = variableAccess.getMappedName(); String variableName = variableAccess.getVariableName(); if (variableAccess.isWritable()) { Object value = workItem.getParameter(mappedName); if (value != null) { VariableScopeInstance variableScopeInstance = (VariableScopeInstance) nodeInstance.resolveContextInstance(VariableScope.VARIABLE_SCOPE, variableName); variableScopeInstance.setVariable(variableName, value); } } } } } } else { // the default behaviour is that all task-local variables are flushed to the process VariableScopeInstance variableScopeInstance = (VariableScopeInstance) nodeInstance.getProcessInstance().getContextInstance(VariableScope.VARIABLE_SCOPE); for (Map.Entry<String, Object> entry: workItem.getResults().entrySet()) { variableScopeInstance.setVariable(entry.getKey(), entry.getValue()); } } } }