[jboss-user] [jBPM Users] - Re: [JBPM4] Is there a way to create subprocess programatica
sushantgupta402
do-not-reply at jboss.com
Wed Nov 18 01:29:39 EST 2009
Hi ZP,
Really sorry for not sending you this earlier. I had the files ready but somehow just couldn't send it to you. Here is the outline of what I did. Where-ever I wanted the fork functionality I have created a simple node and added the following as the handler "CustomNodeHandlerFork.java" and where ever I needed join I added "CustomNodeHandlerJoin.java" as the handler. Above 2 handler are the modified form of the "ForkActivity" and "JoinActivity" class of JBPMv4. Below is the code:
=================================================
| import java.util.ArrayList;
| import java.util.List;
|
| import org.jbpm.api.Execution;
| import org.jbpm.api.activity.ActivityExecution;
| import org.jbpm.jpdl.internal.activity.JpdlActivity;
| import org.jbpm.pvm.internal.model.Activity;
| import org.jbpm.pvm.internal.model.ActivityImpl;
| import org.jbpm.pvm.internal.model.Condition;
| import org.jbpm.pvm.internal.model.ExecutionImpl;
| import org.jbpm.pvm.internal.model.Transition;
| import org.jbpm.pvm.internal.model.TransitionImpl;
|
|
| public class CustomNodeHandler extends JpdlActivity {
|
| private static final long serialVersionUID = 1L;
|
| public void execute(ActivityExecution execution) {
| execute((ExecutionImpl)execution);
| }
|
| public void execute(ExecutionImpl execution) {
| Activity activity = execution.getActivity();
| List<ExecutionImpl> listOfExecution = new ArrayList();
| int noOfTrantisions = Integer.parseInt(JBPMTransientStorage.getTransientVariable(execution.getId(),"noOfTrantisionsFromNode").toString());
| // evaluate the conditions and find the transitions that should be forked
| List<Transition> forkingTransitions = new ArrayList<Transition>();
| for(int i=0 ; i < noOfTrantisions-1 ; i++) {
| forkingTransitions.add(activity.getOutgoingTransitions().get(0));
| }
| List<Transition> outgoingTransitions = activity.getOutgoingTransitions();
| for (Transition transition: outgoingTransitions) {
| Condition condition = transition.getCondition();
| if ( (condition==null)
| || (condition.evaluate(execution))
| ) {
| forkingTransitions.add(transition);
| }
| }
|
| // if no outgoing transitions should be forked,
| if (forkingTransitions.size()==0) {
| // end this execution
| execution.end();
|
| // if there is exactly 1 transition to be taken, just use the incoming execution
| } else if (forkingTransitions.size()==1) {
| execution.take(forkingTransitions.get(0));
|
| // if there are more transitions
| } else {
| ExecutionImpl concurrentRoot = null;
| if (Execution.STATE_ACTIVE_ROOT.equals(execution.getState())) {
| concurrentRoot = execution;
| execution.setState(Execution.STATE_INACTIVE_CONCURRENT_ROOT);
| execution.setActivity(null);
| } else if (Execution.STATE_ACTIVE_CONCURRENT.equals(execution.getState())) {
| concurrentRoot = execution.getParent();
| }
|
| for (Transition transition: forkingTransitions) {
| // launch a concurrent path of execution
| String childExecutionName = transition.getName();
| ExecutionImpl concurrentExecution = concurrentRoot.createExecution(childExecutionName);
| concurrentExecution.setActivity(activity);
| concurrentExecution.setState(Execution.STATE_ACTIVE_CONCURRENT);
| concurrentExecution.take(transition);
| listOfExecution.add(concurrentExecution.getSubProcessInstance());
| if (concurrentRoot.isEnded()) {
| break;
| }
| }
| JBPMTransientStorage.setTransientVariable(execution.getId(),"LIST_OF_EXECUTIONS", listOfExecution);
| }
| }
| }
| =================================================
| import java.util.ArrayList;
| import java.util.List;
|
| import org.hibernate.LockMode;
| import org.hibernate.Session;
| import org.jbpm.api.Execution;
| import org.jbpm.api.JbpmException;
| import org.jbpm.api.activity.ActivityExecution;
| import org.jbpm.jpdl.internal.activity.JpdlActivity;
| import org.jbpm.pvm.internal.env.Environment;
| import org.jbpm.pvm.internal.model.Activity;
| import org.jbpm.pvm.internal.model.ExecutionImpl;
| import org.jbpm.pvm.internal.model.Transition;
|
|
| public class CustomNodeHandlerJoin extends JpdlActivity {
|
| private static final long serialVersionUID = 1L;
|
| int multiplicity = -1;
| LockMode lockMode = LockMode.UPGRADE;
|
| public void execute(ActivityExecution execution) {
| execute((ExecutionImpl)execution);
| }
|
| public void execute(ExecutionImpl execution) {
| Activity activity = execution.getActivity();
| // if this is a single, non concurrent root
| if (Execution.STATE_ACTIVE_ROOT.equals(execution.getState())) {
| // just pass through
| Transition transition = activity.getDefaultOutgoingTransition();
| if (transition==null) {
| throw new JbpmException("join must have an outgoing transition");
| }
| execution.take(transition);
| } else if (Execution.STATE_ACTIVE_CONCURRENT.equals(execution.getState())) {
| // force version increment in the parent execution
| Session session = Environment.getFromCurrent(Session.class);
| session.lock(execution.getParent(), lockMode);
| execution.setState(Execution.STATE_INACTIVE_JOIN);
| execution.waitForSignal();
| ExecutionImpl concurrentRoot = execution.getParent();
| List<ExecutionImpl> joinedExecutions = getJoinedExecutions(concurrentRoot, activity);
| if (isComplete(joinedExecutions, activity, concurrentRoot)) {
| endJoinedExecutions(joinedExecutions);
| ExecutionImpl outgoingExecution = null;
| if (concurrentRoot.getExecutions().size()==0) {
| outgoingExecution = concurrentRoot;
| outgoingExecution.setState(Execution.STATE_ACTIVE_ROOT);
| } else {
| outgoingExecution = concurrentRoot.createExecution();
| outgoingExecution.setState(Execution.STATE_ACTIVE_CONCURRENT);
| }
| execution.setActivity(activity, outgoingExecution);
| Transition transition = activity.getDefaultOutgoingTransition();
| if (transition==null) {
| throw new JbpmException("join must have an outgoing transition");
| }
| outgoingExecution.take(transition);
| }
| } else {
| throw new JbpmException("invalid execution state");
| }
| }
|
| protected boolean isComplete(List<ExecutionImpl> joinedExecutions, Activity activity, ExecutionImpl concurrentRoot) {
| int nbrOfExecutionsToJoin = multiplicity;
| if (multiplicity==-1) {
| nbrOfExecutionsToJoin = getActiveExecutions(concurrentRoot).size();
| }
| return joinedExecutions.size()==nbrOfExecutionsToJoin;
| }
|
| protected List<ExecutionImpl> getJoinedExecutions(ExecutionImpl concurrentRoot, Activity activity) {
| List<ExecutionImpl> joinedExecutions = new ArrayList<ExecutionImpl>();
| List concurrentExecutions = (List)concurrentRoot.getExecutions();
| for (ExecutionImpl concurrentExecution: (List<ExecutionImpl>)concurrentExecutions) {
| if ( (Execution.STATE_INACTIVE_JOIN.equals(concurrentExecution.getState()))
| && (concurrentExecution.getActivity()==activity)
| ) {
| joinedExecutions.add(concurrentExecution);
| }
| }
| return joinedExecutions;
| }
| protected List<ExecutionImpl> getActiveExecutions(ExecutionImpl concurrentRoot) {
| List<ExecutionImpl> activeExecutions = new ArrayList<ExecutionImpl>();
| List concurrentExecutions = (List)concurrentRoot.getExecutions();
| for (ExecutionImpl concurrentExecution: (List<ExecutionImpl>)concurrentExecutions) {
| // if ( !concurrentExecution.isEnded()) {
| activeExecutions.add(concurrentExecution);
| //}
| }
| return activeExecutions;
| }
| protected void endJoinedExecutions(List<ExecutionImpl> joinedExecutions) {
| for (ExecutionImpl joinedExecution: joinedExecutions) {
| joinedExecution.end();
| }
| }
|
| public void setMultiplicity(int multiplicity) {
| this.multiplicity = multiplicity;
| }
| public void setLockMode(LockMode lockMode) {
| this.lockMode = lockMode;
| }
| }
| =================================================
| import java.util.HashMap;
| import java.util.Map;
|
| public class JBPMTransientStorage {
| private static ThreadLocal storage = new ThreadLocal();
| //private static Map executionContextMap = new HashMap();
|
| public static void setTransientVariable(String executionId,String key,Object value){
| Object obj = storage.get();
| System.out.println("The object in thread local == "+obj+" while setting key == "+key);
| Map executionContextMap = (null != obj?(Map)obj:new HashMap());
|
| if(executionContextMap.containsKey(executionId)){
| HashMap contextSpecificMap = (HashMap) executionContextMap.get(executionId);
| contextSpecificMap.put(key, value);
| }else{
| Map contextSpecificMap = new HashMap();
| contextSpecificMap.put(key, value);
| executionContextMap.put(executionId, contextSpecificMap);
| }
| storage.set(null);
| storage.set(executionContextMap);
|
| }
|
| public static Object getTransientVariable(String executionId,String key){
| Map executionContextMap = (Map) storage.get();
| Object value = ((Map)executionContextMap.get(executionId)).get(key);
| return value;
| }
|
| public static void clear(){
| storage.set(null);
| }
| }
| =================================================
View the original post : http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4266212#4266212
Reply to the post : http://www.jboss.org/index.html?module=bb&op=posting&mode=reply&p=4266212
More information about the jboss-user
mailing list