/*
|
* JBoss, Home of Professional Open Source
|
* Copyright 2005, JBoss Inc., and individual contributors as indicated
|
* by the @authors tag. See the copyright.txt in the distribution for a
|
* full listing of individual contributors.
|
*
|
* This is free software; you can redistribute it and/or modify it
|
* under the terms of the GNU Lesser General Public License as
|
* published by the Free Software Foundation; either version 2.1 of
|
* the License, or (at your option) any later version.
|
*
|
* This software is distributed in the hope that it will be useful,
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* Lesser General Public License for more details.
|
*
|
* You should have received a copy of the GNU Lesser General Public
|
* License along with this software; if not, write to the Free
|
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
*/
|
package org.jbpm.jpdl.internal.activity;
|
|
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.Method;
|
import java.util.Collection;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.Set;
|
|
import org.apache.commons.collections.map.ListOrderedMap;
|
import org.jbpm.api.JbpmException;
|
import org.jbpm.api.ProcessEngine;
|
import org.jbpm.api.TaskQuery;
|
import org.jbpm.api.activity.ActivityBehaviour;
|
import org.jbpm.api.activity.ActivityExecution;
|
import org.jbpm.api.model.OpenExecution;
|
import org.jbpm.api.task.Assignable;
|
import org.jbpm.internal.log.Log;
|
import org.jbpm.properties.JBpm4Properties;
|
import org.jbpm.pvm.internal.env.EnvironmentFactory;
|
import org.jbpm.pvm.internal.env.EnvironmentImpl;
|
import org.jbpm.pvm.internal.history.HistoryEvent;
|
import org.jbpm.pvm.internal.history.events.TaskActivityStart;
|
import org.jbpm.pvm.internal.model.Activity;
|
import org.jbpm.pvm.internal.model.ActivityImpl;
|
import org.jbpm.pvm.internal.model.ExecutionImpl;
|
import org.jbpm.pvm.internal.model.ProcessDefinitionImpl;
|
import org.jbpm.pvm.internal.model.TimerDefinitionImpl;
|
import org.jbpm.pvm.internal.model.Transition;
|
import org.jbpm.pvm.internal.model.TransitionImpl;
|
import org.jbpm.pvm.internal.session.DbSession;
|
import org.jbpm.pvm.internal.task.ParticipationImpl;
|
import org.jbpm.pvm.internal.task.SwimlaneDefinitionImpl;
|
import org.jbpm.pvm.internal.task.SwimlaneImpl;
|
import org.jbpm.pvm.internal.task.TaskConstants;
|
import org.jbpm.pvm.internal.task.TaskDefinitionImpl;
|
import org.jbpm.pvm.internal.task.TaskImpl;
|
|
|
/**
|
* @author Tom Baeyens
|
*/
|
public class TaskActivity extends JpdlExternalActivity {
|
|
private static final long serialVersionUID = 1L;
|
|
private static final Log log = Log.getLog(TaskActivity.class.getName());
|
|
protected TaskDefinitionImpl taskDefinition;
|
|
private static String className = JBpm4Properties
|
.getStringProperty("jbpm4.engin.checkTaskUser");
|
|
private static Object newInstance = null;
|
private static Method method = null;
|
public void execute(ActivityExecution execution) throws Exception {
|
execute((ExecutionImpl) execution);
|
}
|
|
public void execute(ExecutionImpl execution) throws Exception {
|
DbSession dbSession = EnvironmentImpl.getFromCurrent(DbSession.class);
|
TaskImpl task = (TaskImpl) dbSession.createTask();
|
task.setTaskDefinition(taskDefinition);
|
task.setExecution(execution);
|
task.setProcessInstance(execution.getProcessInstance());
|
task.setSignalling(true);
|
|
// initialize the name
|
if (taskDefinition.getName() != null) {
|
task.setName(taskDefinition.getName());
|
} else {
|
task.setName(execution.getActivityName());
|
}
|
|
task.setDescription(taskDefinition.getDescription());
|
task.setPriority(taskDefinition.getPriority());
|
task.setFormResourceName(taskDefinition.getFormResourceName());
|
|
// save task so that TaskDbSession.findTaskByExecution works for assign
|
// event listeners
|
dbSession.save(task);
|
|
SwimlaneDefinitionImpl swimlaneDefinition = taskDefinition
|
.getSwimlaneDefinition();
|
if (swimlaneDefinition != null) {
|
SwimlaneImpl swimlane = execution
|
.getInitializedSwimlane(swimlaneDefinition);
|
task.setSwimlane(swimlane);
|
|
// copy the swimlane assignments to the task
|
task.setAssignee(swimlane.getAssignee());
|
for (ParticipationImpl participant : swimlane.getParticipations()) {
|
task.addParticipation(participant.getUserId(),
|
participant.getGroupId(), participant.getType());
|
}
|
}
|
if (className != null && !"".equals(className)) {
|
getInstance();
|
Object invoke = method.invoke(newInstance, execution
|
.getProcessInstance().getId(), task.getName());
|
int index = 0;
|
if(invoke!=null){
|
if (invoke instanceof String[]) {
|
String[] invoke2 = (String[]) invoke;
|
if (invoke2.length == 1) {
|
taskDefinition.setAssigneeExpression(invoke2[0]);
|
} else if (invoke2.length > 1) {
|
for (String user : invoke2) {
|
if (index == 0) {
|
this.taskDefinition.setAssigneeExpression(user);
|
}
|
task.addCandidateUser(user);
|
|
index++;
|
}
|
}
|
}
|
}
|
}
|
execution.initializeAssignments(taskDefinition, task);
|
|
HistoryEvent.fire(new TaskActivityStart(task), execution);
|
|
execution.waitForSignal();
|
}
|
|
private static void getInstance() throws SecurityException, NoSuchMethodException, ClassNotFoundException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException{
|
Class<?> cls = Class.forName(className);
|
getMethod(cls);
|
if(newInstance ==null){
|
newInstance = cls.getConstructor().newInstance();
|
}
|
}
|
private static void getMethod(Class<?> cls) throws SecurityException, NoSuchMethodException{
|
if(method==null){
|
method = cls.getMethod("userList", String.class,
|
String.class);
|
}
|
}
|
public void signal(ActivityExecution execution, String signalName,
|
Map<String, ?> parameters) throws Exception {
|
signal((ExecutionImpl) execution, signalName, parameters);
|
}
|
|
public void signal(ExecutionImpl execution, String signalName,
|
Map<String, ?> parameters) throws Exception {
|
Activity activity = execution.getActivity();
|
|
if (parameters != null) {
|
execution.setVariables(parameters);
|
}
|
|
execution.fire(signalName, activity);
|
|
DbSession taskDbSession = EnvironmentImpl
|
.getFromCurrent(DbSession.class);
|
TaskImpl task = (TaskImpl) taskDbSession.findTaskByExecution(execution);
|
task.setSignalling(false);
|
|
Transition transition = null;
|
List<Transition> outgoingTransitions = activity
|
.getOutgoingTransitions();
|
|
if ((outgoingTransitions != null) && (!outgoingTransitions.isEmpty())) {
|
|
// Lookup the outgoing transition
|
|
boolean noOutcomeSpecified = TaskConstants.NO_TASK_OUTCOME_SPECIFIED
|
.equals(signalName);
|
if (noOutcomeSpecified
|
&& activity.findOutgoingTransition(signalName) == null) {
|
// When no specific outcome was specified, the unnamed
|
// transition
|
// is looked up (name is null). If a null outcome was
|
// specifically
|
// used, then the else clause will be used (but the result is
|
// the same)
|
// Note: the second part of the if clause is to avoid the
|
// siutation
|
// where the user would have chosen the same name as the
|
// constant
|
transition = activity.findOutgoingTransition(null);
|
} else {
|
transition = activity.findOutgoingTransition(signalName);
|
}
|
|
// If no transition has been found, we check if we have a special
|
// case
|
// in which we can still deduce the outgoing transition
|
|
if (transition == null) { // no unnamed transition found
|
|
if (signalName == null) {
|
|
// null was explicitely given as outcome
|
throw new JbpmException(
|
"No unnamed transitions were found for the task '"
|
+ getTaskDefinition().getName() + "'");
|
|
} else if (noOutcomeSpecified) { // Special case: complete(id)
|
|
if (outgoingTransitions.size() == 1) { // If only 1
|
// transition, take
|
// that one
|
transition = outgoingTransitions.get(0);
|
} else {
|
throw new JbpmException(
|
"No unnamed transitions were found for the task '"
|
+ getTaskDefinition().getName() + "'");
|
}
|
|
} else {
|
// Likely a programmatic error.
|
throw new JbpmException("No transition named '"
|
+ signalName + "' was found.");
|
}
|
|
}
|
|
if (transition != null) {
|
execution.take(transition);
|
}
|
|
}
|
}
|
|
/**
|
* Checks if the given collection of transitions are all named or not.
|
*/
|
private boolean allTransitionsNamed(Collection<Transition> transitions) {
|
for (Transition transition : transitions) {
|
if (transition.getName() == null) {
|
return false;
|
}
|
}
|
return true;
|
}
|
|
public TaskDefinitionImpl getTaskDefinition() {
|
return taskDefinition;
|
}
|
|
public void setTaskDefinition(TaskDefinitionImpl taskDefinition) {
|
this.taskDefinition = taskDefinition;
|
}
|
}
|