cancel
Showing results for 
Search instead for 
Did you mean: 

Problem mapping form property to object property

bsoto
Champ on-the-rise
Champ on-the-rise

Greeting to everyone,

I want to map a form to a object, i'm using the expressions, but i doesn't work and i am not getting any error.

Here is my code

This is a POJO that i use to save data

public class Entry implements Serializable{
    private static final long serialVersionUID = -2724915954211057511L;

    private String name;
    private boolean accept;

    public Entry(){
    }

    public Entry(String name, boolean accept) {
       super();
       this.name = name;
       this.accept = accept;
    }

    public String getName() {
       return name;
    }

    public void setName(String name) {
       this.name = name;
    }

    public boolean isAccepted() {
       return accept;
    }

    public void setAccept(boolean accept) {
       this.accept = accept;
    }
}


This class have methods to answer question in the workflow

public class BusinessLogic implements ExecutionListener { 

    private static final long serialVersionUID = 2757426697395433840L;

    private static final Logger LOGGER = LoggerFactory.getLogger(BusinessLogic.class);

    private Entry entry;

    //Start of the process
    @Override
    public void notify(DelegateExecution execution) throws Exception {
        LOGGER.info("Initiating process");
        execution.setVariable("business", this);
        execution.setVariable("entry", new Entry());
    }

    public void persistData(String name, boolean accept, DelegateExecution execution){
        LOGGER.warn("persistData({}, {})", name, accept);
        entry = new Entry(name, accept);
    }

    public void persistData(Entry entry){
        LOGGER.warn("persistData({})", entry);
        this.entry = entry;
    }

    public boolean isAccepted(){
        if(entry == null){
            throw new RuntimeException("Data not yet entered");
        }

        return entry.isAccepted();
    }

    public void AcceptedMessage(){
        LOGGER.info("Accepted mesagge");
    }

    public void RejectedMessage(){
        LOGGER.info("Rejected mesagge");
    }

    public void end(){
        LOGGER.info("Finalizing process");
    }
}

test.bpmn

<process id="Test" name="Test" isExecutable="true">
<startEvent id="start" name="start">
<extensionElements>
<activiti:executionListener event="start" class="cl.pardo.business.BusinessLogic"></activiti:executionListener>
</extensionElements>
</startEvent>
<userTask id="dataEntry" name="Data Entry">
<extensionElements>
<activiti:formProperty id="name" name="Name" type="string" expression="${entry.name}"></activiti:formProperty>
<activiti:formProperty id="accept" name="Accept" type="boolean" expression="${entry.accept}" required="true"></activiti:formProperty>
</extensionElements>
</userTask>
<exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"></exclusiveGateway>
<serviceTask id="acceptedMessage" name="Accepted Message" activiti:expression="${business.AcceptedMessage()}"></serviceTask>
<serviceTask id="rejectedMessage" name="Rejected Message" activiti:expression="${business.RejectedMessage()}"></serviceTask>
<endEvent id="end" name="end">
<extensionElements>
<activiti:executionListener event="end" expression="${business.end()}"></activiti:executionListener>
</extensionElements>
</endEvent>
<sequenceFlow id="accept" name="Accept" sourceRef="exclusivegateway1" targetRef="acceptedMessage">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${business.isAccepted()}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="reject" name="Reject" sourceRef="exclusivegateway1" targetRef="rejectedMessage">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${!business.isAccepted()}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow4" sourceRef="rejectedMessage" targetRef="end"></sequenceFlow>
<sequenceFlow id="flow5" sourceRef="acceptedMessage" targetRef="end"></sequenceFlow>
<sequenceFlow id="flow6" sourceRef="start" targetRef="dataEntry"></sequenceFlow>
<serviceTask id="persistData" name="Persist Data" activiti:expression="${business.persistData(entry)}"></serviceTask>
<sequenceFlow id="flow7" sourceRef="dataEntry" targetRef="persistData"></sequenceFlow>
<sequenceFlow id="flow8" sourceRef="persistData" targetRef="exclusivegateway1"></sequenceFlow>
</process>

A test for the bpmn

@Test
public void startProcess() throws Exception {
    RepositoryService repositoryService = activitiRule.getRepositoryService();
    repositoryService.createDeployment().addInputStream("Test.bpmn20.xml", new FileInputStream(filename)).deploy();
    RuntimeService runtimeService = activitiRule.getRuntimeService();

    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("Test");
    assertNotNull(processInstance.getId());
    LOGGER.info("id {} {}", processInstance.getId(), processInstance.getProcessDefinitionId());

    TaskService taskService = activitiRule.getTaskService();
    Task task = taskService.createTaskQuery().singleResult();
    LOGGER.info("TASK NAME: {}", task.getName());
    taskService.setVariable(task.getId(), "name", "Benjamin");
    taskService.setVariable(task.getId(), "accept", true);
    taskService.complete(task.getId());
}

When the methond ${business.persistData(entry)} is reached, the entry object is initialized, but the properties are null (false in the case of the boolean), but If I delete the expression in the form property and I change the expression in persist data task from ${business.persistData(entry)} to ${business.persistData(name, accept)} the vars (name and accept) have the values that i entered.

According to chapter 9.Form from activiti's user guide it should work.

Any idea why the mapping is not working?

PD: The code can be formated and colored like others forums?

1 ACCEPTED ANSWER

gdharley
Elite Collaborator
Elite Collaborator

I think there are a couple of problems with your implementation.

First, your unit test should make use of the formService rather than setting the execution variables.

Next, I think you need to use JUEL expressions (#) rather than delegate expressions ($) in your form property.

Take a look at the FormServiceTest.testFormPropertyExpression(), it demonstrates how to map data into a pojo.
If after you look at this it still doesnt work, create a unit test and attach to the forum thread so we can take a look.

Thanks,

Greg

View answer in original post

3 REPLIES 3

gdharley
Elite Collaborator
Elite Collaborator

I think there are a couple of problems with your implementation.

First, your unit test should make use of the formService rather than setting the execution variables.

Next, I think you need to use JUEL expressions (#) rather than delegate expressions ($) in your form property.

Take a look at the FormServiceTest.testFormPropertyExpression(), it demonstrates how to map data into a pojo.
If after you look at this it still doesnt work, create a unit test and attach to the forum thread so we can take a look.

Thanks,

Greg

bsoto
Champ on-the-rise
Champ on-the-rise

Thank you for your answer. 

In some point i use deferred expression (#{}) instead of immediate expression (${}) but it doesn't work. Anyway, reading the JUEL documentation I should using  deferred expression since it is used for set and get while the immediate is only suitable for get, so i will change.

I gonna test the formService thing, thank you again.

Smiley Happy

bsoto
Champ on-the-rise
Champ on-the-rise

Finally it works, I modified the bpmn to use the deferred expression in the form and the unit test to use formService. 

test.bpmn

<process id="Test" name="Test" isExecutable="true">
<startEvent id="start" name="start">
<extensionElements>
<activiti:executionListener event="start" class="cl.pardo.business.BusinessLogic"></activiti:executionListener>
</extensionElements>
</startEvent>
<userTask id="dataEntry" name="Data Entry">
<extensionElements>
<activiti:formProperty id="name" name="Name" type="string" expression="#{entry.name}"></activiti:formProperty>
<activiti:formProperty id="accept" name="Accept" type="boolean" expression="#{entry.accept}" required="true"></activiti:formProperty>
</extensionElements>
</userTask>
<exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"></exclusiveGateway>
<serviceTask id="acceptedMessage" name="Accepted Message" activiti:expression="${business.AcceptedMessage()}"></serviceTask>
<serviceTask id="rejectedMessage" name="Rejected Message" activiti:expression="${business.RejectedMessage()}"></serviceTask>
<endEvent id="end" name="end">
<extensionElements>
<activiti:executionListener event="end" expression="${business.end()}"></activiti:executionListener>
</extensionElements>
</endEvent>
<sequenceFlow id="accept" name="Accept" sourceRef="exclusivegateway1" targetRef="acceptedMessage">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${business.isAccepted()}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="reject" name="Reject" sourceRef="exclusivegateway1" targetRef="rejectedMessage">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${!business.isAccepted()}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow4" sourceRef="rejectedMessage" targetRef="end"></sequenceFlow>
<sequenceFlow id="flow5" sourceRef="acceptedMessage" targetRef="end"></sequenceFlow>
<sequenceFlow id="flow6" sourceRef="start" targetRef="dataEntry"></sequenceFlow>
<serviceTask id="persistData" name="Persist Data" activiti:expression="${business.persistData(entry)}"></serviceTask>
<sequenceFlow id="flow7" sourceRef="dataEntry" targetRef="persistData"></sequenceFlow>
<sequenceFlow id="flow8" sourceRef="persistData" targetRef="exclusivegateway1"></sequenceFlow>
</process>

the unit test

@Test
public void startProcess() throws Exception {
    RepositoryService repositoryService = activitiRule.getRepositoryService();
    repositoryService.createDeployment().addInputStream("Test.bpmn20.xml", new FileInputStream(filename)).deploy();
    RuntimeService runtimeService = activitiRule.getRuntimeService();

    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("Test");
    assertNotNull(processInstance.getId());
    LOGGER.info("id {} {}", processInstance.getId(), processInstance.getProcessDefinitionId());

    TaskService taskService = activitiRule.getTaskService();
    FormService formService = activitiRule.getFormService();

    Task task = taskService.createTaskQuery().singleResult();
    LOGGER.info("TASK NAME: {}", task.getName());
    Map<String, String> formData = new HashMap<String, String>();
    formData.put("name", "Benjamin");
    formData.put("accept", "false");
    formService.submitTaskFormData(task.getId(), formData);
    // taskService.setVariable(task.getId(), "name", "Benjamin");
    // taskService.setVariable(task.getId(), "accept", true);
    taskService.complete(task.getId());
}

Than you.