[jboss-user] [jBPM] - Re: dataInputAssociation <assignment> expressions

M Arnold do-not-reply at jboss.com
Tue Jan 24 06:32:43 EST 2012


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&containerType=14&container=2034]

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/jboss-user/attachments/20120124/e68633d8/attachment-0001.html 


More information about the jboss-user mailing list