[jboss-svn-commits] JBL Code SVN: r26014 - in labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task: event and 1 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Fri Apr 10 19:02:03 EDT 2009


Author: stampy88
Date: 2009-04-10 19:02:03 -0400 (Fri, 10 Apr 2009)
New Revision: 26014

Added:
   labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/CannotAddTaskException.java
   labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/PermissionDeniedException.java
   labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/TaskException.java
Modified:
   labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/AccessType.java
   labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/AllowedToDelegate.java
   labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/Attachment.java
   labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/Content.java
   labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/Notification.java
   labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/NotificationType.java
   labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/Reassignment.java
   labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/Status.java
   labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/TaskData.java
   labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/event/TaskEvent.java
   labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/Allowed.java
   labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/CommandName.java
   labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/Operation.java
   labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/SendIcal.java
   labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/TaskServerHandler.java
   labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/TaskService.java
   labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/TaskServiceSession.java
Log:
Refactoring of TaskServiceSession part 1. Moved some business logic into classes, ensure transactions are properly handled, added some new exceptions, catch exceptions in server, etc.

Modified: labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/AccessType.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/AccessType.java	2009-04-10 22:53:48 UTC (rev 26013)
+++ labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/AccessType.java	2009-04-10 23:02:03 UTC (rev 26014)
@@ -4,5 +4,5 @@
 package org.drools.task;
 
 public enum AccessType {
-    Inline, Url;
+    Inline, Url
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/AllowedToDelegate.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/AllowedToDelegate.java	2009-04-10 22:53:48 UTC (rev 26013)
+++ labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/AllowedToDelegate.java	2009-04-10 23:02:03 UTC (rev 26014)
@@ -4,5 +4,5 @@
 package org.drools.task;
 
 public enum AllowedToDelegate {
-    Anybody, Nobody, PotentialOwners, Other;
+    Anybody, Nobody, PotentialOwners, Other
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/Attachment.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/Attachment.java	2009-04-10 22:53:48 UTC (rev 26013)
+++ labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/Attachment.java	2009-04-10 23:02:03 UTC (rev 26014)
@@ -118,6 +118,15 @@
         return size;
     }
 
+    /**
+     * Sets the content for this attachment, i.e. the <field>size</field> and the <field>attachmentContentId</field>.
+     * @param content attachment content
+     */
+    public void setContent(Content content) {
+        setSize(content.getContent().length);
+        setAttachmentContentId(content.getId());
+    }
+
     public void setSize(int size) {
         this.size = size;
     }

Modified: labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/Content.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/Content.java	2009-04-10 22:53:48 UTC (rev 26013)
+++ labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/Content.java	2009-04-10 23:02:03 UTC (rev 26014)
@@ -23,7 +23,11 @@
     
     public Content() {
         
-    }    
+    }
+
+    public Content(byte[] content) {
+        this.content = content;
+    }
     
     public void writeExternal(ObjectOutput out) throws IOException {
         out.writeLong( id );

Modified: labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/Notification.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/Notification.java	2009-04-10 22:53:48 UTC (rev 26013)
+++ labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/Notification.java	2009-04-10 23:02:03 UTC (rev 26014)
@@ -34,7 +34,7 @@
     
     @ManyToMany
     @JoinTable(name = "Notification_Recipients", joinColumns = @JoinColumn(name = "task_id"), inverseJoinColumns = @JoinColumn(name = "entity_id"))    
-    private List<OrganizationalEntity>       recipients = Collections.emptyList();;
+    private List<OrganizationalEntity>       recipients = Collections.emptyList();
 
     @ManyToMany
     @JoinTable(name = "Notification_BusinessAdministrators", joinColumns = @JoinColumn(name = "task_id"), inverseJoinColumns = @JoinColumn(name = "entity_id"))

Modified: labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/NotificationType.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/NotificationType.java	2009-04-10 22:53:48 UTC (rev 26013)
+++ labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/NotificationType.java	2009-04-10 23:02:03 UTC (rev 26014)
@@ -1,5 +1,5 @@
 package org.drools.task;
 
 public enum NotificationType {
-    Default, Email;
+    Default, Email
 }

Modified: labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/Reassignment.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/Reassignment.java	2009-04-10 22:53:48 UTC (rev 26013)
+++ labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/Reassignment.java	2009-04-10 23:02:03 UTC (rev 26014)
@@ -27,11 +27,11 @@
 
     @OneToMany(cascade = CascadeType.ALL)
     @JoinColumn(name = "Reassignment_Documentation_Id", nullable = true)     
-    private List<I18NText>             documentation = Collections.emptyList();; 
+    private List<I18NText>             documentation = Collections.emptyList();
     
     @ManyToMany
     @JoinTable(name = "Reassignment_potentialOwners", joinColumns = @JoinColumn(name = "task_id"), inverseJoinColumns = @JoinColumn(name = "entity_id"))    
-    private List<OrganizationalEntity> potentialOwners = Collections.emptyList();;
+    private List<OrganizationalEntity> potentialOwners = Collections.emptyList();
 
     public void writeExternal(ObjectOutput out) throws IOException {
         out.writeLong( id );

Modified: labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/Status.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/Status.java	2009-04-10 22:53:48 UTC (rev 26013)
+++ labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/Status.java	2009-04-10 23:02:03 UTC (rev 26014)
@@ -2,5 +2,5 @@
 
 
 public enum Status {
-    Created, Ready, Reserved, InProgress, Suspended, Completed, Failed, Error, Exited, Obsolete;
+    Created, Ready, Reserved, InProgress, Suspended, Completed, Failed, Error, Exited, Obsolete
 }

Modified: labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/TaskData.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/TaskData.java	2009-04-10 22:53:48 UTC (rev 26013)
+++ labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/TaskData.java	2009-04-10 23:02:03 UTC (rev 26014)
@@ -1,306 +1,377 @@
 package org.drools.task;
 
+import org.drools.task.service.FaultData;
+import org.drools.task.service.ContentData;
+import org.drools.task.utils.CollectionUtils;
+
+import javax.persistence.*;
 import java.io.Externalizable;
 import java.io.IOException;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 
-import javax.persistence.CascadeType;
-import javax.persistence.Embeddable;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-import javax.persistence.JoinColumn;
-import javax.persistence.ManyToOne;
-import javax.persistence.OneToMany;
-
-import org.drools.task.utils.CollectionUtils;
-
 @Embeddable
 public class TaskData
-    implements
-    Externalizable {
+        implements
+        Externalizable {
     @Enumerated(EnumType.STRING)
-    private Status           status      = Status.Created;         // initial default state
+    private Status status = Status.Created;         // initial default state
 
-    private Status           previousStatus = null;
+    private Status previousStatus = null;
 
     @ManyToOne()
-    private User             actualOwner;
+    private User actualOwner;
 
     @ManyToOne()
-    private User             createdBy;
+    private User createdBy;
 
-    private Date             createdOn;
+    private Date createdOn;
 
-    private Date             activationTime;
+    private Date activationTime;
 
-    private Date             expirationTime;
+    private Date expirationTime;
 
-    private boolean          skipable;
+    private boolean skipable;
 
-    private long             workItemId = -1;
+    private long workItemId = -1;
 
-    private AccessType       documentAccessType;
+    private AccessType documentAccessType;
 
-    private String           documentType;
+    private String documentType;
 
-    private long             documentContentId = -1;
+    private long documentContentId = -1;
 
-    private AccessType       outputAccessType;
+    private AccessType outputAccessType;
 
-    private String           outputType;
+    private String outputType;
 
-    private long             outputContentId = -1;
+    private long outputContentId = -1;
 
-    private String 	         faultName;
+    private String faultName;
 
-    private AccessType       faultAccessType;
+    private AccessType faultAccessType;
 
-    private String           faultType;
+    private String faultType;
 
-    private long             faultContentId = -1;
+    private long faultContentId = -1;
 
-    private long             parentId = -1;
+    private long parentId = -1;
 
     @OneToMany(cascade = CascadeType.ALL)
     @JoinColumn(name = "TaskData_Comments_Id", nullable = true)
-    private List<Comment>    comments    = Collections.emptyList();
+    private List<Comment> comments = Collections.emptyList();
 
     @OneToMany(cascade = CascadeType.ALL)
     @JoinColumn(name = "TaskData_Attachments_Id", nullable = true)
     private List<Attachment> attachments = Collections.emptyList();
 
     public void writeExternal(ObjectOutput out) throws IOException {
-        if ( status != null ) {
-            out.writeBoolean( true );
-            out.writeUTF( status.toString() );
+        if (status != null) {
+            out.writeBoolean(true);
+            out.writeUTF(status.toString());
         } else {
-            out.writeBoolean( false );
+            out.writeBoolean(false);
         }
 
-        if ( previousStatus != null ) {
-            out.writeBoolean( true );
-            out.writeUTF( previousStatus.toString() );
+        if (previousStatus != null) {
+            out.writeBoolean(true);
+            out.writeUTF(previousStatus.toString());
         } else {
-            out.writeBoolean( false );
+            out.writeBoolean(false);
         }
 
-        if ( actualOwner != null ) {
-            out.writeBoolean( true );
-            actualOwner.writeExternal( out );
+        if (actualOwner != null) {
+            out.writeBoolean(true);
+            actualOwner.writeExternal(out);
         } else {
-            out.writeBoolean( false );
+            out.writeBoolean(false);
         }
 
-        if ( createdBy != null ) {
-            out.writeBoolean( true );
-            createdBy.writeExternal( out );
+        if (createdBy != null) {
+            out.writeBoolean(true);
+            createdBy.writeExternal(out);
         } else {
-            out.writeBoolean( false );
+            out.writeBoolean(false);
         }
 
-        if ( createdOn != null ) {
-            out.writeBoolean( true );
-            out.writeLong( createdOn.getTime() );
+        if (createdOn != null) {
+            out.writeBoolean(true);
+            out.writeLong(createdOn.getTime());
         } else {
-            out.writeBoolean( false );
+            out.writeBoolean(false);
         }
 
-        if ( activationTime != null ) {
-            out.writeBoolean( true );
-            out.writeLong( activationTime.getTime() );
+        if (activationTime != null) {
+            out.writeBoolean(true);
+            out.writeLong(activationTime.getTime());
         } else {
-            out.writeBoolean( false );
+            out.writeBoolean(false);
         }
 
-        if ( expirationTime != null ) {
-            out.writeBoolean( true );
-            out.writeLong( expirationTime.getTime() );
+        if (expirationTime != null) {
+            out.writeBoolean(true);
+            out.writeLong(expirationTime.getTime());
         } else {
-            out.writeBoolean( false );
+            out.writeBoolean(false);
         }
 
-        out.writeBoolean( skipable );
+        out.writeBoolean(skipable);
 
-        if ( workItemId != -1 ) {
-            out.writeBoolean( true );
-            out.writeLong( workItemId );
+        if (workItemId != -1) {
+            out.writeBoolean(true);
+            out.writeLong(workItemId);
         } else {
-            out.writeBoolean( false );
+            out.writeBoolean(false);
         }
 
-        if ( documentAccessType != null ) {
-            out.writeBoolean( true );
-            out.writeObject( documentAccessType );
+        if (documentAccessType != null) {
+            out.writeBoolean(true);
+            out.writeObject(documentAccessType);
         } else {
-            out.writeBoolean( false );
+            out.writeBoolean(false);
         }
 
-        if ( documentType != null ) {
-            out.writeBoolean( true );
-            out.writeUTF( documentType );
+        if (documentType != null) {
+            out.writeBoolean(true);
+            out.writeUTF(documentType);
         } else {
-            out.writeBoolean( false );
+            out.writeBoolean(false);
         }
 
-        if ( documentContentId != -1 ) {
-            out.writeBoolean( true );
-            out.writeLong( documentContentId );
+        if (documentContentId != -1) {
+            out.writeBoolean(true);
+            out.writeLong(documentContentId);
         } else {
-            out.writeBoolean( false );
+            out.writeBoolean(false);
         }
 
-        if ( outputAccessType != null ) {
-            out.writeBoolean( true );
-            out.writeObject( outputAccessType );
+        if (outputAccessType != null) {
+            out.writeBoolean(true);
+            out.writeObject(outputAccessType);
         } else {
-            out.writeBoolean( false );
+            out.writeBoolean(false);
         }
 
-        if ( outputType != null ) {
-            out.writeBoolean( true );
-            out.writeUTF( outputType );
+        if (outputType != null) {
+            out.writeBoolean(true);
+            out.writeUTF(outputType);
         } else {
-            out.writeBoolean( false );
+            out.writeBoolean(false);
         }
 
-        if ( outputContentId != -1 ) {
-            out.writeBoolean( true );
-            out.writeLong( outputContentId );
+        if (outputContentId != -1) {
+            out.writeBoolean(true);
+            out.writeLong(outputContentId);
         } else {
-            out.writeBoolean( false );
+            out.writeBoolean(false);
         }
 
-        if ( faultName != null ) {
-            out.writeBoolean( true );
-            out.writeUTF( faultName );
+        if (faultName != null) {
+            out.writeBoolean(true);
+            out.writeUTF(faultName);
         } else {
-            out.writeBoolean( false );
+            out.writeBoolean(false);
         }
 
-        if ( faultAccessType != null ) {
-            out.writeBoolean( true );
-            out.writeObject( faultAccessType );
+        if (faultAccessType != null) {
+            out.writeBoolean(true);
+            out.writeObject(faultAccessType);
         } else {
-            out.writeBoolean( false );
+            out.writeBoolean(false);
         }
 
-        if ( faultType != null ) {
-            out.writeBoolean( true );
-            out.writeUTF( faultType );
+        if (faultType != null) {
+            out.writeBoolean(true);
+            out.writeUTF(faultType);
         } else {
-            out.writeBoolean( false );
+            out.writeBoolean(false);
         }
 
-        if ( faultContentId != -1 ) {
-            out.writeBoolean( true );
-            out.writeLong( faultContentId );
+        if (faultContentId != -1) {
+            out.writeBoolean(true);
+            out.writeLong(faultContentId);
         } else {
-            out.writeBoolean( false );
+            out.writeBoolean(false);
         }
 
-        if ( parentId != -1 ) {
-            out.writeBoolean( true );
-            out.writeLong( parentId );
+        if (parentId != -1) {
+            out.writeBoolean(true);
+            out.writeLong(parentId);
         } else {
-            out.writeBoolean( false );
+            out.writeBoolean(false);
         }
 
-        CollectionUtils.writeCommentList( comments,
-                                          out );
-        CollectionUtils.writeAttachmentList( attachments,
-                                             out );
+        CollectionUtils.writeCommentList(comments,
+                out);
+        CollectionUtils.writeAttachmentList(attachments,
+                out);
     }
 
     public void readExternal(ObjectInput in) throws IOException,
-                                            ClassNotFoundException {
-        if ( in.readBoolean() ) {
-            status = Status.valueOf( in.readUTF() );
+            ClassNotFoundException {
+        if (in.readBoolean()) {
+            status = Status.valueOf(in.readUTF());
         }
 
-        if ( in.readBoolean() ) {
-            previousStatus = Status.valueOf( in.readUTF() );
+        if (in.readBoolean()) {
+            previousStatus = Status.valueOf(in.readUTF());
         }
 
-        if ( in.readBoolean() ) {
+        if (in.readBoolean()) {
             actualOwner = new User();
-            actualOwner.readExternal( in );
+            actualOwner.readExternal(in);
         }
 
-        if ( in.readBoolean() ) {
+        if (in.readBoolean()) {
             createdBy = new User();
-            createdBy.readExternal( in );
+            createdBy.readExternal(in);
         }
 
-        if ( in.readBoolean() ) {
-            createdOn = new Date( in.readLong() );
+        if (in.readBoolean()) {
+            createdOn = new Date(in.readLong());
         }
 
-        if ( in.readBoolean() ) {
-            activationTime = new Date( in.readLong() );
+        if (in.readBoolean()) {
+            activationTime = new Date(in.readLong());
         }
 
-        if ( in.readBoolean() ) {
-            expirationTime = new Date( in.readLong() );
+        if (in.readBoolean()) {
+            expirationTime = new Date(in.readLong());
         }
 
         skipable = in.readBoolean();
 
-        if ( in.readBoolean() ) {
+        if (in.readBoolean()) {
             workItemId = in.readLong();
         }
 
-        if ( in.readBoolean() ) {
+        if (in.readBoolean()) {
             documentAccessType = (AccessType) in.readObject();
         }
 
-        if ( in.readBoolean() ) {
+        if (in.readBoolean()) {
             documentType = in.readUTF();
         }
 
-        if ( in.readBoolean() ) {
+        if (in.readBoolean()) {
             documentContentId = in.readLong();
         }
 
-        if ( in.readBoolean() ) {
+        if (in.readBoolean()) {
             outputAccessType = (AccessType) in.readObject();
         }
 
-        if ( in.readBoolean() ) {
+        if (in.readBoolean()) {
             outputType = in.readUTF();
         }
 
-        if ( in.readBoolean() ) {
+        if (in.readBoolean()) {
             outputContentId = in.readLong();
         }
 
-        if ( in.readBoolean() ) {
+        if (in.readBoolean()) {
             faultName = in.readUTF();
         }
 
-        if ( in.readBoolean() ) {
+        if (in.readBoolean()) {
             faultAccessType = (AccessType) in.readObject();
         }
 
-        if ( in.readBoolean() ) {
+        if (in.readBoolean()) {
             faultType = in.readUTF();
         }
 
-        if ( in.readBoolean() ) {
+        if (in.readBoolean()) {
             faultContentId = in.readLong();
         }
 
-        if ( in.readBoolean() ) {
+        if (in.readBoolean()) {
             parentId = in.readLong();
         }
-        comments = CollectionUtils.readCommentList( in );
-        attachments = CollectionUtils.readAttachmentList( in );
+        comments = CollectionUtils.readCommentList(in);
+        attachments = CollectionUtils.readAttachmentList(in);
 
     }
 
+    /**
+     * Initializes the state of the TaskData, i.e. sets the <field>createdOn</field>, <field>activationTime</field>
+     * and sets the state to <code>Status.Created</code>.
+     *
+     * @return returns the current state of the TaskData
+     */
+    public Status initialize() {
+        Date createdOn = getCreatedOn();
+        // set the CreatedOn date if it's not already set
+        if (createdOn == null) {
+            createdOn = new Date();
+            setCreatedOn(createdOn);
+        }
+
+        //@FIXME for now we activate on creation, unless date is supplied
+        if (getActivationTime() == null) {
+            setActivationTime(createdOn);
+        }
+
+        setStatus(Status.Created);
+
+        return Status.Created;
+    }
+
+    /**
+     * This method will potentially assign the actual owner of this TaskData and set the status
+     * of the data.
+     * <li>If there is only 1 potential owner, and it is a <code>User</code>, that will become the actual
+     * owner of the TaskData and the status will be set to <code>Status.Reserved</code>.</li>
+     * <li>f there is only 1 potential owner, and it is a <code>Group</code>,  no owner will be assigned
+     * and the status will be set to <code>Status.Ready</code>.</li>
+     * <li>If there are more than 1 potential owners, the status will be set to <code>Status.Ready</code>.</li>
+     * <li>otherwise, the task data will be unchanged</li>
+     *
+     * @param potentialOwners - list of potential owners
+     * @return current status of task data
+     */
+    public Status assignOwnerAndStatus(List<OrganizationalEntity> potentialOwners) {
+        if (getStatus() != Status.Created) {
+            throw new IllegalStateException("Can only assign task owner if status is Created!");
+        }
+
+        Status assignedStatus = null;
+
+        if (potentialOwners.size() == 1) {
+            // if there is a single potential owner, assign and set status to Reserved
+            OrganizationalEntity potentialOwner = potentialOwners.get(0);
+            // if there is a single potential user owner, assign and set status to Reserved
+            if (potentialOwner instanceof User) {
+                setActualOwner((User) potentialOwner);
+
+                assignedStatus = Status.Reserved;
+            }
+            //If there is a group set as potentialOwners, set the status to Ready ??
+            if (potentialOwner instanceof Group) {
+
+                assignedStatus = Status.Ready;
+            }
+        } else if (potentialOwners.size() > 1) {
+            // multiple potential owners, so set to Ready so one can claim.
+            assignedStatus = Status.Ready;
+        } else {
+            //@TODO we have no potential owners
+        }
+
+        if (assignedStatus != null) {
+            setStatus(assignedStatus);
+        } else {
+            // status wasn't assigned, so just return the currrent status
+            assignedStatus = getStatus();
+        }
+
+        return assignedStatus;
+    }
+
     public Status getStatus() {
         return status;
     }
@@ -342,7 +413,7 @@
         this.createdOn = createdOn;
     }
 
-    public Date getActivationTime() {
+    Date getActivationTime() {
         return activationTime;
     }
 
@@ -367,13 +438,26 @@
     }
 
     public void setWorkItemId(long workItemId) {
-    	this.workItemId = workItemId;
+        this.workItemId = workItemId;
     }
 
     public long getWorkItemId() {
-    	return workItemId;
+        return workItemId;
     }
 
+    /**
+     * Sets the document content data for this task data. It will set the <field>documentContentId</field> from the specified
+     * documentID, <field>documentAccessType</field>, <field>documentType</field> from the specified
+     * documentConentData.
+     * @param documentID id of document content
+     * @param documentConentData ContentData
+     */
+    public void setDocument(long documentID, ContentData documentConentData) {
+        setDocumentContentId(documentID);
+        setDocumentAccessType(documentConentData.getAccessType());
+        setDocumentType(documentConentData.getType());
+    }
+
     public AccessType getDocumentAccessType() {
         return documentAccessType;
     }
@@ -398,66 +482,129 @@
         this.documentType = documentType;
     }
 
+    /**
+     * Sets the content data for this task data. It will set the <field>outputContentId</field> from the specified
+     * outputContentId, <field>outputAccessType</field>, <field>outputType</field> from the specified
+     * outputContentData.
+     * @param outputContentId id of output content
+     * @param outputContentData contentData
+     */
+    public void setOutput(long outputContentId, ContentData outputContentData) {
+        setOutputContentId(outputContentId);
+        setOutputAccessType(outputContentData.getAccessType());
+        setOutputType(outputContentData.getType());
+    }
+
     public AccessType getOutputAccessType() {
-		return outputAccessType;
-	}
+        return outputAccessType;
+    }
 
-	public void setOutputAccessType(AccessType outputAccessType) {
-		this.outputAccessType = outputAccessType;
-	}
+    void setOutputAccessType(AccessType outputAccessType) {
+        this.outputAccessType = outputAccessType;
+    }
 
-	public String getOutputType() {
-		return outputType;
-	}
+    public String getOutputType() {
+        return outputType;
+    }
 
-	public void setOutputType(String outputType) {
-		this.outputType = outputType;
-	}
+    void setOutputType(String outputType) {
+        this.outputType = outputType;
+    }
 
-	public long getOutputContentId() {
-		return outputContentId;
-	}
+    public long getOutputContentId() {
+        return outputContentId;
+    }
 
-	public void setOutputContentId(long outputContentId) {
-		this.outputContentId = outputContentId;
-	}
+    void setOutputContentId(long outputContentId) {
+        this.outputContentId = outputContentId;
+    }
 
-	public String getFaultName() {
-		return faultName;
-	}
+    /**
+     * Sets the fault data for this task data. It will set the <field>faultContentId</field> from the specified
+     * faultContentId, <field>faultAccessType</field>, <field>faultType</field>, <field>faultName</field> from the
+     * specified faultData.
+     * @param faultContentId id of fault content
+     * @param faultData FaultData
+     */
+    public void setFault(long faultContentId, FaultData faultData) {
+        setFaultContentId(faultContentId);
+        setFaultAccessType(faultData.getAccessType());
+        setFaultType(faultData.getType());
+        setFaultName(faultData.getFaultName());
+    }
 
-	public void setFaultName(String faultName) {
-		this.faultName = faultName;
-	}
+    public String getFaultName() {
+        return faultName;
+    }
 
-	public AccessType getFaultAccessType() {
-		return faultAccessType;
-	}
+    void setFaultName(String faultName) {
+        this.faultName = faultName;
+    }
 
-	public void setFaultAccessType(AccessType faultAccessType) {
-		this.faultAccessType = faultAccessType;
-	}
+    public AccessType getFaultAccessType() {
+        return faultAccessType;
+    }
 
-	public String getFaultType() {
-		return faultType;
-	}
+    void setFaultAccessType(AccessType faultAccessType) {
+        this.faultAccessType = faultAccessType;
+    }
 
-	public void setFaultType(String faultType) {
-		this.faultType = faultType;
-	}
+    public String getFaultType() {
+        return faultType;
+    }
 
-	public long getFaultContentId() {
-		return faultContentId;
-	}
+    void setFaultType(String faultType) {
+        this.faultType = faultType;
+    }
 
-	public void setFaultContentId(long faultContentId) {
-		this.faultContentId = faultContentId;
-	}
+    public long getFaultContentId() {
+        return faultContentId;
+    }
 
-	public List<Comment> getComments() {
+    void setFaultContentId(long faultContentId) {
+        this.faultContentId = faultContentId;
+    }
+
+    public List<Comment> getComments() {
         return comments;
     }
 
+    /**
+     * Adds the specified comment to our list of comments.
+     *
+     * @param comment comment to add
+     */
+    public void addComment(Comment comment) {
+        if (comments == null || comments == Collections.<Comment>emptyList()) {
+            comments = new ArrayList<Comment>();
+        }
+
+        comments.add(comment);
+    }
+
+    /**
+     * Removes the Comment specified by the commentId.
+     *
+     * @param commentId id of Comment to remove
+     * @return removed Comment or null if one was not found with the id
+     */
+    public Comment removeComment(final long commentId) {
+        Comment removedComment = null;
+
+        if (comments != null) {
+            for (int index = comments.size() - 1; index >= 0; --index) {
+                Comment currentComment = comments.get(index);
+
+                if (currentComment.getId() == commentId) {
+                    removedComment = comments.remove(index);
+                    break;
+                }
+            }
+        }
+
+        return removedComment;
+    }
+
     public void setComments(List<Comment> comments) {
         this.comments = comments;
     }
@@ -466,6 +613,42 @@
         return attachments;
     }
 
+    /**
+     * Adds the specified attachment to our list of Attachments.
+     *
+     * @param attachment attachment to add
+     */
+    public void addAttachment(Attachment attachment) {
+        if (attachments == null || attachments == Collections.<Attachment>emptyList()) {
+            attachments = new ArrayList<Attachment>();
+        }
+
+        attachments.add(attachment);
+    }
+
+    /**
+     * Removes the Attachment specified by the attachmentId.
+     *
+     * @param attachmentId id of attachment to remove
+     * @return removed Attachment or null if one was not found with the id
+     */
+    public Attachment removeAttachment(final long attachmentId) {
+        Attachment removedAttachment = null;
+
+        if (attachments != null) {
+            for (int index = attachments.size() - 1; index >= 0; --index) {
+                Attachment currentAttachment = attachments.get(index);
+
+                if (currentAttachment.getId() == attachmentId) {
+                    removedAttachment = attachments.remove(index);
+                    break;
+                }
+            }
+        }
+
+        return removedAttachment;
+    }
+
     public void setAttachments(List<Attachment> attachments) {
         this.attachments = attachments;
     }
@@ -483,8 +666,8 @@
         final int prime = 31;
         int result = 1;
         result = prime * result + ((activationTime == null) ? 0 : activationTime.hashCode());
-        result = prime * result + CollectionUtils.hashCode( attachments );
-        result = prime * result + CollectionUtils.hashCode( comments );
+        result = prime * result + CollectionUtils.hashCode(attachments);
+        result = prime * result + CollectionUtils.hashCode(comments);
         result = prime * result + ((createdOn == null) ? 0 : createdOn.hashCode());
         result = prime * result + ((expirationTime == null) ? 0 : expirationTime.hashCode());
         result = prime * result + (skipable ? 1231 : 1237);
@@ -497,57 +680,57 @@
 
     @Override
     public boolean equals(Object obj) {
-        if ( this == obj ) return true;
-        if ( obj == null ) return false;
-        if ( !(obj instanceof TaskData) ) return false;
+        if (this == obj) return true;
+        if (obj == null) return false;
+        if (!(obj instanceof TaskData)) return false;
         TaskData other = (TaskData) obj;
 
-        if ( actualOwner == null ) {
-            if ( other.actualOwner != null ) return false;
-        } else if ( !actualOwner.equals( other.actualOwner ) ) {
+        if (actualOwner == null) {
+            if (other.actualOwner != null) return false;
+        } else if (!actualOwner.equals(other.actualOwner)) {
             return false;
         }
 
-        if ( createdBy == null ) {
-            if ( other.createdBy != null ) return false;
-        } else if ( !createdBy.equals( other.createdBy ) ) {
+        if (createdBy == null) {
+            if (other.createdBy != null) return false;
+        } else if (!createdBy.equals(other.createdBy)) {
             return false;
         }
 
-        if ( createdOn == null ) {
-            if ( other.createdOn != null ) return false;
-        } else if ( createdOn.getTime() != other.createdOn.getTime() ) return false;
-        if ( expirationTime == null ) {
-            if ( other.expirationTime != null ) return false;
-        } else if ( expirationTime.getTime() != other.expirationTime.getTime() ) return false;
-        if ( skipable != other.skipable ) return false;
-        if ( workItemId != other.workItemId) return false;
-        if ( status == null ) {
-            if ( other.status != null ) return false;
-        } else if ( !status.equals( other.status ) ) return false;
-        if ( previousStatus == null ) {
-            if ( other.previousStatus != null ) return false;
-        } else if ( !previousStatus.equals( other.previousStatus ) ) return false;
-        if ( activationTime == null ) {
-            if ( other.activationTime != null ) return false;
-        } else if ( activationTime.getTime() != other.activationTime.getTime() ) return false;
+        if (createdOn == null) {
+            if (other.createdOn != null) return false;
+        } else if (createdOn.getTime() != other.createdOn.getTime()) return false;
+        if (expirationTime == null) {
+            if (other.expirationTime != null) return false;
+        } else if (expirationTime.getTime() != other.expirationTime.getTime()) return false;
+        if (skipable != other.skipable) return false;
+        if (workItemId != other.workItemId) return false;
+        if (status == null) {
+            if (other.status != null) return false;
+        } else if (!status.equals(other.status)) return false;
+        if (previousStatus == null) {
+            if (other.previousStatus != null) return false;
+        } else if (!previousStatus.equals(other.previousStatus)) return false;
+        if (activationTime == null) {
+            if (other.activationTime != null) return false;
+        } else if (activationTime.getTime() != other.activationTime.getTime()) return false;
 
-        if ( workItemId != other.workItemId ) return false;
+        if (workItemId != other.workItemId) return false;
 
-        if ( documentAccessType == null ) {
-            if ( other.documentAccessType != null ) return false;
-        } else if ( !documentAccessType.equals( other.documentAccessType ) ) return false;
+        if (documentAccessType == null) {
+            if (other.documentAccessType != null) return false;
+        } else if (!documentAccessType.equals(other.documentAccessType)) return false;
 
-        if ( documentContentId != other.documentContentId ) return false;
-        if ( documentType == null ) {
-            if ( other.documentType != null ) return false;
-        } else if ( !documentType.equals( other.documentType ) ) return false;
+        if (documentContentId != other.documentContentId) return false;
+        if (documentType == null) {
+            if (other.documentType != null) return false;
+        } else if (!documentType.equals(other.documentType)) return false;
         // I think this is OK!
-        if ( parentId != other.parentId ) return false;
+        if (parentId != other.parentId) return false;
 
-        return CollectionUtils.equals( attachments,
-                                       other.attachments ) && CollectionUtils.equals( comments,
-                                                                                      other.comments );
+        return CollectionUtils.equals(attachments,
+                other.attachments) && CollectionUtils.equals(comments,
+                other.comments);
     }
 
 }

Modified: labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/event/TaskEvent.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/event/TaskEvent.java	2009-04-10 22:53:48 UTC (rev 26013)
+++ labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/event/TaskEvent.java	2009-04-10 23:02:03 UTC (rev 26014)
@@ -17,7 +17,7 @@
     
     public TaskEvent(long taskId) {
         super( taskId );
-        this.taskId = (Long) taskId;
+        this.taskId = taskId;
     }
     
     public void writeExternal(ObjectOutput out) throws IOException {

Modified: labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/Allowed.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/Allowed.java	2009-04-10 22:53:48 UTC (rev 26013)
+++ labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/Allowed.java	2009-04-10 23:02:03 UTC (rev 26014)
@@ -4,5 +4,5 @@
     Owner,
     Initiator,
     PotentialOwner,
-    BusinessAdministrator;
+    BusinessAdministrator
 }

Added: labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/CannotAddTaskException.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/CannotAddTaskException.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/CannotAddTaskException.java	2009-04-10 23:02:03 UTC (rev 26014)
@@ -0,0 +1,18 @@
+package org.drools.task.service;
+
+/**
+ * Exception thrown from the <code>TaskServiceSession</code> when there is a problem adding task. This exception
+ * is specififically thrown when custom logic in rules has not allowed the <code>Task</code> to be added.
+ *
+ * @author <a href="mailto:stampy88 at yahoo.com">dave sinclair</a>
+ * @see org.drools.task.service.TaskServiceSession#addTask(org.drools.task.Task, ContentData)
+ */
+public class CannotAddTaskException extends TaskException {
+    public CannotAddTaskException(String message) {
+        super(message);
+    }
+
+    public CannotAddTaskException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}

Modified: labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/CommandName.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/CommandName.java	2009-04-10 22:53:48 UTC (rev 26013)
+++ labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/CommandName.java	2009-04-10 23:02:03 UTC (rev 26014)
@@ -75,5 +75,5 @@
     RegisterForEventRequest,
     EventTriggerResponse,
     
-    RegisterClient;
+    RegisterClient
 }

Modified: labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/Operation.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/Operation.java	2009-04-10 22:53:48 UTC (rev 26013)
+++ labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/Operation.java	2009-04-10 23:02:03 UTC (rev 26014)
@@ -11,5 +11,5 @@
     Delegate,
     Forward,
     Complete,
-    Fail;
+    Fail
 }

Added: labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/PermissionDeniedException.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/PermissionDeniedException.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/PermissionDeniedException.java	2009-04-10 23:02:03 UTC (rev 26014)
@@ -0,0 +1,13 @@
+package org.drools.task.service;
+
+/**
+ * Exception that is thrown when a <code>User</code> try to perform an <code>Operation</code> on a <code>Task</code>
+ *
+ * @author <a href="mailto:stampy88 at yahoo.com">dave sinclair</a>
+ * @see org.drools.task.service.TaskServiceSession#taskOperation(Operation, long, String, String, ContentData)  
+ */
+public class PermissionDeniedException extends TaskException{
+    public PermissionDeniedException(String message) {
+        super(message);
+    }
+}

Modified: labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/SendIcal.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/SendIcal.java	2009-04-10 22:53:48 UTC (rev 26013)
+++ labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/SendIcal.java	2009-04-10 23:02:03 UTC (rev 26014)
@@ -281,13 +281,13 @@
         builder.append( "VERSION:2.0\n" );
         builder.append( "METHOD:REQUEST\n" );
         builder.append( "BEGIN:VEVENT\n" );
-        builder.append( "DTSTART;TZID=UTC:" + df.format( date ) + "\n" );
-        builder.append( "UID:" + UUID.randomUUID().toString() + "\n" );
-        builder.append( "ORGANIZER;CN=\"" + organizerDisplayName + "\":mailto:" + organizerEmail + "\n" );
-        builder.append( "DTSTAMP;TZID=UTC:" + df.format( new Date() ) + "\n" );
-        builder.append( "SUMMARY:\"Task " + type + " : " + summary + "\"\n" );
-        builder.append( "DESCRIPTION:\"" + description + "\"\n" );
-        builder.append( "PRIORITY:" + priority + "\n" );
+        builder.append("DTSTART;TZID=UTC:").append(df.format(date)).append("\n");
+        builder.append("UID:").append(UUID.randomUUID().toString()).append("\n");
+        builder.append("ORGANIZER;CN=\"").append(organizerDisplayName).append("\":mailto:").append(organizerEmail).append("\n");
+        builder.append("DTSTAMP;TZID=UTC:").append(df.format(new Date())).append("\n");
+        builder.append("SUMMARY:\"Task ").append(type).append(" : ").append(summary).append("\"\n");
+        builder.append("DESCRIPTION:\"").append(description).append("\"\n");
+        builder.append("PRIORITY:").append(priority).append("\n");
         builder.append( "END:VEVENT\n" );
         builder.append( "END:VCALENDAR\n" );
         return builder.toString();

Added: labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/TaskException.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/TaskException.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/TaskException.java	2009-04-10 23:02:03 UTC (rev 26014)
@@ -0,0 +1,18 @@
+package org.drools.task.service;
+
+/**
+ * Base class for all exceptions for the task related activities
+ *
+ * @author <a href="mailto:stampy88 at yahoo.com">dave sinclair</a>
+ * @see org.drools.task.service.TaskServiceSession#addTask(org.drools.task.Task, ContentData)
+ */
+public abstract class TaskException extends RuntimeException {
+
+    public TaskException(String message) {
+        super(message);
+    }
+
+    public TaskException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}

Modified: labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/TaskServerHandler.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/TaskServerHandler.java	2009-04-10 22:53:48 UTC (rev 26013)
+++ labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/TaskServerHandler.java	2009-04-10 23:02:03 UTC (rev 26014)
@@ -1,28 +1,26 @@
 package org.drools.task.service;
 
-import java.util.*;
-
-import javax.persistence.EntityManager;
-
 import org.apache.mina.core.service.IoHandlerAdapter;
 import org.apache.mina.core.session.IdleStatus;
 import org.apache.mina.core.session.IoSession;
+import org.drools.SystemEventListener;
 import org.drools.eventmessaging.EventKey;
 import org.drools.task.Attachment;
 import org.drools.task.Comment;
 import org.drools.task.Content;
 import org.drools.task.Task;
 import org.drools.task.query.TaskSummary;
-import org.drools.SystemEventListener;
 
+import java.util.*;
+
 public class TaskServerHandler extends IoHandlerAdapter {
-    private TaskService service;
-    private Map<String, IoSession> clients;
+    private final TaskService service;
+    private final Map<String, IoSession> clients;
 
     /**
      * Listener used for logging
      */
-    private SystemEventListener systemEventListener;
+    private final SystemEventListener systemEventListener;
 
     public TaskServerHandler(TaskService service, SystemEventListener systemEventListener) {
         this.service = service;
@@ -32,7 +30,7 @@
 
     @Override
     public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
-        systemEventListener.exception("Uncaught exception on Server",cause);
+        systemEventListener.exception("Uncaught exception on Server", cause);
     }
 
     @Override
@@ -40,7 +38,6 @@
                                 Object message) throws Exception {
         Command cmd = (Command) message;
         TaskServiceSession taskSession = service.createSession();
-        TaskError error = null;
         CommandName response = null;
         try {
             systemEventListener.debug("Message receieved on server : " + cmd.getName());
@@ -63,15 +60,9 @@
                     if (cmd.getArguments().size() > 4) {
                         data = (ContentData) cmd.getArguments().get(4);
                     }
-                    error = taskSession.taskOperation(operation, taskId, userId, targetEntityId, data);
+                    taskSession.taskOperation(operation, taskId, userId, targetEntityId, data);
 
-                    List args;
-                    if (error != null) {
-                        args = new ArrayList(1);
-                        args.add(error);
-                    } else {
-                        args = Collections.emptyList();
-                    }
+                    List args = Collections.emptyList();
 
                     Command resultsCmnd = new Command(cmd.getId(), CommandName.OperationResponse, args);
                     session.write(resultsCmnd);
@@ -80,17 +71,14 @@
                 case GetTaskRequest: {
                     response = CommandName.GetTaskResponse;
                     long taskId = (Long) cmd.getArguments().get(0);
-                    EntityManager em = service.getEntityManagerFactory().createEntityManager();
-                    try {
-                        Task task = taskSession.getTask(taskId);
 
-                        List args = new ArrayList(1);
-                        args.add(task);
-                        Command resultsCmnd = new Command(cmd.getId(), CommandName.GetTaskResponse, args);
-                        session.write(resultsCmnd);
-                    } finally {
-                        em.close();
-                    }
+                    Task task = taskSession.getTask(taskId);
+
+                    List args = new ArrayList(1);
+                    args.add(task);
+                    Command resultsCmnd = new Command(cmd.getId(), CommandName.GetTaskResponse, args);
+                    session.write(resultsCmnd);
+
                     break;
                 }
                 case AddTaskRequest: {
@@ -345,18 +333,18 @@
                 }
                 case RegisterClient: {
                     String uuid = (String) cmd.getArguments().get(0);
-                    clients.put(uuid,
-                            session);
+                    clients.put(uuid, session);
                     break;
                 }
                 default: {
                     systemEventListener.debug("Unknown command recieved on server");
                 }
             }
-        } catch (Exception e) {
-            systemEventListener.exception(e);
+        } catch (Throwable e) {
+            systemEventListener.exception(e.getMessage(),e);
 
-            List list = new ArrayList(1);
+            TaskError error = new TaskError(e.getMessage());
+            List<Object> list = new ArrayList<Object>(1);
             list.add(error);
             Command resultsCmnd = new Command(cmd.getId(), response, list);
             session.write(resultsCmnd);

Modified: labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/TaskService.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/TaskService.java	2009-04-10 22:53:48 UTC (rev 26013)
+++ labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/TaskService.java	2009-04-10 23:02:03 UTC (rev 26014)
@@ -82,7 +82,7 @@
     }
 
     public TaskServiceSession createSession() {
-        return new TaskServiceSession(this, emf.createEntityManager(), systemEventListener);
+        return new TaskServiceSession(this, emf.createEntityManager());
     }
 
     public void schedule(ScheduledTaskDeadline deadline,
@@ -96,6 +96,10 @@
         return operations;
     }
 
+    public List<OperationCommand> getCommandsForOperation(Operation operation) {
+        return operations.get(operation);
+    }
+
     public EventKeys getEventKeys() {
         return eventKeys;
     }
@@ -124,10 +128,6 @@
         this.userInfo = userInfo;
     }
 
-    public EntityManagerFactory getEntityManagerFactory() {
-        return emf;
-    }
-
     public EntityManager getEntityManager() {
         return em;
     }
@@ -156,7 +156,7 @@
     }
 
     public static String toString(Reader reader) throws IOException {
-        int charValue = 0;
+        int charValue  ;
         StringBuffer sb = new StringBuffer(1024);
         while ((charValue = reader.read()) != -1) {
             sb.append((char) charValue);

Modified: labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/TaskServiceSession.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/TaskServiceSession.java	2009-04-10 22:53:48 UTC (rev 26013)
+++ labs/jbossrules/trunk/drools-process/drools-process-task/src/main/java/org/drools/task/service/TaskServiceSession.java	2009-04-10 23:02:03 UTC (rev 26014)
@@ -1,55 +1,30 @@
 package org.drools.task.service;
 
-import java.io.IOException;
-import java.io.Reader;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import javax.persistence.EntityManager;
-import javax.persistence.Query;
-
 import org.drools.RuleBase;
 import org.drools.StatefulSession;
-import org.drools.SystemEventListener;
 import org.drools.eventmessaging.EventKeys;
-import org.drools.task.Attachment;
-import org.drools.task.Comment;
-import org.drools.task.Content;
-import org.drools.task.Deadline;
-import org.drools.task.Group;
-import org.drools.task.OrganizationalEntity;
-import org.drools.task.PeopleAssignments;
-import org.drools.task.Status;
-import org.drools.task.SubTasksStrategy;
-import org.drools.task.Task;
-import org.drools.task.TaskData;
-import org.drools.task.User;
+import org.drools.task.*;
 import org.drools.task.query.DeadlineSummary;
 import org.drools.task.query.TaskSummary;
 import org.drools.task.service.TaskService.ScheduledTaskDeadline;
 
+import javax.persistence.*;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 public class TaskServiceSession {
 
-    private TaskService service;
-    private EntityManager em;
+    private final TaskService service;
+    private final EntityManager em;
     private Map<String, RuleBase> ruleBases;
     private Map<String, Map<String, Object>> globals;
     private EventKeys eventKeys;
 
-    /**
-     * Listener used for logging
-     */
-    private SystemEventListener systemEventListener;
-
-    public TaskServiceSession(TaskService service, EntityManager em, SystemEventListener systemEventListener) {
+    public TaskServiceSession(final TaskService service, final EntityManager em) {
         this.service = service;
         this.em = em;
-        this.systemEventListener = systemEventListener;
     }
 
     public void dispose() {
@@ -60,162 +35,146 @@
         return em;
     }
 
-    public void setRuleBase(String type, RuleBase ruleBase) {
+    public void setRuleBase(final String type, final RuleBase ruleBase) {
         if (ruleBases == null) {
             ruleBases = new HashMap<String, RuleBase>();
         }
         ruleBases.put(type, ruleBase);
     }
 
-    public void setGlobals(String type, Map<String, Object> globals) {
+    public void setGlobals(final String type, final Map<String, Object> globals) {
         if (this.globals == null) {
             this.globals = new HashMap<String, Map<String, Object>>();
         }
         this.globals.put(type, globals);
     }
 
-    public void addUser(User user) {
-        em.getTransaction().begin();
-        em.persist(user);
-        em.getTransaction().commit();
+    public void addUser(final User user) {
+        persistInTransaction(user);
     }
 
-    public void addGroup(Group group) {
-        em.getTransaction().begin();
-        em.persist(group);
-        em.getTransaction().commit();
+    public void addGroup(final Group group) {
+        persistInTransaction(group);
     }
 
-    public void addTask(Task task, ContentData contentData) {
-        TaskData taskData = task.getTaskData();
-        // new tasks start off with status created
-        taskData.setStatus(Status.Created);
-
-        // execute "addTask" rules
-        if (ruleBases != null) {
-            RuleBase ruleBase = ruleBases.get("addTask");
-            if (ruleBase != null) {
-                StatefulSession session = ruleBase.newStatefulSession();
-                Map<String, Object> globals = this.globals.get("addTask");
-                if (globals != null) {
-                    for (Map.Entry<String, Object> entry : globals.entrySet()) {
-                        session.setGlobal(entry.getKey(), entry.getValue());
-                    }
+    /**
+     * Runs any custom rules against the specified Task and ContentData to ensure that the
+     * task is allowed to be added. If the task cannot be added, a <code>CannotAddTaskException</code>
+     * will be thrown.
+     * @param task task that is being added
+     * @param contentData content data for task
+     * @throws CannotAddTaskException throw if the task is not allowed to be added
+     */
+    private void executeTaskAddRules(final Task task, final ContentData contentData)
+        throws CannotAddTaskException
+    {
+        RuleBase ruleBase = ruleBases.get("addTask");
+        if (ruleBase != null) {
+            StatefulSession session = ruleBase.newStatefulSession();
+            Map<String, Object> globals = this.globals.get("addTask");
+            if (globals != null) {
+                for (Map.Entry<String, Object> entry : globals.entrySet()) {
+                    session.setGlobal(entry.getKey(), entry.getValue());
                 }
-                TaskServiceRequest request = new TaskServiceRequest("addTask", null, null);
-                session.setGlobal("request", request);
-                session.insert(task);
-                session.insert(contentData);
-                session.fireAllRules();
-                if (!request.isAllowed()) {
-                    String error = "Cannot add Task:\n";
-                    if (request.getReasons() != null) {
-                        for (String reason : request.getReasons()) {
-                            error += reason + "\n";
-                        }
-                    }
-                    throw new RuntimeException(error);
-                }
             }
-        }
+            TaskServiceRequest request = new TaskServiceRequest("addTask", null, null);
+            session.setGlobal("request", request);
+            session.insert(task);
+            session.insert(contentData);
+            session.fireAllRules();
 
-        if (task.getPeopleAssignments() != null) {
-            List<OrganizationalEntity> potentialOwners = task.getPeopleAssignments().getPotentialOwners();
-            if (potentialOwners.size() == 1) {
-                // if there is a single potential owner, assign and set status to Reserved
-                OrganizationalEntity potentialOwner = potentialOwners.get(0);
-                // if there is a single potential user owner, assign and set status to Reserved
-                if (potentialOwner instanceof User) {
-                    taskData.setActualOwner((User) potentialOwners.get(0));
-                    taskData.setStatus(Status.Reserved);
+            if (!request.isAllowed()) {
+                StringBuilder error = new StringBuilder("Cannot add Task:\n");
+                if (request.getReasons() != null) {
+                    for (String reason : request.getReasons()) {
+                        error.append( reason).append('\n');
+                    }
                 }
-                //If there is a group set as potentialOwners, set the status to Ready ??
-                if (potentialOwner instanceof Group) {
 
-                    taskData.setStatus(Status.Ready);
-                }
-            } else if (potentialOwners.size() > 1) {
-                // multiple potential owners, so set to Ready so one can claim.
-                taskData.setStatus(Status.Ready);
-            } else {
-                //@TODO we have no potential owners
+                throw new CannotAddTaskException(error.toString());
             }
-        } else {
-            //@TODO we have no potential owners
         }
+    }
 
-        // set the CreatedOn date if it's not already set
-        if (taskData.getCreatedOn() == null) {
-            taskData.setCreatedOn(new Date());
-        }
+    public void addTask(final Task task, final ContentData contentData)
+        throws CannotAddTaskException
+    {
+        final TaskData taskData = task.getTaskData();
 
-        //@FIXME for now we activate on creation, unless date is supplied
-        if (taskData.getActivationTime() == null) {
-            taskData.setActivationTime(taskData.getCreatedOn());
+        // initialize the task data
+        Status currentStatus = taskData.initialize();
+
+        if (ruleBases != null) {
+            executeTaskAddRules(task, contentData);
         }
 
-        em.getTransaction().begin();
-        em.persist(task);
-        if (contentData != null) {
-            Content content = new Content();
-            content.setContent(contentData.getContent());
-            em.persist(content);
-            taskData.setDocumentAccessType(contentData.getAccessType());
-            taskData.setDocumentType(contentData.getType());
-            taskData.setDocumentContentId(content.getId());
+        // than assign the TaskData an owner and status based on the task assignments
+        PeopleAssignments assignments = task.getPeopleAssignments();
+        if (assignments != null) {
+            List<OrganizationalEntity> potentialOwners = assignments.getPotentialOwners();
+            currentStatus = taskData.assignOwnerAndStatus(potentialOwners);
         }
-        em.getTransaction().commit();
 
-        long now = System.currentTimeMillis();
-        // schedule after it's been persisted, otherwise the id's won't be assigned
-        if (task.getDeadlines() != null) {
-            if (task.getDeadlines().getStartDeadlines() != null) {
-                for (Deadline deadline : task.getDeadlines().getStartDeadlines()) {
-                    if (!deadline.isEscalated()) {
-                        // only escalate when true - typically this would only be true
-                        // if the user is requested that the notification should never be escalated
-                        Date date = deadline.getDate();
-                        service.schedule(new ScheduledTaskDeadline(task.getId(),
-                                deadline.getId(),
-                                service),
-                                date.getTime() - now);
-                    }
-                }
-            }
+        doOperationInTransaction(new TransactedOperation() {
+            public void doOperation() {
+                em.persist(task);
 
-            if (task.getDeadlines().getEndDeadlines() != null) {
-                for (Deadline deadline : task.getDeadlines().getEndDeadlines()) {
-                    // only escalate when true - typically this would only be true
-                    // if the user is requested that the notification should never be escalated
-                    if (!deadline.isEscalated()) {
-                        Date date = deadline.getDate();
-                        service.schedule(new ScheduledTaskDeadline(task.getId(),
-                                deadline.getId(),
-                                service),
-                                date.getTime() - now);
-                    }
+                if (contentData != null) {
+                    Content content = new Content(contentData.getContent());
+                    em.persist(content);
+
+                    taskData.setDocument(content.getId(), contentData);
                 }
             }
+        });
+
+        // schedule after it's been persisted, otherwise the id's won't be assigned
+        if (task.getDeadlines() != null) {
+            scheduleTask(task);
         }
 
-        if (task.getTaskData().getStatus() == Status.Reserved) {
+        if (currentStatus == Status.Reserved) {
             // Task was reserved so owner should get icals
-            SendIcal.getInstance().sendIcalForTask(task,
-                    service.getUserinfo());
+            SendIcal.getInstance().sendIcalForTask(task, service.getUserinfo());
 
             // trigger event support
-            service.getEventSupport().fireTaskClaimed(task.getId(),
-                    task.getTaskData().getActualOwner().getId());
+            service.getEventSupport().fireTaskClaimed(task.getId(), task.getTaskData().getActualOwner().getId());
         }
     }
 
-    public TaskError evalCommand(Operation operation,
-                                 List<OperationCommand> commands,
-                                 Task task,
-                                 User user,
-                                 OrganizationalEntity targetEntity) {
-        TaskData taskData = task.getTaskData();
+    private void scheduleTask(final Task task) {
+        final long now = System.currentTimeMillis();
+
+        final List<Deadline> startDeadlines = task.getDeadlines().getStartDeadlines();
+
+        if (startDeadlines != null) {
+            scheduleDeadlines(startDeadlines, now, task.getId());
+        }
+
+        final List<Deadline> endDeadlines = task.getDeadlines().getEndDeadlines();
+
+        if (endDeadlines != null) {
+            scheduleDeadlines(endDeadlines, now, task.getId());
+        }
+    }
+
+    private void scheduleDeadlines(final List<Deadline> deadlines, final long now, final long taskId) {
+        for (Deadline deadline : deadlines) {
+            if (!deadline.isEscalated()) {
+                // only escalate when true - typically this would only be true
+                // if the user is requested that the notification should never be escalated
+                Date date = deadline.getDate();
+                service.schedule(new ScheduledTaskDeadline(taskId, deadline.getId(), service), date.getTime() - now);
+            }
+        }
+    }
+
+    void evalCommand(final Operation operation, final List<OperationCommand> commands, final Task task,
+                     final User user, final OrganizationalEntity targetEntity) throws PermissionDeniedException {
+
+        final TaskData taskData = task.getTaskData();
         boolean statusMatched = false;
+
         for (OperationCommand command : commands) {
             // first find out if we have a matching status
             if (command.getStatus() != null) {
@@ -223,19 +182,14 @@
                     if (taskData.getStatus() == status) {
                         statusMatched = true;
 
-                        // next find out if the user can execute this operation                
+                        // next find out if the user can execute this doOperation
                         if (!isAllowed(command, task, user)) {
                             String errorMessage = "User '" + user + "' does not have permissions to execution operation '" + operation + "' on task id " + task.getId();
-                            systemEventListener.debug("Task error: " + errorMessage);
 
-                            return new TaskError(errorMessage);
+                            throw new PermissionDeniedException(errorMessage);
                         }
 
-                        commands(command,
-                                task,
-                                user,
-                                targetEntity);
-                        return null;
+                        commands(command, task, user, targetEntity);
                     }
                 }
             }
@@ -245,36 +199,26 @@
                     if (taskData.getPreviousStatus() == status) {
                         statusMatched = true;
 
-                        // next find out if the user can execute this operation                
+                        // next find out if the user can execute this doOperation
                         if (!isAllowed(command, task, user)) {
                             String errorMessage = "User '" + user + "' does not have permissions to execution operation '" + operation + "' on task id " + task.getId();
-                            systemEventListener.debug("Task error: " + errorMessage);
-
-                            return new TaskError(errorMessage);
+                            throw new PermissionDeniedException(errorMessage);
                         }
 
                         commands(command, task, user, targetEntity);
-                        return null;
                     }
                 }
             }
         }
         if (!statusMatched) {
             String errorMessage = "User '" + user + "' was unable to execution operation '" + operation + "' on task id " + task.getId() + " due to no 'current status' matchines";
-            systemEventListener.debug("Task error: " + errorMessage);
-
-            return new TaskError(errorMessage);
+            throw new PermissionDeniedException(errorMessage);
         }
-
-        return null;
     }
 
-    private boolean isAllowed(OperationCommand command,
-                              Task task,
-                              User user
-    ) {
-        PeopleAssignments people = task.getPeopleAssignments();
-        TaskData taskData = task.getTaskData();
+    private static boolean isAllowed(final OperationCommand command, final Task task, final User user) {
+        final PeopleAssignments people = task.getPeopleAssignments();
+        final TaskData taskData = task.getTaskData();
 
         boolean operationAllowed = false;
         for (Allowed allowed : command.getAllowed()) {
@@ -283,21 +227,19 @@
             }
             switch (allowed) {
                 case Owner: {
-                    operationAllowed = (taskData.getActualOwner() != null && taskData.getActualOwner().getId() == user.getId());
+                    operationAllowed = (taskData.getActualOwner() != null && taskData.getActualOwner().equals(user));
                     break;
                 }
                 case Initiator: {
-                    operationAllowed = (taskData.getCreatedBy() != null && taskData.getCreatedBy().getId() == user.getId());
+                    operationAllowed = (taskData.getCreatedBy() != null && taskData.getCreatedBy().equals(user));
                     break;
                 }
                 case PotentialOwner: {
-                    operationAllowed = isAllowed(user,
-                            people.getPotentialOwners());
+                    operationAllowed = isAllowed(user, people.getPotentialOwners());
                     break;
                 }
                 case BusinessAdministrator: {
-                    operationAllowed = isAllowed(user,
-                            people.getBusinessAdministrators());
+                    operationAllowed = isAllowed(user, people.getBusinessAdministrators());
                     break;
                 }
             }
@@ -315,12 +257,10 @@
         return operationAllowed;
     }
 
-    private void commands(OperationCommand command,
-                          Task task,
-                          User user,
-                          OrganizationalEntity targetEntity) {
-        PeopleAssignments people = task.getPeopleAssignments();
-        TaskData taskData = task.getTaskData();
+    private void commands(final OperationCommand command, final Task task, final User user,
+                          final OrganizationalEntity targetEntity) {
+        final PeopleAssignments people = task.getPeopleAssignments();
+        final TaskData taskData = task.getTaskData();
 
         if (command.getNewStatus() != null) {
             taskData.setStatus(command.getNewStatus());
@@ -349,8 +289,7 @@
                 case Claim: {
                     taskData.setActualOwner((User) targetEntity);
                     // Task was reserved so owner should get icals
-                    SendIcal.getInstance().sendIcalForTask(task,
-                            service.getUserinfo());
+                    SendIcal.getInstance().sendIcalForTask(task, service.getUserinfo());
 
                     // trigger event support
                     service.getEventSupport().fireTaskClaimed(task.getId(),
@@ -361,29 +300,24 @@
         }
     }
 
-    public TaskError taskOperation(Operation operation, long taskId, String userId,
-                                   String targetEntityId, ContentData data) {
-        Task task = em.find(Task.class, taskId);
-        User user = em.find(User.class, userId);
-
+    public void taskOperation(final Operation operation, final long taskId, final String userId,
+                              final String targetEntityId, final ContentData data) throws TaskException {
         OrganizationalEntity targetEntity = null;
+
         if (targetEntityId != null) {
-            targetEntity = em.find(OrganizationalEntity.class, targetEntityId);
+            targetEntity = getEntity(OrganizationalEntity.class, targetEntityId);
         }
 
-        if (!em.getTransaction().isActive()) {
-            em.getTransaction().begin();
-        }
+        final Task task = getTask(taskId);
+        final User user = getEntity(User.class, userId);
 
-        TaskError error = null;
         try {
-            Map<Operation, List<OperationCommand>> dsl = service.getOperations();
-            List<OperationCommand> commands = dsl.get(operation);
-            error = evalCommand(operation, commands, task, user, targetEntity);
+            final List<OperationCommand> commands = service.getCommandsForOperation(operation);
 
-            if (error != null) {
-                throw new RuntimeException("TaskOperationException");
-            }
+            beginOrUseExistingTransaction();
+
+            evalCommand(operation, commands, task, user, targetEntity);
+
             switch (operation) {
                 case Claim: {
                     taskClaimOperation(task);
@@ -402,48 +336,42 @@
                     break;
                 }
             }
-        } catch (Exception e) {
-            e.printStackTrace();
+        } catch (RuntimeException e) {
             em.getTransaction().rollback();
 
-            em.getTransaction().begin();
-            task.getTaskData().setStatus(Status.Error);
-            em.getTransaction().commit();
+            doOperationInTransaction(new TransactedOperation() {
+                public void doOperation() {
+                    task.getTaskData().setStatus(Status.Error);
+                }
+            });
 
-            String errorMessage = "User '" + user + "' was unable to execution operation '" + operation + "' on task id " + task.getId() + " due to exception:\n" + e.getMessage();
-            systemEventListener.debug("Task error: " + errorMessage);
-            systemEventListener.exception(e);
-
-            error = new TaskError(errorMessage);
+            throw e;
         } finally {
             if (em.getTransaction().isActive()) {
                 em.getTransaction().commit();
             }
         }
-        return error;
     }
 
-    private void taskClaimOperation(Task task) {
+    private void taskClaimOperation(final Task task) {
         // Task was reserved so owner should get icals
         SendIcal.getInstance().sendIcalForTask(task, service.getUserinfo());
         // trigger event support
         service.getEventSupport().fireTaskClaimed(task.getId(), task.getTaskData().getActualOwner().getId());
     }
 
-    private void taskCompleteOperation(Task task, ContentData data) {
+    private void taskCompleteOperation(final Task task, final ContentData data) {
         if (data != null) {
-            TaskData taskData = task.getTaskData();
-            Content content = new Content();
-            content.setContent(data.getContent());
-            em.persist(content);
+            doOperationInTransaction(new TransactedOperation() {
+                public void doOperation() {
+                    final Content content = new Content();
+                    content.setContent(data.getContent());
+                    em.persist(content);
 
-            taskData.setOutputContentId(content.getId());
-            taskData.setOutputAccessType(data.getAccessType());
-            taskData.setOutputType(data.getType());
-
-            // tranaction needs to be commited before events can be triggered
-            // this is because a registered listener may callback and look at the modified task/data
-            em.getTransaction().commit();
+                    final TaskData taskData = task.getTaskData();
+                    taskData.setOutput(content.getId(), data);
+                }
+            });
         }
 
         // trigger event support
@@ -451,316 +379,318 @@
         checkSubTaskStrategy(task);
     }
 
-    private void taskFailOperation(Task task, ContentData data) {
+    private void taskFailOperation(final Task task, final ContentData data) {
         // set fault data
         if (data != null) {
-            TaskData taskData = task.getTaskData();
-            Content content = new Content();
-            content.setContent(data.getContent());
-            em.persist(content);
-            taskData.setFaultContentId(content.getId());
-            taskData.setFaultAccessType(data.getAccessType());
-            taskData.setFaultType(data.getType());
-            taskData.setFaultName(((FaultData) data).getFaultName());
+            doOperationInTransaction(new TransactedOperation() {
+                public void doOperation() {
+                    final Content content = new Content(data.getContent());
+                    em.persist(content);
 
-            // tranaction needs to be commited before events can be triggered
-            // this is because a registered listener may callback and look at the modified task/data
-            em.getTransaction().commit();
+                    final TaskData taskData = task.getTaskData();
+                    taskData.setFault(content.getId(), (FaultData) data);
+                }
+            });
         }
 
         // trigger event support
         service.getEventSupport().fireTaskFailed(task.getId(), task.getTaskData().getActualOwner().getId());
     }
 
-    private void taskSkipOperation(Task task,String userId) {
+    private void taskSkipOperation(final Task task, final String userId) {
         // trigger event support
-        service.getEventSupport().fireTaskSkipped(task.getId(),   userId);
+        service.getEventSupport().fireTaskSkipped(task.getId(), userId);
         checkSubTaskStrategy(task);
     }
 
-    public void addComment(long taskId, Comment comment) {
-        Task task = em.find(Task.class,
-                taskId);
-        if (task == null) {
-            // todo throw some exception
-        }
+    public Task getTask(final long taskId) {
+        return getEntity(Task.class, taskId);
+    }
 
-        em.getTransaction().begin();
+    public void addComment(final long taskId, final Comment comment) {
+        final Task task = getTask(taskId);
 
-        List<Comment> list = task.getTaskData().getComments();
-        if (list == null || list == Collections.<Comment>emptyList()) {
-            list = new ArrayList<Comment>(1);
-            task.getTaskData().setComments(list);
-        }
-
-        list.add(comment);
-
-        em.getTransaction().commit();
+        doOperationInTransaction(new TransactedOperation() {
+            public void doOperation() {
+                task.getTaskData().addComment(comment);
+            }
+        });
     }
 
-    public void addAttachment(long taskId,
-                              Attachment attachment,
-                              Content content) {
-        Task task = em.find(Task.class,
-                taskId);
+    public void addAttachment(final long taskId, final Attachment attachment, final Content content) {
+        final Task task = getTask(taskId);
 
-        if (task == null) {
-            // todo throw some exception
-        }
+        doOperationInTransaction(new TransactedOperation() {
+            public void doOperation() {
+                em.persist(content);
 
-        em.getTransaction().begin();
-
-        em.persist(content);
-        attachment.setSize(content.getContent().length);
-        attachment.setAttachmentContentId(content.getId());
-
-        List<Attachment> list = task.getTaskData().getAttachments();
-        if (list == null || list == Collections.<Attachment>emptyList()) {
-            list = new ArrayList<Attachment>(1);
-            task.getTaskData().setAttachments(list);
-        }
-
-        list.add(attachment);
-        em.getTransaction().commit();
+                attachment.setContent(content);
+                task.getTaskData().addAttachment(attachment);
+            }
+        });
     }
 
-    public void setDocumentContent(long taskId,
-                                   Content content) {
-        Task task = em.find(Task.class, taskId);
+    public void setDocumentContent(final long taskId, final Content content) {
+        final Task task = getTask(taskId);
 
-        if (task == null) {
-            // todo throw some exception
-        }
+        doOperationInTransaction(new TransactedOperation() {
+            public void doOperation() {
+                em.persist(content);
 
-        em.getTransaction().begin();
-
-        em.persist(content);
-
-        task.getTaskData().setDocumentContentId(content.getId());
-
-        em.getTransaction().commit();
+                task.getTaskData().setDocumentContentId(content.getId());
+            }
+        });
     }
 
-    public Content getContent(long contentId) {
-        return em.find(Content.class, contentId);
+    public Content getContent(final long contentId) {
+        return getEntity(Content.class, contentId);
     }
 
-    public void deleteAttachment(long taskId,
-                                 long attachmentId,
-                                 long contentId) {
+    public void deleteAttachment(final long taskId, final long attachmentId, final long contentId) {
         // @TODO I can't get this to work with HQL deleting the Attachment. Hibernate needs both the item removed from the collection
         // and also the item deleted, so for now have to load the entire Task, I suspect that this is due to using the same EM which 
         // is caching things.
-        Task task = em.find(Task.class,
-                taskId);
+        final Task task = getTask(taskId);
 
-        em.getTransaction().begin();
-        for (Iterator<Attachment> it = task.getTaskData().getAttachments().iterator(); it.hasNext();) {
-            Attachment attachment = it.next();
-            if (attachment.getId() == attachmentId) {
-                it.remove();
-                em.remove(attachment); // need to do this otherwise it just removes the link id, without removing the attachment
-                break;
-            }
-        }
+        doOperationInTransaction(new TransactedOperation() {
+            public void doOperation() {
+                final Attachment removedAttachment = task.getTaskData().removeAttachment(attachmentId);
 
-        // we do this as HQL to avoid streaming in the entire HQL
-        String deleteContent = "delete from Content where id = :id";
-        em.createQuery(deleteContent).setParameter("id",
-                contentId).executeUpdate();
+                if (removedAttachment != null) {
+                    // need to do this otherwise it just removes the link id, without removing the attachment
+                    em.remove(removedAttachment);
+                }
 
-        em.getTransaction().commit();
+                // we do this as HQL to avoid streaming in the entire HQL
+                final String deleteContent = "delete from Content c where c.id = :id";
+                em.createQuery(deleteContent).setParameter("id", contentId).executeUpdate();
+            }
+        });
     }
 
-    public void deleteComment(long taskId,
-                              long commentId) {
+    public void deleteComment(final long taskId, final long commentId) {
         // @TODO I can't get this to work with HQL deleting the Comment. Hibernate needs both the item removed from the collection
         // and also the item deleted, so for now have to load the entire Task, I suspect that this is due to using the same EM which 
         // is caching things.
-        Task task = em.find(Task.class,
-                taskId);
-        em.getTransaction().begin();
-        for (Iterator<Comment> it = task.getTaskData().getComments().iterator(); it.hasNext();) {
-            Comment comment = it.next();
-            if (comment.getId() == commentId) {
-                it.remove();
-                em.remove(comment); // need to do this otherwise it just removes the link id, without removing the comment
-                break;
+        final Task task = getTask(taskId);
+
+        doOperationInTransaction(new TransactedOperation() {
+            public void doOperation() {
+                final Comment removedComment = task.getTaskData().removeComment(commentId);
+
+                if (removedComment != null) {
+                    // need to do this otherwise it just removes the link id, without removing the attachment
+                    em.remove(removedComment);
+                }
             }
-        }
-        em.getTransaction().commit();
+        });
     }
 
-    public Task getTask(long taskId) {
-        return em.find(Task.class, taskId);
-    }
-
     public List<DeadlineSummary> getUnescalatedDeadlines() {
         return (List<DeadlineSummary>) em.createNamedQuery("UnescalatedDeadlines").getResultList();
     }
 
-    public List<TaskSummary> getTasksOwned(String userId,
-                                           String language) {
-        Query tasksOwned = em.createNamedQuery("TasksOwned");
-        tasksOwned.setParameter("userId",
-                userId);
-        tasksOwned.setParameter("language",
-                language);
+    public List<TaskSummary> getTasksOwned(final String userId, final String language) {
+        final Query tasksOwned = em.createNamedQuery("TasksOwned");
+        tasksOwned.setParameter("userId", userId);
+        tasksOwned.setParameter("language", language);
+
         return (List<TaskSummary>) tasksOwned.getResultList();
     }
 
-    public List<TaskSummary> getTasksAssignedAsBusinessAdministrator(String userId,
-                                                                     String language) {
-        Query tasksAssignedAsBusinessAdministrator = em.createNamedQuery("TasksAssignedAsBusinessAdministrator");
-        tasksAssignedAsBusinessAdministrator.setParameter("userId",
-                userId);
-        tasksAssignedAsBusinessAdministrator.setParameter("language",
-                language);
+    public List<TaskSummary> getTasksAssignedAsBusinessAdministrator(final String userId,
+                                                                     final String language) {
+        final Query tasksAssignedAsBusinessAdministrator = em.createNamedQuery("TasksAssignedAsBusinessAdministrator");
+        tasksAssignedAsBusinessAdministrator.setParameter("userId", userId);
+        tasksAssignedAsBusinessAdministrator.setParameter("language", language);
+
         return (List<TaskSummary>) tasksAssignedAsBusinessAdministrator.getResultList();
     }
 
-    public List<TaskSummary> getTasksAssignedAsExcludedOwner(String userId,
-                                                             String language) {
-        Query tasksAssignedAsExcludedOwner = em.createNamedQuery("TasksAssignedAsExcludedOwner");
-        tasksAssignedAsExcludedOwner.setParameter("userId",
-                userId);
-        tasksAssignedAsExcludedOwner.setParameter("language",
-                language);
+    public List<TaskSummary> getTasksAssignedAsExcludedOwner(final String userId,
+                                                             final String language) {
+        final Query tasksAssignedAsExcludedOwner = em.createNamedQuery("TasksAssignedAsExcludedOwner");
+        tasksAssignedAsExcludedOwner.setParameter("userId", userId);
+        tasksAssignedAsExcludedOwner.setParameter("language", language);
+
         return (List<TaskSummary>) tasksAssignedAsExcludedOwner.getResultList();
     }
 
-    public List<TaskSummary> getTasksAssignedAsPotentialOwner(String userId,
-                                                              String language) {
-        Query tasksAssignedAsPotentialOwner = em.createNamedQuery("TasksAssignedAsPotentialOwner");
-        tasksAssignedAsPotentialOwner.setParameter("userId",
-                userId);
-        tasksAssignedAsPotentialOwner.setParameter("language",
-                language);
+    public List<TaskSummary> getTasksAssignedAsPotentialOwner(final String userId,
+                                                              final String language) {
+        final Query tasksAssignedAsPotentialOwner = em.createNamedQuery("TasksAssignedAsPotentialOwner");
+        tasksAssignedAsPotentialOwner.setParameter("userId", userId);
+        tasksAssignedAsPotentialOwner.setParameter("language", language);
+
         return (List<TaskSummary>) tasksAssignedAsPotentialOwner.getResultList();
     }
 
-    public List<TaskSummary> getTasksAssignedAsPotentialOwner(String userId, String groupId,
-                                                              String language) {
-        Query tasksAssignedAsPotentialOwner = em.createNamedQuery("TasksAssignedAsPotentialOwnerWithGroup");
-        tasksAssignedAsPotentialOwner.setParameter("userId",
-                userId);
-        tasksAssignedAsPotentialOwner.setParameter("groupId",
-                groupId);
-        tasksAssignedAsPotentialOwner.setParameter("language",
-                language);
+    public List<TaskSummary> getTasksAssignedAsPotentialOwner(final String userId, final String groupId,
+                                                              final String language) {
+        final Query tasksAssignedAsPotentialOwner = em.createNamedQuery("TasksAssignedAsPotentialOwnerWithGroup");
+        tasksAssignedAsPotentialOwner.setParameter("userId", userId);
+        tasksAssignedAsPotentialOwner.setParameter("groupId", groupId);
+        tasksAssignedAsPotentialOwner.setParameter("language", language);
+
         return (List<TaskSummary>) tasksAssignedAsPotentialOwner.getResultList();
     }
 
 
-    public List<TaskSummary> getSubTasksAssignedAsPotentialOwner(long parentId, String userId,
-                                                                 String language) {
-        Query tasksAssignedAsPotentialOwner = em.createNamedQuery("SubTasksAssignedAsPotentialOwner");
-        tasksAssignedAsPotentialOwner.setParameter("parentId",
-                parentId);
-        tasksAssignedAsPotentialOwner.setParameter("userId",
-                userId);
-        tasksAssignedAsPotentialOwner.setParameter("language",
-                language);
+    public List<TaskSummary> getSubTasksAssignedAsPotentialOwner(final long parentId, final String userId,
+                                                                 final String language) {
+        final Query tasksAssignedAsPotentialOwner = em.createNamedQuery("SubTasksAssignedAsPotentialOwner");
+        tasksAssignedAsPotentialOwner.setParameter("parentId", parentId);
+        tasksAssignedAsPotentialOwner.setParameter("userId", userId);
+        tasksAssignedAsPotentialOwner.setParameter("language", language);
+
         return (List<TaskSummary>) tasksAssignedAsPotentialOwner.getResultList();
     }
 
-    public List<TaskSummary> getTasksAssignedAsPotentialOwnerByGroup(String groupId,
-                                                                     String language) {
-        Query tasksAssignedAsPotentialOwnerByGroup = em.createNamedQuery("TasksAssignedAsPotentialOwnerByGroup");
-        tasksAssignedAsPotentialOwnerByGroup.setParameter("groupId",
-                groupId);
-        tasksAssignedAsPotentialOwnerByGroup.setParameter("language",
-                language);
+    public List<TaskSummary> getTasksAssignedAsPotentialOwnerByGroup(final String groupId,
+                                                                     final String language) {
+        final Query tasksAssignedAsPotentialOwnerByGroup = em.createNamedQuery("TasksAssignedAsPotentialOwnerByGroup");
+        tasksAssignedAsPotentialOwnerByGroup.setParameter("groupId", groupId);
+        tasksAssignedAsPotentialOwnerByGroup.setParameter("language", language);
 
         return (List<TaskSummary>) tasksAssignedAsPotentialOwnerByGroup.getResultList();
     }
 
-    public List<TaskSummary> getSubTasksByParent(long parentId, String language) {
-        Query subTaskByParent = em.createNamedQuery("GetSubTasksByParentTaskId");
-        subTaskByParent.setParameter("parentId",
-                parentId);
-        subTaskByParent.setParameter("language",
-                language);
+    public List<TaskSummary> getSubTasksByParent(final long parentId, final String language) {
+        final Query subTaskByParent = em.createNamedQuery("GetSubTasksByParentTaskId");
+        subTaskByParent.setParameter("parentId", parentId);
+        subTaskByParent.setParameter("language", language);
 
-
         return (List<TaskSummary>) subTaskByParent.getResultList();
     }
 
-    public List<TaskSummary> getTasksAssignedAsRecipient(String userId,
-                                                         String language) {
-        Query tasksAssignedAsRecipient = em.createNamedQuery("TasksAssignedAsRecipient");
-        tasksAssignedAsRecipient.setParameter("userId",
-                userId);
-        tasksAssignedAsRecipient.setParameter("language",
-                language);
+    public List<TaskSummary> getTasksAssignedAsRecipient(final String userId,
+                                                         final String language) {
+        final Query tasksAssignedAsRecipient = em.createNamedQuery("TasksAssignedAsRecipient");
+        tasksAssignedAsRecipient.setParameter("userId", userId);
+        tasksAssignedAsRecipient.setParameter("language", language);
+
         return (List<TaskSummary>) tasksAssignedAsRecipient.getResultList();
     }
 
-    public List<TaskSummary> getTasksAssignedAsTaskInitiator(String userId,
-                                                             String language) {
-        Query tasksAssignedAsTaskInitiator = em.createNamedQuery("TasksAssignedAsTaskInitiator");
-        tasksAssignedAsTaskInitiator.setParameter("userId",
-                userId);
-        tasksAssignedAsTaskInitiator.setParameter("language",
-                language);
+    public List<TaskSummary> getTasksAssignedAsTaskInitiator(final String userId,
+                                                             final String language) {
+        final Query tasksAssignedAsTaskInitiator = em.createNamedQuery("TasksAssignedAsTaskInitiator");
+        tasksAssignedAsTaskInitiator.setParameter("userId", userId);
+        tasksAssignedAsTaskInitiator.setParameter("language", language);
+
         return (List<TaskSummary>) tasksAssignedAsTaskInitiator.getResultList();
     }
 
-    public List<TaskSummary> getTasksAssignedAsTaskStakeholder(String userId,
-                                                               String language) {
-        Query tasksAssignedAsTaskStakeholder = em.createNamedQuery("TasksAssignedAsTaskStakeholder");
-        tasksAssignedAsTaskStakeholder.setParameter("userId",
-                userId);
-        tasksAssignedAsTaskStakeholder.setParameter("language",
-                language);
+    public List<TaskSummary> getTasksAssignedAsTaskStakeholder(final String userId,
+                                                               final String language) {
+        final Query tasksAssignedAsTaskStakeholder = em.createNamedQuery("TasksAssignedAsTaskStakeholder");
+        tasksAssignedAsTaskStakeholder.setParameter("userId", userId);
+        tasksAssignedAsTaskStakeholder.setParameter("language", language);
+
         return (List<TaskSummary>) tasksAssignedAsTaskStakeholder.getResultList();
     }
 
-    public boolean isAllowed(User user,
-                             List<OrganizationalEntity>[] people) {
+    public static boolean isAllowed(final User user, final List<OrganizationalEntity>[] people) {
         for (List<OrganizationalEntity> list : people) {
-            if (isAllowed(user,
-                    list)) {
+            if (isAllowed(user, list)) {
                 return true;
             }
         }
         return false;
     }
 
-    public boolean isAllowed(User user,
-                             List<OrganizationalEntity> entities) {
+    static boolean isAllowed(final User user, final List<OrganizationalEntity> entities) {
         // for now just do a contains, I'll figure out group membership later.
         for (OrganizationalEntity entity : entities) {
-            if (entity.getId().equals(user.getId())) {
+            if (entity.equals(user)) {
                 return true;
             }
         }
         return false;
     }
 
-    public static String toString(Reader reader) throws IOException {
-        int charValue;
-        StringBuffer sb = new StringBuffer(1024);
-        while ((charValue = reader.read()) != -1) {
-            //result = result + (char) charValue;
-            sb.append((char) charValue);
+    private void checkSubTaskStrategy(final Task task) {
+        for (SubTasksStrategy strategy : task.getSubTaskStrategies()) {
+            strategy.execute(this, service, task);
         }
-        return sb.toString();
+
+        final Task parentTask;
+        if (task.getTaskData().getParentId() != -1) {
+            parentTask = getTask(task.getTaskData().getParentId());
+            for (SubTasksStrategy strategy : parentTask.getSubTaskStrategies()) {
+                strategy.execute(this, service, parentTask);
+            }
+        }
     }
 
-    private void checkSubTaskStrategy(Task task) {
-        if (task != null) {
-            for (SubTasksStrategy strategy : task.getSubTaskStrategies()) {
-                strategy.execute(this, service, task);
+    /**
+     * Returns the entity of the specified class by for the specified primaryKey.
+     *
+     * @param entityClass - class of entity to return
+     * @param primaryKey  - key of entity
+     * @return entity or <code>EntityNotFoundException</code> if the entity cannot be found
+     * @throws EntityNotFoundException if entity not found
+     */
+    private <T> T getEntity(final Class<T> entityClass, final Object primaryKey) {
+        final T entity = em.find(entityClass, primaryKey);
+
+        if (entity == null) {
+            throw new EntityNotFoundException("No " + entityClass.getSimpleName() + " with ID " + primaryKey + " was found!");
+        }
+
+        return entity;
+    }
+   
+    /**
+     * Persists the specified object within a new transaction. If there are any problems, the
+     * transaction will be rolled back.
+     *
+     * @param object object to persists
+     */
+    private void persistInTransaction(final Object object) {
+        doOperationInTransaction(new TransactedOperation() {
+            public void doOperation() {
+                em.persist(object);
             }
+        });
+    }
 
-            Task parentTask;
-            if (task.getTaskData().getParentId() != -1) {
-                parentTask = getTask(task.getTaskData().getParentId());
-                for (SubTasksStrategy strategy : parentTask.getSubTaskStrategies()) {
-                    strategy.execute(this, service, parentTask);
-                }
+    /**
+     * Starts a transaction if there isn't one currently in progess.
+     */
+    private void beginOrUseExistingTransaction() {
+        final EntityTransaction tx = em.getTransaction();
+
+        if (!tx.isActive()) {
+            tx.begin();
+        }
+    }
+
+    /**
+     * Executes the specified operation within a transaction. Note that if there is a currently active
+     * transaction, if will reuse it.
+     *
+     * @param operation operation to execute
+     */
+    private void doOperationInTransaction(final TransactedOperation operation) {
+        final EntityTransaction tx = em.getTransaction();
+
+        try {
+            if (!tx.isActive()) {
+                tx.begin();
             }
+
+            operation.doOperation();
+
+            tx.commit();
+        } finally {
+            if (tx.isActive()) {
+                tx.rollback();
+            }
         }
     }
+
+    private interface TransactedOperation {
+        void doOperation();
+    }
 }




More information about the jboss-svn-commits mailing list