-
1. Re: Interception a signal event
enazareno Jan 5, 2006 7:21 PM (in response to brianmb99)Hi Brian,
Have you checked out the decision node? You don't need to create an ActionHandler class, you just specify a condition and script for evaluation to a certain transition path.
Regards,
Elmo -
2. Re: Interception a signal event
brianmb99 Jan 6, 2006 12:42 PM (in response to brianmb99)Thanks, Elmo.
I was tending away from using decision nodes, because that would require that I put a decision node after every state that requires the "transition filter" code. I'd rather be able to execute some code on the leave node event that would somehow cancel the signal event that's already in progress.
Good thought, though. I'm using decision nodes for many instances of less-ubiquitous decision logic in my processes.
-Brian -
3. Re: Interception a signal event
brianmb99 Jan 6, 2006 9:20 PM (in response to brianmb99)Here's what I did - it's a bit of a hack, but it seems to be working okay with many concurrent instances running.
Each node has node-leave event code that checks for certain conditions that may indicate assignment to an arbitrary node in the process instance is desired. If these conditions are found, a transient variable is set in the context instance with a reference to the current (proper) toNode of the transition that's about to execute (nothing happens in Node.leave(...) between the line where the node-leave event code is triggered and transition.take() is called except logging and the setting of the transitionSource). After the transient variable is set, I get a reference to the transition about to execute from executionContext.getTransition(), and set the 'to' of the transition to the node indicated by the triggering conditions. I now allow the transition code to run, sending the token to the desired node.
Each node also has node-enter event code that sets the 'to' of the transition back to what it's supposed to be (otherwise the temporary 'to' will be persisted when the transaction is committed and tokens following the normal workflow will be routed incorrectly). This code simply checks for a transient variable in the current ContextInstance with the appropriate name, and if it's there, it sets the 'to' of the ExecutionContext's transition to the original (proper) node.
Here's the code for the node-leave:Node n = executionContext.getProcessDefinition().getNode(nodeToGoTo); Transition transition = executionContext.getTransition(); executionContext.getContextInstance().setTransientVariable(ORIGINAL_TO_NODE, transition.getTo()); transition.setTo(n);
And here's the code for the node-enter:Node n = (Node)executionContext.getContextInstance().getTransientVariable(ORIGINAL_TO_NODE); if (n != null){ executionContext.getTransition().setTo(n); executionContext.getContextInstance().deleteTransientVariable(ORIGINAL_TO_NODE); }
Of course I have a lot more validation and other stuff in my production code, but this is the part that does the work.
Putting this code at the node-enter and node-leave events of every one of my nodes allows me more flexibility for routing an individual token at runtime, without specifying all possible paths in a workflow graph. So, for example, I can allow an end user to specify that after task "X" has been completed, whether that's two days or two months from now, and no matter where it has gone in that time, the token should come back to them and assign them a "Y" task, even though "Y" is never done after "X" normally.
I don't know if this is a reasonable way to accomplish my aim, or if this will ever make sense to or help anyone, but I thought I'd post my solution anyway! If there is a 'proper' way to do this (outside of adding many decisions and/or transitions to graphs), and someone wants to post how, that would be cool.
-Brian -
4. Re: Interception a signal event
enazareno Jan 6, 2006 11:43 PM (in response to brianmb99)Hi Brian,
Yes your code will work fine but I would probably do things differently. My personal rule of thumb is "always leave each node via transition". If you make a visual graph, there should be a connection for each node, and that connection is the transistion. If you just "look up" a node, then there won't be that transition, and it will look like a hack. If your project gets bigger, you wont be able to see the relationship of each node and it might be difficult to maintain. To illustrate, you can also probably define it this way ,I have not tested this code, but maybe you can get the idea:<state name="s"> <event type="node-enter"> <script> /*validation script that results some_condition*/ token.signal( some_condition ); </script> </event> <transition name="cond1" to="node1"/> <transition name="cond2" to="node2"/> <transition name="cond3" to="node3"/> </state>
First, this node should be a wait state. Second, validation code is done at node-enter. The validation code returns the name of the next transition. I have not program anything in node-leave, there is nothing you can do once it leaves a node. Just my 2 cents
Regards,
Elmo