5 Replies Latest reply on Jan 24, 2012 6:32 AM by marnold

    dataInputAssociation <assignment> expressions

    marnold

      Hi,

       

      I'm struggling to map input parameters to my task from process variables.  I can't find much documentation besides 5.8.1. Data, and the BPMN2 spec from OMG is cryptic.

       

      I have a task something like this:

       

              <task id="_4" tns:taskName="Custom" name="sendCustom">

                  <incoming>_2-_4</incoming>

                  <outgoing>_4-_5</outgoing>

                  <ioSpecification id="InputOutputSpecification_1">

                      <dataInput id="_4_messageInInput" name="messageIn" />

                      <dataOutput id="_4_messageOutOutput" name="messageOut" />

                      <inputSet id="InputSet_1">

                          <dataInputRefs>_4_messageInInput</dataInputRefs>

                      </inputSet>

                      <outputSet id="OutputSet_1">

                          <dataOutputRefs>_4_messageOutOutput</dataOutputRefs>

                      </outputSet>

                  </ioSpecification>

                  <dataInputAssociation id="DataInputAssociation_2">

                      <sourceRef>event</sourceRef>

                      <targetRef>_4_messageInInput</targetRef>

                      <assignment id="Assignment_2">

                          <from xsi:type="tFormalExpression" id="FormalExpression_3">.</from>

                          <to xsi:type="tFormalExpression" id="FormalExpression_4">.</to>

                      </assignment>

                  </dataInputAssociation>

                  <dataOutputAssociation id="DataOutputAssociation_1">

                      <sourceRef>_4_messageOutOutput</sourceRef>

                      <targetRef>resultMessage_4</targetRef>

                  </dataOutputAssociation>

       

              </task>

       

      Where 'event' is a process variable.  So what can I put in the <assignment><to> and <from>?  An XPath expression?  What if it's not XML?  When I can I use #{event}?  What are the valid values for from@xsi:type besides "tFormalExpression"?

       

      When I execute this task as it is above, I get:

       

      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)

              ... 81 more

       

      I'm sorry if this is a very basic or broad question.  I've scoured the web and really can't find many examples.

       

      Thanks in advance for help.

        • 1. Re: dataInputAssociation <assignment> expressions
          tsurdilovic

          Your task specifies a data input "messageIn" and a data output "messageOut". Let's say you have a process variable "event" as you say specified, here are some scenarios to look at:

           

          1) Simple data input mapping (lets say mapping process variable event to data input messageIn):

           

          <bpmn2:dataInputAssociation id="_fIGIxELFEeGV7InrpvHmpg">

          <bpmn2:sourceRef>event</bpmn2:sourceRef>

          <bpmn2:targetRef>_815293A1-6C79-403F-A469-55DD5991F788_messageInInput</bpmn2:targetRef> 

          </bpmn2:dataInputAssociation>

           

          2) Doing an input assignment (lets say we want to assign data input messageIn a value "hello"):

           

          <bpmn2:dataInputAssociation id="_fIGIxULFEeGV7InrpvHmpg">

          <bpmn2:targetRef>_815293A1-6C79-403F-A469-55DD5991F788_messageInInput</bpmn2:targetRef> 

          <bpmn2:assignment id="_fIGIxkLFEeGV7InrpvHmpg">

          <bpmn2:from xsi:type="bpmn2:tFormalExpression" id="_fIGIx0LFEeGV7InrpvHmpg">hello</bpmn2:from>

          <bpmn2:to xsi:type="bpmn2:tFormalExpression" id="_fIGIyELFEeGV7InrpvHmpg">_815293A1-6C79-403F-A469-55DD5991F788_messageInInput</bpmn2:to>

          </bpmn2:assignment>

          </bpmn2:dataInputAssociation>

           

          3) Doing a data output association (lets say we want to map data output messageOut to the process variable event):

          <bpmn2:dataOutputAssociation id="_fVO9c0PkEeGI-ernV8JyGw">

                  <bpmn2:sourceRef>_3D204743-FBA0-497D-86C3-D1525E592376_messageOutOutput</bpmn2:sourceRef>

                  <bpmn2:targetRef>event</bpmn2:targetRef>

                </bpmn2:dataOutputAssociation>

           

          When you want to map process variables to data inputs of your task or map data outputs of your task back to process variables you would use scenarios 1) and 3). If you want to set a value to your data inputs (in jBPM for example that is used for the GroupId and TaskName data inputs) you would use scenario 2).

           

          Hope this helps.

          1 of 1 people found this helpful
          • 2. Re: dataInputAssociation <assignment> expressions
            marnold

            Thanks Tihomir, that helps a lot.

             

            A couple of further questions would help me to get beyond the basics if you have the time.

             

            1. Supposing my process variable, event, is an XML document.  Is it possible to create an <assignment> that will use a XPath expression to select only a certain part of the XML document (a single element's text value, say) and assign to a data input of my task?

             

            2. Supposing my process variable, event, is a Java object.  Is it possible to create an <assignment> that will use the result of a Java method of the object (e.g event.getId()) and assign to a data input of my task?

             

            Thanks

            • 3. Re: dataInputAssociation <assignment> expressions
              tsurdilovic

              For both 1. and 2. the spec defines association transformations. For example you want to associate process variable x.someParameter to your task data input xIn:

               

              <bpmn2:dataInputAssociation id="_ta2cskLFEeGV7InrpvHmpg">

              <bpmn2:sourceRef>x</bpmn2:sourceRef>

              <bpmn2:targetRef>_815293A1-6C79-403F-A469-55DD5991F788_xInInput</bpmn2:targetRef>

              <bpmn2:transformation xsi:type="bpmn2:tFormalExpression" id="_ta2cs0LFEeGV7InrpvHmpg">x.someParameter</bpmn2:transformation>

              </bpmn2:dataInputAssociation>

               

              Even tho you can specify these type of transformations in the jBPM Web Designer easily (in the assignment portion for example you would do "x.someParameter->xIn", you would have to test this in the runtime. Alternatives would be for example to use on-Entry/Exit actions, script tasks, in your rules via Rule tasks, or if you are using domain-specific nodes you can do any transformation in your executeWorkitem method.

              • 4. Re: dataInputAssociation <assignment> expressions
                marnold

                Thanks Tihomir.

                 

                Unfortunately that doesn't work, I get a NullPointerException at org.jbpm.bpmn2.xml.TaskHandler.readDataInputAssociation(TaskHandler.java:120).

                 

                My reading of the code suggests <transformation> is not implemented in jBPM 5.2.0_Final.  To me, it seems readDataInputAssociation() only handles <assignment>.  And indeed, <transformation> is not listed as supported in chapter '6.3 Supported elements' of the documentation.

                 

                The code looks like it's setup to always treat the <to> and <from> as an XPath expression, so I guess I'll have to go through the code to find out what it can do and how to do it.  Unless someone can point me to some documentation..?

                 

                Thank you for your suggested alternatives, but to be honest, I don't really like them.  My goal is to make the process to be as 'business process' as possible, so a task to prepare the parameters for the next task is not in-line with that goal.  I'm only using domain-specific tasks, but I don't think it's their job to prepare their own input and output parameters from whatever format the caller uses.  I think there should be a way to map tasks' inputs and outputs in the process itself, and that's what I'm trying to do with these dataInputAssociation/dataOutputAssociations. 

                 

                I will update this discussion thread with any progress I may make.  In the meantime, any other suggestions would be most welcome.

                 

                Thanks again.

                • 5. Re: dataInputAssociation <assignment> expressions
                  marnold

                  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"

                                                     xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"

                                                     xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"

                                                     xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"

                                                     xmlns:di="http://www.omg.org/spec/DD/20100524/DI"

                                                     xmlns:g="http://www.jboss.org/drools/flow/gpd"

                                                     xmlns:tns="http://www.jboss.org/drools"

                                                     xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd"

                                                     id="Definition"

                                                     expressionLanguage="http://www.mvel.org/2.0"

                                                     targetNamespace="http://www.jboss.org/drools"

                                                     typeLanguage="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