1 2 Previous Next 29 Replies Latest reply: Nov 8, 2013 7:27 AM by Arun Krishna RSS

Jbpm 5 user form variables

npereira Newbie

Hi forum,

 

I've investigation JBPM5, but I'm stuck with a variable problem.

 

The problem is basically with accessing the variable in the user task form.

 

I have a user task with an ftl, I'm using the "Parameter Mapping" but I'm not able to access the variable in the form. (I have attached the bpmn and the ftl files to the Discussion.)

 

The interesting part is that thru the "Result Mapping" I'm able to change the process variable that is comming out od the form user task.

 

Hope you can help.

  • 1. Re: Jbpm 5 user form variables
    Mauricio Salatino Master

    Hi, the variables that you want to access inside the the Human task needs to be inserted in the content field

    <dataInputAssociation>
            <targetRef>_5_ContentInput</targetRef>
            <assignment>
              <from xs:type="tFormalExpression">#{doctor.id}, #{ambulance.id},  #{patient.id}, #{patient.name}, #{patient.age}, #{patient.gender}, #{emergency.location}, #{emergency.type}</from>
              <to xs:type="tFormalExpression">_5_ContentInput</to>
            </assignment>
          </dataInputAssociation>

     

    I have something like that in my process and then from your client side (Human Task Client UI):

     

    client.start(taskSum.getId(), "control_operator", null);
            BlockingGetTaskResponseHandler handlerT = new BlockingGetTaskResponseHandler();
            client.getTask(taskSum.getId(), handlerT);
            Task task2 = handlerT.getTask();
            TaskData taskData = task2.getTaskData();
           
            System.out.println("TaskData = "+taskData);
            BlockingGetContentResponseHandler handlerC = new BlockingGetContentResponseHandler();
            client.getContent(taskData.getDocumentContentId(), handlerC);
            Content content = handlerC.getContent();
           
            System.out.println("Content= "+content);
            ByteArrayInputStream bais = new ByteArrayInputStream(content.getContent());
           
        ObjectInputStream ois = new ObjectInputStream(bais);
            String taskinfo =(String) ois.readObject();
            System.out.println("TASKINFO = "+taskinfo);
            //#{doctor.id}, #{ambulance.id},  #{patient.id}, #{patient.name}, #{patient.age}, #{patient.gender}, #{emergency.location}, #{emergency.type}
            String[] values= taskinfo.split(",");
           
            Assert.assertEquals(8 , values.length);

  • 2. Re: Jbpm 5 user form variables
    npereira Newbie

    Thanks, got it to work.... not with the ftl's but it's working thru java...

  • 3. Re: Jbpm 5 user form variables
    Kris Verlaenen Master

    To get access to data in your ftl's, you need to pass the values as part of the "Content" parameter.  So, in this case, you could create a new process variable contentVariable and set that to a Map that contains the value of one or more parameters you want to pass (like userT).  You can then use the parameter mapping to map this contentVariable to the Content parameter.  You can then access the values of these parameters in the Map inside your ftls.

     

    Kris

  • 4. Re: Jbpm 5 user form variables
    rafitanba Newbie

    Hi there!

     

    Were you finally able to achieve it? It happens exactly the same to me. I can retrieve data from the form, but I always get an exception when trying to get access to data in the ftl.

     

    I have a process variable called "name". Then I use #{name} as value of the Content property of the Human Task. I also map this process variable to a parameter also called "name". Finally, I use ${name} within the ftl code, but it doesn't work :-( I get the following exception:

     

    freemarker.core.InvalidReferenceException: Expression name is undefined in line ...

     

    What am I doing wrong?

     

    Thanks in advance,

    Rafa.

  • 5. Re: Jbpm 5 user form variables
    Matthew Wojtowicz Newbie

    Kris Verlaenen wrote:

     

    you could create a new process variable contentVariable and set that to a Map that contains the value of one or more parameters you want to pass (like userT).

     

     

    How would this be done? Would I have to do this in java? Can I set the variables in a map using xml?

  • 6. Re: Jbpm 5 user form variables
    onkar ruikar Newbie

    You can try this solution:

     

    In content variable pass the map as mvel. Following is the sample map:

         [ 'reminderInterval' : new String("#{reminderInterval}"),
               'report' : new String( "#{report}")
             ];

    And in human task handler(WSHumanTaskHandler or CommandBasedWSHumanTaskHandler) modify executeWorkItem(WorkItem,WorkItemManager) method. Add following lines at bottom part of the method before serialisation:

            ContentData content = null;
            String contentString = workItem.getParameter("Content").toString();
            //evaluate mvel
            ExpressionCompiler compiler = new ExpressionCompiler(contentString.trim());
            ParserContext context = new ParserContext();
            context.addPackageImport("java.lang");
            Map<String, String> contentObject =(Map<String, String>) MVEL.executeExpression(compiler.compile(context));
  • 7. Re: Jbpm 5 user form variables
    Kris Verlaenen Master

    You could simply create an action (for example using an action node aka script node, or an on-entry / on-exit action on nodes that behave as a wait state), and then use either mvel or java syntax to set your map (example uses Java syntax):

      java.util.Map map = new java.util.HashMap();

      map.put("variable1", ...);

      ...

      kcontext.setVariable("myMap", map);

    Then just map the myMap variable to the Content parameter.

     

    Kris

  • 8. Re: Jbpm 5 user form variables
    Matthew Wojtowicz Newbie

    Thanks got this to work.

     

    Code for Script before Human Task(Don't forget to add import java.util.HashMap):

    map = new HashMap();
    map.put("id",id);
    map.put("priority",priority);
    map.put("quantity",quantity);
    kcontext.setVariable("map", map);

    map = new HashMap();

    map.put("id",id);

    map.put("priority",priority);

    map.put("quantity",quantity);

    kcontext.setVariable("map", map);

     

    Then Human task Node

     

    <userTask id="_2" name="Order Evaluation" >

          <ioSpecification>

            <dataInput id="_2_ContentInput" name="Content" />

            <dataInput id="_2_CommentInput" name="Comment" />

            <dataInput id="_2_SkippableInput" name="Skippable" />

            <dataInput id="_2_TaskNameInput" name="TaskName" />

            <inputSet>

              <dataInputRefs>_2_ContentInput</dataInputRefs>

              <dataInputRefs>_2_CommentInput</dataInputRefs>

              <dataInputRefs>_2_SkippableInput</dataInputRefs>

              <dataInputRefs>_2_TaskNameInput</dataInputRefs>

            </inputSet>

            <outputSet>

            </outputSet>

          </ioSpecification>

          <dataInputAssociation>

            <sourceRef>map</sourceRef>

            <targetRef>_2_ContentInput</targetRef>

          </dataInputAssociation>

          <dataInputAssociation>

            <targetRef>_2_CommentInput</targetRef>

            <assignment>

              <from xs:type="tFormalExpression">Please create an order.</from>

              <to xs:type="tFormalExpression">_2_CommentInput</to>

            </assignment>

          </dataInputAssociation>

          <dataInputAssociation>

            <targetRef>_2_SkippableInput</targetRef>

            <assignment>

              <from xs:type="tFormalExpression">false</from>

              <to xs:type="tFormalExpression">_2_SkippableInput</to>

            </assignment>

          </dataInputAssociation>

          <dataInputAssociation>

            <targetRef>_2_TaskNameInput</targetRef>

            <assignment>

              <from xs:type="tFormalExpression">Order Evaluation</from>

              <to xs:type="tFormalExpression">_2_TaskNameInput</to>

            </assignment>

          </dataInputAssociation>

          <potentialOwner>

            <resourceAssignmentExpression>

              <formalExpression>krisv</formalExpression>

            </resourceAssignmentExpression>

          </potentialOwner>

        </userTask>

     

    I accessed the variables in my ftl as ${id} ${priority}. DO NOT use ${content.id} or ${map.id}

  • 9. Re: Jbpm 5 user form variables
    rafitanba Newbie

    Mmmm, it's true! I used ${content.xxxx} but it also works just using ${xxxx}

     

    However, is it going to be always necessary to create a script node before the human task? Or is this some kind of workaround? I ask because my business users will not understand why they are going to have to create those extra nodes...

     

    Rafa.

  • 10. Re: Jbpm 5 user form variables
    Kris Verlaenen Master

    You will always need a map of parameters if you have multiple parameters you want to pass.  This however doesn't mean you need to present this complexity to the end users.  I could see how you could extend the current editor for the human task node to not simply show one text box for the content parameter but show an additional option where the user could specify he has multiple ones and allows the user to specify each of them.  This will then be translated back to an on-entry action creating the map underneath.

     

    I'll see if I can slip this extension in the next few days.

     

    Kris

  • 11. Re: Jbpm 5 user form variables
    rafitanba Newbie

    Ok, thanks Kris! That would be fantastic!

     

    However, it would be enough for me if I could set the map using the on-entry action of the human task. I understand this action to be executed before the user uses the form, but it seems it doesn't work. The editor doesn't translate the action into bpmn2.0, so the ftl doesn't access the variables...

     

    Thanks again!

    Rafa.

  • 12. Jbpm 5 user form variables
    rodri tes23 Newbie

    Matthew Wojtowicz, rafitanba,

     

    What are versions of JBPM/Drools you have have used?

    I used the same script node and the map Matthew suggested (http://community.jboss.org/thread/161936?tstart=0)

     

    It did not work and I keep getting the following message while loading the bpmn file.

     

    'There is no ID/IDREF binding for IDREF 'myMap'.

  • 13. Jbpm 5 user form variables
    Matthew Wojtowicz Newbie

    You need to initialize the variables for the process. Also the map is called "map" not myMap in my example.

  • 14. Re: Jbpm 5 user form variables
    rodri tes23 Newbie

    Thanks for your reply.

     

    I renamed the map to "map" and also initialized the variables as follows:

     

     

    java.util.HashMap map = new java.util.HashMap();

    map.put("id","1");

    map.put("priority","High");

    map.put("quantity","100");

    kcontext.setVariable("map", map);

     

    I still get the same errors as shown below and  I could not access the variables from ftl

    (null: 127, 15): cvc-id.1: There is no ID/IDREF binding for IDREF 'map'.

    Could not find variable map

    Using process-level scope

    Could not find variable scope for variable map

    when trying to execute Work Item Human Task

    Continuing without setting parameter.

     

     

     

     

    I am not sure what I am missing here (I tried with the SNAPSHOT code). Attached please find the complete bpmn file I used.

1 2 Previous Next