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 _______________________________________________ jboss-user mailing list jboss-user@lists.jboss.org https://lists.jboss.org/mailman/listinfo/jboss-user