M Arnold [
https://community.jboss.org/people/marnold] created the discussion
"Re: dataInputAssociation <assignment> expressions"
To view the discussion, visit:
https://community.jboss.org/message/648375#648375
--------------------------------------------------------------
Hi,
I spend a little time working this out. Sorry about the long post. I took some notes,
which I have reproduced below in case it helps anyone. I used jBPM 5.2.0 Final (the latest
version at Jan 2012).
It's all a bit weird... so I still think I'm doing something fundamentally wrong,
because the way it works is hard to understand, and furthermore, it's hard to imagine
anyone being able to use it as it is currently.
If you create a simple WorkItemHandler like the class below:
public final class EchoWorkItemHandler implements WorkItemHandler {
@Override
public void executeWorkItem(WorkItem workItem, WorkItemManager
manager) {
Map<String, Object> parameters =
workItem.getParameters();
for (String parameterName : parameters.keySet()) {
System.out.println("parameter: " +
parameterName +
" is type " +
parameters.get(parameterName).getClass().getCanonicalName() +
" and has value " +
parameters.get(parameterName).toString());
}
}
@Override
public void abortWorkItem(WorkItem workItem, WorkItemManager manager)
{
}
}
Start a process like this, note the globals: one String, one BigDecimal, one
org.w3c.dom.Node (from the BPMN2 document itself):
Map<String, Object> parameters = new HashMap<String, Object>();
parameters.put("globalString", "GLOBALSTRING");
parameters.put("globalDecimal", new BigDecimal("1234.56"));
parameters.put("globalNode", doc.getDocumentElement());
// Put a the DOM of the BPMN2 file itself
StatefulKnowledgeSession ksession = null;
try {
ksession = kbase.newStatefulKnowledgeSession();
ksession.getWorkItemManager().registerWorkItemHandler("echoParameters",
new EchoWorkItemHandler());
ksession.startProcess(processName, parameters);
} finally {
if (ksession != null) ksession.dispose();
}
And the business process you execute is like this:
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance
http://www.w3.org/2001/XMLSchema-instance"
xmlns="
http://www.omg.org/spec/BPMN/20100524/MODEL
http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:bpmndi="
http://www.omg.org/spec/BPMN/20100524/DI http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:dc="
http://www.omg.org/spec/DD/20100524/DC
http://www.omg.org/spec/DD/20100524/DC"
xmlns:di="
http://www.omg.org/spec/DD/20100524/DI
http://www.omg.org/spec/DD/20100524/DI"
xmlns:g="
http://www.jboss.org/drools/flow/gpd
http://www.jboss.org/drools/flow/gpd"
xmlns:tns="
http://www.jboss.org/drools
http://www.jboss.org/drools"
xsi:schemaLocation="
http://www.omg.org/spec/BPMN/20100524/MODEL http://www.omg.org/spec/BPMN/20100524/MODEL
BPMN20.xsd"
id="Definition"
expressionLanguage="
http://www.mvel.org/2.0
http://www.mvel.org/2.0"
targetNamespace="
http://www.jboss.org/drools
http://www.jboss.org/drools"
typeLanguage="
http://www.java.com/javaTypes
http://www.java.com/javaTypes">
<process
id="com.xxxxx.processes.testDataInputAssociation"
name="testDataInputAssociation" isExecutable="true"
processType="Private">
<property id="globalString"
itemSubjectRef="tns:_globalString" />
<property id="globalDecimal"
itemSubjectRef="tns:_globalDecimal" />
<property id="globalNode"
itemSubjectRef="tns:_globalNode" />
<startEvent id="_1" name="Start">
<outgoing>_1-_4</outgoing>
</startEvent>
<task id="_4"
tns:taskName="echoParameters" name="echo1">
<incoming>_1-_4</incoming>
<outgoing>_4-_9</outgoing>
<ioSpecification
id="InputOutputSpecification_4">
<dataInput
id="_4_messageInput" name="messageIn" />
<inputSet
id="InputSet_1">
<dataInputRefs>_4_messageInput</dataInputRefs>
</inputSet>
<outputSet />
</ioSpecification>
<dataInputAssociation
id="DataInputAssociation_4">
<sourceRef>globalDecimal</sourceRef>
<targetRef>_4_messageInput</targetRef>
</dataInputAssociation>
</task>
<endEvent id="_9" name="End">
<incoming>_4-_9</incoming>
<terminateEventDefinition
id="TerminateEventDefinition_1" />
</endEvent>
<sequenceFlow id="_1-_4"
sourceRef="_1" targetRef="_4" />
<sequenceFlow id="_4-_9"
sourceRef="_4" targetRef="_9" />
</process>
</definitions>
Then what you get to System.out depends on the <dataInputAssociation>.
1. If you have <sourceRef> and <targetRef> and no <assignment>, then the
variable referred to by <sourceRef> will be copied to the variable referred to by
<targetRef>
<dataInputAssociation id="DataInputAssociation_4">
<sourceRef>globalDecimal</sourceRef>
<targetRef>_4_messageInput</targetRef>
</dataInputAssociation>
parameter: messageIn is type java.math.BigDecimal and has value 1234.56
<dataInputAssociation id="DataInputAssociation_4">
<sourceRef>globalString</sourceRef>
<targetRef>_4_messageInput</targetRef>
</dataInputAssociation>
parameter: messageIn is type java.lang.String and has value GLOBALSTRING
2. If you have no <sourceRef> but a <targetRef> and a <assignment>, then
whatever text you have in the <from> will be copied into the variable referred to by
<targetRef>, so you'll always get a java.lang.String. Anything you have in the
<to> is completely ignored.
<dataInputAssociation id="DataInputAssociation_4">
<targetRef>_4_messageInput</targetRef>
<assignment id="Assignment_1">
<from xsi:type="tFormalExpression"
id="FormalExpression_1">VALUE</from>
<to xsi:type="tFormalExpression"
id="FormalExpression_2">This Is Ignored</to>
</assignment>
</dataInputAssociation>
parameter: messageIn is type java.lang.String and has value VALUE
3.1.1. If you have a <sourceRef> and a <targetRef> and an <assignment>,
then the text in in the <from> and the <to> MUST be a valid XPath (must
compile), but how they're used depends on the class of the variable referred to by
<sourceRef>. Check class org.jbpm.bpmn2.xpath.XPATHAssigmentAction. If
<sourceRef> is an instanceof org.w3c.dom.Node, then <from> is an XPath
expression which will select a part of the XML document from the variable referred to by
<sourceRef>. If selects an attribute, the variable referred to by <sourceRef>
will be a java.lang.String with the attribute's value. If the variable referred to
<targetRef> is null (would be for a <dataInputAssociation> for a <task>)
then <to> ignored (but still must be a valid XPath!)
<dataInputAssociation id="DataInputAssociation_4">
<sourceRef>globalNode</sourceRef>
<targetRef>_4_messageInput</targetRef>
<assignment id="Assignment_1">
<from xsi:type="tFormalExpression"
id="FormalExpression_1">/definitions/process/@name</from>
<to xsi:type="tFormalExpression"
id="FormalExpression_2">ThisOnlyHasToBeAValidXPathButIsIgnored</to>
-->
</assignment>
</dataInputAssociation>
parameter: messageIn is type java.lang.String and has value
testDataInputAssociation
3.1.2. If <sourceRef> is an instanceof org.w3c.dom.Node and <from> selects a
text node, the variable referred to by <targetRef> will be a java.lang.String with
the text node's text value.
<dataInputAssociation id="DataInputAssociation_4">
<sourceRef>globalNode</sourceRef>
<targetRef>_4_messageInput</targetRef>
<assignment id="Assignment_1">
<from xsi:type="tFormalExpression"
id="FormalExpression_1">/definitions/process/task/ioSpecification/inputSet/dataInputRefs/text()</from>
<to xsi:type="tFormalExpression"
id="FormalExpression_2">ThisOnlyHasToBeAValidXPathButIsIgnored</to>
-->
</assignment>
</dataInputAssociation>
parameter: messageIn is type java.lang.String and has value _4_messageInput
3.1.3. If <sourceRef> is an instanceof org.w3c.dom.Node and <from> selects any
other single Node, the variable referred to by <targetRef> will be the single Node.
(Using xerces as DOM implementation.)
<dataInputAssociation id="DataInputAssociation_4">
<sourceRef>globalNode</sourceRef>
<targetRef>_4_messageInput</targetRef>
<assignment id="Assignment_1">
<from xsi:type="tFormalExpression"
id="FormalExpression_1">/definitions/process/task/ioSpecification/inputSet/dataInputRefs/text()</from>
<to xsi:type="tFormalExpression"
id="FormalExpression_2">ThisOnlyHasToBeAValidXPathButIsIgnored</to>
-->
</assignment>
</dataInputAssociation>
parameter: messageIn is type org.apache.xerces.dom.ElementImpl and has value
[dataInputRefs: null]
3.1.4. If <sourceRef> is an instanceof org.w3c.dom.Node and <from> selects
multiple Nodes... haven't checked this yet!
3.2. If <sourceRef> is an instanceof java.lang.String, then its value will be copied
to the variable referred to by <targetRef>. The <from> and <to> XPath
expressions are ignored. (But they still must be valid XPath expressions!)
<dataInputAssociation id="DataInputAssociation_4">
<sourceRef>globalString</sourceRef>
<targetRef>_4_messageInput</targetRef>
<assignment id="Assignment_1">
<from xsi:type="tFormalExpression"
id="FormalExpression_1">ThisOnlyHasToBeAValidXPathButIsIgnored</from>
<to xsi:type="tFormalExpression"
id="FormalExpression_2">ThisOnlyHasToBeAValidXPathButIsIgnored</to>
</assignment>
</dataInputAssociation>
parameter: messageIn is type java.lang.String and has value GLOBALSTRING
3.3. If <sourceRef> is any other class (not instanceof org.w3c.dom.Node or
java.lang.String) then you get a NullPointerException.
<dataInputAssociation id="DataInputAssociation_4">
<sourceRef>globalDecimal</sourceRef>
<targetRef>_4_messageInput</targetRef>
<assignment id="Assignment_1">
<from xsi:type="tFormalExpression"
id="FormalExpression_1">ThisOnlyHasToBeAValidXPathButIsIgnored</from>
<to xsi:type="tFormalExpression"
id="FormalExpression_2">ThisOnlyHasToBeAValidXPathButIsIgnored</to>
</assignment>
</dataInputAssociation>
[snip]
Caused by: java.lang.NullPointerException
at
org.jbpm.bpmn2.xpath.XPATHAssignmentAction.execute(XPATHAssignmentAction.java:91)
at
org.jbpm.workflow.instance.node.WorkItemNodeInstance.handleAssignment(WorkItemNodeInstance.java:193)
... 17 more
--------------------------------------------------------------
Reply to this message by going to Community
[
https://community.jboss.org/message/648375#648375]
Start a new discussion in jBPM at Community
[
https://community.jboss.org/choose-container!input.jspa?contentType=1&...]