Hi Friends,

As you guys all know jbpm has came up with new version. It has some beautiful features. In this post I will show you how can we make dyanamic process using JBPM 5 API.  While it is recommended to define processes using the graphical editor or the underlying XML (to shield yourself from internal APIs) but sometime we come across such scenario where this feature would really helpful.

Using this API  you can
  • Create process and set the attributes.
  • Create task and add to that process. Also you can set the task related attributes.
  • Establish connections between task. 
  • Get the xml representation of process. 
  • Last but not least we can validation the process and can get the list of errors which were found during validation.
Isn't it great!!!! Let see how can we do it.

Here I created simple process with human task .
package com.sample;

import org.drools.KnowledgeBase;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.ResourceFactory;
import org.drools.runtime.StatefulKnowledgeSession;
import org.jbpm.bpmn2.xml.XmlBPMNProcessDumper;
import org.jbpm.process.workitem.wsht.WSHumanTaskHandler;
import org.jbpm.ruleflow.core.RuleFlowProcessFactory;
import org.jbpm.ruleflow.core.factory.HumanTaskNodeFactory;

/**
 * This is a sample file to launch a process.
 */
public class ProcessTest {

    public static final void main(String[] args) {
        try {

            RuleFlowProcessFactory factory =

            RuleFlowProcessFactory.createProcess("org.jbpm.createLetter");

            //creating process dynamically
            factory = factory.name("LetterCreation").version("1.0")
                    .packageName("org.atul");

            
            // adding start node
            factory.startNode(1).name("start").done();

            // adding human task
            HumanTaskNodeFactory nodefactory = factory.humanTaskNode(2);
            nodefactory.name("atul").actorId("department").done();

            // adding end node
            factory.endNode(3).name("end").done();

            // making connections
            factory.connection(1, 2);
            factory.connection(2, 3);

            System.out.println("id is:-"
                    + factory.validate().getProcess().getId());

            // We can get xml for the process using following code.
            String asXml = XmlBPMNProcessDumper.INSTANCE.dump(
                    factory.getProcess(), XmlBPMNProcessDumper.NO_META_DATA);
            System.out.println(asXml);

            //adding to the knowledge base
            KnowledgeBuilder kbuilder = KnowledgeBuilderFactory
                    .newKnowledgeBuilder();
            kbuilder.add(ResourceFactory
                    .newByteArrayResource(XmlBPMNProcessDumper.INSTANCE.dump(
                            factory.getProcess()).getBytes()),
                    ResourceType.BPMN2);

            StatefulKnowledgeSession ksession = kbuilder.newKnowledgeBase()
                    .newStatefulKnowledgeSession();
            ksession.getWorkItemManager().registerWorkItemHandler("Human Task",
                    new WSHumanTaskHandler());
            
            // start a new process instance
            ksession.startProcess("org.jbpm.createLetter");
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }
}

As you can see in the example that we can create process using "createProcess" method if  "RuleFlowProcessFactory" class. This class also provides method to set the attributes of the process. It provides method to create start, end node.you can see that these methods return a specific NodeFactory, that allows you to set the properties of that node. Once you have finished configuring that specific node, the done() method returns you to the current RuleFlowProcessFactory so you can add more nodes, if necessary.  Using "connection" method we can establish connections between the task.

Using following code we can get xml presentation of the process.
            String asXml = XmlBPMNProcessDumper.INSTANCE.dump(
                    factory.getProcess(), XmlBPMNProcessDumper.NO_META_DATA);

Finally once you done with creation of the process, you can validate the process by validate() method.

We can add the process in to the knowledge base as BPMN2 process.
            kbuilder.add(ResourceFactory
                    .newByteArrayResource(XmlBPMNProcessDumper.INSTANCE.dump(
                            factory.getProcess()).getBytes()),
                    ResourceType.BPMN2);
  
 
 
Please let me know your view and suggestion to make this post better !!!