OK, here is the JoinAsync class. Instead of using a join when you have 
asychronous logic going on, use a standard node that calls this in its action 
and asynchronous logic should work.

Yes, it is a bit of a hack because it essentially reloads the parentToken for 
analysis and then throws it away, but hey, it gets the job done.


  | /**
  |  * 
  |  */
  | package com.whatever.jbpm;
  | 
  | import java.rmi.RemoteException;
  | import java.util.Collection;
  | import java.util.Iterator;
  | 
  | import org.apache.commons.logging.Log;
  | import org.apache.commons.logging.LogFactory;
  | import org.dom4j.Element;
  | import org.jbpm.graph.action.Script;
  | import org.jbpm.graph.def.Node;
  | import org.jbpm.graph.exe.ExecutionContext;
  | import org.jbpm.graph.exe.Token;
  | import org.jbpm.jpdl.xml.JpdlXmlReader;
  | import org.jbpm.jpdl.xml.Parsable;
  | import org.jbpm.graph.def.ActionHandler;
  | import org.jbpm.db.JbpmSession;
  | import org.jbpm.db.JbpmSessionFactory;
  | 
  | //public class JoinAsync extends Node implements Parsable {
  | 
  | public class JoinAsync implements ActionHandler {
  | 
  |     private static final long serialVersionUID = 1L;
  | 
  |     /**
  |      * specifies if this joinhandler is a discriminator. a descriminator
  |      * reactivates the parent when the first concurrent token enters the 
join.
  |      */
  |     private boolean isDiscriminator = false;
  | 
  |     /**
  |      * a fixed set of concurrent tokens.
  |      */
  |     private Collection tokenNames = null;
  | 
  |     /**
  |      * a script that calculates concurrent tokens at runtime.
  |      */
  |     private Script script = null;
  | 
  |     /**
  |      * reactivate the parent if the n-th token arrives in the join.
  |      */
  |     private int nOutOfM = -1;
  |     
  |     private static final JbpmSessionFactory jbpmSessionFactory = 
JbpmSessionFactory.buildJbpmSessionFactory();
  | 
  |     public void read(Element element, JpdlXmlReader jpdlReader) {
  |     }
  | 
  |     public void execute(ExecutionContext executionContext) {
  |             Token token = executionContext.getToken();
  | 
  |             // if this token is not able to reactivate the parent,
  |             // we don't need to check anything
  |             if (token.isAbleToReactivateParent()) {
  | 
  |                     // the token arrived in the join and can only reactivate
  |                     // the parent once
  |                     token.setAbleToReactivateParent(false);
  | 
  |                     Node joinNode = token.getNode();
  | 
  |                     Token parentToken = token.getParent();
  |                     Token originalParentToken = parentToken;
  |                     
  |                     if (parentToken != null) {
  |                             
  |                             /* 
========================================================== */
  | 
  |                             // The parent token must be reloaded from the 
database for
  |                             // asynchronous behaviour to work properly
  |                             log.debug("need to reload parent token from 
database");
  |                             JbpmSession jbpmSession = null;
  |                             try {
  |                                     jbpmSession = 
jbpmSessionFactory.openJbpmSession();
  | 
  |                                     // Get the parent token from the 
database
  |                                     log.debug("about to reload parent token 
from database");
  |                                     parentToken = 
jbpmSession.getGraphSession().loadToken(parentToken.getId());
  |                                     log.debug("reloaded parent token from 
database!");
  |                                     // Need to load the children before 
closing the session
  |                                     Iterator iter = 
parentToken.getChildren().values().iterator();
  |                                     while (iter.hasNext()) {
  |                                             Token t = (Token) iter.next();
  |                                             // Need to set the flag on this 
token since it isn't committed yet
  |                                             if (t.getId() == token.getId()) 
{
  |                                                     
t.setAbleToReactivateParent(false);
  |                                             }
  |                                     }
  |                                     log.debug("reloaded parent token's 
children from database!");
  | 
  |                             } catch (Exception ex) {
  |                                     System.out.println("error: " + 
ex.toString());
  |                             } finally {
  |                                     if (jbpmSession != null) {
  |                                             jbpmSession.close();
  |                                     }
  |                             }
  |                             
  |                             /* 
========================================================== */
  | 
  |                             boolean reactivateParent = true;
  | 
  |                             // if this is a discriminator
  |                             if (isDiscriminator) {
  |                                     // reactivate the parent when the first 
token arrives in the
  |                                     // join. this must be the first token 
arriving because otherwise
  |                                     // the isAbleToReactivateParent() of 
this token should have been
  |                                     // false
  |                                     // above.
  |                                     reactivateParent = true;
  | 
  |                                     // if a fixed set of tokenNames is 
specified at design time...
  |                             }
  |                             else if (tokenNames != null) {
  |                                     // check reactivation on the basis of 
those tokenNames
  |                                     reactivateParent = 
mustParentBeReactivated(parentToken, tokenNames.iterator());
  | 
  |                                     // if a script is specified
  |                             }
  |                             else if (script != null) {
  | 
  |                                     // check if the script returns a 
collection or a boolean
  |                                     Object result = script.eval(token);
  |                                     // if the result is a collection
  |                                     if (result instanceof Collection) {
  |                                             // it must be a collection of 
tokenNames
  |                                             Collection runtimeTokenNames = 
(Collection) result;
  |                                             reactivateParent = 
mustParentBeReactivated(parentToken, runtimeTokenNames.iterator());
  | 
  |                                             // if it's a boolean...
  |                                     }
  |                                     else if (result instanceof Boolean) {
  |                                             // the boolean specifies if the 
parent needs to be reactivated
  |                                             reactivateParent = ((Boolean) 
result).booleanValue();
  |                                     }
  | 
  |                                     // if a nOutOfM is specified
  |                             }
  |                             else if (nOutOfM != -1) {
  | 
  |                                     int n = 0;
  |                                     // wheck how many tokens already 
arrived in the join
  |                                     Iterator iter = 
parentToken.getChildren().values().iterator();
  |                                     while (iter.hasNext()) {
  |                                             Token concurrentToken = (Token) 
iter.next();
  |                                             if (joinNode == 
concurrentToken.getNode()) {
  |                                                     n++;
  |                                             }
  |                                     }
  |                                     if (n < nOutOfM) {
  |                                             reactivateParent = false;
  |                                     }
  | 
  |                                     // if no configuration is specified..
  |                             }
  |                             else {
  |                                     // the default behaviour is to check 
all concurrent tokens and
  |                                     // reactivate
  |                                     // the parent if the last token arrives 
in the join
  |                                     reactivateParent = 
mustParentBeReactivated(parentToken, parentToken.getChildren().keySet()
  |                                                     .iterator());
  |                             }
  | 
  |                             /* 
========================================================== */
  |                             
  |                             // Reset the parent token back to the one on 
the open session
  |                             parentToken = originalParentToken;
  |                             
  |                             /* 
========================================================== */
  | 
  |                             // if the parent token needs to be reactivated 
from this join node
  |                             if (reactivateParent) {
  | 
  |                                     // write to all child tokens that the 
parent is already reactivated
  |                                     Iterator iter = 
parentToken.getChildren().values().iterator();
  |                                     while (iter.hasNext()) {
  |                                             ((Token) 
iter.next()).setAbleToReactivateParent(false);
  |                                     }
  | 
  |                                     // write to all child tokens that the 
parent is already reactivated
  |                                     ExecutionContext parentContext = new 
ExecutionContext(parentToken);
  |                                     joinNode.leave(parentContext);
  |                             }
  |                     }
  |             }
  |     }
  | 
  |     public boolean mustParentBeReactivated(Token parentToken, Iterator 
childTokenNameIterator) {
  |             boolean reactivateParent = true;
  |             while ((childTokenNameIterator.hasNext()) && 
(reactivateParent)) {
  |                     String concurrentTokenName = (String) 
childTokenNameIterator.next();
  | 
  |                     Token concurrentToken = 
parentToken.getChild(concurrentTokenName);
  | 
  |                     if (concurrentToken.isAbleToReactivateParent()) {
  |                             
log.debug("===================================================");
  |                             
log.debug("===================================================");
  |                             log.debug("join will not yet reactivate parent: 
found concurrent token '" + concurrentToken + "'");
  |                             
log.debug("===================================================");
  |                             
log.debug("===================================================");
  |                             reactivateParent = false;
  |                     }
  |             }
  |             if (reactivateParent) {
  |                     
log.debug("===================================================");
  |                     
log.debug("===================================================");
  |                     log.debug("all tokens have reached join. allowing 
passage");
  |                     
log.debug("===================================================");
  |                     
log.debug("===================================================");
  |             }
  |             return reactivateParent;
  |     }
  | 
  |     public Script getScript() {
  |             return script;
  |     }
  | 
  |     public void setScript(Script script) {
  |             this.script = script;
  |     }
  | 
  |     public Collection getTokenNames() {
  |             return tokenNames;
  |     }
  | 
  |     public void setTokenNames(Collection tokenNames) {
  |             this.tokenNames = tokenNames;
  |     }
  | 
  |     public boolean isDiscriminator() {
  |             return isDiscriminator;
  |     }
  | 
  |     public void setDiscriminator(boolean isDiscriminator) {
  |             this.isDiscriminator = isDiscriminator;
  |     }
  | 
  |     public int getNOutOfM() {
  |             return nOutOfM;
  |     }
  | 
  |     public void setNOutOfM(int nOutOfM) {
  |             this.nOutOfM = nOutOfM;
  |     }
  | 
  |     private static final Log log = LogFactory.getLog(JoinAsync.class);
  | }
  | 

View the original post : 
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3911813#3911813

Reply to the post : 
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3911813


-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click
_______________________________________________
JBoss-user mailing list
JBoss-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jboss-user

Reply via email to