Warning: A non-numeric value encountered in /home/ricston2/public_html/blogarchive/wp-content/themes/Divi/functions.php on line 5766

Bonita Open Solution end-users interact with forms to input and view process data as well as execute tasks. Sometimes we’ll want to change the appearance of these forms. While Bonita Studio allows us to modify the form HTML presented to the user, one might not necessarily want to use HTML. For example, it isn’t hard to imagine that we may want to render our forms according to the native look and feel of a mobile device.

Form definitions reside in the forms.xml file within the business archive (.bar). The User XP reads this XML file to, among other things, render forms and bind form fields with process variables. Bonita’s API makes it trivial to retrieve forms.xml‘s contents:

package com.ricston;

import java.io.ByteArrayInputStream;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.bonitasoft.forms.client.model.FormWidget;
import org.bonitasoft.forms.server.accessor.IApplicationFormDefAccessor;
import org.bonitasoft.forms.server.accessor.impl.XMLApplicationFormDefAccessorImpl;
import org.ow2.bonita.facade.QueryDefinitionAPI;
import org.ow2.bonita.facade.QueryRuntimeAPI;
import org.ow2.bonita.facade.runtime.TaskInstance;
import org.ow2.bonita.facade.uuid.ActivityInstanceUUID;
import org.ow2.bonita.facade.uuid.ProcessDefinitionUUID;
import org.ow2.bonita.util.AccessorUtil;
import org.w3c.dom.Document;

public class BonitaBpms {

    public void renderTaskForm() throws Exception {
        ...
	QueryDefinitionAPI queryDefinitionAPI = AccessorUtil.getQueryDefinitionAPI();
	QueryRuntimeAPI queryRuntimeAPI = AccessorUtil.getQueryRuntimeAPI();

	ActivityInstanceUUID activityInstanceUUID = new ActivityInstanceUUID("Arrival_of_a_New_Employee--4.1--27--Receive_signed_contract--it1--mainActivityInstance--noLoop");

	TaskInstance task = queryRuntimeAPI.getTask(activityInstanceUUID);
	ProcessDefinitionUUID processDefinitionUUID = task.getProcessDefinitionUUID();
	byte[] forms = queryDefinitionAPI.getBusinessArchive(processDefinitionUUID).getResource("forms/forms.xml");

	InputStream inputStream = new ByteArrayInputStream(forms);
	DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
	Document document = builder.parse(inputStream);
        ...
    }
}

In the code we:

  1. Obtain the process definition UUID of task instance “Arrival_of_a_New_Employee–4.1–27–Receive_signed_contract–it1–mainActivityInstance–noLoop”.
  2. Get the business archive and extract the forms.xml using getResource(…).
  3. Build a DOM based on the forms.xml.

So what am I suggesting? Traversing the document using the DOM API to get the information needed? Anyone who worked with DOM will know that this usually involves quite some work. Luckily we have a class which provides easier traversal of the form data:

    ...
    String formID = task.getActivityDefinitionUUID() + "$entry";
    IApplicationFormDefAccessor applicationFormDefAccessor = new XMLApplicationFormDefAccessorImpl(formID, document, null, null);
    ...

What we do here is:

  1. Construct the form ID of the task form we want to render. The ID is constructed by appending the string “$entry” to the task definition UUID.
  2. Use the form ID plus the form document to create a XMLApplicationFormDefAccessorImpl object which we use to retrieve the form data.

Below is an example of using XMLApplicationFormDefAccessorImpl to print the form field labels. In addition, initialised field values are printed by obtaining the process variables bound to them and then querying the Bonita Engine for their values.

    ...
    for (String pageID : applicationFormDefAccessor.getPages()) {
        for (FormWidget formWidget : applicationFormDefAccessor.getPageWidgets(pageID)) {
            System.out.println(formWidget.getLabel())

            if (formWidget.getInitialValueExpression() != null && formWidget.getInitialValueExpression().startsWith("${")) {
                Object fieldValue = queryRuntimeAPI.getVariable(activityInstanceUUID, formWidget.getInitialValueExpression().substring(2, formWidget.getInitialValueExpression().length() - 1));
                if (fieldValue != null) {
                    System.out.println(fieldValue.toString());
                }
            }
        }
    }
    ...

I hope you enjoyed this post.