[jbpm-commits] JBoss JBPM SVN: r2506 - in projects/spec/trunk/modules: cts/src/test/java/org/jbpm/test/cts/task and 2 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Wed Oct 8 07:06:20 EDT 2008


Author: thomas.diesler at jboss.com
Date: 2008-10-08 07:06:20 -0400 (Wed, 08 Oct 2008)
New Revision: 2506

Added:
   projects/spec/trunk/modules/api/src/main/java/org/jbpm/api/model/UserTask.java
   projects/spec/trunk/modules/api/src/main/java/org/jbpm/api/model/UserTaskCallback.java
   projects/spec/trunk/modules/cts/src/test/java/org/jbpm/test/cts/task/UserTaskCallbackTest.java
Modified:
   projects/spec/trunk/modules/cts/src/test/java/org/jbpm/test/cts/task/ReceiveTaskTest.java
   projects/spec/trunk/modules/cts/src/test/java/org/jbpm/test/cts/task/UserTaskTest.java
   projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/UserTaskImpl.java
   projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/runtime/MessageSender.java
Log:
Add UserTaskCallback API

Added: projects/spec/trunk/modules/api/src/main/java/org/jbpm/api/model/UserTask.java
===================================================================
--- projects/spec/trunk/modules/api/src/main/java/org/jbpm/api/model/UserTask.java	                        (rev 0)
+++ projects/spec/trunk/modules/api/src/main/java/org/jbpm/api/model/UserTask.java	2008-10-08 11:06:20 UTC (rev 2506)
@@ -0,0 +1,44 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.api.model;
+
+//$Id$
+
+/**
+ * A Task is an Atomic Activity that is included within a Process.
+ * 
+ * A Task is used when the work in the Process is not broken down to a finer level of Process Model detail. Generally, an end-user and/or an application are used to
+ * perform the Task when it is executed.
+ * 
+ * @author thomas.diesler at jboss.com
+ * @since 08-Jul-2008
+ */
+public interface UserTask extends Task
+{
+  UserTaskCallback getUserTaskCallback();
+  
+  void setUserTaskCallback(UserTaskCallback callback);
+  
+  Message getOutMessageRef();
+  
+  Message getInMessageRef();
+}
\ No newline at end of file


Property changes on: projects/spec/trunk/modules/api/src/main/java/org/jbpm/api/model/UserTask.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF

Added: projects/spec/trunk/modules/api/src/main/java/org/jbpm/api/model/UserTaskCallback.java
===================================================================
--- projects/spec/trunk/modules/api/src/main/java/org/jbpm/api/model/UserTaskCallback.java	                        (rev 0)
+++ projects/spec/trunk/modules/api/src/main/java/org/jbpm/api/model/UserTaskCallback.java	2008-10-08 11:06:20 UTC (rev 2506)
@@ -0,0 +1,123 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.api.model;
+
+//$Id$
+
+import javax.management.ObjectName;
+
+import org.jbpm.api.client.MessageListener;
+import org.jbpm.api.model.builder.MessageBuilder;
+import org.jbpm.api.model.builder.ObjectNameFactory;
+import org.jbpm.api.runtime.Attachments;
+import org.jbpm.api.runtime.BasicAttachments;
+import org.jbpm.api.service.MessageBuilderService;
+import org.jbpm.api.service.MessageService;
+
+/**
+ * A callback that can be attached to a {@link UserTask} to facilitate message handling; 
+ * 
+ * The callback registers a {@link MessageListener}, extracts the data from the received message 
+ * and calls the user provided 'callback' method. The response message is then constructed from 
+ * the user provided data and automatically sent back to the {@link UserTask}.
+ *  
+ * @author thomas.diesler at jboss.com
+ * @since 08-Oct-2008
+ */
+public abstract class UserTaskCallback
+{
+  private MessageListener messageListener;
+
+  public MessageListener getMessageListener()
+  {
+    return messageListener;
+  }
+
+  public void attach(UserTask userTask)
+  {
+    if (userTask.getUserTaskCallback() != this)
+      userTask.setUserTaskCallback(this);
+    
+    messageListener = new CallbackMessageListener(userTask);
+    
+    MessageService msgService = userTask.getProcessEngine().getService(MessageService.class);
+    msgService.addMessageListener(messageListener);
+  }
+  
+  public void detach(UserTask userTask)
+  {
+    MessageService msgService = userTask.getProcessEngine().getService(MessageService.class);
+    msgService.removeMessageListener(messageListener.getKey());
+  }
+  
+  public abstract void callback(Attachments att);
+
+  class CallbackMessageListener implements MessageListener
+  {
+    private UserTask userTask;
+    
+    public CallbackMessageListener(UserTask userTask)
+    {
+      this.userTask = userTask;
+    }
+
+    @Override
+    public void catchMessage(Message msg)
+    {
+      // Get the message data
+      Attachments att = new BasicAttachments();
+      for (String propName : msg.getPropertyNames())
+      {
+        String value = msg.getProperty(propName).getValue();
+        att.addAttachment(propName, value);
+      }
+        
+      // Call the user callback
+      callback(att);
+
+      // Build the response message
+      Message msgRef = userTask.getInMessageRef();
+      MessageBuilder msgBuilder = MessageBuilderService.locateMessageBuilder();
+      msgBuilder.newMessage(msgRef.getName());
+      for (String propName : msgRef.getPropertyNames())
+      {
+        Object value = att.getAttachment(propName);
+        if (value == null)
+          throw new IllegalStateException("Cannot obtain required property: " + propName);
+        msgBuilder.addProperty(propName, value);
+      }
+      Message resMessage = msgBuilder.getMessage();
+      
+      MessageService msgService = MessageService.locateMessageService();
+      
+      ObjectName procID = userTask.getProcess().getKey();
+      msgService.sendMessage(procID, userTask.getName(), resMessage);
+    }
+
+    @Override
+    public ObjectName getKey()
+    {
+      String oname = userTask.getKey().getCanonicalName();
+      return ObjectNameFactory.create(oname + ",msgListener=UserTaskCallback");
+    }
+  }
+}
\ No newline at end of file


Property changes on: projects/spec/trunk/modules/api/src/main/java/org/jbpm/api/model/UserTaskCallback.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF

Modified: projects/spec/trunk/modules/cts/src/test/java/org/jbpm/test/cts/task/ReceiveTaskTest.java
===================================================================
--- projects/spec/trunk/modules/cts/src/test/java/org/jbpm/test/cts/task/ReceiveTaskTest.java	2008-10-08 10:08:08 UTC (rev 2505)
+++ projects/spec/trunk/modules/cts/src/test/java/org/jbpm/test/cts/task/ReceiveTaskTest.java	2008-10-08 11:06:20 UTC (rev 2506)
@@ -55,7 +55,7 @@
  */
 public class ReceiveTaskTest extends CTSTestCase
 {
-  public void _testReceiveTaskWithNoMessage() throws Exception
+  public void testReceiveTaskWithNoMessage() throws Exception
   {
     ProcessBuilder procBuilder = ProcessBuilderService.locateProcessBuilder();
     procBuilder.addProcess("ReceiveTaskTest").addStartEvent("Start").addSequenceFlow("TaskA");
@@ -71,7 +71,7 @@
     }
   }
 
-  public void _testUnregisteredProcess() throws Exception
+  public void testUnregisteredProcess() throws Exception
   {
     ProcessDefinition procDef = unregisterOnTearDown(getProcessDefinition());
     Process proc = procDef.newInstance();
@@ -88,7 +88,7 @@
     }
   }
 
-  public void _testSuspendedMessage() throws Exception
+  public void testSuspendedMessage() throws Exception
   {
     ProcessDefinitionService procDefService = ProcessDefinitionService.locateProcessDefinitionService();
     ProcessService procService = ProcessService.locateProcessService();
@@ -146,7 +146,7 @@
     try
     {
       proc.startProcess();
-      proc.waitForEnd();
+      proc.waitForEnd(1000);
     }
     finally
     {

Added: projects/spec/trunk/modules/cts/src/test/java/org/jbpm/test/cts/task/UserTaskCallbackTest.java
===================================================================
--- projects/spec/trunk/modules/cts/src/test/java/org/jbpm/test/cts/task/UserTaskCallbackTest.java	                        (rev 0)
+++ projects/spec/trunk/modules/cts/src/test/java/org/jbpm/test/cts/task/UserTaskCallbackTest.java	2008-10-08 11:06:20 UTC (rev 2506)
@@ -0,0 +1,91 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.test.cts.task;
+
+// $Id$
+
+import java.io.IOException;
+import java.util.List;
+
+import org.jbpm.api.model.Message;
+import org.jbpm.api.model.Process;
+import org.jbpm.api.model.ProcessDefinition;
+import org.jbpm.api.model.UserTask;
+import org.jbpm.api.model.UserTaskCallback;
+import org.jbpm.api.model.Event.EventDetailType;
+import org.jbpm.api.model.Task.TaskType;
+import org.jbpm.api.model.builder.ProcessBuilder;
+import org.jbpm.api.runtime.Attachments;
+import org.jbpm.api.runtime.BasicAttachments;
+import org.jbpm.api.service.ProcessBuilderService;
+import org.jbpm.api.test.CTSTestCase;
+
+/**
+ * Test User Task
+ * 
+ * @author thomas.diesler at jboss.com
+ * @since 07-Oct-2008
+ */
+public class UserTaskCallbackTest extends CTSTestCase
+{
+  public void testUserTask() throws Exception
+  {
+    ProcessDefinition procDef = unregisterOnTearDown(getProcessDefinition());
+    Process proc = procDef.newInstance();
+
+    // Attach the callback to the UserTask
+    UserTask userTask = proc.getNode(UserTask.class, "UserTask");
+    userTask.setUserTaskCallback(new TaskCallback());
+
+    BasicAttachments att = new BasicAttachments();
+    att.addAttachment("foo", "xxx");
+    proc.startProcess(att);
+    proc.waitForEnd();
+
+    List<Message> messages = getMessages();
+    assertEquals(1, messages.size());
+    assertEquals("xxx", messages.get(0).getProperty("bar").getValue());
+  }
+
+  protected ProcessDefinition getProcessDefinition() throws IOException
+  {
+    ProcessBuilder procBuilder = ProcessBuilderService.locateProcessBuilder();
+    procBuilder.addProcess("UserTaskTest");
+    procBuilder.addProcessMessage("OutMessage").addProperty("foo", null, true);
+    procBuilder.addProcessMessage("InMessage").addProperty("bar", null, true);
+    procBuilder.addProcessMessage("EndMessage").addToRef(getTestID()).addProperty("bar", null, true);
+    procBuilder.addStartEvent("Start").addSequenceFlow("UserTask");
+    procBuilder.addTask("UserTask", TaskType.User).addOutMessageRef("OutMessage").addInMessageRef("InMessage");
+    procBuilder.addSequenceFlow("End").addEndEvent("End", EventDetailType.Message).addMessageRef("EndMessage");
+    return procBuilder.getProcessDefinition();
+  }
+  
+  public static class TaskCallback extends UserTaskCallback
+  {
+    @Override
+    public void callback(Attachments att)
+    {
+      Object value = att.removeAttachment("foo");
+      att.addAttachment("bar", value);
+    }
+  }
+}


Property changes on: projects/spec/trunk/modules/cts/src/test/java/org/jbpm/test/cts/task/UserTaskCallbackTest.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF

Modified: projects/spec/trunk/modules/cts/src/test/java/org/jbpm/test/cts/task/UserTaskTest.java
===================================================================
--- projects/spec/trunk/modules/cts/src/test/java/org/jbpm/test/cts/task/UserTaskTest.java	2008-10-08 10:08:08 UTC (rev 2505)
+++ projects/spec/trunk/modules/cts/src/test/java/org/jbpm/test/cts/task/UserTaskTest.java	2008-10-08 11:06:20 UTC (rev 2506)
@@ -55,16 +55,16 @@
 {
   static final ObjectName MSG_LISTENER_ID = ObjectNameFactory.create(Constants.ID_DOMAIN, "msgListener", "UserTaskTest");
   
-  public void testSendTask() throws Exception
+  public void testUserTask() throws Exception
   {
     ProcessDefinition procDef = unregisterOnTearDown(getProcessDefinition());
     Process proc = procDef.newInstance();
     
-    // Register the process - this assignes the procID
+    // Register the process - this assigns the procID
     ProcessService procService = ProcessService.locateProcessService();
     procService.registerProcess(proc);
     
-    // Add the message user message listener
+    // Add the user message listener
     MessageService msgService = MessageService.locateMessageService();
     msgService.addMessageListener(new UserMessageListener(proc.getKey()));
     
@@ -73,7 +73,7 @@
       BasicAttachments att = new BasicAttachments();
       att.addAttachment("foo", "xxx");
       proc.startProcess(att);
-      proc.waitForEnd();
+      proc.waitForEnd(1000);
       
       List<Message> messages = getMessages();
       assertEquals(1, messages.size());
@@ -92,8 +92,8 @@
     procBuilder.addProcessMessage("OutMessage").addToRef(MSG_LISTENER_ID).addProperty("foo", null, true);
     procBuilder.addProcessMessage("InMessage").addProperty("bar", null, true);
     procBuilder.addProcessMessage("EndMessage").addToRef(getTestID()).addProperty("bar", null, true);
-    procBuilder.addStartEvent("Start").addSequenceFlow("TaskA");
-    procBuilder.addTask("TaskA", TaskType.User).addOutMessageRef("OutMessage").addInMessageRef("InMessage");
+    procBuilder.addStartEvent("Start").addSequenceFlow("UserTask");
+    procBuilder.addTask("UserTask", TaskType.User).addOutMessageRef("OutMessage").addInMessageRef("InMessage");
     procBuilder.addSequenceFlow("End").addEndEvent("End", EventDetailType.Message).addMessageRef("EndMessage");
     return procBuilder.getProcessDefinition();
   }
@@ -115,7 +115,7 @@
       Message resMessage = msgBuilder.newMessage("InMessage").addProperty("bar", propValue, true).getMessage();
       
       MessageService msgService = MessageService.locateMessageService();
-      msgService.sendMessage(procID, "TaskA", resMessage);
+      msgService.sendMessage(procID, "UserTask", resMessage);
     }
 
     @Override

Modified: projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/UserTaskImpl.java
===================================================================
--- projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/UserTaskImpl.java	2008-10-08 10:08:08 UTC (rev 2505)
+++ projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/model/UserTaskImpl.java	2008-10-08 11:06:20 UTC (rev 2506)
@@ -26,6 +26,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.management.ObjectName;
 import javax.persistence.Entity;
 import javax.persistence.Transient;
 
@@ -35,6 +36,8 @@
 import org.jbpm.api.model.Process;
 import org.jbpm.api.model.ProcessDefinition;
 import org.jbpm.api.model.ProcessStructure;
+import org.jbpm.api.model.UserTask;
+import org.jbpm.api.model.UserTaskCallback;
 import org.jbpm.api.runtime.ExecutionContext;
 import org.jbpm.api.runtime.Token;
 import org.jbpm.api.runtime.TokenExecutor;
@@ -50,7 +53,7 @@
  * @since 08-Jul-2008
  */
 @Entity(name = "UserTask")
-public class UserTaskImpl extends TaskImpl implements MessageListener
+public class UserTaskImpl extends TaskImpl implements UserTask, MessageListener
 {
   private static final long serialVersionUID = 1L;
 
@@ -72,6 +75,9 @@
   @Transient
   private transient TokenExecutor tokenExecutor;
   
+  @Transient
+  private transient UserTaskCallback userCallback;
+  
   public UserTaskImpl(ProcessStructure procStruct, String name)
   {
     super(procStruct, name, TaskType.User);
@@ -82,6 +88,19 @@
   {
   }
 
+  @Override
+  public UserTaskCallback getUserTaskCallback()
+  {
+    return userCallback;
+  }
+
+  @Override
+  public void setUserTaskCallback(UserTaskCallback callback)
+  {
+    this.userCallback = callback;
+  }
+
+  @Override
   public Message getOutMessageRef()
   {
     return outMessageRef;
@@ -92,6 +111,7 @@
     this.outMessageRef = message;
   }
 
+  @Override
   public Message getInMessageRef()
   {
     return inMessageRef;
@@ -188,4 +208,28 @@
     procDefImpl.initializeMessageRef(outMessageRef);
     procDefImpl.initializeMessageRef(inMessageRef);
   }
+
+  @Override
+  protected void register(Process proc)
+  {
+    super.register(proc);
+    
+    if (userCallback != null)
+    {
+      userCallback.attach(this);
+
+      // Redirect the outgoing message to the callback message listener
+      ObjectName listenerID = userCallback.getMessageListener().getKey();
+      outMessageRef.setToRef(new ParticipantImpl(listenerID));
+    }
+  }
+
+  @Override
+  protected void unregister(Process proc)
+  {
+    super.unregister(proc);
+    
+    if (userCallback != null)
+      userCallback.detach(this);
+  }
 }
\ No newline at end of file

Modified: projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/runtime/MessageSender.java
===================================================================
--- projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/runtime/MessageSender.java	2008-10-08 10:08:08 UTC (rev 2505)
+++ projects/spec/trunk/modules/impl/src/main/java/org/jbpm/ri/runtime/MessageSender.java	2008-10-08 11:06:20 UTC (rev 2506)
@@ -54,7 +54,7 @@
   {
     this.fromNode = fromNode;
     this.messageRef = messageRef;
-    this.fromRef = new ParticipantImpl(fromNode.getProcessDefinition().getKey());
+    this.fromRef = new ParticipantImpl(fromNode.getKey());
     
     if (messageRef == null)
       throw new IllegalArgumentException("MessageRef cannot be null");




More information about the jbpm-commits mailing list