01-16-2017 12:58 PM
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?
01-16-2017 05:05 PM
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
01-16-2017 05:05 PM
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
01-17-2017 07:36 AM
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.
01-17-2017 08:17 AM
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.
Explore our Alfresco products with the links below. Use labels to filter content by product module.