<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<body link="#355491" alink="#4262a1" vlink="#355491" style="background: #e2e2e2; margin: 0; padding: 20px;">
<div>
        <table cellpadding="0" bgcolor="#FFFFFF" border="0" cellspacing="0" style="border: 1px solid #dadada; margin-bottom: 30px; width: 100%; -moz-border-radius: 6px; -webkit-border-radius: 6px;">
                <tbody>
                        <tr>
                                <td>
                                        <table border="0" cellpadding="0" cellspacing="0" bgcolor="#FFFFFF" style="border: solid 2px #ccc; background: #dadada; width: 100%; -moz-border-radius: 6px; -webkit-border-radius: 6px;">
                                                <tbody>
                                                        <tr>
                                                                <td bgcolor="#000000" valign="middle" height="58px" style="border-bottom: 1px solid #ccc; padding: 20px; -moz-border-radius-topleft: 3px; -moz-border-radius-topright: 3px; -webkit-border-top-right-radius: 5px; -webkit-border-top-left-radius: 5px;">
                                                                        <h1 style="color: #333333; font: bold 22px Arial, Helvetica, sans-serif; margin: 0; display: block !important;">
                                                                        <!-- To have a header image/logo replace the name below with your img tag -->
                                                                        <!-- Email clients will render the images when the message is read so any image -->
                                                                        <!-- must be made available on a public server, so that all recipients can load the image. -->
                                                                        <a href="http://community.jboss.org/index.jspa" style="text-decoration: none; color: #E1E1E1">JBoss Community</a></h1>
                                                                </td>
                                                        </tr>
                                                        <tr>
                                                                <td bgcolor="#FFFFFF" style="font: normal 12px Arial, Helvetica, sans-serif; color:#333333; padding: 20px; -moz-border-radius-bottomleft: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 5px; -webkit-border-bottom-left-radius: 5px;"><h3 style="margin: 10px 0 5px; font-size: 17px; font-weight: normal;">
Re: Human task API, how to move forward in the workflow ?
</h3>
<span style="margin-bottom: 10px;">
created by <a href="http://community.jboss.org/people/jcharnet">John Augusto Charnet</a> in <i>jBPM</i> - <a href="http://community.jboss.org/message/615187#615187">View the full discussion</a>
</span>
<hr style="margin: 20px 0; border: none; background-color: #dadada; height: 1px;">
<div class="jive-rendered-content"><p>Hi Demian,</p><p>not sure what type of configuration you want me to share.</p><p>If you need any other information, please let me know.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>Spring 3.0.1</p><p>Jbpm 5.1.0-Final</p><p>JPA 1.2</p><p>Hibernate 3.3.2.GA</p><pre>/**
* Todos os direitos reservados para Softway.
*
* Data de criacao: 27/06/2011 16:12:28
*/
package br.com.softcomex.components.workflow.service.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.persistence.EntityManagerFactory;
import javax.transaction.TransactionManager;
import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.SystemEventListener;
import org.drools.SystemEventListenerFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.ResourceFactory;
import org.drools.logger.KnowledgeRuntimeLogger;
import org.drools.logger.KnowledgeRuntimeLoggerFactory;
import org.drools.persistence.jpa.JPAKnowledgeService;
import org.drools.runtime.Environment;
import org.drools.runtime.EnvironmentName;
import org.drools.runtime.KnowledgeSessionConfiguration;
import org.drools.runtime.StatefulKnowledgeSession;
import org.drools.runtime.process.ProcessInstance;
import org.drools.spi.ProcessContext;
import org.jbpm.process.audit.JPAProcessInstanceDbLog;
import org.jbpm.process.audit.JPAWorkingMemoryDbLogger;
import org.jbpm.process.workitem.wsht.CommandBasedWSHumanTaskHandler;
import org.jbpm.task.Status;
import org.jbpm.task.query.TaskSummary;
import org.jbpm.task.service.TaskClient;
import org.jbpm.task.service.TaskServer;
import org.jbpm.task.service.TaskService;
import org.jbpm.task.service.mina.MinaTaskClientConnector;
import org.jbpm.task.service.mina.MinaTaskClientHandler;
import org.jbpm.task.service.mina.MinaTaskServer;
import org.jbpm.task.service.responsehandlers.BlockingTaskOperationResponseHandler;
import org.jbpm.task.service.responsehandlers.BlockingTaskSummaryResponseHandler;
import br.com.softcomex.components.log.SfwLogger;
import br.com.softcomex.components.log.SfwLoggerFactory;
import br.com.softcomex.components.workflow.service.SfwJbpmWorkFlow;
/**
* <p>
* Implementação da classe responsável por criar o ambiente do JBPM.
* </p> * @author <a class="jive-link-email-small" href="mailto:jcharnet@sfw.com.br">João Augusto Charnet</a> *
*/
public class SfwJbpmWorkFlowImpl implements SfwJbpmWorkFlow {
    /**
     * Log.
     */
    private SfwLogger sfwLogger = SfwLoggerFactory.getLogger(getClass());
   
    /**
     * Entity Manager Factory injetado.
     */
    private EntityManagerFactory emf;
   
    /**
     * Transação.
     */
    private TransactionManager transactionManager;
   
    /**
     * Sessão da base de conhecimento do JBPM.
     */
    private StatefulKnowledgeSession kSession;
   
    /**
     * Thread do servidor de tarefa humana.
     */
    private TaskServer humanTaskServerThread;
   
    /**
     * Porta do sevidor de tarefa humana.
     */
    private int humanTaskServerPort = -1;
   
    /**
     * Endereço do Servidor de tarefa humana.
     */
    private String humanTaskServerLocalAddress = "127.0.0.1";
   
    /**
     * Lista com os jbpm que precisa ser carregado.
     */
    private List workFlowResourcesList;
   
    /**
     * Responsável por se comunicar com o servidor de tarefas humanas.
     */
    private TaskClient taskClient;
   
    /**
     * Contexto do processo.
     */
   
    /**
     * Construtor padrão.
     */
    public SfwJbpmWorkFlowImpl() {
    }
    @Override
    public void prepareSession() {
        KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
       
        for (String resource : this.workFlowResourcesList) {
            kbuilder.add(ResourceFactory.newClassPathResource(resource), ResourceType.BPMN2);
        }
       
        KnowledgeBase kbase = kbuilder.newKnowledgeBase();
       
        Environment env = KnowledgeBaseFactory.newEnvironment();
        env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, this.emf);
        env.set(EnvironmentName.TRANSACTION_MANAGER,
            this.transactionManager);
       
        // Human Task
        SystemEventListener systemEventListener = SystemEventListenerFactory.getSystemEventListener();
       
        TaskService taskService = new TaskService(this.emf, systemEventListener);
      
        this.startHumanTaskServer(taskService);
       
        Properties properties = new Properties();
        properties.put("drools.processInstanceManagerFactory", "org.jbpm.persistence.processinstance.JPAProcessInstanceManagerFactory");
        properties.put("drools.processSignalManagerFactory", "org.jbpm.persistence.processinstance.JPASignalManagerFactory");
        KnowledgeSessionConfiguration config = KnowledgeBaseFactory.newKnowledgeSessionConfiguration(properties);
       
        StatefulKnowledgeSession ksession =
            JPAKnowledgeService.newStatefulKnowledgeSession(kbase, config, env);
       
      //this will log in audit tables
        JPAWorkingMemoryDbLogger jpaWorkingMemoryLog = new JPAWorkingMemoryDbLogger(ksession);
        JPAProcessInstanceDbLog processLog = new JPAProcessInstanceDbLog(ksession.getEnvironment());
        KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newConsoleLogger(ksession);
       
       
        CommandBasedWSHumanTaskHandler humanTask = new CommandBasedWSHumanTaskHandler(ksession);
        humanTask.setConnection(this.humanTaskServerLocalAddress, this.humanTaskServerPort);
        ksession.getWorkItemManager().registerWorkItemHandler("Human Task", humanTask);
     
        this.setkSession(ksession);
    }
    /**
     * Inicia o servidor para a tarefa humana.
     *
     * @param taskService Serviço da tarefa.
     */
    private void startHumanTaskServer(TaskService taskService) {
        if (this.humanTaskServerPort <= 0) {
            this.humanTaskServerPort = SfwJbpmWorkFlow.DEFAULT_HUMAN_TASK_SERVER_PORT;
        }
        this.sfwLogger.debug("Iniciando Human Task Server! ip [ " + this.humanTaskServerLocalAddress + "] port [" + this.humanTaskServerPort +"]");
        this.humanTaskServerThread = new MinaTaskServer(taskService, this.humanTaskServerPort);
        Thread thread = new Thread(this.humanTaskServerThread);
        thread.start();
    }
    @Override
    public void stopHumanTaskServer() throws Exception {
       if (this.humanTaskServerThread != null &&
           this.humanTaskServerThread.isRunning()) {
          
           this.taskClient.disconnect();
           this.humanTaskServerThread.stop();
          
           this.sfwLogger.debug("Encerrando Human Task Server!");
       }
    }
    @Override
    public void setHumanTaskServerPort(int humanTaskServerPort) {
        this.humanTaskServerPort = humanTaskServerPort;
    }
    @Override
    public int getHumanTaskServerPort() {
        return humanTaskServerPort;
    }
   
    @Override
    public EntityManagerFactory getEmf() {
   
        return emf;
    }
   
    @Override
    public void setEmf(EntityManagerFactory emf) {
   
        this.emf = emf;
    }
    @Override
    public void setkSession(StatefulKnowledgeSession kSession) {
        this.kSession = kSession;
    }
    @Override
    public StatefulKnowledgeSession getkSession() {
        return kSession;
    }
    @Override
    public void setTransactionManager(TransactionManager transactionManager) {
        this.transactionManager = transactionManager;
    }
    @Override
    public TransactionManager getTransactionManager() {
        return transactionManager;
    }
    @Override
    public ProcessInstance startProcess(String processId, Map params) {
        return this.kSession.startProcess(processId, params);
       
    }
    @Override
    public void setWorkFlowResourcesList(List workFlowResourcesList) {
        this.workFlowResourcesList = workFlowResourcesList;
    }
    @Override
    public List getWorkFlowResourcesList() {
        return workFlowResourcesList;
    }
    @Override
    public void addWorkFlowResource(String workFlowResource) {
        if (this.workFlowResourcesList == null) {
            this.workFlowResourcesList = new ArrayList();
        }
       
        this.workFlowResourcesList.add(workFlowResource);
       
    }
    @Override
    public String getHumanTaskServerLocalAddress() {
   
        return humanTaskServerLocalAddress;
    }
   
    @Override
    public void setHumanTaskServerLocalAddress(String humanTaskServerLocalAddress) {
   
        this.humanTaskServerLocalAddress = humanTaskServerLocalAddress;
    }
    @Override
    public ProcessContext getProcessContext() {
        ProcessContext procContext = new ProcessContext(this.kSession);
        return procContext;
    }
   
    /**
     * Cria um TaskClient conectando no servido de tarefa humana.
     * @return TaskClient TaskClient.
     */
    private TaskClient createTaskClient() {
       
        if (this.taskClient == null) {
            this.taskClient = new TaskClient(new MinaTaskClientConnector("SfwTaskClient",
                                                    new MinaTaskClientHandler(SystemEventListenerFactory.getSystemEventListener())));
           
            boolean connected = this.taskClient.connect(this.humanTaskServerLocalAddress, this.humanTaskServerPort);
            if (!connected) {
                this.sfwLogger.error("Não foi possível conectar no servidor de tarefa humana. Server [" + this.humanTaskServerLocalAddress + "] - Port [" + this.humanTaskServerPort + "]");
            }
        }
        return this.taskClient;
    }
   
    @Override
    public TaskClient getTaskClient() {
   
        return taskClient;
    }
   
    @Override
    public void setTaskClient(TaskClient taskClient) {
   
        this.taskClient = taskClient;
    }
    @Override
    public List getTasksByUser(String user) {
        this.createTaskClient();
       
        BlockingTaskSummaryResponseHandler taskSummaryResponseHandler =
            new BlockingTaskSummaryResponseHandler();
        this.taskClient.getTasksAssignedAsPotentialOwner(user, "en-UK", taskSummaryResponseHandler);
        final int oneSec = 1000;
        taskSummaryResponseHandler.waitTillDone(oneSec);
       
        List tasks = taskSummaryResponseHandler.getResults();
       
        return tasks;
    }
   
    /**
     * Cria uma TaskClient, caso necessário e retorna um taskResponseHandler
     * para se comunicar com o servidor de tarefa humana.
     *
     * @return BlockingTaskOperationResponseHandler
     */
    private BlockingTaskOperationResponseHandler createTaskClientAndReturnTaskOperationResponseHandler() {
        this.createTaskClient();
       
        BlockingTaskOperationResponseHandler taskResponseHandler =
            new BlockingTaskOperationResponseHandler();
        return taskResponseHandler;
    }
    @Override
    public void completeTask(List tasks, String user) {
        for (TaskSummary task : tasks) {
            this.sfwLogger.debug("Completando tarefa [" + task.getName() + "] do usuário [" + user + "]");
            this.completeTask(task, user);
        }
       
    }
    @Override
    public void completeTask(TaskSummary task, String user) {
       
        BlockingTaskOperationResponseHandler taskResponseHandler =
            this.createTaskClientAndReturnTaskOperationResponseHandler();
        this.taskClient.complete(task.getId(), user, null, taskResponseHandler);
        final int oneSec = 1000;
        taskResponseHandler.waitTillDone(oneSec);
    }
    @Override
    public void failTask(TaskSummary task, String user) {
        BlockingTaskOperationResponseHandler taskResponseHandler =
            this.createTaskClientAndReturnTaskOperationResponseHandler();
       
        this.taskClient.fail(task.getId(), user, null, taskResponseHandler);
        final int oneSec = 1000;
        taskResponseHandler.waitTillDone(oneSec);
    }
    @Override
    public void suspendTask(TaskSummary task, String user) {
        BlockingTaskOperationResponseHandler taskResponseHandler =
            this.createTaskClientAndReturnTaskOperationResponseHandler();
       
        this.taskClient.suspend(task.getId(), user, taskResponseHandler);
    }
    @Override
    public void startTask(TaskSummary task,
        String user) {
        BlockingTaskOperationResponseHandler taskResponseHandler =
            this.createTaskClientAndReturnTaskOperationResponseHandler();
        if (!task.getStatus().equals(Status.InProgress)) {
       
            this.taskClient.start(task.getId(), user, taskResponseHandler);
            final int oneSec = 1000;
            taskResponseHandler.waitTillDone(oneSec);
        }
       
       
    }
    @Override
    public void stopTask(TaskSummary task,
        String user) {
        BlockingTaskOperationResponseHandler taskResponseHandler =
            this.createTaskClientAndReturnTaskOperationResponseHandler();
        this.taskClient.stop(task.getId(), user, taskResponseHandler);
        final int oneSec = 1000;
        taskResponseHandler.waitTillDone(oneSec);
    }
    @Override
    public void releaseTask(TaskSummary task,
        String user) {
        BlockingTaskOperationResponseHandler taskResponseHandler =
            this.createTaskClientAndReturnTaskOperationResponseHandler();
        this.taskClient.release(task.getId(), user, taskResponseHandler);
        final int oneSec = 1000;
        taskResponseHandler.waitTillDone(oneSec);
    }
    @Override
    public void resumeTask(TaskSummary task,
        String user) {
        BlockingTaskOperationResponseHandler taskResponseHandler =
            this.createTaskClientAndReturnTaskOperationResponseHandler();
        this.taskClient.resume(task.getId(), user, taskResponseHandler);
        final int oneSec = 1000;
        taskResponseHandler.waitTillDone(oneSec);
    }
    @Override
    public void skipTask(TaskSummary task,
        String user) {
        BlockingTaskOperationResponseHandler taskResponseHandler =
            this.createTaskClientAndReturnTaskOperationResponseHandler();
        this.taskClient.skip(task.getId(), user, taskResponseHandler);
        final int oneSec = 1000;
        taskResponseHandler.waitTillDone(oneSec);
       
    }
    @Override
    public void claimTask(TaskSummary task,
        String user) {
        BlockingTaskOperationResponseHandler taskResponseHandler =
            this.createTaskClientAndReturnTaskOperationResponseHandler();
       
        this.taskClient.claim(task.getId(), user, taskResponseHandler);
        final int oneSec = 1000;
        taskResponseHandler.waitTillDone(oneSec);
       
    }
}
</pre><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p><br/>Unit Test case</p><pre>/**
* Todos os direitos reservados para Softway.
*
* Data de criacao: 28/06/2011 15:18:56
*/
package br.com.softcomex.components.workflow.service.impl;
import java.net.ConnectException;
import java.net.Socket;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;
import junit.framework.Assert;
import org.drools.runtime.process.ProcessInstance;
import org.drools.runtime.process.WorkItem;
import org.drools.runtime.process.WorkItemHandler;
import org.drools.runtime.process.WorkItemManager;
import org.drools.spi.ProcessContext;
import org.jbpm.task.query.TaskSummary;
import org.junit.BeforeClass;
import org.junit.Test;
import bitronix.tm.TransactionManagerServices;
import bitronix.tm.resource.jdbc.PoolingDataSource;
import br.com.softcomex.components.workflow.service.SfwJbpmWorkFlow;
import br.com.softcomex.test.serviceeao.SfwBaseServiceTestCase;
/**
* Classe de teste do serviço SfwJbmWorkFlowImpl.
*
* @author <a class="jive-link-email-small" href="mailto:jcharnet@sfw.com.br">João Augusto Charnet</a> *
*/
public class SfwJbpmWorkFlowImplTest extends SfwBaseServiceTestCase {
    /**
     * Serviço.
     */
    @Inject
    private SfwJbpmWorkFlow sfwWorkFlow;
   
    /**
     * Prepara o datasource.
     */
    @BeforeClass
    public static void prepareDatasource() {
        PoolingDataSource ds = new PoolingDataSource();
        ds.setUniqueName("localDataSource");
        ds.setClassName("oracle.jdbc.xa.client.OracleXADataSource");
        ds.setMaxPoolSize(3);
        ds.setAllowLocalTransactions(true);
       
        ResourceBundle rb = ResourceBundle.getBundle("jdbc");
       
        ds.getDriverProperties().put("user", rb.getString("jdbc.username"));
        ds.getDriverProperties().put("password", rb.getString("jdbc.password"));
        ds.getDriverProperties().put("URL", rb.getString("jdbc.url"));
        ds.init();
    }
   
    /**
     * Teste.
     * @throws Exception Exceção.
     */
    @Test
    public void testJbpmWorkFlow() throws Exception {
       
        this.sfwWorkFlow.setTransactionManager(TransactionManagerServices.getTransactionManager());
this.sfwWorkFlow.getTransactionManager().begin();
        //this.sfwWorkFlow.setHumanTaskServerPort(1234);
        this.sfwWorkFlow.addWorkFlowResource("test.bpmn");
        this.sfwWorkFlow.addWorkFlowResource("testHumanTask.bpmn");
        this.sfwWorkFlow.prepareSession();
       
        MyAutomaticHumanSimulatorWorkItemHandler workHandler = new MyAutomaticHumanSimulatorWorkItemHandler();
        TestWorkItemHandler workItemHandler = new TestWorkItemHandler();
       
       
        //this.sfwWorkFlow.getkSession().getWorkItemManager().registerWorkItemHandler("Human Task", workHandler);
       
        Socket socket = new Socket("127.0.0.1", this.sfwWorkFlow.getHumanTaskServerPort());
        Assert.assertNotNull(socket);
        Map params = new HashMap();
        params.put("ator", "Joao");
        params.put("responsible", "Joao");
        //ProcessInstance processInstance = this.sfwWorkFlow.startProcess("test.bpmn", params);
        ProcessInstance processInstance = this.sfwWorkFlow.startProcess("testHumanTask", params);
       
        Thread.currentThread().sleep(3000);
       
        List tasks = this.sfwWorkFlow.getTasksByUser("John");
       
        this.sfwWorkFlow.startTask(tasks.get(0), "John");
       
        this.sfwWorkFlow.completeTask(tasks.get(0), "John");
       
        Thread.currentThread().sleep(5000);
       
        Assert.assertEquals(ProcessInstance.STATE_COMPLETED, processInstance.getState());
       
        this.sfwWorkFlow.stopHumanTaskServer();
       
        try {
            socket = new Socket("127.0.0.1", this.sfwWorkFlow.getHumanTaskServerPort());
            Assert.fail("Esperando exceção, por não ter ninguém escutando na porta do sevidor " + this.sfwWorkFlow.getHumanTaskServerPort());
        } catch (ConnectException excep) {
            Assert.assertTrue(true);
        } finally {
            this.sfwWorkFlow.getTransactionManager().rollback();
        }
    }
   
   
}
</pre><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p><a href="http://community.jboss.org/servlet/JiveServlet/showImage/2-615187-16726/testHumanTask.JPG"><span> http://community.jboss.org/servlet/JiveServlet/downloadImage/2-615187-16726/408-442/testHumanTask.JPG </span></a></p><p>jbpm xml </p><pre>         <?xml version="1.0" encoding="UTF-8"?> 
<definitions id="Definition"
             targetNamespace="http://www.jboss.org/drools"
             typeLanguage="http://www.java.com/javaTypes"
             expressionLanguage="http://www.mvel.org/2.0"
             xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
             xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
             xs:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd"
             xmlns:g="http://www.jboss.org/drools/flow/gpd"
             xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
             xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
             xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
             xmlns:tns="http://www.jboss.org/drools">
  <itemDefinition id="_responsibleItem" structureRef="String" />
  <process processType="Private" isExecutable="true" id="testHumanTask" name="testHumanTask" >
    <!-- process variables -->
    <property id="responsible" itemSubjectRef="_responsibleItem"/>
    <!-- nodes -->
    <startEvent id="_1" name="Start" />
    <userTask id="_2" name="User Task" >
      <ioSpecification>
        <dataInput id="_2_TaskNameInput" name="TaskName" />
        <inputSet>
          <dataInputRefs> _2_TaskNameInput</dataInputRefs>
        </inputSet>
        <outputSet>
        </outputSet>
      </ioSpecification>
      <dataInputAssociation>
        <targetRef> _2_TaskNameInput</targetRef>
        <assignment>
          <from xs:type="tFormalExpression"> Test Human Task</from>
          <to xs:type="tFormalExpression"> _2_TaskNameInput</to>
        </assignment>
      </dataInputAssociation>
      <potentialOwner>
        <resourceAssignmentExpression>
          <formalExpression> #{responsible}</formalExpression>
        </resourceAssignmentExpression>
      </potentialOwner>
    </userTask>
    <scriptTask id="_3" name="Script" scriptFormat="http://www.java.com/java" >
      <script> System.out.println("Script task :" + new java.util.Date());</script>
    </scriptTask>
    <endEvent id="_4" name="End" >
        <terminateEventDefinition/>
    </endEvent>
    <!-- connections -->
    <sequenceFlow id="_1-_2" sourceRef="_1" targetRef="_2" />
    <sequenceFlow id="_2-_3" sourceRef="_2" targetRef="_3" />
    <sequenceFlow id="_3-_4" sourceRef="_3" targetRef="_4" />
  </process>
  <bpmndi:BPMNDiagram>
    <bpmndi:BPMNPlane bpmnElement="testHumanTask" >
      <bpmndi:BPMNShape bpmnElement="_1" >
        <dc:Bounds x="51" y="34" width="48" height="48" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_2" >
        <dc:Bounds x="165" y="35" width="100" height="48" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_3" >
        <dc:Bounds x="176" y="158" width="80" height="48" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_4" >
        <dc:Bounds x="191" y="301" width="48" height="48" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="_1-_2" >
        <di:waypoint x="75" y="58" />
        <di:waypoint x="215" y="59" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_2-_3" >
        <di:waypoint x="215" y="59" />
        <di:waypoint x="216" y="182" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_3-_4" >
        <di:waypoint x="216" y="182" />
        <di:waypoint x="215" y="325" />
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>                                                                                                                                 
</pre></div>
<div style="background-color: #f4f4f4; padding: 10px; margin-top: 20px;">
<p style="margin: 0;">Reply to this message by <a href="http://community.jboss.org/message/615187#615187">going to Community</a></p>
        <p style="margin: 0;">Start a new discussion in jBPM at <a href="http://community.jboss.org/choose-container!input.jspa?contentType=1&containerType=14&container=2034">Community</a></p>
</div></td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>