diff --git a/jbpm-distribution/pom.xml b/jbpm-distribution/pom.xml
index 9cab2e013f..191a31e10e 100644
--- a/jbpm-distribution/pom.xml
+++ b/jbpm-distribution/pom.xml
@@ -181,6 +181,8 @@
jbpm-human-task-audit
sources
+
+
org.jbpm
jbpm-shared-services
diff --git a/jbpm-distribution/src/main/assembly/pre-bin.xml b/jbpm-distribution/src/main/assembly/pre-bin.xml
index 67807acd32..788b0b5705 100644
--- a/jbpm-distribution/src/main/assembly/pre-bin.xml
+++ b/jbpm-distribution/src/main/assembly/pre-bin.xml
@@ -19,7 +19,10 @@
org.jbpm:jbpm-human-task-core
org.jbpm:jbpm-human-task-workitems
org.jbpm:jbpm-human-task-audit
+
+
org.jbpm:jbpm-shared-services
org.jbpm:jbpm-test
org.jbpm:jbpm-runtime-manager
@@ -42,7 +45,10 @@
org.jbpm:jbpm-human-task-core
org.jbpm:jbpm-human-task-workitems
org.jbpm:jbpm-human-task-audit
+
+
org.jbpm:jbpm-shared-services
org.jbpm:jbpm-test
org.jbpm:jbpm-runtime-manager
diff --git a/jbpm-human-task/jbpm-human-task-audit/pom.xml b/jbpm-human-task/jbpm-human-task-audit/pom.xml
index e66ee0a23a..85ff7b03ff 100644
--- a/jbpm-human-task/jbpm-human-task-audit/pom.xml
+++ b/jbpm-human-task/jbpm-human-task-audit/pom.xml
@@ -112,10 +112,13 @@
logback-classic
test
+
+
diff --git a/jbpm-human-task/jbpm-human-task-core/pom.xml b/jbpm-human-task/jbpm-human-task-core/pom.xml
index b914d12c8d..3fe37dca76 100644
--- a/jbpm-human-task/jbpm-human-task-core/pom.xml
+++ b/jbpm-human-task/jbpm-human-task-core/pom.xml
@@ -36,6 +36,10 @@
jsr250-api
+
+ org.drools
+ drools-persistence-jpa
+
org.hibernate.javax.persistence
hibernate-jpa-2.0-api
@@ -124,11 +128,14 @@
0.9.9-RC1
test
+
+
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/exception/IllegalTaskStateException.java b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/exception/IllegalTaskStateException.java
new file mode 100644
index 0000000000..a55491b91c
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/exception/IllegalTaskStateException.java
@@ -0,0 +1,16 @@
+package org.jbpm.services.task.exception;
+
+import org.kie.internal.task.exception.TaskException;
+
+public class IllegalTaskStateException extends TaskException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ public IllegalTaskStateException(String message) {
+ super(message);
+ }
+
+}
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/AttachmentImpl.java b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/AttachmentImpl.java
new file mode 100644
index 0000000000..2609cc80a7
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/AttachmentImpl.java
@@ -0,0 +1,227 @@
+/**
+ * Copyright 2010 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jbpm.services.task.impl.model;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+
+import org.kie.api.task.model.Content;
+import org.kie.api.task.model.User;
+import org.kie.internal.task.api.model.AccessType;
+import org.kie.internal.task.api.model.InternalAttachment;
+
+@Entity
+@Table(name="Attachment")
+@SequenceGenerator(name="attachmentIdSeq", sequenceName="ATTACHMENT_ID_SEQ", allocationSize=1)
+public class AttachmentImpl implements InternalAttachment {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO, generator="attachmentIdSeq")
+ @Column(name = "id")
+ private Long id = 0L;
+
+ /**
+ * Several attachments may have the same name
+ */
+ private String name;
+
+ /**
+ * current "inline" and "URL" are allowed, this is extendable though and others may be added
+ */
+ private AccessType accessType = AccessType.Unknown;
+
+ /**
+ * MIME type
+ */
+ private String contentType;
+
+ @ManyToOne()
+ private UserImpl attachedBy;
+
+ private Date attachedAt;
+
+ @Column(name = "attachment_size")
+ private int size;
+
+ private long attachmentContentId;
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeLong( id );
+ if( name == null ) {
+ name = "";
+ }
+ out.writeUTF( name );
+ out.writeUTF( accessType.toString() );
+ if( contentType == null ) {
+ contentType = "";
+ }
+ out.writeUTF( contentType );
+ // There are no guarantees that attachedBy is not null == potential bug
+ attachedBy.writeExternal( out );
+ long attachedAtTime = 0;
+ if( attachedAt != null ) {
+ attachedAtTime = attachedAt.getTime();
+ }
+ out.writeLong( attachedAtTime );
+ out.writeInt( size );
+ out.writeLong( attachmentContentId );
+ }
+
+ public void readExternal(ObjectInput in) throws IOException,
+ ClassNotFoundException {
+ id = in.readLong();
+ name = in.readUTF();
+ accessType = AccessType.valueOf( in.readUTF() );
+ contentType = in.readUTF();
+ attachedBy = new UserImpl();
+ attachedBy.readExternal( in );
+ attachedAt = new Date( in.readLong() );
+ size = in.readInt( );
+ attachmentContentId = in.readLong();
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public AccessType getAccessType() {
+ return accessType;
+ }
+
+ public void setAccessType(AccessType accessType) {
+ this.accessType = accessType;
+ }
+
+ public String getContentType() {
+ return contentType;
+ }
+
+ public void setContentType(String contentType) {
+ this.contentType = contentType;
+ }
+
+ public Date getAttachedAt() {
+ return attachedAt;
+ }
+
+ public void setAttachedAt(Date attachedAt) {
+ this.attachedAt = attachedAt;
+ }
+
+ public User getAttachedBy() {
+ return attachedBy;
+ }
+
+ public void setAttachedBy(User attachedBy) {
+ this.attachedBy = (UserImpl)attachedBy;
+ }
+
+ public int getSize() {
+ return size;
+ }
+
+ /**
+ * Sets the content for this attachment, i.e. the size and the attachmentContentId.
+ * @param content attachment content
+ */
+ public void setContent(Content content) {
+ setSize(content.getContent().length);
+ setAttachmentContentId(content.getId());
+ }
+
+ public void setSize(int size) {
+ this.size = size;
+ }
+
+ public long getAttachmentContentId() {
+ return attachmentContentId;
+ }
+
+ public void setAttachmentContentId(long contentId) {
+ this.attachmentContentId = contentId;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((accessType == null) ? 0 : accessType.hashCode());
+ result = prime * result + ((attachedAt == null) ? 0 : attachedAt.hashCode());
+ result = prime * result + ((attachedBy == null) ? 0 : attachedBy.hashCode());
+ result = prime * result + size;
+ result = prime * result + (int) (attachmentContentId ^ (attachmentContentId >>> 32));
+ result = prime * result + ((contentType == null) ? 0 : contentType.hashCode());
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if ( this == obj ) return true;
+ if ( obj == null ) return false;
+ if ( !(obj instanceof AttachmentImpl) ) return false;
+ AttachmentImpl other = (AttachmentImpl) obj;
+ if ( accessType == null ) {
+ if ( other.accessType != null ) return false;
+ } else if ( !accessType.equals( other.accessType ) ) return false;
+ if ( attachedAt == null ) {
+ if ( other.attachedAt != null ) return false;
+ } else if ( attachedAt.getTime() != other.attachedAt.getTime() ) return false;
+ if ( attachedBy == null ) {
+ if ( other.attachedBy != null ) return false;
+ } else if ( !attachedBy.equals( other.attachedBy ) ) return false;
+ if ( size != other.size ) return false;
+ if ( attachmentContentId != other.attachmentContentId ) return false;
+ if ( contentType == null ) {
+ if ( other.contentType != null ) return false;
+ } else if ( !contentType.equals( other.contentType ) ) return false;
+ if ( name == null ) {
+ if ( other.name != null ) return false;
+ } else if ( !name.equals( other.name ) ) return false;
+ return true;
+ }
+
+
+
+
+
+
+
+}
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/BooleanExpressionImpl.java b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/BooleanExpressionImpl.java
new file mode 100644
index 0000000000..0f6bc5aba7
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/BooleanExpressionImpl.java
@@ -0,0 +1,122 @@
+/**
+ * Copyright 2010 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jbpm.services.task.impl.model;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Lob;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+
+@Entity
+@Table(name="BooleanExpression")
+@SequenceGenerator(name="booleanExprIdSeq", sequenceName="BOOLEANEXPR_ID_SEQ", allocationSize=1)
+public class BooleanExpressionImpl implements org.kie.internal.task.api.model.BooleanExpression {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO, generator="booleanExprIdSeq")
+ private Long id;
+ private String type;
+
+ @Lob @Column(length=65535)
+ private String expression;
+
+ public BooleanExpressionImpl() {
+
+ }
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeLong( id );
+ if( type == null ) {
+ type = "";
+ }
+ out.writeUTF( type );
+ if( expression == null ) {
+ expression = "";
+ }
+ out.writeUTF( expression );
+ }
+
+ public void readExternal(ObjectInput in) throws IOException,
+ ClassNotFoundException {
+ id = in.readLong();
+ type = in.readUTF();
+ expression = in.readUTF();
+ }
+
+ public BooleanExpressionImpl(String type, String expression) {
+ this.type = type;
+ this.expression = expression;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getExpression() {
+ return expression;
+ }
+
+ public void setExpression(String expression) {
+ this.expression = expression;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((expression == null) ? 0 : expression.hashCode());
+ result = prime * result + ((type == null) ? 0 : type.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if ( this == obj ) return true;
+ if ( obj == null ) return false;
+ if ( !(obj instanceof BooleanExpressionImpl) ) return false;
+ BooleanExpressionImpl other = (BooleanExpressionImpl) obj;
+ if ( expression == null ) {
+ if ( other.expression != null ) return false;
+ } else if ( !expression.equals( other.expression ) ) return false;
+ if ( type == null ) {
+ if ( other.type != null ) return false;
+ } else if ( !type.equals( other.type ) ) return false;
+ return true;
+ }
+
+
+}
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/CommentImpl.java b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/CommentImpl.java
new file mode 100644
index 0000000000..5d8eb1af45
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/CommentImpl.java
@@ -0,0 +1,139 @@
+/**
+ * Copyright 2010 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jbpm.services.task.impl.model;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Lob;
+import javax.persistence.ManyToOne;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+
+import org.kie.api.task.model.User;
+import org.kie.internal.task.api.model.InternalComment;
+
+@Entity
+@Table(name = "task_comment")
+@SequenceGenerator(name="commentIdSeq", sequenceName="COMMENT_ID_SEQ", allocationSize=1)
+public class CommentImpl implements InternalComment {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO, generator="commentIdSeq")
+ private Long id = 0L;
+
+ @Lob @Column(length=65535)
+ private String text;
+
+ @ManyToOne()
+ private UserImpl addedBy;
+
+ private Date addedAt;
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeLong( id );
+ if( text == null ) {
+ text = "";
+ }
+ out.writeUTF( text );
+ // There are no guarantees that addedBy is not null = potential bug
+ addedBy.writeExternal( out );
+ long addedAtTime = 0;
+ if( addedAt != null ) {
+ addedAtTime = addedAt.getTime();
+ }
+ out.writeLong( addedAtTime );
+ }
+
+ public void readExternal(ObjectInput in) throws IOException,
+ ClassNotFoundException {
+ id = in.readLong();
+ text = in.readUTF();
+ addedBy = new UserImpl();
+ addedBy.readExternal( in );
+ addedAt = new Date( in.readLong() );
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ public void setText(String text) {
+ this.text = text;
+ }
+
+ public Date getAddedAt() {
+ return addedAt;
+ }
+
+ public void setAddedAt(Date addedDate) {
+ this.addedAt = addedDate;
+ }
+
+ public User getAddedBy() {
+ return addedBy;
+ }
+
+ public void setAddedBy(User addedBy) {
+ this.addedBy = (UserImpl)addedBy;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((addedBy == null) ? 0 : addedBy.hashCode());
+ result = prime * result + ((addedAt == null) ? 0 : addedAt.hashCode());
+ result = prime * result + ((text == null) ? 0 : text.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if ( this == obj ) return true;
+ if ( obj == null ) return false;
+ if ( !(obj instanceof CommentImpl) ) return false;
+ CommentImpl other = (CommentImpl) obj;
+ if ( addedBy == null ) {
+ if ( other.addedBy != null ) return false;
+ } else if ( !addedBy.equals( other.addedBy ) ) return false;
+ if ( addedAt == null ) {
+ if ( other.addedAt != null ) return false;
+ } else if ( addedAt.getTime() != other.addedAt.getTime() ) return false;
+ if ( text == null ) {
+ if ( other.text != null ) return false;
+ } else if ( !text.equals( other.text ) ) return false;
+ return true;
+ }
+
+
+}
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/CompletionBehaviorImpl.java b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/CompletionBehaviorImpl.java
new file mode 100644
index 0000000000..03090bdfe4
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/CompletionBehaviorImpl.java
@@ -0,0 +1,23 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.jbpm.services.task.impl.model;
+
+import java.io.Serializable;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+
+@Entity
+@Table(name="CompletionBehavior")
+public class CompletionBehaviorImpl implements Serializable {
+
+ @Id
+ @GeneratedValue
+ private Long id;
+
+
+}
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/ContentDataImpl.java b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/ContentDataImpl.java
new file mode 100644
index 0000000000..f9fa96040c
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/ContentDataImpl.java
@@ -0,0 +1,91 @@
+/**
+ * Copyright 2010 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jbpm.services.task.impl.model;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import org.kie.internal.task.api.model.AccessType;
+
+public class ContentDataImpl implements org.kie.internal.task.api.model.ContentData {
+
+ private AccessType accessType;
+ private String type;
+ private byte[] content;
+
+ public AccessType getAccessType() {
+ return accessType;
+ }
+
+ public void setAccessType(AccessType accessType) {
+ this.accessType = accessType;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public byte[] getContent() {
+ return content;
+ }
+
+ public void setContent(byte[] content) {
+ this.content = content;
+ }
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ if ( accessType != null ) {
+ out.writeBoolean( true );
+ out.writeUTF( accessType.toString() );
+ } else {
+ out.writeBoolean( false );
+ }
+ if ( type != null ) {
+ out.writeBoolean( true );
+ out.writeUTF( type );
+ } else {
+ out.writeBoolean( false );
+ }
+ if ( content != null ) {
+ out.writeBoolean( true );
+ out.writeInt( content.length );
+ out.write( content );
+ } else {
+ out.writeBoolean( false );
+ }
+ }
+
+ public void readExternal(ObjectInput in) throws IOException,
+ ClassNotFoundException {
+ if (in.readBoolean()) {
+ accessType = AccessType.valueOf(in.readUTF());
+ }
+ if (in.readBoolean()) {
+ type = in.readUTF();
+ }
+ if (in.readBoolean()) {
+ content = new byte[ in.readInt() ];
+ in.readFully( content );
+ }
+ }
+
+}
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/ContentImpl.java b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/ContentImpl.java
new file mode 100644
index 0000000000..52b24efc8d
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/ContentImpl.java
@@ -0,0 +1,104 @@
+/**
+ * Copyright 2010 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jbpm.services.task.impl.model;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Arrays;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Lob;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+
+import org.kie.internal.task.api.model.InternalContent;
+
+@Entity
+@Table(name="Content")
+@SequenceGenerator(name="contentIdSeq", sequenceName="CONTENT_ID_SEQ", allocationSize=1)
+public class ContentImpl implements InternalContent {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO, generator="contentIdSeq")
+ private Long id;
+
+ @Lob
+ @Column(length=2147483647)
+ private byte[] content;
+
+ public ContentImpl() {
+
+ }
+
+ public ContentImpl(byte[] content) {
+ this.content = content;
+ }
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeLong( id );
+ out.writeInt( content.length );
+ out.write( content );
+ }
+
+ public void readExternal(ObjectInput in) throws IOException,
+ ClassNotFoundException {
+ id = in.readLong();
+ content = new byte[ in.readInt() ];
+ in.readFully( content );
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public byte[] getContent() {
+ return content;
+ }
+
+ public void setContent(byte[] content) {
+ this.content = content;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + Arrays.hashCode( content );
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if ( this == obj ) return true;
+ if ( obj == null ) return false;
+ if ( !(obj instanceof ContentImpl) ) return false;
+ ContentImpl other = (ContentImpl) obj;
+ if ( !Arrays.equals( content,
+ other.content ) ) return false;
+ return true;
+ }
+
+}
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/DeadlineImpl.java b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/DeadlineImpl.java
new file mode 100644
index 0000000000..1ed47b3d2b
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/DeadlineImpl.java
@@ -0,0 +1,177 @@
+/**
+ * Copyright 2010 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.jbpm.services.task.impl.model;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.OneToMany;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+
+import org.jbpm.services.task.utils.CollectionUtils;
+import org.kie.api.task.model.I18NText;
+import org.kie.internal.task.api.model.Escalation;
+
+@Entity
+@Table(name="Deadline")
+@SequenceGenerator(name="deadlineIdSeq", sequenceName="DEADLINE_ID_SEQ", allocationSize=1)
+public class DeadlineImpl implements org.kie.internal.task.api.model.Deadline {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO, generator="deadlineIdSeq")
+ private Long id;
+ @OneToMany(cascade = CascadeType.ALL, targetEntity=I18NTextImpl.class)
+ @JoinColumn(name = "Deadline_Documentation_Id", nullable = true)
+ private List documentation = Collections.emptyList();
+ @Column(name = "deadline_date")
+ private Date date;
+ @OneToMany(cascade = CascadeType.ALL, targetEntity=EscalationImpl.class)
+ @JoinColumn(name = "Deadline_Escalation_Id", nullable = true)
+ private List escalations = Collections.emptyList();
+
+ @Basic
+ private Short escalated = 0;
+
+ public Boolean isEscalated() {
+ if (escalated == null) {
+ return null;
+ }
+ return (escalated == 1) ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ public void setEscalated(Boolean escalated) {
+ if (escalated == null) {
+ this.escalated = null;
+ } else {
+ this.escalated = (escalated == true) ? new Short("1") : new Short("0");
+ }
+ }
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeLong(id);
+
+ if (date != null) {
+ out.writeBoolean(true);
+ out.writeLong(date.getTime());
+ } else {
+ out.writeBoolean(false);
+ }
+ CollectionUtils.writeI18NTextList(documentation, out);
+ CollectionUtils.writeEscalationList(escalations, out);
+
+ out.writeShort(escalated);
+
+ }
+
+ public void readExternal(ObjectInput in) throws IOException,
+ ClassNotFoundException {
+ id = in.readLong();
+
+ if (in.readBoolean()) {
+ date = new Date(in.readLong());
+ }
+ documentation = CollectionUtils.readI18NTextList(in);
+ escalations = CollectionUtils.readEscalationList(in);
+
+ escalated = in.readShort();
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public List getDocumentation() {
+ return documentation;
+ }
+
+ public void setDocumentation(List documentation) {
+ this.documentation = documentation;
+ }
+
+ public Date getDate() {
+ return date;
+ }
+
+ public void setDate(Date date) {
+ this.date = date;
+ }
+
+ public List getEscalations() {
+ return escalations;
+ }
+
+ public void setEscalations(List escalations) {
+ this.escalations = escalations;
+ }
+
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((date == null) ? 0 : date.hashCode());
+ result = prime * result + CollectionUtils.hashCode(documentation);
+ result = prime * result + CollectionUtils.hashCode(escalations);
+ result = prime * result + (isEscalated() ? 1231 : 1237);
+ result = prime * result + (int) (id ^ (id >>> 32));
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (!(obj instanceof DeadlineImpl)) {
+ return false;
+ }
+ DeadlineImpl other = (DeadlineImpl) obj;
+
+ if (date == null) {
+ if (other.date != null) {
+ return false;
+ }
+ } else if (date.getTime() != other.date.getTime()) {
+ return false;
+ }
+
+ if (isEscalated() != other.isEscalated()) {
+ return false;
+ }
+
+ return CollectionUtils.equals(documentation, other.documentation) && CollectionUtils.equals(escalations, other.escalations);
+ }
+}
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/DeadlinesImpl.java b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/DeadlinesImpl.java
new file mode 100644
index 0000000000..571c16d417
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/DeadlinesImpl.java
@@ -0,0 +1,90 @@
+/**
+ * Copyright 2010 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jbpm.services.task.impl.model;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Collections;
+import java.util.List;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Embeddable;
+import javax.persistence.JoinColumn;
+import javax.persistence.OneToMany;
+
+import org.jbpm.services.task.utils.CollectionUtils;
+import org.kie.internal.task.api.model.Deadline;
+
+@Embeddable
+public class DeadlinesImpl implements org.kie.internal.task.api.model.Deadlines {
+ @OneToMany(cascade = CascadeType.ALL, targetEntity=DeadlineImpl.class)
+ @JoinColumn(name = "Deadlines_StartDeadLine_Id", nullable = true)
+ private List startDeadlines = Collections.emptyList();
+
+ @OneToMany(cascade = CascadeType.ALL, targetEntity=DeadlineImpl.class)
+ @JoinColumn(name = "Deadlines_EndDeadLine_Id", nullable = true)
+ private List endDeadlines = Collections.emptyList();
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ CollectionUtils.writeDeadlineList( startDeadlines, out );
+ CollectionUtils.writeDeadlineList( endDeadlines, out );
+ }
+
+ public void readExternal(ObjectInput in) throws IOException,
+ ClassNotFoundException {
+ startDeadlines = CollectionUtils.readDeadlinesList( in );
+ endDeadlines = CollectionUtils.readDeadlinesList( in );
+ }
+
+ public List getStartDeadlines() {
+ return startDeadlines;
+ }
+
+ public void setStartDeadlines(List startDeadlines) {
+ this.startDeadlines = startDeadlines;
+ }
+
+ public List getEndDeadlines() {
+ return endDeadlines;
+ }
+
+ public void setEndDeadlines(List endDeadlines) {
+ this.endDeadlines = endDeadlines;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + CollectionUtils.hashCode( endDeadlines );
+ result = prime * result + CollectionUtils.hashCode( startDeadlines );
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if ( this == obj ) return true;
+ if ( obj == null ) return false;
+ if ( !(obj instanceof DeadlinesImpl) ) return false;
+ DeadlinesImpl other = (DeadlinesImpl) obj;
+
+ return CollectionUtils.equals( endDeadlines, other.endDeadlines ) && CollectionUtils.equals( startDeadlines, other.startDeadlines );
+ }
+
+
+}
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/DelegationImpl.java b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/DelegationImpl.java
new file mode 100644
index 0000000000..bed151b286
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/DelegationImpl.java
@@ -0,0 +1,103 @@
+/**
+ * Copyright 2010 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jbpm.services.task.impl.model;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Collections;
+import java.util.List;
+
+import javax.persistence.Embeddable;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+
+import org.jbpm.services.task.utils.CollectionUtils;
+import org.kie.api.task.model.OrganizationalEntity;
+import org.kie.internal.task.api.model.AllowedToDelegate;
+
+@Embeddable
+public class DelegationImpl implements org.kie.internal.task.api.model.Delegation {
+ @Enumerated(EnumType.STRING)
+ private AllowedToDelegate allowedToDelegate;
+
+ @ManyToMany(targetEntity=OrganizationalEntityImpl.class)
+ @JoinTable(name = "Delegation_delegates", joinColumns = @JoinColumn(name = "task_id"), inverseJoinColumns = @JoinColumn(name = "entity_id"))
+ private List delegates = Collections.emptyList();
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ if ( allowedToDelegate != null ) {
+ out.writeBoolean( true );
+ out.writeUTF( allowedToDelegate.toString() );
+ } else {
+ out.writeBoolean( false );
+ }
+ CollectionUtils.writeOrganizationalEntityList( delegates, out );
+ }
+
+ public void readExternal(ObjectInput in) throws IOException,
+ ClassNotFoundException {
+ if ( in.readBoolean() ) {
+ allowedToDelegate = AllowedToDelegate.valueOf( in.readUTF() );
+ }
+ delegates = CollectionUtils.readOrganizationalEntityList( in );
+ }
+
+ public AllowedToDelegate getAllowed() {
+ return allowedToDelegate;
+ }
+
+ public void setAllowed(AllowedToDelegate allowedToDelegate) {
+ this.allowedToDelegate = allowedToDelegate;
+ }
+
+ public List getDelegates() {
+ return delegates;
+ }
+
+
+ public void setDelegates(List delegates) {
+ this.delegates = delegates;
+ }
+
+
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((allowedToDelegate == null) ? 0 : allowedToDelegate.hashCode());
+ result = prime * result + CollectionUtils.hashCode( delegates );
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if ( this == obj ) return true;
+ if ( obj == null ) return false;
+ if ( !(obj instanceof DelegationImpl) ) return false;
+ DelegationImpl other = (DelegationImpl) obj;
+ if ( allowedToDelegate == null ) {
+ if ( other.allowedToDelegate != null ) return false;
+ } else if ( !allowedToDelegate.equals( other.allowedToDelegate ) ) return false;
+
+ return CollectionUtils.equals( delegates, other.delegates );
+ }
+}
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/EmailNotificationHeaderImpl.java b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/EmailNotificationHeaderImpl.java
new file mode 100644
index 0000000000..62e76c2736
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/EmailNotificationHeaderImpl.java
@@ -0,0 +1,206 @@
+/**
+ * Copyright 2010 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ *
+ */
+package org.jbpm.services.task.impl.model;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Lob;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "email_header")
+@SequenceGenerator(name="emailNotificationHeadIdSeq", sequenceName="EMAILNOTIFHEAD_ID_SEQ", allocationSize=1)
+public class EmailNotificationHeaderImpl implements org.kie.internal.task.api.model.EmailNotificationHeader {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO, generator="emailNotificationHeadIdSeq")
+ private Long id;
+
+ private String language;
+
+ @Column( name = "replyToAddress" ) // just rename for consistency
+ private String replyTo;
+
+ @Column( name = "fromAddress" ) // have to rename as schema's break otherwise
+ private String from;
+
+ private String subject;
+
+ @Lob @Column(length=65535)
+ private String body;
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeLong( id );
+
+ if ( language != null ) {
+ out.writeBoolean( true );
+ out.writeUTF( language );
+ } else {
+ out.writeBoolean( false );
+ }
+
+ if ( subject != null ) {
+ out.writeBoolean( true );
+ out.writeUTF( subject );
+ } else {
+ out.writeBoolean( false );
+ }
+
+ if ( replyTo != null ) {
+ out.writeBoolean( true );
+ out.writeUTF( replyTo );
+ } else {
+ out.writeBoolean( false );
+ }
+
+ if ( from != null ) {
+ out.writeBoolean( true );
+ out.writeUTF( from );
+ } else {
+ out.writeBoolean( false );
+ }
+
+ if ( body != null ) {
+ out.writeBoolean( true );
+ out.writeUTF( body );
+ } else {
+ out.writeBoolean( false );
+ }
+ }
+
+
+ public void readExternal(ObjectInput in) throws IOException,
+ ClassNotFoundException {
+ id = in.readLong();
+
+ if ( in.readBoolean() ) {
+ language = in.readUTF();
+ }
+
+ if ( in.readBoolean() ) {
+ subject = in.readUTF();
+ }
+
+ if ( in.readBoolean() ) {
+ replyTo = in.readUTF();
+ }
+
+ if ( in.readBoolean() ) {
+ from = in.readUTF();
+ }
+
+ if ( in.readBoolean() ) {
+ body = in.readUTF();
+ }
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getLanguage() {
+ return language;
+ }
+
+ public void setLanguage(String language) {
+ this.language = language;
+ }
+
+ public String getSubject() {
+ return subject;
+ }
+
+ public void setSubject(String subject) {
+ this.subject = subject;
+ }
+
+ public String getBody() {
+ return body;
+ }
+
+ public void setBody(String body) {
+ this.body = body;
+ }
+
+ public String getReplyTo() {
+ return replyTo;
+ }
+
+ public void setReplyTo(String replyTo) {
+ this.replyTo = replyTo;
+ }
+
+ public String getFrom() {
+ return from;
+ }
+
+ public void setFrom(String from) {
+ this.from = from;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((subject == null) ? 0 : subject.hashCode());
+ result = prime * result + ((body == null) ? 0 : body.hashCode());
+ result = prime * result + ((from == null) ? 0 : from.hashCode());
+ result = prime * result + ((language == null) ? 0 : language.hashCode());
+ result = prime * result + ((replyTo == null) ? 0 : replyTo.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if ( this == obj ) return true;
+ if ( obj == null ) return false;
+ if ( !(obj instanceof EmailNotificationHeaderImpl) ) return false;
+ EmailNotificationHeaderImpl other = (EmailNotificationHeaderImpl) obj;
+ if ( subject == null ) {
+ if ( other.subject != null ) return false;
+ } else if ( !subject.equals( other.subject ) ) return false;
+ if ( body == null ) {
+ if ( other.body != null ) return false;
+ } else if ( !body.equals( other.body ) ) return false;
+ if ( from == null ) {
+ if ( other.from != null ) return false;
+ } else if ( !from.equals( other.from ) ) return false;
+ if ( language == null ) {
+ if ( other.language != null ) return false;
+ } else if ( !language.equals( other.language ) ) return false;
+ if ( replyTo == null ) {
+ if ( other.replyTo != null ) return false;
+ } else if ( !replyTo.equals( other.replyTo ) ) return false;
+ return true;
+ }
+
+}
\ No newline at end of file
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/EmailNotificationImpl.java b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/EmailNotificationImpl.java
new file mode 100644
index 0000000000..05679cef31
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/EmailNotificationImpl.java
@@ -0,0 +1,105 @@
+/**
+ * Copyright 2010 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jbpm.services.task.impl.model;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.MapKeyColumn;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+
+import org.kie.internal.task.api.model.EmailNotificationHeader;
+import org.kie.internal.task.api.model.Language;
+import org.kie.internal.task.api.model.NotificationType;
+
+
+@Entity
+public class EmailNotificationImpl extends NotificationImpl implements org.kie.internal.task.api.model.EmailNotification{
+
+ @OneToMany(cascade = CascadeType.ALL)
+ @MapKeyColumn(name="mapkey")
+ private Map emailHeaders;
+
+ @Override
+ public void writeExternal(ObjectOutput out) throws IOException {
+ super.writeExternal( out );
+ if ( emailHeaders != null ) {
+ out.writeInt( emailHeaders.size() );
+ for ( EmailNotificationHeader header : emailHeaders.values() ) {
+ header.writeExternal( out );
+ }
+ } else {
+ out.writeInt( 0 );
+ }
+ }
+
+ @Override
+ public void readExternal(ObjectInput in) throws IOException,
+ ClassNotFoundException {
+ super.readExternal( in );
+ int size = in.readInt();
+ if ( size > 0 ) {
+ emailHeaders = new HashMap(size);
+ for ( int i = 0; i < size; i++ ) {
+ EmailNotificationHeaderImpl header = new EmailNotificationHeaderImpl();
+ header.readExternal( in );
+ emailHeaders.put( new LanguageImpl(header.getLanguage()), header);
+ }
+ }
+ }
+
+ public NotificationType getNotificationType() {
+ return NotificationType.Email;
+ }
+
+ public Map extends Language, ? extends EmailNotificationHeader> getEmailHeaders() {
+ return emailHeaders;
+ }
+
+ public void setEmailHeaders(Map extends Language, ? extends EmailNotificationHeader> emailHeaders) {
+ this.emailHeaders = (Map) emailHeaders;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = super.hashCode();
+ result = prime * result + ((emailHeaders == null) ? 0 : emailHeaders.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if ( this == obj ) return true;
+ if ( !super.equals( obj ) ) return false;
+ if ( !(obj instanceof EmailNotificationImpl) ) return false;
+ EmailNotificationImpl other = (EmailNotificationImpl) obj;
+ if ( emailHeaders == null ) {
+ if ( other.emailHeaders != null ) return false;
+ } else if ( !emailHeaders.equals( other.emailHeaders ) ) return false;
+ return true;
+ }
+
+
+
+}
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/EscalationImpl.java b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/EscalationImpl.java
new file mode 100644
index 0000000000..c466bb4423
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/EscalationImpl.java
@@ -0,0 +1,158 @@
+/**
+ * Copyright 2010 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jbpm.services.task.impl.model;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Collections;
+import java.util.List;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.OneToMany;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+
+import org.jbpm.services.task.utils.CollectionUtils;
+import org.kie.internal.task.api.model.BooleanExpression;
+import org.kie.internal.task.api.model.Notification;
+import org.kie.internal.task.api.model.Reassignment;
+
+@Entity
+@Table(name="Escalation")
+@SequenceGenerator(name="escalationIdSeq", sequenceName="ESCALATION_ID_SEQ", allocationSize=1)
+public class EscalationImpl implements org.kie.internal.task.api.model.Escalation {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO, generator="escalationIdSeq")
+ private Long id;
+
+ private String name;
+
+ @OneToMany(cascade = CascadeType.ALL, targetEntity=BooleanExpressionImpl.class)
+ @JoinColumn(name = "Escalation_Constraints_Id", nullable = true)
+ private List constraints = Collections.emptyList();
+
+ @OneToMany(cascade = CascadeType.ALL, targetEntity=NotificationImpl.class)
+ @JoinColumn(name = "Escalation_Notifications_Id", nullable = true)
+ private List notifications = Collections.emptyList();
+
+ @OneToMany(cascade = CascadeType.ALL, targetEntity=ReassignmentImpl.class)
+ @JoinColumn(name = "Escalation_Reassignments_Id", nullable = true)
+ private List reassignments = Collections.emptyList();
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeLong( id );
+
+ if ( name != null ) {
+ out.writeBoolean( true );
+ out.writeUTF( name );
+ } else {
+ out.writeBoolean( false );
+ }
+ CollectionUtils.writeBooleanExpressionList( constraints, out );
+ CollectionUtils.writeNotificationList( notifications, out );
+ CollectionUtils.writeReassignmentList( reassignments, out );
+ }
+
+ public void readExternal(ObjectInput in) throws IOException,
+ ClassNotFoundException {
+ id = in.readLong();
+ if ( in.readBoolean() ) {
+ name = in.readUTF();
+ }
+ constraints = CollectionUtils.readBooleanExpressionList( in );
+ notifications = CollectionUtils.readNotificationList( in );
+ reassignments = CollectionUtils.readReassignmentList( in );
+
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public List getConstraints() {
+ return constraints;
+ }
+
+ public void setConstraints(List constraints) {
+ this.constraints = constraints;
+ }
+
+ public List getNotifications() {
+ return notifications;
+ }
+
+ public void setNotifications(List notifications) {
+ this.notifications = notifications;
+ }
+
+ public List getReassignments() {
+ return reassignments;
+ }
+
+ public void setReassignments(List reassignments) {
+ this.reassignments = reassignments;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + CollectionUtils.hashCode( constraints );
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ result = prime * result + CollectionUtils.hashCode( notifications );
+ result = prime * result + CollectionUtils.hashCode( reassignments );
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if ( this == obj ) return true;
+ if ( obj == null ) return false;
+ if ( !(obj instanceof EscalationImpl) ) return false;
+ EscalationImpl other = (EscalationImpl) obj;
+
+ if ( name == null ) {
+ if ( other.name != null ) return false;
+ } else if ( !name.equals( other.name ) ) return false;
+
+ return CollectionUtils.equals( constraints,
+ other.constraints ) && CollectionUtils.equals( notifications,
+ other.notifications ) && CollectionUtils.equals( reassignments,
+ other.reassignments );
+
+ }
+
+}
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/FaultDataImpl.java b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/FaultDataImpl.java
new file mode 100644
index 0000000000..2eead123ae
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/FaultDataImpl.java
@@ -0,0 +1,46 @@
+/**
+ * Copyright 2010 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jbpm.services.task.impl.model;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+public class FaultDataImpl extends ContentDataImpl implements org.kie.internal.task.api.model.FaultData {
+
+ private String faultName;
+
+ public String getFaultName() {
+ return faultName;
+ }
+
+ public void setFaultName(String faultName) {
+ this.faultName = faultName;
+ }
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeUTF( faultName );
+ super.writeExternal( out );
+ }
+
+ public void readExternal(ObjectInput in) throws IOException,
+ ClassNotFoundException {
+ faultName = in.readUTF();
+ super.readExternal( in );
+ }
+
+}
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/GroupImpl.java b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/GroupImpl.java
new file mode 100644
index 0000000000..b93aa52a7b
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/GroupImpl.java
@@ -0,0 +1,50 @@
+/**
+ * Copyright 2010 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jbpm.services.task.impl.model;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.kie.api.task.model.Group;
+
+@Entity
+@DiscriminatorValue("Group")
+public class GroupImpl extends OrganizationalEntityImpl implements Group {
+
+ public GroupImpl() {
+ super();
+ }
+
+ public GroupImpl(String id) {
+ super( id );
+ }
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ super.writeExternal( out );
+
+ }
+
+ public void readExternal(ObjectInput in) throws IOException,
+ ClassNotFoundException {
+ super.readExternal( in );
+ }
+
+}
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/I18NTextImpl.java b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/I18NTextImpl.java
new file mode 100644
index 0000000000..34782849a1
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/I18NTextImpl.java
@@ -0,0 +1,168 @@
+/**
+ * Copyright 2010 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jbpm.services.task.impl.model;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.List;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Lob;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+
+import org.kie.internal.task.api.model.InternalI18NText;
+
+@Entity
+@Table(name="I18NText")
+@SequenceGenerator(name="i18nTextIdSeq", sequenceName="I18NTEXT_ID_SEQ", allocationSize=1)
+public class I18NTextImpl implements InternalI18NText {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO, generator="i18nTextIdSeq")
+ @Column(name = "id")
+ private Long id = 0L;
+
+ private String language;
+
+ private String shortText;
+
+ @Lob @Column(length=65535)
+ private String text;
+
+ public I18NTextImpl() {
+
+ }
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeLong( id );
+ if( language == null ) {
+ language = "";
+ }
+ out.writeUTF( language );
+
+ if( shortText == null ) {
+ shortText = "";
+ }
+ out.writeUTF( shortText );
+
+ if( text == null ) {
+ text = "";
+ }
+ out.writeUTF( text );
+ }
+
+ public void readExternal(ObjectInput in) throws IOException,
+ ClassNotFoundException {
+ id = in.readLong();
+ language = in.readUTF();
+ shortText = in.readUTF();
+ text = in.readUTF();
+ }
+
+ public I18NTextImpl(String language,
+ String text) {
+ this.language = language;
+ if (text != null && text.length() > 256) {
+ this.shortText = text.substring(0, 256);
+ } else {
+ this.shortText = text;
+ }
+ this.text = text;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getLanguage() {
+ return language;
+ }
+
+ public void setLanguage(String language) {
+ this.language = language;
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ public void setText(String text) {
+ if (text != null && text.length() > 256) {
+ this.shortText = text.substring(0, 256);
+ } else {
+ this.shortText = text;
+ }
+ this.text = text;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((language == null) ? 0 : language.hashCode());
+ result = prime * result + ((shortText == null) ? 0 : shortText.hashCode());
+ result = prime * result + ((text == null) ? 0 : text.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if ( this == obj ) return true;
+ if ( obj == null ) return false;
+ if ( !(obj instanceof I18NTextImpl) ) return false;
+ I18NTextImpl other = (I18NTextImpl) obj;
+ if ( language == null ) {
+ if ( other.language != null ) return false;
+ } else if ( !language.equals( other.language ) ) return false;
+ if ( shortText == null ) {
+ if ( other.shortText != null ) return false;
+ } else if ( !shortText.equals( other.shortText ) ) return false;
+ if ( text == null ) {
+ if ( other.text != null ) return false;
+ } else if ( !text.equals( other.text ) ) return false;
+ return true;
+ }
+
+ public static String getLocalText(List list, String prefferedLanguage, String defaultLanguage) {
+ for ( I18NTextImpl text : list) {
+ if ( text.getLanguage().equals( prefferedLanguage )) {
+ return text.getText();
+ }
+ }
+ if ( defaultLanguage == null ) {
+ for ( I18NTextImpl text : list) {
+ if ( text.getLanguage().equals( defaultLanguage )) {
+ return text.getText();
+ }
+ }
+ }
+ return "";
+ }
+
+
+
+}
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/LanguageImpl.java b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/LanguageImpl.java
new file mode 100644
index 0000000000..63388547b4
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/LanguageImpl.java
@@ -0,0 +1,63 @@
+package org.jbpm.services.task.impl.model;
+
+import javax.persistence.Column;
+import javax.persistence.Embeddable;
+
+@Embeddable
+public class LanguageImpl implements org.kie.internal.task.api.model.Language {
+
+ @Column(nullable=false)
+ private String mapkey;
+
+ public String getMapkey() {
+ return mapkey;
+ }
+
+ public void setMapkey(String language) {
+ this.mapkey = language;
+ }
+
+ public LanguageImpl() {
+
+ }
+
+ public LanguageImpl(String lang) {
+ this.mapkey = lang;
+ }
+
+ @Override
+ public int hashCode() {
+ return this.mapkey == null ? 0 : this.mapkey.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if( obj == null ) {
+ if( this.mapkey == null ) {
+ return true;
+ }
+ return false;
+ }
+ else if( obj instanceof String ) {
+ return obj.equals(this.mapkey);
+ }
+ else if( obj instanceof LanguageImpl ) {
+ LanguageImpl other = (LanguageImpl) obj;
+ if( this.mapkey == null ) {
+ return (other).mapkey == null;
+ }
+ else {
+ return this.mapkey.equals(other.mapkey);
+ }
+ }
+ else {
+ return false;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return mapkey == null ? null : mapkey.toString();
+ }
+
+}
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/NotificationImpl.java b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/NotificationImpl.java
new file mode 100644
index 0000000000..f5dbd42501
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/NotificationImpl.java
@@ -0,0 +1,201 @@
+/**
+ * Copyright 2010 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jbpm.services.task.impl.model;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Collections;
+import java.util.List;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.OneToMany;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+
+import org.jbpm.services.task.utils.CollectionUtils;
+import org.kie.api.task.model.I18NText;
+import org.kie.api.task.model.OrganizationalEntity;
+import org.kie.internal.task.api.model.NotificationType;
+
+@Entity
+@Table(name="Notification")
+@SequenceGenerator(name="notificationIdSeq", sequenceName="NOTIFICATION_ID_SEQ", allocationSize=1)
+public class NotificationImpl implements org.kie.internal.task.api.model.Notification {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO, generator="notificationIdSeq")
+ @Column(name = "id")
+ private Long id;
+
+ @OneToMany(cascade = CascadeType.ALL, targetEntity=I18NTextImpl.class)
+ @JoinColumn(name = "Notification_Documentation_Id", nullable = true)
+ private List documentation = Collections.emptyList();
+
+ private int priority;
+
+ @ManyToMany(targetEntity=OrganizationalEntityImpl.class)
+ @JoinTable(name = "Notification_Recipients", joinColumns = @JoinColumn(name = "task_id"), inverseJoinColumns = @JoinColumn(name = "entity_id"))
+ private List recipients = Collections.emptyList();
+
+ @ManyToMany(targetEntity=OrganizationalEntityImpl.class)
+ @JoinTable(name = "Notification_BAs", joinColumns = @JoinColumn(name = "task_id"), inverseJoinColumns = @JoinColumn(name = "entity_id"))
+ private List businessAdministrators = Collections.emptyList();
+
+ @OneToMany(cascade = CascadeType.ALL, targetEntity=I18NTextImpl.class)
+ @JoinColumn(name = "Notification_Names_Id", nullable = true)
+ private List names = Collections.emptyList();
+
+ @OneToMany(cascade = CascadeType.ALL, targetEntity=I18NTextImpl.class)
+ @JoinColumn(name = "Notification_Subjects_Id", nullable = true)
+ private List subjects = Collections.emptyList();
+
+ @OneToMany(cascade = CascadeType.ALL, targetEntity=I18NTextImpl.class)
+ @JoinColumn(name = "Notification_Descriptions_Id", nullable = true)
+ private List descriptions = Collections.emptyList();
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeLong( id );
+ out.writeInt( priority );
+
+ CollectionUtils.writeOrganizationalEntityList( recipients, out );
+ CollectionUtils.writeOrganizationalEntityList( businessAdministrators, out );
+
+ CollectionUtils.writeI18NTextList( documentation, out );
+ CollectionUtils.writeI18NTextList( names, out );
+ CollectionUtils.writeI18NTextList( subjects, out );
+ CollectionUtils.writeI18NTextList( descriptions, out );
+
+ }
+
+ public void readExternal(ObjectInput in) throws IOException,
+ ClassNotFoundException {
+ id = in.readLong();
+ priority = in.readInt();
+
+ recipients = CollectionUtils.readOrganizationalEntityList( in );
+ businessAdministrators = CollectionUtils.readOrganizationalEntityList( in );
+
+ documentation = CollectionUtils.readI18NTextList( in );
+ names = CollectionUtils.readI18NTextList( in );
+ subjects = CollectionUtils.readI18NTextList( in );
+ descriptions = CollectionUtils.readI18NTextList( in );
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public NotificationType getNotificationType() {
+ return NotificationType.Default;
+ }
+
+ public List getDocumentation() {
+ return documentation;
+ }
+
+ public void setDocumentation(List documentation) {
+ this.documentation = documentation;
+ }
+
+ public int getPriority() {
+ return priority;
+ }
+
+ public void setPriority(int priority) {
+ this.priority = priority;
+ }
+
+ public List getRecipients() {
+ return recipients;
+ }
+
+ public void setRecipients(List recipients) {
+ this.recipients = recipients;
+ }
+
+ public List getBusinessAdministrators() {
+ return businessAdministrators;
+ }
+
+ public void setBusinessAdministrators(List businessAdministrators) {
+ this.businessAdministrators = businessAdministrators;
+ }
+
+ public List getNames() {
+ return names;
+ }
+
+ public void setNames(List names) {
+ this.names = names;
+ }
+
+ public List getSubjects() {
+ return subjects;
+ }
+
+ public void setSubjects(List subjects) {
+ this.subjects = subjects;
+ }
+
+ public List getDescriptions() {
+ return descriptions;
+ }
+
+ public void setDescriptions(List descriptions) {
+ this.descriptions = descriptions;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + priority;
+ result = prime * result + CollectionUtils.hashCode( documentation );
+ result = prime * result + CollectionUtils.hashCode( recipients );
+ result = prime * result + CollectionUtils.hashCode( businessAdministrators );
+ result = prime * result + CollectionUtils.hashCode( names );
+ result = prime * result + CollectionUtils.hashCode( subjects );
+ result = prime * result + CollectionUtils.hashCode( descriptions );
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if ( this == obj ) return true;
+ if ( obj == null ) return false;
+ if ( !(obj instanceof NotificationImpl) ) return false;
+ NotificationImpl other = (NotificationImpl) obj;
+
+ return CollectionUtils.equals( businessAdministrators, other.businessAdministrators ) && CollectionUtils.equals( documentation, other.documentation )
+ && CollectionUtils.equals( recipients, other.recipients ) && CollectionUtils.equals( descriptions, other.descriptions ) && CollectionUtils.equals( names, other.names )
+ && CollectionUtils.equals( subjects, other.subjects );
+ }
+
+}
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/OrganizationalEntityImpl.java b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/OrganizationalEntityImpl.java
new file mode 100644
index 0000000000..d5b7db7f14
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/OrganizationalEntityImpl.java
@@ -0,0 +1,90 @@
+/**
+ * Copyright 2010 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jbpm.services.task.impl.model;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import org.kie.internal.task.api.model.InternalOrganizationalEntity;
+
+@Entity
+@Table(name="OrganizationalEntity")
+public abstract class OrganizationalEntityImpl implements InternalOrganizationalEntity {
+
+ @Id
+ private String id;
+
+ public OrganizationalEntityImpl() {
+ }
+
+
+ public OrganizationalEntityImpl(String id ) {
+ this.id = id;
+ }
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ // id should never be "", given that it's the only field here!
+ if( id == null ) {
+ id = "";
+ }
+ out.writeUTF( id );
+ }
+
+ public void readExternal(ObjectInput in) throws IOException,
+ ClassNotFoundException {
+ id = in.readUTF();
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((id == null) ? 0 : id.hashCode());
+ return result;
+ }
+
+
+ @Override
+ public boolean equals(Object obj) {
+ if ( this == obj ) return true;
+ if ( obj == null ) return false;
+ if ( !(obj instanceof OrganizationalEntityImpl) ) return false;
+ OrganizationalEntityImpl other = (OrganizationalEntityImpl) obj;
+ if ( id == null ) {
+ if ( other.id != null ) return false;
+ } else if ( !id.equals( other.id ) ) return false;
+ return true;
+ }
+
+ public String toString() {
+ return "[" + getClass().getSimpleName() + ":'" + id + "']";
+ }
+}
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/PeopleAssignmentsImpl.java b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/PeopleAssignmentsImpl.java
new file mode 100644
index 0000000000..12f3047af4
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/PeopleAssignmentsImpl.java
@@ -0,0 +1,179 @@
+/**
+ * Copyright 2010 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jbpm.services.task.impl.model;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Collections;
+import java.util.List;
+
+import javax.persistence.Embeddable;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.ManyToOne;
+
+import org.jbpm.services.task.utils.CollectionUtils;
+import org.kie.api.task.model.OrganizationalEntity;
+import org.kie.api.task.model.User;
+import org.kie.internal.task.api.model.InternalPeopleAssignments;
+
+@Embeddable
+public class PeopleAssignmentsImpl implements InternalPeopleAssignments {
+
+ @ManyToOne()
+ private UserImpl taskInitiator;
+
+ @ManyToMany(targetEntity=OrganizationalEntityImpl.class)
+ @JoinTable(name = "PeopleAssignments_PotOwners", joinColumns = @JoinColumn(name = "task_id"), inverseJoinColumns = @JoinColumn(name = "entity_id"))
+ private List potentialOwners = Collections.emptyList();
+
+ @ManyToMany(targetEntity=OrganizationalEntityImpl.class)
+ @JoinTable(name = "PeopleAssignments_ExclOwners", joinColumns = @JoinColumn(name = "task_id"), inverseJoinColumns = @JoinColumn(name = "entity_id"))
+ private List excludedOwners = Collections.emptyList();
+
+ @ManyToMany(targetEntity=OrganizationalEntityImpl.class)
+ @JoinTable(name = "PeopleAssignments_Stakeholders", joinColumns = @JoinColumn(name = "task_id"), inverseJoinColumns = @JoinColumn(name = "entity_id"))
+ private List taskStakeholders = Collections.emptyList();
+
+ @ManyToMany(targetEntity=OrganizationalEntityImpl.class)
+ @JoinTable(name = "PeopleAssignments_BAs", joinColumns = @JoinColumn(name = "task_id"), inverseJoinColumns = @JoinColumn(name = "entity_id"))
+ private List businessAdministrators = Collections.emptyList();
+
+ @ManyToMany(targetEntity=OrganizationalEntityImpl.class)
+ @JoinTable(name = "PeopleAssignments_Recipients", joinColumns = @JoinColumn(name = "task_id"), inverseJoinColumns = @JoinColumn(name = "entity_id"))
+ private List recipients = Collections.emptyList();
+
+ public PeopleAssignmentsImpl() {
+
+ }
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ if ( taskInitiator != null ) {
+ out.writeBoolean( true );
+ taskInitiator.writeExternal( out );
+ } else {
+ out.writeBoolean( false );
+ }
+ CollectionUtils.writeOrganizationalEntityList( potentialOwners,
+ out );
+ CollectionUtils.writeOrganizationalEntityList( excludedOwners,
+ out );
+ CollectionUtils.writeOrganizationalEntityList( taskStakeholders,
+ out );
+ CollectionUtils.writeOrganizationalEntityList( businessAdministrators,
+ out );
+ CollectionUtils.writeOrganizationalEntityList( recipients,
+ out );
+ }
+
+ public void readExternal(ObjectInput in) throws IOException,
+ ClassNotFoundException {
+ if ( in.readBoolean() ) {
+ taskInitiator = new UserImpl();
+ taskInitiator.readExternal( in );
+ }
+ potentialOwners = CollectionUtils.readOrganizationalEntityList( in );
+ excludedOwners = CollectionUtils.readOrganizationalEntityList( in );
+ taskStakeholders = CollectionUtils.readOrganizationalEntityList( in );
+ businessAdministrators = CollectionUtils.readOrganizationalEntityList( in );
+ recipients = CollectionUtils.readOrganizationalEntityList( in );
+ }
+
+ public User getTaskInitiator() {
+ return taskInitiator;
+ }
+
+ public void setTaskInitiator(User taskInitiator) {
+ this.taskInitiator = (UserImpl) taskInitiator;
+ }
+
+ public List getPotentialOwners() {
+ return potentialOwners;
+ }
+
+ public void setPotentialOwners(List potentialOwners) {
+ this.potentialOwners = potentialOwners;
+ }
+
+ public List getExcludedOwners() {
+ return excludedOwners;
+ }
+
+ public void setExcludedOwners(List excludedOwners) {
+ this.excludedOwners = excludedOwners;
+ }
+
+ public List getTaskStakeholders() {
+ return taskStakeholders;
+ }
+
+ public void setTaskStakeholders(List taskStakeholders) {
+ this.taskStakeholders = taskStakeholders;
+ }
+
+ public List getBusinessAdministrators() {
+ return businessAdministrators;
+ }
+
+ public void setBusinessAdministrators(List businessAdministrators) {
+ this.businessAdministrators = businessAdministrators;
+ }
+
+ public List getRecipients() {
+ return recipients;
+ }
+
+ public void setRecipients(List recipients) {
+ this.recipients = recipients;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + CollectionUtils.hashCode( businessAdministrators );
+ result = prime * result + CollectionUtils.hashCode( excludedOwners );
+ result = prime * result + ((potentialOwners == null) ? 0 : CollectionUtils.hashCode( potentialOwners ));
+ result = prime * result + CollectionUtils.hashCode( recipients );
+ result = prime * result + ((taskInitiator == null) ? 0 : taskInitiator.hashCode());
+ result = prime * result + CollectionUtils.hashCode( taskStakeholders );
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if ( this == obj ) return true;
+ if ( obj == null ) return false;
+ if ( !(obj instanceof PeopleAssignmentsImpl) ) return false;
+ PeopleAssignmentsImpl other = (PeopleAssignmentsImpl) obj;
+
+ if ( taskInitiator == null ) {
+ if ( other.taskInitiator != null ) return false;
+ } else if ( !taskInitiator.equals( other.taskInitiator ) ) return false;
+
+ return CollectionUtils.equals( businessAdministrators,
+ other.businessAdministrators ) && CollectionUtils.equals( excludedOwners,
+ other.excludedOwners ) && CollectionUtils.equals( potentialOwners,
+ other.potentialOwners ) && CollectionUtils.equals( recipients,
+ other.recipients )
+ && CollectionUtils.equals( taskStakeholders,
+ other.taskStakeholders );
+ }
+
+}
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/PresentationElement.java b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/PresentationElement.java
new file mode 100644
index 0000000000..3105843ca5
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/PresentationElement.java
@@ -0,0 +1,18 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.jbpm.services.task.impl.model;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+
+@Entity
+public class PresentationElement {
+
+ @Id
+ @GeneratedValue
+ private Long id;
+}
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/ReassignmentImpl.java b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/ReassignmentImpl.java
new file mode 100644
index 0000000000..49371a9de9
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/ReassignmentImpl.java
@@ -0,0 +1,115 @@
+/**
+ * Copyright 2010 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jbpm.services.task.impl.model;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Collections;
+import java.util.List;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.OneToMany;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+
+import org.jbpm.services.task.utils.CollectionUtils;
+import org.kie.api.task.model.I18NText;
+import org.kie.api.task.model.OrganizationalEntity;
+
+@Entity
+@Table(name="Reassignment")
+@SequenceGenerator(name="reassignmentIdSeq", sequenceName="REASSIGNMENT_ID_SEQ", allocationSize=1)
+public class ReassignmentImpl implements org.kie.internal.task.api.model.Reassignment {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO, generator="reassignmentIdSeq")
+ private Long id;
+
+ @OneToMany(cascade = CascadeType.ALL, targetEntity=I18NTextImpl.class)
+ @JoinColumn(name = "Reassignment_Documentation_Id", nullable = true)
+ private List documentation = Collections.emptyList();
+
+ @ManyToMany(targetEntity=OrganizationalEntityImpl.class)
+ @JoinTable(name = "Reassignment_potentialOwners", joinColumns = @JoinColumn(name = "task_id"), inverseJoinColumns = @JoinColumn(name = "entity_id"))
+ private List potentialOwners = Collections.emptyList();
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeLong( id );
+ CollectionUtils.writeI18NTextList( documentation, out );
+ CollectionUtils.writeOrganizationalEntityList( potentialOwners, out );
+ }
+
+ public void readExternal(ObjectInput in) throws IOException,
+ ClassNotFoundException {
+ id = in.readLong();
+ documentation = CollectionUtils.readI18NTextList( in );
+ potentialOwners = CollectionUtils.readOrganizationalEntityList( in );
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public List getDocumentation() {
+ return documentation;
+ }
+
+ public void setDocumentation(List documentation) {
+ this.documentation = documentation;
+ }
+
+ public List getPotentialOwners() {
+ return potentialOwners;
+ }
+
+ public void setPotentialOwners(List potentialOwners) {
+ this.potentialOwners = potentialOwners;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + CollectionUtils.hashCode( documentation );
+ result = prime * result + CollectionUtils.hashCode( potentialOwners );
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if ( this == obj ) return true;
+ if ( obj == null ) return false;
+ if ( !(obj instanceof ReassignmentImpl) ) return false;
+ ReassignmentImpl other = (ReassignmentImpl) obj;
+ return CollectionUtils.equals( documentation, other.documentation ) && CollectionUtils.equals( potentialOwners, other.potentialOwners );
+ }
+
+
+
+}
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/TaskDataImpl.java b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/TaskDataImpl.java
new file mode 100644
index 0000000000..e401af9f8b
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/TaskDataImpl.java
@@ -0,0 +1,851 @@
+/**
+ * Copyright 2010 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jbpm.services.task.impl.model;
+
+
+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 javax.persistence.Temporal;
+
+import org.jbpm.services.task.exception.IllegalTaskStateException;
+import org.jbpm.services.task.utils.CollectionUtils;
+import org.kie.api.task.model.Attachment;
+import org.kie.api.task.model.Comment;
+import org.kie.api.task.model.OrganizationalEntity;
+import org.kie.api.task.model.Status;
+import org.kie.api.task.model.User;
+import org.kie.internal.task.api.model.AccessType;
+import org.kie.internal.task.api.model.ContentData;
+import org.kie.internal.task.api.model.FaultData;
+import org.kie.internal.task.api.model.InternalTaskData;
+
+@Embeddable
+public class TaskDataImpl implements InternalTaskData {
+ @Enumerated(EnumType.STRING)
+ private Status status = Status.Created; // initial default state
+
+ private Status previousStatus = null;
+
+ @ManyToOne(targetEntity=UserImpl.class)
+ private User actualOwner;
+
+ @ManyToOne(targetEntity=UserImpl.class)
+ private User createdBy;
+
+ @Temporal(javax.persistence.TemporalType.TIMESTAMP)
+ private Date createdOn;
+
+ @Temporal(javax.persistence.TemporalType.TIMESTAMP)
+ private Date activationTime;
+
+ @Temporal(javax.persistence.TemporalType.TIMESTAMP)
+ private Date expirationTime;
+
+ private boolean skipable;
+
+ private long workItemId = -1;
+
+ private long processInstanceId = -1;
+
+ private AccessType documentAccessType;
+
+ private String documentType;
+
+ private long documentContentId = -1;
+
+ private AccessType outputAccessType;
+
+ private String outputType;
+
+ private long outputContentId = -1;
+
+ private String faultName;
+
+ private AccessType faultAccessType;
+
+ private String faultType;
+
+ private long faultContentId = -1;
+
+ private long parentId = -1;
+
+ private String processId;
+
+ private String deploymentId;
+
+ private int processSessionId;
+
+ @OneToMany(cascade = CascadeType.ALL, targetEntity=CommentImpl.class)
+ @JoinColumn(name = "TaskData_Comments_Id", nullable = true)
+ private List comments = Collections.emptyList();
+
+ @OneToMany(cascade = CascadeType.ALL, targetEntity=AttachmentImpl.class)
+ @JoinColumn(name = "TaskData_Attachments_Id", nullable = true)
+ private List attachments = Collections.emptyList();
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ if (status != null) {
+ out.writeBoolean(true);
+ out.writeUTF(status.toString());
+ } else {
+ out.writeBoolean(false);
+ }
+
+ if (previousStatus != null) {
+ out.writeBoolean(true);
+ out.writeUTF(previousStatus.toString());
+ } else {
+ out.writeBoolean(false);
+ }
+
+ if (actualOwner != null) {
+ out.writeBoolean(true);
+ actualOwner.writeExternal(out);
+ } else {
+ out.writeBoolean(false);
+ }
+
+ if (createdBy != null) {
+ out.writeBoolean(true);
+ createdBy.writeExternal(out);
+ } else {
+ out.writeBoolean(false);
+ }
+
+ if (createdOn != null) {
+ out.writeBoolean(true);
+ out.writeLong(createdOn.getTime());
+ } else {
+ out.writeBoolean(false);
+ }
+
+ if (activationTime != null) {
+ out.writeBoolean(true);
+ out.writeLong(activationTime.getTime());
+ } else {
+ out.writeBoolean(false);
+ }
+
+ if (expirationTime != null) {
+ out.writeBoolean(true);
+ out.writeLong(expirationTime.getTime());
+ } else {
+ out.writeBoolean(false);
+ }
+
+ out.writeBoolean(skipable);
+
+ if (workItemId != -1) {
+ out.writeBoolean(true);
+ out.writeLong(workItemId);
+ } else {
+ out.writeBoolean(false);
+ }
+
+ if (processInstanceId != -1) {
+ out.writeBoolean(true);
+ out.writeLong(processInstanceId);
+ } else {
+ out.writeBoolean(false);
+ }
+
+ if (documentAccessType != null) {
+ out.writeBoolean(true);
+ out.writeObject(documentAccessType);
+ } else {
+ out.writeBoolean(false);
+ }
+
+ if (documentType != null) {
+ out.writeBoolean(true);
+ out.writeUTF(documentType);
+ } else {
+ out.writeBoolean(false);
+ }
+
+ if (documentContentId != -1) {
+ out.writeBoolean(true);
+ out.writeLong(documentContentId);
+ } else {
+ out.writeBoolean(false);
+ }
+
+ if (outputAccessType != null) {
+ out.writeBoolean(true);
+ out.writeObject(outputAccessType);
+ } else {
+ out.writeBoolean(false);
+ }
+
+ if (outputType != null) {
+ out.writeBoolean(true);
+ out.writeUTF(outputType);
+ } else {
+ out.writeBoolean(false);
+ }
+
+ if (outputContentId != -1) {
+ out.writeBoolean(true);
+ out.writeLong(outputContentId);
+ } else {
+ out.writeBoolean(false);
+ }
+
+ if (faultName != null) {
+ out.writeBoolean(true);
+ out.writeUTF(faultName);
+ } else {
+ out.writeBoolean(false);
+ }
+
+ if (faultAccessType != null) {
+ out.writeBoolean(true);
+ out.writeObject(faultAccessType);
+ } else {
+ out.writeBoolean(false);
+ }
+
+ if (faultType != null) {
+ out.writeBoolean(true);
+ out.writeUTF(faultType);
+ } else {
+ out.writeBoolean(false);
+ }
+
+ if (faultContentId != -1) {
+ out.writeBoolean(true);
+ out.writeLong(faultContentId);
+ } else {
+ out.writeBoolean(false);
+ }
+
+ if (parentId != -1) {
+ out.writeBoolean(true);
+ out.writeLong(parentId);
+ } else {
+ out.writeBoolean(false);
+ }
+
+ if (processId != null) {
+ out.writeBoolean(true);
+ out.writeUTF(processId);
+ } else {
+ out.writeBoolean(false);
+ }
+
+ if (processSessionId != -1) {
+ out.writeBoolean(true);
+ out.writeInt(processSessionId);
+ } else {
+ out.writeBoolean(false);
+ }
+
+ CollectionUtils.writeCommentList(comments,
+ out);
+ CollectionUtils.writeAttachmentList(attachments,
+ out);
+ }
+
+ public void readExternal(ObjectInput in) throws IOException,
+ ClassNotFoundException {
+ if (in.readBoolean()) {
+ status = Status.valueOf(in.readUTF());
+ }
+
+ if (in.readBoolean()) {
+ previousStatus = Status.valueOf(in.readUTF());
+ }
+
+ if (in.readBoolean()) {
+ actualOwner = new UserImpl();
+ actualOwner.readExternal(in);
+ }
+
+ if (in.readBoolean()) {
+ createdBy = new UserImpl();
+ createdBy.readExternal(in);
+ }
+
+ if (in.readBoolean()) {
+ createdOn = new Date(in.readLong());
+ }
+
+ if (in.readBoolean()) {
+ activationTime = new Date(in.readLong());
+ }
+
+ if (in.readBoolean()) {
+ expirationTime = new Date(in.readLong());
+ }
+
+ skipable = in.readBoolean();
+
+ if (in.readBoolean()) {
+ workItemId = in.readLong();
+ }
+
+ if (in.readBoolean()) {
+ processInstanceId = in.readLong();
+ }
+
+ if (in.readBoolean()) {
+ documentAccessType = (AccessType) in.readObject();
+ }
+
+ if (in.readBoolean()) {
+ documentType = in.readUTF();
+ }
+
+ if (in.readBoolean()) {
+ documentContentId = in.readLong();
+ }
+
+ if (in.readBoolean()) {
+ outputAccessType = (AccessType) in.readObject();
+ }
+
+ if (in.readBoolean()) {
+ outputType = in.readUTF();
+ }
+
+ if (in.readBoolean()) {
+ outputContentId = in.readLong();
+ }
+
+ if (in.readBoolean()) {
+ faultName = in.readUTF();
+ }
+
+ if (in.readBoolean()) {
+ faultAccessType = (AccessType) in.readObject();
+ }
+
+ if (in.readBoolean()) {
+ faultType = in.readUTF();
+ }
+
+ if (in.readBoolean()) {
+ faultContentId = in.readLong();
+ }
+
+ if (in.readBoolean()) {
+ parentId = in.readLong();
+ }
+
+ if (in.readBoolean()) {
+ processId = in.readUTF();
+ }
+
+ if (in.readBoolean()) {
+ processSessionId = in.readInt();
+ }
+
+ comments = CollectionUtils.readCommentList(in);
+ attachments = CollectionUtils.readAttachmentList(in);
+
+ }
+
+ /**
+ * Initializes the state of the TaskData, i.e. sets the createdOn, activationTime
+ * and sets the state to Status.Created
.
+ *
+ * @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.
+ * If there is only 1 potential owner, and it is a User
, that will become the actual
+ * owner of the TaskData and the status will be set to Status.Reserved
.
+ * f there is only 1 potential owner, and it is a Group
, no owner will be assigned
+ * and the status will be set to Status.Ready
.
+ * If there are more than 1 potential owners, the status will be set to Status.Ready
.
+ * otherwise, the task data will be unchanged
+ *
+ * @param potentialOwners - list of potential owners
+ * @return current status of task data
+ */
+ public Status assignOwnerAndStatus(List potentialOwners) {
+ if (getStatus() != Status.Created) {
+ throw new IllegalTaskStateException("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 UserImpl) {
+ setActualOwner((UserImpl) potentialOwner);
+
+ assignedStatus = Status.Reserved;
+ }
+ //If there is a group set as potentialOwners, set the status to Ready ??
+ if (potentialOwner instanceof GroupImpl) {
+
+ 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;
+ }
+
+ public void setStatus(Status status) {
+ previousStatus = this.status;
+ this.status = status;
+ }
+
+ public Status getPreviousStatus() {
+ return previousStatus;
+ }
+
+ public void setPreviousStatus(Status previousStatus) {
+ this.previousStatus = previousStatus;
+ }
+
+ public User getActualOwner() {
+ return actualOwner;
+ }
+
+ public void setActualOwner(User actualOwner) {
+ this.actualOwner = (UserImpl) actualOwner;
+ }
+
+ public User getCreatedBy() {
+ return createdBy;
+ }
+
+ public void setCreatedBy(User createdBy) {
+ this.createdBy = (UserImpl) createdBy;
+ }
+
+ public Date getCreatedOn() {
+ return createdOn;
+ }
+
+ public void setCreatedOn(Date createdOn) {
+ this.createdOn = createdOn;
+ }
+
+ public Date getActivationTime() {
+ return activationTime;
+ }
+
+ public void setActivationTime(Date activationTime) {
+ this.activationTime = activationTime;
+ }
+
+ public Date getExpirationTime() {
+ return expirationTime;
+ }
+
+ public void setExpirationTime(Date expirationTime) {
+ this.expirationTime = expirationTime;
+ }
+
+ public boolean isSkipable() {
+ return skipable;
+ }
+
+ public void setSkipable(boolean isSkipable) {
+ this.skipable = isSkipable;
+ }
+
+ public void setWorkItemId(long workItemId) {
+ this.workItemId = workItemId;
+ }
+
+ public long getWorkItemId() {
+ return workItemId;
+ }
+
+ public void setProcessInstanceId(long processInstanceId) {
+ this.processInstanceId = processInstanceId;
+ }
+
+ public long getProcessInstanceId() {
+ return processInstanceId;
+ }
+
+ public String getProcessId() {
+ return processId;
+ }
+
+ public void setProcessId(String processId) {
+ this.processId = processId;
+ }
+
+ public int getProcessSessionId() {
+ return processSessionId;
+ }
+
+ public void setProcessSessionId(int processSessionId) {
+ this.processSessionId = processSessionId;
+ }
+
+ /**
+ * Sets the document content data for this task data. It will set the documentContentId from the specified
+ * documentID, documentAccessType, documentType 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;
+ }
+
+ public void setDocumentAccessType(AccessType accessType) {
+ this.documentAccessType = accessType;
+ }
+
+ public String getDocumentType() {
+ return documentType;
+ }
+
+ public long getDocumentContentId() {
+ return documentContentId;
+ }
+
+ public void setDocumentContentId(long documentContentId) {
+ this.documentContentId = documentContentId;
+ }
+
+ public void setDocumentType(String documentType) {
+ this.documentType = documentType;
+ }
+
+ /**
+ * Sets the content data for this task data. It will set the outputContentId from the specified
+ * outputContentId, outputAccessType, outputType 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;
+ }
+
+ public void setOutputAccessType(AccessType outputAccessType) {
+ this.outputAccessType = outputAccessType;
+ }
+
+ public String getOutputType() {
+ return outputType;
+ }
+
+ public void setOutputType(String outputType) {
+ this.outputType = outputType;
+ }
+
+ public long getOutputContentId() {
+ return outputContentId;
+ }
+
+ public void setOutputContentId(long outputContentId) {
+ this.outputContentId = outputContentId;
+ }
+
+ /**
+ * Sets the fault data for this task data. It will set the faultContentId from the specified
+ * faultContentId, faultAccessType, faultType, faultName 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 String getFaultName() {
+ return faultName;
+ }
+
+ public void setFaultName(String faultName) {
+ this.faultName = faultName;
+ }
+
+ public AccessType getFaultAccessType() {
+ return faultAccessType;
+ }
+
+ public void setFaultAccessType(AccessType faultAccessType) {
+ this.faultAccessType = faultAccessType;
+ }
+
+ public String getFaultType() {
+ return faultType;
+ }
+
+ public void setFaultType(String faultType) {
+ this.faultType = faultType;
+ }
+
+ public long getFaultContentId() {
+ return faultContentId;
+ }
+
+ public void setFaultContentId(long faultContentId) {
+ this.faultContentId = faultContentId;
+ }
+
+ public List 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.size() == 0) {
+ comments = new ArrayList();
+ }
+
+ comments.add((CommentImpl) 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 comments) {
+ this.comments = comments;
+ }
+
+ public List getAttachments() {
+ 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.emptyList()) {
+ attachments = new ArrayList();
+ }
+
+ attachments.add((AttachmentImpl) 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 attachments) {
+ this.attachments = attachments;
+ }
+
+ public long getParentId() {
+ return parentId;
+ }
+
+ public void setParentId(long parentId) {
+ this.parentId = parentId;
+ }
+
+ @Override
+ public int hashCode() {
+ 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 + ((createdOn == null) ? 0 : createdOn.hashCode());
+ result = prime * result + ((expirationTime == null) ? 0 : expirationTime.hashCode());
+ result = prime * result + (skipable ? 1231 : 1237);
+ result = prime * result + ((status == null) ? 0 : status.hashCode());
+ result = prime * result + ((previousStatus == null) ? 0 : previousStatus.hashCode());
+ result = prime * result + ((workItemId == -1) ? 0 : (int) workItemId);
+ //Should I add parentId to this hashCode?
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (obj == null) return false;
+ if (!(obj instanceof TaskDataImpl)) return false;
+ TaskDataImpl other = (TaskDataImpl) obj;
+
+ 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)) {
+ 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 (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;
+ // I think this is OK!
+ if (parentId != other.parentId) return false;
+ if (processId == null) {
+ if (other.processId != null) return false;
+ } else if (!processId.equals(other.processId)) return false;
+ if (processSessionId != other.processSessionId) return false;
+ if (deploymentId == null) {
+ if (other.deploymentId != null) return false;
+ } else if (!deploymentId.equals(other.deploymentId)) return false;
+ return CollectionUtils.equals(attachments,
+ other.attachments) && CollectionUtils.equals(comments,
+ other.comments);
+ }
+
+ @Override
+ public String getDeploymentId() {
+ return deploymentId;
+ }
+
+ @Override
+ public void setDeploymentId(String deploymentId) {
+ this.deploymentId = deploymentId;
+ }
+
+}
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/TaskDefImpl.java b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/TaskDefImpl.java
new file mode 100644
index 0000000000..281ecc6a7b
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/TaskDefImpl.java
@@ -0,0 +1,88 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.jbpm.services.task.impl.model;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import javax.persistence.Column;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+
+/**
+ *
+ */
+@Entity
+@Table(name="TaskDef")
+@SequenceGenerator(name="taskDefIdSeq", sequenceName="TASK_DEF_ID_SEQ")
+public class TaskDefImpl implements org.kie.internal.task.api.model.TaskDef {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO, generator="taskDefIdSeq")
+ @Column(name = "id")
+ private long id;
+
+ private String name;
+
+ private int priority;
+
+
+ public TaskDefImpl() {
+
+ }
+
+
+ public TaskDefImpl(String name) {
+ this.name = name;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public int getPriority() {
+ return priority;
+ }
+
+ public void setPriority(int priority) {
+ this.priority = priority;
+ }
+
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeLong( id );
+ if( name == null ) {
+ name = "";
+ }
+ out.writeUTF( name );
+
+ out.writeInt( priority );
+ }
+
+ public void readExternal(ObjectInput in) throws IOException,
+ ClassNotFoundException {
+ id = in.readLong();
+ name = in.readUTF();
+ priority = in.readInt();
+ }
+
+}
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/TaskImpl.java b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/TaskImpl.java
new file mode 100644
index 0000000000..874e00b7ea
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/TaskImpl.java
@@ -0,0 +1,371 @@
+/**
+ * Copyright 2010 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jbpm.services.task.impl.model;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Collections;
+import java.util.List;
+
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Embedded;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.OneToMany;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.persistence.Version;
+
+import org.jbpm.services.task.utils.CollectionUtils;
+import org.kie.api.task.model.I18NText;
+import org.kie.api.task.model.PeopleAssignments;
+import org.kie.api.task.model.TaskData;
+import org.kie.internal.task.api.model.Deadlines;
+import org.kie.internal.task.api.model.Delegation;
+import org.kie.internal.task.api.model.InternalTask;
+import org.kie.internal.task.api.model.SubTasksStrategy;
+
+@Entity
+@Table(name="Task")
+@SequenceGenerator(name="taskIdSeq", sequenceName="TASK_ID_SEQ", allocationSize=1)
+public class TaskImpl implements InternalTask {
+ /**
+ * WSHT uses a name for the unique identifier, for now we use a generated ID which is also the key, which can be
+ * mapped to the name or a unique name field added later.
+ */
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO, generator="taskIdSeq")
+ @Column(name = "id")
+ private Long id = 0L;
+
+ @Version
+ @Column(name = "OPTLOCK")
+ private int version;
+
+ /**
+ * While WSHT says this is an expression, it always resolves to an integer, so resolve before setting
+ * default value is 0.
+ */
+ private int priority;
+
+ @OneToMany(cascade = CascadeType.ALL, targetEntity=I18NTextImpl.class)
+ @JoinColumn(name = "Task_Names_Id", nullable = true)
+ private List names = Collections.emptyList();
+
+ @OneToMany(cascade = CascadeType.ALL, targetEntity=I18NTextImpl.class)
+ @JoinColumn(name = "Task_Subjects_Id", nullable = true)
+ private List subjects = Collections.emptyList();
+
+ @OneToMany(cascade = CascadeType.ALL, targetEntity=I18NTextImpl.class)
+ @JoinColumn(name = "Task_Descriptions_Id", nullable = true)
+ private List descriptions = Collections.emptyList();
+
+
+ @Embedded
+ private PeopleAssignmentsImpl peopleAssignments;
+
+ @Embedded
+ private DelegationImpl delegation;
+
+ @Embedded
+ private TaskDataImpl taskData;
+
+ @Embedded
+ private DeadlinesImpl deadlines;
+
+ @Enumerated(EnumType.STRING)
+ // Default Behaviour
+ private SubTasksStrategy subTaskStrategy = SubTasksStrategy.NoAction;
+
+ private String taskType;
+
+ private String formName;
+
+ @Basic
+ private Short archived = 0;
+
+
+ public TaskImpl() {
+ }
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeLong( id );
+ out.writeInt( priority );
+ out.writeShort( archived );
+ out.writeUTF(taskType);
+ out.writeUTF(formName);
+ CollectionUtils.writeI18NTextList( names, out );
+ CollectionUtils.writeI18NTextList( subjects, out );
+ CollectionUtils.writeI18NTextList( descriptions, out );
+
+ if (subTaskStrategy != null) {
+ out.writeBoolean(true);
+ out.writeUTF(subTaskStrategy.toString());
+ } else {
+ out.writeBoolean(false);
+ }
+
+ if ( peopleAssignments != null ) {
+ out.writeBoolean( true );
+ peopleAssignments.writeExternal( out );
+ } else {
+ out.writeBoolean( false );
+ }
+
+ if ( delegation != null ) {
+ out.writeBoolean( true );
+ delegation.writeExternal( out );
+ } else {
+ out.writeBoolean( false );
+ }
+
+ if ( taskData != null ) {
+ out.writeBoolean( true );
+ taskData.writeExternal( out );
+ } else {
+ out.writeBoolean( false );
+ }
+
+ if ( deadlines != null ) {
+ out.writeBoolean( true );
+ deadlines.writeExternal( out );
+ } else {
+ out.writeBoolean( false );
+ }
+
+ }
+
+ public void readExternal(ObjectInput in) throws IOException,
+ ClassNotFoundException {
+ id = in.readLong();
+ priority = in.readInt();
+ archived = in.readShort();
+ taskType = in.readUTF();
+ formName = in.readUTF();
+ names = CollectionUtils.readI18NTextList( in );
+ subjects = CollectionUtils.readI18NTextList( in );
+ descriptions = CollectionUtils.readI18NTextList( in );
+
+ if (in.readBoolean()) {
+ subTaskStrategy = SubTasksStrategy.valueOf(in.readUTF());
+ }
+
+ if ( in.readBoolean() ) {
+ peopleAssignments = new PeopleAssignmentsImpl();
+ peopleAssignments.readExternal( in );
+ }
+
+ if ( in.readBoolean() ) {
+ delegation = new DelegationImpl();
+ delegation.readExternal( in );
+ }
+
+ if ( in.readBoolean() ) {
+ taskData = new TaskDataImpl();
+ taskData.readExternal( in );
+ }
+
+ if ( in.readBoolean() ) {
+ deadlines = new DeadlinesImpl();
+ deadlines.readExternal( in );
+ }
+
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public Boolean isArchived() {
+ if (archived == null) {
+ return null;
+ }
+ return (archived == 1) ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ public void setArchived(Boolean archived) {
+ if (archived == null) {
+ this.archived = null;
+ } else {
+ this.archived = (archived == true) ? new Short("1") : new Short("0");
+ }
+ }
+
+ public int getVersion() {
+ return this.version;
+ }
+
+ public int getPriority() {
+ return priority;
+ }
+
+ public void setPriority(int priority) {
+ this.priority = priority;
+ }
+
+ public List getNames() {
+ return names;
+ }
+
+ public void setNames(List names) {
+ this.names = names;
+ }
+
+ public List getSubjects() {
+ return subjects;
+ }
+
+ public void setSubjects(List subjects) {
+ this.subjects = subjects;
+ }
+
+ public List getDescriptions() {
+ return descriptions;
+ }
+
+ public void setDescriptions(List descriptions) {
+ this.descriptions = descriptions;
+ }
+
+ public PeopleAssignments getPeopleAssignments() {
+ return peopleAssignments;
+ }
+
+ public void setPeopleAssignments(PeopleAssignments peopleAssignments) {
+ this.peopleAssignments = (PeopleAssignmentsImpl) peopleAssignments;
+ }
+
+ public Delegation getDelegation() {
+ return delegation;
+ }
+
+ public void setDelegation(Delegation delegation) {
+ this.delegation = (DelegationImpl) delegation;
+ }
+
+ public TaskData getTaskData() {
+ return taskData;
+ }
+
+ public void setTaskData(TaskData taskData) {
+ this.taskData = (TaskDataImpl) taskData;
+ }
+
+ public Deadlines getDeadlines() {
+ return deadlines;
+ }
+
+ public void setDeadlines(Deadlines deadlines) {
+ this.deadlines = (DeadlinesImpl) deadlines;
+ }
+
+ public String getTaskType() {
+ return taskType;
+ }
+
+ public void setTaskType(String taskType) {
+ this.taskType = taskType;
+ }
+
+ public String getFormName() {
+ return formName;
+ }
+
+ public void setFormName(String formName) {
+ this.formName = formName;
+ }
+
+
+ public Short getArchived() {
+ return archived;
+ }
+
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + version;
+ result = prime * result + priority;
+ result = prime * result + archived.hashCode();
+ result = prime * result + ((taskType == null) ? 0 : taskType.hashCode());
+ result = prime * result + CollectionUtils.hashCode( descriptions );
+ result = prime * result + CollectionUtils.hashCode( names );
+ result = prime * result + CollectionUtils.hashCode( subjects );
+ result = prime * result + ((peopleAssignments == null) ? 0 : peopleAssignments.hashCode());
+ result = prime * result + ((delegation == null) ? 0 : delegation.hashCode());
+ result = prime * result + ((taskData == null) ? 0 : taskData.hashCode());
+ result = prime * result + ((deadlines == null) ? 0 : deadlines.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if ( this == obj ) return true;
+ if ( obj == null ) return false;
+ if ( !(obj instanceof TaskImpl) ) return false;
+ TaskImpl other = (TaskImpl) obj;
+ if ( this.version != other.version ) {
+ return false;
+ }
+ if ( this.archived != other.archived ) {
+ return false;
+ }
+ if (taskType == null) {
+ if (other.taskType != null) return false;
+ } else if (!taskType.equals(other.taskType)) return false;
+ if ( deadlines == null ) {
+ if ( other.deadlines != null ) {
+
+ }
+ } else if ( !deadlines.equals( other.deadlines ) ) return false;
+ if ( delegation == null ) {
+ if ( other.delegation != null ) return false;
+ } else if ( !delegation.equals( other.delegation ) ) return false;
+ if ( peopleAssignments == null ) {
+ if ( other.peopleAssignments != null ) return false;
+ } else if ( !peopleAssignments.equals( other.peopleAssignments ) ) return false;
+
+ if ( priority != other.priority ) return false;
+ if ( taskData == null ) {
+ if ( other.taskData != null ) return false;
+ } else if ( !taskData.equals( other.taskData ) ) return false;
+ return ( CollectionUtils.equals( descriptions, other.descriptions ) && CollectionUtils.equals( names, other.names )
+ && CollectionUtils.equals( subjects, other.subjects ));
+ }
+
+ public SubTasksStrategy getSubTaskStrategy() {
+ return subTaskStrategy;
+ }
+
+ public void setSubTaskStrategy(SubTasksStrategy subTaskStrategy) {
+ this.subTaskStrategy = subTaskStrategy;
+ }
+
+}
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/UserImpl.java b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/UserImpl.java
new file mode 100644
index 0000000000..80948f6453
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/impl/model/UserImpl.java
@@ -0,0 +1,52 @@
+/**
+ * Copyright 2010 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jbpm.services.task.impl.model;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.kie.api.task.model.User;
+
+@Entity
+@DiscriminatorValue("User")
+public class UserImpl extends OrganizationalEntityImpl implements User {
+
+ public UserImpl() {
+ super();
+ }
+
+ public UserImpl(String id) {
+ super(id);
+ }
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ super.writeExternal( out );
+ }
+
+ public void readExternal(ObjectInput in) throws IOException,
+ ClassNotFoundException {
+ super.readExternal( in );
+ }
+
+
+
+
+}
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/persistence/JPATaskModelFactory.java b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/persistence/JPATaskModelFactory.java
new file mode 100644
index 0000000000..dbd71bece9
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/persistence/JPATaskModelFactory.java
@@ -0,0 +1,189 @@
+package org.jbpm.services.task.persistence;
+
+import org.jbpm.services.task.impl.model.AttachmentImpl;
+import org.jbpm.services.task.impl.model.BooleanExpressionImpl;
+import org.jbpm.services.task.impl.model.CommentImpl;
+import org.jbpm.services.task.impl.model.ContentDataImpl;
+import org.jbpm.services.task.impl.model.ContentImpl;
+import org.jbpm.services.task.impl.model.DeadlineImpl;
+import org.jbpm.services.task.impl.model.DeadlinesImpl;
+import org.jbpm.services.task.impl.model.DelegationImpl;
+import org.jbpm.services.task.impl.model.EmailNotificationHeaderImpl;
+import org.jbpm.services.task.impl.model.EmailNotificationImpl;
+import org.jbpm.services.task.impl.model.EscalationImpl;
+import org.jbpm.services.task.impl.model.FaultDataImpl;
+import org.jbpm.services.task.impl.model.GroupImpl;
+import org.jbpm.services.task.impl.model.I18NTextImpl;
+import org.jbpm.services.task.impl.model.LanguageImpl;
+import org.jbpm.services.task.impl.model.NotificationImpl;
+import org.jbpm.services.task.impl.model.PeopleAssignmentsImpl;
+import org.jbpm.services.task.impl.model.ReassignmentImpl;
+import org.jbpm.services.task.impl.model.TaskDataImpl;
+import org.jbpm.services.task.impl.model.TaskDefImpl;
+import org.jbpm.services.task.impl.model.TaskImpl;
+import org.jbpm.services.task.impl.model.UserImpl;
+import org.kie.api.task.model.Attachment;
+import org.kie.api.task.model.Comment;
+import org.kie.api.task.model.Content;
+import org.kie.api.task.model.Group;
+import org.kie.api.task.model.I18NText;
+import org.kie.api.task.model.OrganizationalEntity;
+import org.kie.api.task.model.PeopleAssignments;
+import org.kie.api.task.model.Task;
+import org.kie.api.task.model.TaskData;
+import org.kie.api.task.model.User;
+import org.kie.internal.task.api.TaskModelFactory;
+import org.kie.internal.task.api.model.BooleanExpression;
+import org.kie.internal.task.api.model.ContentData;
+import org.kie.internal.task.api.model.Deadline;
+import org.kie.internal.task.api.model.Deadlines;
+import org.kie.internal.task.api.model.Delegation;
+import org.kie.internal.task.api.model.EmailNotification;
+import org.kie.internal.task.api.model.EmailNotificationHeader;
+import org.kie.internal.task.api.model.Escalation;
+import org.kie.internal.task.api.model.FaultData;
+import org.kie.internal.task.api.model.Language;
+import org.kie.internal.task.api.model.Notification;
+import org.kie.internal.task.api.model.Reassignment;
+import org.kie.internal.task.api.model.TaskDef;
+
+public class JPATaskModelFactory implements TaskModelFactory {
+
+ @Override
+ public Attachment newAttachment() {
+ return new AttachmentImpl();
+ }
+
+ @Override
+ public BooleanExpression newBooleanExpression() {
+
+ return new BooleanExpressionImpl();
+ }
+
+ @Override
+ public Comment newComment() {
+
+ return new CommentImpl();
+ }
+
+ @Override
+ public ContentData newContentData() {
+
+ return new ContentDataImpl();
+ }
+
+ @Override
+ public Content newContent() {
+
+ return new ContentImpl();
+ }
+
+ @Override
+ public Deadline newDeadline() {
+
+ return new DeadlineImpl();
+ }
+
+ @Override
+ public Deadlines newDeadlines() {
+
+ return new DeadlinesImpl();
+ }
+
+ @Override
+ public Delegation newDelegation() {
+
+ return new DelegationImpl();
+ }
+
+ @Override
+ public EmailNotificationHeader newEmailNotificationHeader() {
+
+ return new EmailNotificationHeaderImpl();
+ }
+
+ @Override
+ public EmailNotification newEmialNotification() {
+
+ return new EmailNotificationImpl();
+ }
+
+ @Override
+ public Escalation newEscalation() {
+
+ return new EscalationImpl();
+ }
+
+ @Override
+ public FaultData newFaultData() {
+
+ return new FaultDataImpl();
+ }
+
+ @Override
+ public Group newGroup() {
+
+ return new GroupImpl();
+ }
+
+ @Override
+ public I18NText newI18NText() {
+
+ return new I18NTextImpl();
+ }
+
+ @Override
+ public Language newLanguage() {
+
+ return new LanguageImpl();
+ }
+
+ @Override
+ public Notification newNotification() {
+
+ return new NotificationImpl();
+ }
+
+ @Override
+ public OrganizationalEntity newOrgEntity() {
+
+ throw new UnsupportedOperationException("OrganizationalEntity not supported");
+ }
+
+ @Override
+ public PeopleAssignments newPeopleAssignments() {
+
+ return new PeopleAssignmentsImpl();
+ }
+
+ @Override
+ public Reassignment newReassignment() {
+
+ return new ReassignmentImpl();
+ }
+
+ @Override
+ public TaskData newTaskData() {
+
+ return new TaskDataImpl();
+ }
+
+ @Override
+ public TaskDef newTaskDef() {
+
+ return new TaskDefImpl();
+ }
+
+ @Override
+ public Task newTask() {
+
+ return new TaskImpl();
+ }
+
+ @Override
+ public User newUser() {
+
+ return new UserImpl();
+ }
+
+}
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/persistence/JPATaskPersistenceContext.java b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/persistence/JPATaskPersistenceContext.java
new file mode 100644
index 0000000000..a5c3b24f62
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/persistence/JPATaskPersistenceContext.java
@@ -0,0 +1,556 @@
+package org.jbpm.services.task.persistence;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.locks.ReentrantLock;
+
+import javax.persistence.EntityManager;
+import javax.persistence.FlushModeType;
+import javax.persistence.LockModeType;
+import javax.persistence.Query;
+
+import org.drools.core.util.StringUtils;
+import org.drools.persistence.TransactionManager;
+import org.drools.persistence.TransactionSynchronization;
+import org.drools.persistence.jta.JtaTransactionManager;
+import org.jbpm.services.task.impl.model.AttachmentImpl;
+import org.jbpm.services.task.impl.model.CommentImpl;
+import org.jbpm.services.task.impl.model.ContentImpl;
+import org.jbpm.services.task.impl.model.DeadlineImpl;
+import org.jbpm.services.task.impl.model.GroupImpl;
+import org.jbpm.services.task.impl.model.OrganizationalEntityImpl;
+import org.jbpm.services.task.impl.model.TaskImpl;
+import org.jbpm.services.task.impl.model.UserImpl;
+import org.kie.api.task.model.Attachment;
+import org.kie.api.task.model.Comment;
+import org.kie.api.task.model.Content;
+import org.kie.api.task.model.Group;
+import org.kie.api.task.model.OrganizationalEntity;
+import org.kie.api.task.model.Task;
+import org.kie.api.task.model.User;
+import org.kie.internal.task.api.TaskPersistenceContext;
+import org.kie.internal.task.api.model.Deadline;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class JPATaskPersistenceContext implements TaskPersistenceContext {
+
+ private static Logger logger = LoggerFactory.getLogger(JPATaskPersistenceContext.class);
+
+ private static ReentrantLock lock = new ReentrantLock();
+ private volatile static Set localcache = new CopyOnWriteArraySet();
+
+ public final static String FIRST_RESULT = "firstResult";
+ public final static String MAX_RESULTS = "maxResults";
+ public final static String FLUSH_MODE = "flushMode";
+
+ protected EntityManager em;
+ protected final boolean isJTA;
+ protected final boolean pessimisticLocking;
+
+ public JPATaskPersistenceContext(EntityManager em) {
+ this(em, true, false);
+ }
+
+ public JPATaskPersistenceContext(EntityManager em, boolean isJTA) {
+ this(em, isJTA, false);
+ }
+
+ public JPATaskPersistenceContext(EntityManager em, boolean isJTA, boolean locking) {
+ this.em = em;
+ this.isJTA = isJTA;
+ this.pessimisticLocking = locking;
+
+ logger.debug("TaskPersistenceManager configured with em {}, isJTA {}, pessimistic locking {}", em, isJTA, locking);
+ }
+
+ @Override
+ public Task findTask(Long taskId) {
+ check();
+ Task task = null;
+ if( this.pessimisticLocking ) {
+ task = this.em.find( TaskImpl.class, taskId, LockModeType.PESSIMISTIC_FORCE_INCREMENT );
+ }
+ task = this.em.find( TaskImpl.class, taskId );
+ return task;
+ }
+
+ @Override
+ public Task persistTask(Task task) {
+ check();
+ this.em.persist( task );
+ if( this.pessimisticLocking ) {
+ return this.em.find(TaskImpl.class, task.getId(), LockModeType.PESSIMISTIC_FORCE_INCREMENT );
+ }
+ return task;
+ }
+
+ @Override
+ public Task updateTask(Task task) {
+ check();
+ return this.em.merge(task);
+ }
+
+ @Override
+ public Task removeTask(Task task) {
+ check();
+ em.remove( task );
+
+ return task;
+ }
+
+ @Override
+ public Group findGroup(String groupId) {
+ check();
+ if( this.pessimisticLocking ) {
+ return this.em.find( GroupImpl.class, groupId, LockModeType.PESSIMISTIC_FORCE_INCREMENT );
+ }
+ return this.em.find( GroupImpl.class, groupId );
+ }
+
+ @Override
+ public Group persistGroup(Group group) {
+ check();
+ this.em.persist( group );
+ if( this.pessimisticLocking ) {
+ return this.em.find(GroupImpl.class, group.getId(), LockModeType.PESSIMISTIC_FORCE_INCREMENT );
+ }
+ return group;
+ }
+
+ @Override
+ public Group updateGroup(Group group) {
+ check();
+ return this.em.merge(group);
+ }
+
+ @Override
+ public Group removeGroup(Group group) {
+ check();
+ em.remove( group );
+ return group;
+ }
+
+ @Override
+ public User findUser(String userId) {
+ check();
+ if( this.pessimisticLocking ) {
+ return this.em.find( UserImpl.class, userId, LockModeType.PESSIMISTIC_FORCE_INCREMENT );
+ }
+ return this.em.find( UserImpl.class, userId );
+ }
+
+ @Override
+ public User persistUser(User user) {
+ check();
+ this.em.persist( user );
+ if( this.pessimisticLocking ) {
+ return this.em.find(UserImpl.class, user.getId(), LockModeType.PESSIMISTIC_FORCE_INCREMENT );
+ }
+ return user;
+ }
+
+ @Override
+ public User updateUser(User user) {
+ check();
+ return this.em.merge(user);
+ }
+
+ @Override
+ public User removeUser(User user) {
+ check();
+ em.remove( user );
+ return user;
+ }
+
+ @Override
+ public OrganizationalEntity findOrgEntity(String orgEntityId) {
+ check();
+ if( this.pessimisticLocking ) {
+ return this.em.find( OrganizationalEntityImpl.class, orgEntityId, LockModeType.PESSIMISTIC_FORCE_INCREMENT );
+ }
+ return this.em.find( OrganizationalEntityImpl.class, orgEntityId );
+ }
+
+ @Override
+ public OrganizationalEntity persistOrgEntity(OrganizationalEntity orgEntity) {
+ check();
+ boolean exists = localcache.contains(orgEntity.getId());
+ if (exists) {
+ logger.debug("No need to lock {}", Thread.currentThread().getName());
+ return orgEntity;
+ }
+
+ logger.debug("About to lock {}", Thread.currentThread().getName());
+ lock.lock();
+ logger.debug("Lock accuried {}" + Thread.currentThread().getName());
+ try {
+ exists = localcache.contains(orgEntity.getId());
+ logger.debug("Entity {} exists {} thread {}", orgEntity, exists, Thread.currentThread().getName());
+ if (!StringUtils.isEmpty(orgEntity.getId()) && !exists) {
+ this.em.persist( orgEntity );
+ if( this.pessimisticLocking ) {
+ return this.em.find(OrganizationalEntityImpl.class, orgEntity.getId(), LockModeType.PESSIMISTIC_FORCE_INCREMENT );
+ }
+
+ logger.debug("Persisted {} by thread {}", orgEntity, Thread.currentThread().getName());
+ }
+ } finally {
+ if (exists) {
+ logger.debug("Unlock directly {}", Thread.currentThread().getName());
+ // unlock directly when exists in local cache
+ lock.unlock();
+ } else {
+ logger.debug("Unlock on transaction completion {}", Thread.currentThread().getName());
+
+ TransactionManager txm = new JtaTransactionManager(null, null, null);
+
+ if (txm.getStatus() != JtaTransactionManager.STATUS_NO_TRANSACTION
+ && txm.getStatus() != JtaTransactionManager.STATUS_ROLLEDBACK
+ && txm.getStatus() != JtaTransactionManager.STATUS_COMMITTED) {
+ // unlock after transaction was completed
+ txm.registerTransactionSynchronization(new SynchronizationImpl(orgEntity.getId()));
+ } else {
+ logger.debug("Unlock directly no tx sync avaliable {}", Thread.currentThread().getName());
+ // unlock directly when exists in local cache
+ lock.unlock();
+ }
+ }
+ }
+
+ return orgEntity;
+ }
+
+ @Override
+ public OrganizationalEntity updateOrgEntity(OrganizationalEntity orgEntity) {
+ check();
+ return this.em.merge(orgEntity);
+ }
+
+ @Override
+ public OrganizationalEntity removeOrgEntity(OrganizationalEntity orgEntity) {
+ check();
+ em.remove( orgEntity );
+ return orgEntity;
+ }
+
+ @Override
+ public Content findContent(Long contentId) {
+ check();
+ if( this.pessimisticLocking ) {
+ return this.em.find( ContentImpl.class, contentId, LockModeType.PESSIMISTIC_FORCE_INCREMENT );
+ }
+ return this.em.find( ContentImpl.class, contentId );
+ }
+
+ @Override
+ public Content persistContent(Content content) {
+ check();
+ this.em.persist( content );
+ if( this.pessimisticLocking ) {
+ return this.em.find(ContentImpl.class, content.getId(), LockModeType.PESSIMISTIC_FORCE_INCREMENT );
+ }
+ return content;
+ }
+
+ @Override
+ public Content updateContent(Content content) {
+ check();
+ return this.em.merge(content);
+ }
+
+ @Override
+ public Content removeContent(Content content) {
+ check();
+ em.remove( content );
+ return content;
+ }
+
+ @Override
+ public Attachment findAttachment(Long attachmentId) {
+ check();
+ if( this.pessimisticLocking ) {
+ return this.em.find( AttachmentImpl.class, attachmentId, LockModeType.PESSIMISTIC_FORCE_INCREMENT );
+ }
+ return this.em.find( AttachmentImpl.class, attachmentId );
+ }
+
+ @Override
+ public Attachment persistAttachment(Attachment attachment) {
+ check();
+ this.em.persist( attachment );
+ if( this.pessimisticLocking ) {
+ return this.em.find(AttachmentImpl.class, attachment.getId(), LockModeType.PESSIMISTIC_FORCE_INCREMENT );
+ }
+ return attachment;
+ }
+
+ @Override
+ public Attachment updateAttachment(Attachment attachment) {
+ check();
+ return this.em.merge(attachment);
+ }
+
+ @Override
+ public Attachment removeAttachment(Attachment attachment) {
+ check();
+ em.remove( attachment );
+ return attachment;
+ }
+
+ @Override
+ public Comment findComment(Long commentId) {
+ check();
+ if( this.pessimisticLocking ) {
+ return this.em.find( CommentImpl.class, commentId, LockModeType.PESSIMISTIC_FORCE_INCREMENT );
+ }
+ return this.em.find( CommentImpl.class, commentId );
+ }
+
+ @Override
+ public Comment persistComment(Comment comment) {
+ check();
+ this.em.persist( comment );
+ if( this.pessimisticLocking ) {
+ return this.em.find(CommentImpl.class, comment.getId(), LockModeType.PESSIMISTIC_FORCE_INCREMENT );
+ }
+ return comment;
+ }
+
+ @Override
+ public Comment updateComment(Comment comment) {
+ check();
+ return this.em.merge(comment);
+ }
+
+ @Override
+ public Comment removeComment(Comment comment) {
+ check();
+ em.remove( comment );
+ return comment;
+ }
+
+ @Override
+ public Deadline findDeadline(Long deadlineId) {
+ check();
+ if( this.pessimisticLocking ) {
+ return this.em.find( DeadlineImpl.class, deadlineId, LockModeType.PESSIMISTIC_FORCE_INCREMENT );
+ }
+ return this.em.find( DeadlineImpl.class, deadlineId );
+ }
+
+ @Override
+ public Deadline persistDeadline(Deadline deadline) {
+ check();
+ this.em.persist( deadline );
+ if( this.pessimisticLocking ) {
+ return this.em.find(DeadlineImpl.class, deadline.getId(), LockModeType.PESSIMISTIC_FORCE_INCREMENT );
+ }
+ return deadline;
+ }
+
+ @Override
+ public Deadline updateDeadline(Deadline deadline) {
+ check();
+ return this.em.merge(deadline);
+ }
+
+ @Override
+ public Deadline removeDeadline(Deadline deadline) {
+ check();
+ em.remove( deadline );
+ return deadline;
+ }
+
+ @Override
+ public T queryWithParametersInTransaction(String queryName,
+ Map params, Class clazz) {
+ check();
+ Query query = this.em.createNamedQuery(queryName);
+ return queryStringWithParameters(params, false, LockModeType.NONE, clazz, query);
+ }
+
+ @Override
+ public T queryAndLockWithParametersInTransaction(String queryName,
+ Map params, boolean singleResult, Class clazz) {
+ check();
+ Query query = this.em.createNamedQuery(queryName);
+ return queryStringWithParameters(params, singleResult, LockModeType.NONE, clazz, query);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public T queryInTransaction(String queryName, Class clazz) {
+ check();
+ Query query = this.em.createNamedQuery(queryName);
+ return (T) query.getResultList();
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public T queryStringInTransaction(String queryString, Class clazz) {
+ check();
+ Query query = this.em.createQuery(queryString);
+ return (T) query.getResultList();
+ }
+
+ @Override
+ public T queryStringWithParametersInTransaction(String queryString,
+ Map params, Class clazz) {
+ check();
+ Query query = this.em.createQuery(queryString);
+
+ return queryStringWithParameters(params, false, LockModeType.NONE, clazz, query);
+ }
+
+
+ @Override
+ public T queryAndLockStringWithParametersInTransaction(
+ String queryName, Map params, boolean singleResult,
+ Class clazz) {
+ check();
+ Query query = this.em.createNamedQuery(queryName);
+ return queryStringWithParameters(params, singleResult, LockModeType.PESSIMISTIC_FORCE_INCREMENT, clazz, query);
+ }
+
+ @Override
+ public int executeUpdateString(String updateString) {
+ check();
+ Query query = this.em.createQuery(updateString);
+ return query.executeUpdate();
+ }
+
+ @Override
+ public HashMap addParametersToMap(Object... parameterValues) {
+ HashMap parameters = new HashMap();
+
+ if( parameterValues.length % 2 != 0 ) {
+ throw new RuntimeException("Expected an even number of parameters, not " + parameterValues.length);
+ }
+
+ for( int i = 0; i < parameterValues.length; ++i ) {
+ String parameterName = null;
+ if( parameterValues[i] instanceof String ) {
+ parameterName = (String) parameterValues[i];
+ } else {
+ throw new RuntimeException("Expected a String as the parameter name, not a " + parameterValues[i].getClass().getSimpleName());
+ }
+ ++i;
+ parameters.put(parameterName, parameterValues[i]);
+ }
+
+ return parameters;
+ }
+
+ @Override
+ public T persist(T object) {
+ check();
+ this.em.persist( object );
+ return object;
+ }
+
+ @Override
+ public T find(Class entityClass, Object primaryKey) {
+ check();
+ if( this.pessimisticLocking ) {
+ return this.em.find( entityClass, primaryKey, LockModeType.PESSIMISTIC_FORCE_INCREMENT );
+ }
+ return this.em.find( entityClass, primaryKey );
+ }
+
+ @Override
+ public T remove(T entity) {
+ check();
+ em.remove( entity );
+ return entity;
+ }
+
+ @Override
+ public T merge(T entity) {
+ check();
+ return this.em.merge(entity);
+ }
+
+ @SuppressWarnings("unchecked")
+ private T queryStringWithParameters(Map params, boolean singleResult, LockModeType lockMode,
+ Class clazz, Query query) {
+ ;
+ if (lockMode != null) {
+ query.setLockMode(lockMode);
+ }
+ if (params != null && !params.isEmpty()) {
+ for (String name : params.keySet()) {
+ if (FIRST_RESULT.equals(name)) {
+ query.setFirstResult((Integer) params.get(name));
+ continue;
+ }
+ if (MAX_RESULTS.equals(name)) {
+ query.setMaxResults((Integer) params.get(name));
+ continue;
+ }
+ if (FLUSH_MODE.equals(name)) {
+ query.setFlushMode(FlushModeType.valueOf((String) params.get(name)));
+ continue;
+ }
+ query.setParameter(name, params.get(name));
+ }
+ }
+ if (singleResult) {
+ return (T) query.getSingleResult();
+ }
+ return (T) query.getResultList();
+ }
+
+ @Override
+ public boolean isOpen() {
+ if (this.em == null) {
+ return false;
+ }
+ return this.em.isOpen();
+ }
+
+ @Override
+ public void joinTransaction() {
+ if (this.em == null) {
+ return;
+ }
+ if (this.isJTA) {
+ this.em.joinTransaction();
+ }
+ }
+
+ @Override
+ public void close() {
+ check();
+ this.em.close();
+ }
+
+ protected void check() {
+ if (em == null || !em.isOpen()) {
+ throw new IllegalStateException("Entity manager is null or is closed, exiting...");
+ }
+ }
+
+
+ private static class SynchronizationImpl implements TransactionSynchronization {
+
+ private String entityId;
+ public SynchronizationImpl(String entityId) {
+ }
+
+ public void afterCompletion(int status) {
+ if (lock.hasQueuedThreads()) {
+ localcache.add(entityId);
+ }
+ lock.unlock();
+ logger.debug("Unlocked {}", Thread.currentThread().getName());
+ }
+
+ public void beforeCompletion() {
+ // not used
+ }
+
+ }
+}
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/persistence/JPATaskPersistenceContextManager.java b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/persistence/JPATaskPersistenceContextManager.java
new file mode 100644
index 0000000000..fb3f0defc2
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/persistence/JPATaskPersistenceContextManager.java
@@ -0,0 +1,29 @@
+package org.jbpm.services.task.persistence;
+
+import javax.persistence.EntityManager;
+
+import org.drools.persistence.jpa.AbstractPersistenceContextManager;
+import org.kie.api.runtime.Environment;
+import org.kie.internal.task.api.TaskPersistenceContext;
+import org.kie.internal.task.api.TaskPersistenceContextManager;
+
+public class JPATaskPersistenceContextManager extends
+ AbstractPersistenceContextManager implements
+ TaskPersistenceContextManager {
+
+ public JPATaskPersistenceContextManager(Environment environment) {
+ super(environment);
+ }
+
+ @Override
+ public TaskPersistenceContext getPersistenceContext() {
+ EntityManager em = getCommandScopedEntityManager();
+ return new JPATaskPersistenceContext(em);
+ }
+
+ @Override
+ public void beginCommandScopedEntityManager() {
+ getCommandScopedEntityManager();
+ }
+
+}
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/persistence/TaskTransactionInterceptor.java b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/persistence/TaskTransactionInterceptor.java
new file mode 100644
index 0000000000..68bc55a6d1
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/persistence/TaskTransactionInterceptor.java
@@ -0,0 +1,237 @@
+package org.jbpm.services.task.persistence;
+
+import java.lang.reflect.Constructor;
+
+import org.drools.core.command.CommandService;
+import org.drools.core.command.Interceptor;
+import org.drools.core.command.impl.AbstractInterceptor;
+import org.drools.persistence.OrderedTransactionSynchronization;
+import org.drools.persistence.TransactionManager;
+import org.drools.persistence.TransactionManagerHelper;
+import org.drools.persistence.jta.JtaTransactionManager;
+import org.kie.api.command.Command;
+import org.kie.api.runtime.Environment;
+import org.kie.api.runtime.EnvironmentName;
+import org.kie.api.task.UserGroupCallback;
+import org.kie.api.task.model.Task;
+import org.kie.internal.command.Context;
+import org.kie.internal.command.World;
+import org.kie.internal.task.api.TaskContext;
+import org.kie.internal.task.api.TaskPersistenceContext;
+import org.kie.internal.task.api.TaskPersistenceContextManager;
+import org.kie.internal.task.api.model.InternalPeopleAssignments;
+import org.kie.internal.task.api.model.InternalTask;
+import org.kie.internal.task.exception.TaskException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TaskTransactionInterceptor extends AbstractInterceptor {
+
+ private static Logger logger = LoggerFactory.getLogger(TaskTransactionInterceptor.class);
+ private static String SPRING_TM_CLASSNAME = "org.springframework.transaction.support.AbstractPlatformTransactionManager";
+
+ private CommandService commandService;
+ private TransactionManager txm;
+ private TaskPersistenceContextManager tpm;
+ private boolean eagerDisabled = true;
+
+ public TaskTransactionInterceptor(Environment environment) {
+ this.eagerDisabled = Boolean.getBoolean("jbpm.ht.eager.disabled");
+ initTransactionManager(environment);
+ }
+
+ @Override
+ public T execute(Command command) {
+ boolean transactionOwner = false;
+ T result = null;
+
+ try {
+ transactionOwner = txm.begin();
+ tpm.beginCommandScopedEntityManager();
+ TransactionManagerHelper.registerTransactionSyncInContainer(this.txm, new TaskSynchronizationImpl( this ));
+
+ result = executeNext((Command) command);
+ postInit(result);
+ txm.commit( transactionOwner );
+
+ return result;
+
+ } catch (TaskException e) {
+ // allow to handle TaskException as business exceptions on caller side
+ // if transaction is owned by other component like process engine
+ if (transactionOwner) {
+ rollbackTransaction( e, transactionOwner );
+ throw e;
+ } else {
+ throw e;
+ }
+ }
+ catch ( RuntimeException re ) {
+ rollbackTransaction( re, transactionOwner );
+ throw re;
+ } catch ( Exception t1 ) {
+ rollbackTransaction( t1, transactionOwner );
+ throw new RuntimeException( "Wrapped exception see cause", t1 );
+ }
+
+ }
+
+ private void rollbackTransaction(Exception t1, boolean transactionOwner) {
+ try {
+ logger.warn("Could not commit session", t1);
+ txm.rollback(transactionOwner);
+ } catch (Exception t2) {
+ logger.error("Could not rollback", t2);
+ throw new RuntimeException("Could not commit session or rollback", t2);
+ }
+ }
+
+ public void addInterceptor(Interceptor interceptor) {
+ interceptor.setNext( this.commandService == null ? this : this.commandService );
+ this.commandService = interceptor;
+ }
+
+ @Override
+ public Context getContext() {
+
+ final TaskPersistenceContext persistenceContext = tpm.getPersistenceContext();
+ persistenceContext.joinTransaction();
+
+ return new TaskContext() {
+
+ @Override
+ public void set(String identifier, Object value) {
+ }
+
+ @Override
+ public void remove(String identifier) {
+ }
+
+ @Override
+ public String getName() {
+ return null;
+ }
+
+ @Override
+ public World getContextManager() {
+ return null;
+ }
+
+ @Override
+ public Object get(String identifier) {
+ return null;
+ }
+
+ @Override
+ public void setPersistenceContext(TaskPersistenceContext context) {
+ }
+
+ @Override
+ public TaskPersistenceContext getPersistenceContext() {
+ return persistenceContext;
+ }
+
+ @Override
+ public UserGroupCallback getUserGroupCallback() {
+ return null;
+ }
+ };
+ }
+
+ public void initTransactionManager(Environment env) {
+ Object tm = env.get( EnvironmentName.TRANSACTION_MANAGER );
+ if ( env.get( EnvironmentName.TASK_PERSISTENCE_CONTEXT_MANAGER ) != null &&
+ env.get( EnvironmentName.TRANSACTION_MANAGER ) != null ) {
+ this.txm = (TransactionManager) tm;
+ this.tpm = (TaskPersistenceContextManager) env.get( EnvironmentName.TASK_PERSISTENCE_CONTEXT_MANAGER );
+ } else {
+ if ( tm != null && isSpringTransactionManager(tm.getClass()) ) {
+ try {
+ logger.debug( "Instantiating KieSpringTransactionManager" );
+ Class< ? > cls = Class.forName( "org.kie.spring.persistence.KieSpringTransactionManager" );
+ Constructor< ? > con = cls.getConstructors()[0];
+ this.txm = (TransactionManager) con.newInstance( tm );
+ env.set( EnvironmentName.TRANSACTION_MANAGER, this.txm );
+ cls = Class.forName( "org.kie.spring.persistence.KieSpringTaskJpaManager" );
+ con = cls.getConstructors()[0];
+ this.tpm = (TaskPersistenceContextManager) con.newInstance( new Object[]{env} );
+ } catch ( Exception e ) {
+
+ logger.warn( "Could not instantiate DroolsSpringTransactionManager" );
+ throw new RuntimeException( "Could not instantiate org.kie.container.spring.beans.persistence.DroolsSpringTransactionManager", e );
+ }
+ } else {
+ logger.debug( "Instantiating JtaTransactionManager" );
+ this.txm = new JtaTransactionManager( env.get( EnvironmentName.TRANSACTION ),
+ env.get( EnvironmentName.TRANSACTION_SYNCHRONIZATION_REGISTRY ),
+ tm );
+ env.set( EnvironmentName.TRANSACTION_MANAGER, this.txm );
+ try {
+ this.tpm = new JPATaskPersistenceContextManager( env );
+ } catch ( Exception e ) {
+ throw new RuntimeException( "Error creating JPATaskPersistenceContextManager", e );
+ }
+ }
+ env.set( EnvironmentName.TASK_PERSISTENCE_CONTEXT_MANAGER,
+ this.tpm );
+ env.set( EnvironmentName.TRANSACTION_MANAGER,
+ this.txm );
+ }
+ }
+
+
+ public boolean isSpringTransactionManager( Class> clazz ) {
+ if ( SPRING_TM_CLASSNAME.equals(clazz.getName()) ) {
+ return true;
+ }
+ // Try to find from the ancestors
+ if (clazz.getSuperclass() != null)
+ {
+ return isSpringTransactionManager(clazz.getSuperclass());
+ }
+ return false;
+ }
+
+ private void postInit(Object result) {
+ if (result instanceof Task) {
+ Task task = (Task) result;
+ if (task != null && !eagerDisabled) {
+ task.getNames().size();
+ task.getDescriptions().size();
+ task.getSubjects().size();
+ task.getPeopleAssignments().getBusinessAdministrators().size();
+ task.getPeopleAssignments().getPotentialOwners().size();
+ ((InternalPeopleAssignments) task.getPeopleAssignments()).getRecipients().size();
+ ((InternalPeopleAssignments) task.getPeopleAssignments()).getExcludedOwners().size();
+ ((InternalPeopleAssignments) task.getPeopleAssignments()).getTaskStakeholders().size();
+ task.getTaskData().getAttachments().size();
+ task.getTaskData().getComments().size();
+ ((InternalTask)task).getDeadlines().getStartDeadlines().size();
+ ((InternalTask)task).getDeadlines().getEndDeadlines().size();
+ }
+ }
+ }
+
+ private static class TaskSynchronizationImpl extends
+ OrderedTransactionSynchronization {
+
+ TaskTransactionInterceptor service;
+
+ public TaskSynchronizationImpl(TaskTransactionInterceptor service) {
+ super(1);
+ this.service = service;
+ }
+
+ public void afterCompletion(int status) {
+
+ this.service.tpm.endCommandScopedEntityManager();
+
+ }
+
+ public void beforeCompletion() {
+ // not used
+ }
+
+ }
+
+}
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/utils/CollectionUtils.java b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/utils/CollectionUtils.java
new file mode 100644
index 0000000000..fd749030d4
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/java/org/jbpm/services/task/utils/CollectionUtils.java
@@ -0,0 +1,291 @@
+/**
+ * Copyright 2010 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jbpm.services.task.utils;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.jbpm.services.task.impl.model.AttachmentImpl;
+import org.jbpm.services.task.impl.model.BooleanExpressionImpl;
+import org.jbpm.services.task.impl.model.CommentImpl;
+import org.jbpm.services.task.impl.model.DeadlineImpl;
+import org.jbpm.services.task.impl.model.EmailNotificationImpl;
+import org.jbpm.services.task.impl.model.EscalationImpl;
+import org.jbpm.services.task.impl.model.GroupImpl;
+import org.jbpm.services.task.impl.model.I18NTextImpl;
+import org.jbpm.services.task.impl.model.NotificationImpl;
+import org.jbpm.services.task.impl.model.ReassignmentImpl;
+import org.jbpm.services.task.impl.model.UserImpl;
+import org.kie.api.task.model.Attachment;
+import org.kie.api.task.model.Comment;
+import org.kie.api.task.model.Group;
+import org.kie.api.task.model.I18NText;
+import org.kie.api.task.model.OrganizationalEntity;
+import org.kie.api.task.model.User;
+import org.kie.internal.task.api.model.BooleanExpression;
+import org.kie.internal.task.api.model.Deadline;
+import org.kie.internal.task.api.model.Escalation;
+import org.kie.internal.task.api.model.Notification;
+import org.kie.internal.task.api.model.NotificationType;
+import org.kie.internal.task.api.model.Reassignment;
+
+public class CollectionUtils {
+
+ public static boolean equals(List list1, List list2) {
+ if ( list1 == null && list2 == null ) {
+ // both are null
+ return true;
+ }
+
+ if ( list1 == null || list2 == null ) {
+ // we know both aren't null, so if one is null them obviously false
+ return false;
+ }
+
+ if ( list1.size() != list2.size() ) {
+ return false;
+ }
+
+ if ( list1.isEmpty() && list2.isEmpty() ) {
+ return true;
+ }
+
+
+ for ( Object item1 : list1) {
+ boolean exists = false;
+ for ( Object item2 : list2 ) {
+ if ( item1.equals( item2 )) {
+ exists = true;
+ break;
+ }
+ }
+ if ( !exists ) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public static int hashCode(List list) {
+ if ( list == null ) {
+ return 0;
+ }
+
+ final int prime = 31;
+ int result = 1;
+ for ( Iterator it = list.iterator(); it.hasNext(); ) {
+ Object next = it.next();
+ result = prime * result + ((next == null)? 0 : next.hashCode());
+ }
+ return result;
+ }
+
+ public static void writeCommentList(List list, ObjectOutput out) throws IOException {
+ out.writeInt( list.size() );
+ for( Comment item : list ) {
+ item.writeExternal( out );
+ }
+ }
+
+ public static List readCommentList(ObjectInput in) throws IOException, ClassNotFoundException {
+ int size = in.readInt();
+ List list = new ArrayList(size);
+ for ( int i = 0; i < size; i++ ) {
+ Comment item = new CommentImpl();
+ item.readExternal( in );
+ list.add( item );
+ }
+ return list;
+ }
+
+
+ public static void writeAttachmentList(List list, ObjectOutput out) throws IOException {
+ out.writeInt( list.size() );
+ for( Attachment item : list ) {
+ item.writeExternal( out );
+ }
+ }
+
+ public static List readAttachmentList(ObjectInput in) throws IOException, ClassNotFoundException {
+ int size = in.readInt();
+ List list = new ArrayList(size);
+ for ( int i = 0; i < size; i++ ) {
+ Attachment item = new AttachmentImpl();
+ item.readExternal( in );
+ list.add( item );
+ }
+ return list;
+ }
+
+ public static void writeBooleanExpressionList(List list, ObjectOutput out) throws IOException {
+ out.writeInt( list.size() );
+ for( BooleanExpression item : list ) {
+ item.writeExternal( out );
+ }
+ }
+
+ public static List readBooleanExpressionList(ObjectInput in) throws IOException, ClassNotFoundException {
+ int size = in.readInt();
+ List list = new ArrayList(size);
+ for ( int i = 0; i < size; i++ ) {
+ BooleanExpression item = new BooleanExpressionImpl();
+ item.readExternal( in );
+ list.add( item );
+ }
+ return list;
+ }
+
+
+ public static void writeNotificationList(List list, ObjectOutput out) throws IOException {
+ out.writeInt( list.size() );
+ for( Notification item : list ) {
+ // item.getNotificationType().toString() is never null
+ out.writeUTF( item.getNotificationType().toString() );
+ item.writeExternal( out );
+ }
+ }
+
+ public static List readNotificationList(ObjectInput in) throws IOException, ClassNotFoundException {
+ int size = in.readInt();
+ List list = new ArrayList(size);
+ for ( int i = 0; i < size; i++ ) {
+ Notification item = null;
+ switch( NotificationType.valueOf( in.readUTF() ) ) {
+ case Default : {
+ item = new NotificationImpl();
+ break;
+ }
+ case Email : {
+ item = new EmailNotificationImpl();
+ break;
+ }
+ }
+
+ item.readExternal( in );
+ list.add( item );
+ }
+ return list;
+ }
+
+
+ public static void writeReassignmentList(List list, ObjectOutput out) throws IOException {
+ out.writeInt( list.size() );
+ for( Reassignment item : list ) {
+ item.writeExternal( out );
+ }
+ }
+
+ public static List readReassignmentList(ObjectInput in) throws IOException, ClassNotFoundException {
+ int size = in.readInt();
+ List list = new ArrayList(size);
+ for ( int i = 0; i < size; i++ ) {
+ Reassignment item = new ReassignmentImpl();
+ item.readExternal( in );
+ list.add( item );
+ }
+ return list;
+ }
+
+ public static void writeDeadlineList(List list, ObjectOutput out) throws IOException {
+ out.writeInt( list.size() );
+ for( Deadline item : list ) {
+ item.writeExternal( out );
+ }
+ }
+
+ public static List readDeadlinesList(ObjectInput in) throws IOException, ClassNotFoundException {
+ int size = in.readInt();
+ List list = new ArrayList(size);
+ for ( int i = 0; i < size; i++ ) {
+ Deadline item = new DeadlineImpl();
+ item.readExternal( in );
+ list.add( item );
+ }
+ return list;
+ }
+
+ public static void writeEscalationList(List list, ObjectOutput out) throws IOException {
+ out.writeInt( list.size() );
+ for( Escalation item : list ) {
+ item.writeExternal( out );
+ }
+ }
+
+ public static List readEscalationList(ObjectInput in) throws IOException, ClassNotFoundException {
+ int size = in.readInt();
+ List list = new ArrayList(size);
+ for ( int i = 0; i < size; i++ ) {
+ Escalation item = new EscalationImpl();
+ item.readExternal( in );
+ list.add( item );
+ }
+ return list;
+ }
+
+ public static void writeI18NTextList(List list, ObjectOutput out) throws IOException {
+ out.writeInt( list.size() );
+ for( I18NText item : list ) {
+ item.writeExternal( out );
+ }
+ }
+
+ public static List readI18NTextList(ObjectInput in) throws IOException, ClassNotFoundException {
+ int size = in.readInt();
+ List list = new ArrayList(size);
+ for ( int i = 0; i < size; i++ ) {
+ I18NText item = new I18NTextImpl();
+ item.readExternal( in );
+ list.add( item );
+ }
+ return list;
+ }
+
+ public static void writeOrganizationalEntityList(List list, ObjectOutput out) throws IOException {
+ out.writeInt( list.size() );
+ for( OrganizationalEntity item : list ) {
+ if ( item instanceof User ) {
+ out.writeShort( 0 );
+ } else {
+ out.writeShort( 1 );
+ }
+ item.writeExternal( out );
+ }
+ }
+
+ public static List readOrganizationalEntityList(ObjectInput in) throws IOException, ClassNotFoundException {
+ int size = in.readInt();
+ List list = new ArrayList(size);
+ for ( int i = 0; i < size; i++ ) {
+ short type = in.readShort();
+ if ( type == 0 ) {
+ User user = new UserImpl();
+ user.readExternal( in );
+ list.add( user );
+ } else {
+ Group group = new GroupImpl();
+ group.readExternal( in );
+ list.add( group );
+ }
+ }
+ return list;
+ }
+}
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/resources/META-INF/Taskorm.xml b/jbpm-human-task/jbpm-human-task-core/src/main/resources/META-INF/Taskorm.xml
new file mode 100644
index 0000000000..f7fa0bf33a
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/resources/META-INF/Taskorm.xml
@@ -0,0 +1,1581 @@
+
+
+
+
+select distinct
+ new org.jbpm.services.task.query.TaskSummaryImpl(
+ t.id,
+ t.taskData.processInstanceId,
+ name.shortText,
+ subject.shortText,
+ description.shortText,
+ t.taskData.status,
+ t.priority,
+ t.taskData.skipable,
+ actualOwner,
+ createdBy,
+ t.taskData.createdOn,
+ t.taskData.activationTime,
+ t.taskData.expirationTime,
+ t.taskData.processId,
+ t.taskData.processSessionId,
+ t.subTaskStrategy,
+ t.taskData.parentId )
+from
+ TaskImpl t
+ left join t.taskData.createdBy as createdBy
+ left join t.taskData.actualOwner as actualOwner
+ left join t.subjects as subject
+ left join t.descriptions as description
+ left join t.names as name,
+ OrganizationalEntityImpl businessAdministrator
+where
+ t.archived = 0 and
+ businessAdministrator.id = :userId and
+ businessAdministrator in elements ( t.peopleAssignments.businessAdministrators ) and
+
+ (
+ name.language = :language
+ or t.names.size = 0
+ ) and
+
+ (
+ subject.language = :language
+ or t.subjects.size = 0
+ ) and
+
+ (
+ description.language = :language
+ or t.descriptions.size = 0
+ )
+ order by t.id DESC
+
+
+
+
+
+select distinct
+ new org.jbpm.services.task.query.TaskSummaryImpl(
+ t.id,
+ t.taskData.processInstanceId,
+ name.shortText,
+ subject.shortText,
+ description.shortText,
+ t.taskData.status,
+ t.priority,
+ t.taskData.skipable,
+ actualOwner,
+ createdBy,
+ t.taskData.createdOn,
+ t.taskData.activationTime,
+ t.taskData.expirationTime,
+ t.taskData.processId,
+ t.taskData.processSessionId,
+ t.subTaskStrategy,
+ t.taskData.parentId )
+from
+ TaskImpl t
+ left join t.taskData.createdBy as createdBy
+ left join t.taskData.actualOwner as actualOwner
+ left join t.subjects as subject
+ left join t.descriptions as description
+ left join t.names as name,
+ OrganizationalEntityImpl excludedOwners
+where
+ t.archived = 0 and
+ excludedOwners.id = :userId and
+ excludedOwners in elements ( t.peopleAssignments.excludedOwners ) and
+
+ (
+ name.language = :language
+ or t.names.size = 0
+ ) and
+
+ (
+ subject.language = :language
+ or t.subjects.size = 0
+ ) and
+
+ (
+ description.language = :language
+ or t.descriptions.size = 0
+ )
+ order by t.id DESC
+
+
+
+
+
+select distinct
+ new org.jbpm.services.task.query.TaskSummaryImpl(
+ t.id,
+ t.taskData.processInstanceId,
+ name.shortText,
+ subject.shortText,
+ description.shortText,
+ t.taskData.status,
+ t.priority,
+ t.taskData.skipable,
+ actualOwner,
+ createdBy,
+ t.taskData.createdOn,
+ t.taskData.activationTime,
+ t.taskData.expirationTime,
+ t.taskData.processId,
+ t.taskData.processSessionId,
+ t.subTaskStrategy,
+ t.taskData.parentId )
+from
+ TaskImpl t
+ left join t.taskData.createdBy as createdBy
+ left join t.taskData.actualOwner as actualOwner
+ left join t.subjects as subject
+ left join t.descriptions as description
+ left join t.names as name,
+ OrganizationalEntityImpl potentialOwners
+where
+ t.archived = 0 and
+ potentialOwners.id = :userId and
+ potentialOwners in elements ( t.peopleAssignments.potentialOwners ) and
+
+ (
+ name.language = :language
+ or t.names.size = 0
+ ) and
+
+ (
+ subject.language = :language
+ or t.subjects.size = 0
+ ) and
+
+ (
+ description.language = :language
+ or t.descriptions.size = 0
+ ) and
+
+ t.taskData.status in ('Created', 'Ready', 'Reserved', 'InProgress', 'Suspended')
+ order by t.id DESC
+
+
+
+
+
+select distinct
+ new org.jbpm.services.task.query.TaskSummaryImpl(
+ t.id,
+ t.taskData.processInstanceId,
+ name.shortText,
+ subject.shortText,
+ description.shortText,
+ t.taskData.status,
+ t.priority,
+ t.taskData.skipable,
+ actualOwner,
+ createdBy,
+ t.taskData.createdOn,
+ t.taskData.activationTime,
+ t.taskData.expirationTime,
+ t.taskData.processId,
+ t.taskData.processSessionId,
+ t.subTaskStrategy,
+ t.taskData.parentId )
+from
+ TaskImpl t
+ left join t.taskData.createdBy as createdBy
+ left join t.taskData.actualOwner as actualOwner
+ left join t.subjects as subject
+ left join t.descriptions as description
+ left join t.names as name,
+ OrganizationalEntityImpl potentialOwners
+where
+ t.archived = 0 and
+ potentialOwners.id = :userId and
+ potentialOwners in elements ( t.peopleAssignments.potentialOwners ) and
+
+ (
+ name.language = :language
+ or t.names.size = 0
+ ) and
+
+ (
+ subject.language = :language
+ or t.subjects.size = 0
+ ) and
+
+ (
+ description.language = :language
+ or t.descriptions.size = 0
+ ) and
+
+ t.taskData.status in (:status)
+ order by t.id DESC
+
+
+
+
+
+select distinct
+ new org.jbpm.services.task.query.TaskSummaryImpl(
+ t.id,
+ t.taskData.processInstanceId,
+ name.shortText,
+ subject.shortText,
+ description.shortText,
+ t.taskData.status,
+ t.priority,
+ t.taskData.skipable,
+ actualOwner,
+ createdBy,
+ t.taskData.createdOn,
+ t.taskData.activationTime,
+ t.taskData.expirationTime,
+ t.taskData.processId,
+ t.taskData.processSessionId,
+ t.subTaskStrategy,
+ t.taskData.parentId )
+from
+ TaskImpl t
+ left join t.taskData.createdBy as createdBy
+ left join t.taskData.actualOwner as actualOwner
+ left join t.subjects as subject
+ left join t.descriptions as description
+ left join t.names as name,
+ OrganizationalEntityImpl potentialOwners
+where
+ t.archived = 0 and
+ ( potentialOwners.id = :userId or potentialOwners.id in (:groupIds) ) and
+ potentialOwners in elements ( t.peopleAssignments.potentialOwners ) and
+
+ (
+ name.language = :language
+ or t.names.size = 0
+ ) and
+
+ (
+ subject.language = :language
+ or t.subjects.size = 0
+ ) and
+
+ (
+ description.language = :language
+ or t.descriptions.size = 0
+ ) and
+
+ t.taskData.status in (:status)
+ order by t.id DESC
+
+
+
+
+
+select distinct
+ new org.jbpm.services.task.query.TaskSummaryImpl(
+ t.id,
+ t.taskData.processInstanceId,
+ name.shortText,
+ subject.shortText,
+ description.shortText,
+ t.taskData.status,
+ t.priority,
+ t.taskData.skipable,
+ actualOwner,
+ createdBy,
+ t.taskData.createdOn,
+ t.taskData.activationTime,
+ t.taskData.expirationTime,
+ t.taskData.processId,
+ t.taskData.processSessionId,
+ t.subTaskStrategy,
+ t.taskData.parentId )
+from
+ TaskImpl t
+ left join t.taskData.createdBy as createdBy
+ left join t.taskData.actualOwner as actualOwner
+ left join t.subjects as subject
+ left join t.descriptions as description
+ left join t.names as name,
+ OrganizationalEntityImpl potentialOwners
+where
+ t.archived = 0 and
+ ( potentialOwners.id = :userId or potentialOwners.id in (:groupIds) ) and
+ potentialOwners in elements ( t.peopleAssignments.potentialOwners ) and
+
+ (
+ name.language = :language
+ or t.names.size = 0
+ ) and
+
+ (
+ subject.language = :language
+ or t.subjects.size = 0
+ ) and
+
+ (
+ description.language = :language
+ or t.descriptions.size = 0
+ ) and
+
+ t.taskData.status in ('Created', 'Ready', 'Reserved', 'InProgress', 'Suspended')
+ order by t.id DESC
+
+
+
+
+
+select distinct
+ new org.jbpm.services.task.query.TaskSummaryImpl(
+ t.id,
+ t.taskData.processInstanceId,
+ name.shortText,
+ subject.shortText,
+ description.shortText,
+ t.taskData.status,
+ t.priority,
+ t.taskData.skipable,
+ actualOwner,
+ createdBy,
+ t.taskData.createdOn,
+ t.taskData.activationTime,
+ t.taskData.expirationTime,
+ t.taskData.processId,
+ t.taskData.processSessionId,
+ t.subTaskStrategy,
+ t.taskData.parentId )
+from
+ TaskImpl t
+ left join t.taskData.createdBy as createdBy
+ left join t.taskData.actualOwner as actualOwner
+ left join t.subjects as subject
+ left join t.descriptions as description
+ left join t.names as name,
+ OrganizationalEntityImpl potentialOwners
+where
+ t.archived = 0 and
+ ( potentialOwners.id = :userId or potentialOwners.id in (:groupIds) ) and
+ potentialOwners in elements ( t.peopleAssignments.potentialOwners ) and
+
+ (
+ name.language = :language
+ or t.names.size = 0
+ ) and
+
+ (
+ subject.language = :language
+ or t.subjects.size = 0
+ ) and
+
+ (
+ description.language = :language
+ or t.descriptions.size = 0
+ ) and
+
+ t.taskData.status in (:status)
+ order by t.id DESC
+
+
+
+
+
+select distinct
+ new org.jbpm.services.task.query.TaskSummaryImpl(
+ t.id,
+ t.taskData.processInstanceId,
+ name.shortText,
+ subject.shortText,
+ description.shortText,
+ t.taskData.status,
+ t.priority,
+ t.taskData.skipable,
+ actualOwner,
+ createdBy,
+ t.taskData.createdOn,
+ t.taskData.activationTime,
+ t.taskData.expirationTime,
+ t.taskData.processId,
+ t.taskData.processSessionId,
+ t.subTaskStrategy,
+ t.taskData.parentId )
+from
+ TaskImpl t
+ left join t.taskData.createdBy as createdBy
+ left join t.taskData.actualOwner as actualOwner
+ left join t.subjects as subject
+ left join t.descriptions as description
+ left join t.names as name,
+ OrganizationalEntityImpl potentialOwners
+where
+ t.archived = 0 and
+ t.taskData.actualOwner = null and
+ potentialOwners.id = :groupId and
+ potentialOwners in elements ( t.peopleAssignments.potentialOwners ) and
+
+ (
+ name.language = :language
+ or t.names.size = 0
+ ) and
+
+ (
+ subject.language = :language
+ or t.subjects.size = 0
+ ) and
+
+ (
+ description.language = :language
+ or t.descriptions.size = 0
+ ) and
+
+ t.taskData.status in ('Created', 'Ready', 'Reserved', 'InProgress', 'Suspended')
+ order by t.id DESC
+
+
+
+
+
+
+select
+
+ t.id,
+ potentialOwners.id
+
+from
+ TaskImpl t,
+
+ OrganizationalEntityImpl potentialOwners
+
+where
+
+ potentialOwners.id in (:groupIds) and
+ potentialOwners in elements ( t.peopleAssignments.potentialOwners ) and
+ t.archived = 0 and
+ t.taskData.actualOwner = null and
+
+
+
+ t.taskData.status in ('Created', 'Ready', 'Reserved', 'InProgress', 'Suspended')
+
+
+
+
+
+
+
+
+
+
+select distinct
+ new org.jbpm.services.task.query.TaskSummaryImpl(
+ t.id,
+ t.taskData.processInstanceId,
+ name.shortText,
+ subject.shortText,
+ description.shortText,
+ t.taskData.status,
+ t.priority,
+ t.taskData.skipable,
+ actualOwner,
+ createdBy,
+ t.taskData.createdOn,
+ t.taskData.activationTime,
+ t.taskData.expirationTime,
+ t.taskData.processId,
+ t.taskData.processSessionId,
+ t.subTaskStrategy,
+ t.taskData.parentId )
+from
+ TaskImpl t
+ left join t.taskData.createdBy as createdBy
+ left join t.taskData.actualOwner as actualOwner
+ left join t.subjects as subject
+ left join t.descriptions as description
+ left join t.names as name,
+ OrganizationalEntityImpl potentialOwners
+where
+ t.archived = 0 and
+ ( potentialOwners.id = :userId or potentialOwners.id in (:groupIds) ) and
+ potentialOwners in elements ( t.peopleAssignments.potentialOwners ) and
+
+ (
+ name.language = :language
+ or t.names.size = 0
+ ) and
+
+ (
+ subject.language = :language
+ or t.subjects.size = 0
+ ) and
+
+ (
+ description.language = :language
+ or t.descriptions.size = 0
+ ) and
+ t.taskData.expirationTime = :expirationDate and
+ t.taskData.status in (:status)
+ order by t.id DESC
+
+
+
+
+
+
+select distinct
+ new org.jbpm.services.task.query.TaskSummaryImpl(
+ t.id,
+ t.taskData.processInstanceId,
+ name.shortText,
+ subject.shortText,
+ description.shortText,
+ t.taskData.status,
+ t.priority,
+ t.taskData.skipable,
+ actualOwner,
+ createdBy,
+ t.taskData.createdOn,
+ t.taskData.activationTime,
+ t.taskData.expirationTime,
+ t.taskData.processId,
+ t.taskData.processSessionId,
+ t.subTaskStrategy,
+ t.taskData.parentId )
+from
+ TaskImpl t
+ left join t.taskData.createdBy as createdBy
+ left join t.taskData.actualOwner as actualOwner
+ left join t.subjects as subject
+ left join t.descriptions as description
+ left join t.names as name,
+ OrganizationalEntityImpl potentialOwners
+where
+ t.archived = 0 and
+ ( potentialOwners.id = :userId or potentialOwners.id in (:groupIds) ) and
+ potentialOwners in elements ( t.peopleAssignments.potentialOwners ) and
+
+ (
+ name.language = :language
+ or t.names.size = 0
+ ) and
+
+ (
+ subject.language = :language
+ or t.subjects.size = 0
+ ) and
+
+ (
+ description.language = :language
+ or t.descriptions.size = 0
+ ) and
+ (t.taskData.expirationTime = :expirationDate or t.taskData.expirationTime is null) and
+ t.taskData.status in (:status)
+ order by t.id DESC
+
+
+
+
+
+
+select
+
+ t.id,
+ potentialOwners.id
+
+from
+ TaskImpl t,
+
+ OrganizationalEntityImpl potentialOwners
+
+where
+
+ potentialOwners.id in (:groupIds) and
+ potentialOwners in elements ( t.peopleAssignments.potentialOwners ) and
+ t.archived = 0 and
+ t.taskData.actualOwner = null and
+ t.taskData.expirationTime = :expirationDate and
+ t.taskData.status in ('Created', 'Ready', 'Reserved', 'InProgress', 'Suspended')
+
+
+
+
+
+
+
+
+
+
+
+select
+ t.id,
+ potentialOwners
+from
+ TaskImpl t,
+ OrganizationalEntityImpl potentialOwners
+
+where
+ t.id in (:taskIds) and
+ potentialOwners in elements ( t.peopleAssignments.potentialOwners )
+
+
+
+
+
+
+
+
+select
+
+ t.id,
+ potentialOwners.id
+
+from
+ TaskImpl t,
+
+ OrganizationalEntityImpl potentialOwners
+
+where
+
+ potentialOwners.id in (:groupIds) and
+ potentialOwners in elements ( t.peopleAssignments.potentialOwners ) and
+ t.archived = 0 and
+ t.taskData.actualOwner = null and
+ (t.taskData.expirationTime = :expirationDate or t.taskData.expirationTime is null) and
+ t.taskData.status in ('Created', 'Ready', 'Reserved', 'InProgress', 'Suspended')
+
+
+
+
+
+
+
+
+
+
+select distinct
+ new org.jbpm.services.task.query.TaskSummaryImpl(
+ t.id,
+ t.taskData.processInstanceId,
+ name.shortText,
+ subject.shortText,
+ description.shortText,
+ t.taskData.status,
+ t.priority,
+ t.taskData.skipable,
+ actualOwner,
+ createdBy,
+ t.taskData.createdOn,
+ t.taskData.activationTime,
+ t.taskData.expirationTime,
+ t.taskData.processId,
+ t.taskData.processSessionId,
+ t.subTaskStrategy,
+ t.taskData.parentId )
+from
+ TaskImpl t
+ left join t.taskData.createdBy as createdBy
+ left join t.taskData.actualOwner as actualOwner
+ left join t.subjects as subject
+ left join t.descriptions as description
+ left join t.names as name,
+ OrganizationalEntityImpl potentialOwners
+where
+ t.archived = 0 and
+ t.taskData.parentId = :parentId and
+ (potentialOwners.id = :userId or potentialOwners.id in (:groupIds)) and
+ potentialOwners in elements ( t.peopleAssignments.potentialOwners ) and
+
+ (
+ name.language = :language
+ or t.names.size = 0
+ ) and
+
+ (
+ subject.language = :language
+ or t.subjects.size = 0
+ ) and
+
+ (
+ description.language = :language
+ or t.descriptions.size = 0
+ ) and
+
+ t.taskData.status in ('Created', 'Ready', 'Reserved', 'InProgress', 'Suspended')
+ order by t.id DESC
+
+
+
+
+
+
+select distinct
+ new org.jbpm.services.task.query.TaskSummaryImpl(
+ t.id,
+ t.taskData.processInstanceId,
+ name.shortText,
+ subject.shortText,
+ description.shortText,
+ t.taskData.status,
+ t.priority,
+ t.taskData.skipable,
+ actualOwner,
+ createdBy,
+ t.taskData.createdOn,
+ t.taskData.activationTime,
+ t.taskData.expirationTime,
+ t.taskData.processId,
+ t.taskData.processSessionId,
+ t.subTaskStrategy,
+ t.taskData.parentId )
+from
+ TaskImpl t
+ left join t.taskData.createdBy as createdBy
+ left join t.taskData.actualOwner as actualOwner
+ left join t.subjects as subject
+ left join t.descriptions as description
+ left join t.names as name
+where
+ t.archived = 0 and
+ t.taskData.parentId = :parentId and
+
+ (
+ name.language = :language
+ or t.names.size = 0
+ ) and
+
+ (
+ subject.language = :language
+ or t.subjects.size = 0
+ ) and
+
+ (
+ description.language = :language
+ or t.descriptions.size = 0
+ ) and
+
+ t.taskData.status in ('Created', 'Ready', 'Reserved', 'InProgress', 'Suspended')
+ order by t.id DESC
+
+
+
+
+
+
+
+select distinct
+ new org.jbpm.services.task.query.TaskSummaryImpl(
+ t.id,
+ t.taskData.processInstanceId,
+ name.shortText,
+ subject.shortText,
+ description.shortText,
+ t.taskData.status,
+ t.priority,
+ t.taskData.skipable,
+ actualOwner,
+ createdBy,
+ t.taskData.createdOn,
+ t.taskData.activationTime,
+ t.taskData.expirationTime,
+ t.taskData.processId,
+ t.taskData.processSessionId,
+ t.subTaskStrategy,
+ t.taskData.parentId )
+from
+ TaskImpl t
+ left join t.taskData.createdBy as createdBy
+ left join t.taskData.actualOwner as actualOwner
+ left join t.subjects as subject
+ left join t.descriptions as description
+ left join t.names as name,
+ OrganizationalEntityImpl recipients
+where
+ t.archived = 0 and
+ recipients.id = :userId and
+ recipients in elements ( t.peopleAssignments.recipients ) and
+
+ (
+ name.language = :language
+ or t.names.size = 0
+ ) and
+
+ (
+ subject.language = :language
+ or t.subjects.size = 0
+ ) and
+
+ (
+ description.language = :language
+ or t.descriptions.size = 0
+ )
+ order by t.id DESC
+
+
+
+
+
+select distinct
+ new org.jbpm.services.task.query.TaskSummaryImpl(
+ t.id,
+ t.taskData.processInstanceId,
+ name.shortText,
+ subject.shortText,
+ description.shortText,
+ t.taskData.status,
+ t.priority,
+ t.taskData.skipable,
+ actualOwner,
+ createdBy,
+ t.taskData.createdOn,
+ t.taskData.activationTime,
+ t.taskData.expirationTime,
+ t.taskData.processId,
+ t.taskData.processSessionId,
+ t.subTaskStrategy,
+ t.taskData.parentId )
+from
+ TaskImpl t
+ left join t.taskData.createdBy as createdBy
+ left join t.taskData.actualOwner as actualOwner
+ left join t.subjects as subject
+ left join t.descriptions as description
+ left join t.names as name,
+ OrganizationalEntityImpl taskInitiator
+where
+ t.archived = 0 and
+ taskInitiator.id = :userId and
+ taskInitiator = t.peopleAssignments.taskInitiator and
+
+ (
+ name.language = :language
+ or t.names.size = 0
+ ) and
+
+ (
+ subject.language = :language
+ or t.subjects.size = 0
+ ) and
+
+ (
+ description.language = :language
+ or t.descriptions.size = 0
+ )
+ order by t.id DESC
+
+
+
+
+
+select distinct
+ new org.jbpm.services.task.query.TaskSummaryImpl(
+ t.id,
+ t.taskData.processInstanceId,
+ name.shortText,
+ subject.shortText,
+ description.shortText,
+ t.taskData.status,
+ t.priority,
+ t.taskData.skipable,
+ actualOwner,
+ createdBy,
+ t.taskData.createdOn,
+ t.taskData.activationTime,
+ t.taskData.expirationTime,
+ t.taskData.processId,
+ t.taskData.processSessionId,
+ t.subTaskStrategy,
+ t.taskData.parentId )
+from
+ TaskImpl t
+ left join t.taskData.createdBy as createdBy
+ left join t.taskData.actualOwner as actualOwner
+ left join t.subjects as subject
+ left join t.descriptions as description
+ left join t.names as name,
+ OrganizationalEntityImpl taskStakeholder
+where
+ t.archived = 0 and
+ taskStakeholder.id = :userId and
+ taskStakeholder in elements ( t.peopleAssignments.taskStakeholders ) and
+
+ (
+ name.language = :language
+ or t.names.size = 0
+ ) and
+
+ (
+ subject.language = :language
+ or t.subjects.size = 0
+ ) and
+
+ (
+ description.language = :language
+ or t.descriptions.size = 0
+ )
+ order by t.id DESC
+
+
+
+
+
+select distinct
+ new org.jbpm.services.task.query.TaskSummaryImpl(
+ t.id,
+ t.taskData.processInstanceId,
+ name.shortText,
+ subject.shortText,
+ description.shortText,
+ t.taskData.status,
+ t.priority,
+ t.taskData.skipable,
+ actualOwner,
+ createdBy,
+ t.taskData.createdOn,
+ t.taskData.activationTime,
+ t.taskData.expirationTime,
+ t.taskData.processId,
+ t.taskData.processSessionId,
+ t.subTaskStrategy,
+ t.taskData.parentId )
+from
+ TaskImpl t
+ left join t.taskData.createdBy as createdBy
+ left join t.taskData.actualOwner as actualOwner
+ left join t.subjects as subject
+ left join t.descriptions as description
+ left join t.names as name
+where
+ t.archived = 0 and
+ t.taskData.actualOwner.id = :userId and
+
+ (
+ name.language = :language
+ or t.names.size = 0
+ ) and
+
+ (
+ subject.language = :language
+ or t.subjects.size = 0
+ ) and
+
+ (
+ description.language = :language
+ or t.descriptions.size = 0
+ )
+ order by t.id DESC
+
+
+
+
+
+
+select
+ new org.jbpm.services.task.query.TaskSummaryImpl(
+ t.id,
+ t.taskData.processInstanceId,
+ name.shortText,
+ subject.shortText,
+ description.shortText,
+ t.taskData.status,
+ t.priority,
+ t.taskData.skipable,
+ actualOwner,
+ createdBy,
+ t.taskData.createdOn,
+ t.taskData.activationTime,
+ t.taskData.expirationTime,
+ t.taskData.processId,
+ t.taskData.processSessionId,
+ t.subTaskStrategy,
+ t.taskData.parentId )
+from
+ TaskImpl t
+ left join t.taskData.createdBy as createdBy
+ left join t.taskData.actualOwner as actualOwner
+ left join t.subjects as subject
+ left join t.descriptions as description
+ left join t.names as name
+ left join t.peopleAssignments.potentialOwners potOwners
+where
+ t.archived = 0 and
+ (t.taskData.actualOwner.id = :userId or potOwners.id = :userId) and
+ t.taskData.status in (:status) and
+ t.taskData.expirationTime = :expirationDate and
+ (
+ name.language = :language
+ or t.names.size = 0
+ ) and
+
+ (
+ subject.language = :language
+ or t.subjects.size = 0
+ ) and
+
+ (
+ description.language = :language
+ or t.descriptions.size = 0
+ )
+ order by t.id DESC
+
+
+
+
+
+
+select
+ new org.jbpm.services.task.query.TaskSummaryImpl(
+ t.id,
+ t.taskData.processInstanceId,
+ name.shortText,
+ subject.shortText,
+ description.shortText,
+ t.taskData.status,
+ t.priority,
+ t.taskData.skipable,
+ actualOwner,
+ createdBy,
+ t.taskData.createdOn,
+ t.taskData.activationTime,
+ t.taskData.expirationTime,
+ t.taskData.processId,
+ t.taskData.processSessionId,
+ t.subTaskStrategy,
+ t.taskData.parentId )
+from
+ TaskImpl t
+ left join t.taskData.createdBy as createdBy
+ left join t.taskData.actualOwner as actualOwner
+ left join t.subjects as subject
+ left join t.descriptions as description
+ left join t.names as name
+ left join t.peopleAssignments.potentialOwners potOwners
+where
+ t.archived = 0 and
+ (t.taskData.actualOwner.id = :userId or potOwners.id = :userId) and
+ t.taskData.status in (:status) and
+ t.taskData.expirationTime < :date and
+ (
+ name.language = :language
+ or t.names.size = 0
+ ) and
+
+ (
+ subject.language = :language
+ or t.subjects.size = 0
+ ) and
+
+ (
+ description.language = :language
+ or t.descriptions.size = 0
+ )
+ order by t.id DESC
+
+
+
+
+
+
+select
+ new org.jbpm.services.task.query.TaskSummaryImpl(
+ t.id,
+ t.taskData.processInstanceId,
+ name.shortText,
+ subject.shortText,
+ description.shortText,
+ t.taskData.status,
+ t.priority,
+ t.taskData.skipable,
+ actualOwner,
+ createdBy,
+ t.taskData.createdOn,
+ t.taskData.activationTime,
+ t.taskData.expirationTime,
+ t.taskData.processId,
+ t.taskData.processSessionId,
+ t.subTaskStrategy,
+ t.taskData.parentId )
+from
+ TaskImpl t
+ left join t.taskData.createdBy as createdBy
+ left join t.taskData.actualOwner as actualOwner
+ left join t.subjects as subject
+ left join t.descriptions as description
+ left join t.names as name
+ left join t.peopleAssignments.potentialOwners potOwners
+where
+ t.archived = 0 and
+ (t.taskData.actualOwner.id = :userId or potOwners.id = :userId) and
+ t.taskData.status in (:status) and
+ (t.taskData.expirationTime = :expirationDate or
+ t.taskData.expirationTime is null)
+ and
+ (
+ name.language = :language
+ or t.names.size = 0
+ ) and
+
+ (
+ subject.language = :language
+ or t.subjects.size = 0
+ ) and
+
+ (
+ description.language = :language
+ or t.descriptions.size = 0
+ )
+
+ order by t.id DESC
+
+
+
+
+
+
+
+
+
+ select distinct
+ new org.jbpm.services.task.query.TaskSummaryImpl(
+ t.id,
+ t.taskData.processInstanceId,
+ name.shortText,
+ subject.shortText,
+ description.shortText,
+ t.taskData.status,
+ t.priority,
+ t.taskData.skipable,
+ actualOwner,
+ createdBy,
+ t.taskData.createdOn,
+ t.taskData.activationTime,
+ t.taskData.expirationTime,
+ t.taskData.processId,
+ t.taskData.processSessionId,
+ t.subTaskStrategy,
+ t.taskData.parentId )
+ from
+ TaskImpl t
+ left join t.taskData.createdBy as createdBy
+ left join t.taskData.actualOwner as actualOwner
+ left join t.subjects as subject
+ left join t.descriptions as description
+ left join t.names as name
+ where
+ t.archived = 0 and
+ t.taskData.status = :status and
+
+ (
+ name.language = :language
+ or t.names.size = 0
+ ) and
+
+ (
+ subject.language = :language
+ or t.subjects.size = 0
+ ) and
+
+ (
+ description.language = :language
+ or t.descriptions.size = 0
+ )
+ order by t.id DESC
+
+
+
+
+
+ select
+ new org.jbpm.services.task.query.TaskSummaryImpl(
+ t.id,
+ t.taskData.processInstanceId,
+ name.shortText,
+ subject.shortText,
+ description.shortText,
+ t.taskData.status,
+ t.priority,
+ t.taskData.skipable,
+ actualOwner,
+ createdBy,
+ t.taskData.createdOn,
+ t.taskData.activationTime,
+ t.taskData.expirationTime,
+ t.taskData.processId,
+ t.taskData.processSessionId,
+ t.subTaskStrategy,
+ t.taskData.parentId )
+ from
+ TaskImpl t
+ left join t.taskData.createdBy as createdBy
+ left join t.taskData.actualOwner as actualOwner
+ left join t.subjects as subject
+ left join t.descriptions as description
+ left join t.names as name
+ where
+ t.archived = 0 and
+ t.taskData.status = :status and
+
+ (
+ name.language = :language
+ or t.names.size = 0
+ ) and
+
+ (
+ subject.language = :language
+ or t.subjects.size = 0
+ ) and
+
+ (
+ description.language = :language
+ or t.descriptions.size = 0
+ ) and
+
+ t.taskData.activationTime < :since
+
+ order by t.id DESC
+
+
+
+
+
+
+ select distinct
+ new org.jbpm.services.task.query.TaskSummaryImpl(
+ t.id,
+ t.taskData.processInstanceId,
+ name.shortText,
+ subject.shortText,
+ description.shortText,
+ t.taskData.status,
+ t.priority,
+ t.taskData.skipable,
+ actualOwner,
+ createdBy,
+ t.taskData.createdOn,
+ t.taskData.activationTime,
+ t.taskData.expirationTime,
+ t.taskData.processId,
+ t.taskData.processSessionId,
+ t.subTaskStrategy,
+ t.taskData.parentId )
+ from
+ TaskImpl t
+ left join t.taskData.createdBy as createdBy
+ left join t.taskData.actualOwner as actualOwner
+ left join t.subjects as subject
+ left join t.descriptions as description
+ left join t.names as name
+ where
+ t.archived = 1 and
+
+ (
+ name.language = :language
+ or t.names.size = 0
+ ) and
+
+ (
+ subject.language = :language
+ or t.subjects.size = 0
+ ) and
+
+ (
+ description.language = :language
+ or t.descriptions.size = 0
+ )
+
+
+
+
+
+
+
+select distinct
+ new org.jbpm.services.task.query.TaskSummaryImpl(
+ t.id,
+ t.taskData.processInstanceId,
+ name.shortText,
+ subject.shortText,
+ description.shortText,
+ t.taskData.status,
+ t.priority,
+ t.taskData.skipable,
+ actualOwner,
+ createdBy,
+ t.taskData.createdOn,
+ t.taskData.activationTime,
+ t.taskData.expirationTime,
+ t.taskData.processId,
+ t.taskData.processSessionId,
+ t.subTaskStrategy,
+ t.taskData.parentId )
+from
+ TaskImpl t
+ left join t.taskData.createdBy as createdBy
+ left join t.taskData.actualOwner as actualOwner
+ left join t.subjects as subject
+ left join t.descriptions as description
+ left join t.names as name
+where
+ t.archived = 0 and
+ t.taskData.actualOwner.id = :userId and
+ t.taskData.status in (:status) and
+
+ (
+ name.language = :language
+ or t.names.size = 0
+ ) and
+
+ (
+ subject.language = :language
+ or t.subjects.size = 0
+ ) and
+
+ (
+ description.language = :language
+ or t.descriptions.size = 0
+ )
+ order by t.id DESC
+
+
+
+
+
+
+
+select
+ new org.jbpm.services.task.query.TaskSummaryImpl(
+ t.id,
+ t.taskData.processInstanceId,
+ name.shortText,
+ subject.shortText,
+ description.shortText,
+ t.taskData.status,
+ t.priority,
+ t.taskData.skipable,
+ actualOwner,
+ createdBy,
+ t.taskData.createdOn,
+ t.taskData.activationTime,
+ t.taskData.expirationTime,
+ t.taskData.processId,
+ t.taskData.processSessionId,
+ t.subTaskStrategy,
+ t.taskData.parentId )
+from
+ TaskImpl t
+ left join t.taskData.createdBy as createdBy
+ left join t.taskData.actualOwner as actualOwner
+ left join t.subjects as subject
+ left join t.descriptions as description
+ left join t.names as name
+where
+ t.id in (:taskIds) and
+
+ (
+ name.language = :language
+ or t.names.size = 0
+ ) and
+
+ (
+ subject.language = :language
+ or t.subjects.size = 0
+ ) and
+
+ (
+ description.language = :language
+ or t.descriptions.size = 0
+ )
+ order by t.id DESC
+
+
+
+
+
+
+
+select
+
+ t.id,
+ potentialOwners.id
+
+from
+ TaskImpl t,
+ OrganizationalEntityImpl potentialOwners
+
+where
+
+ t.id in (:taskIds) and
+ potentialOwners in elements ( t.peopleAssignments.potentialOwners ) and
+ t.archived = 0 and
+ t.taskData.status in ('Created', 'Ready', 'Reserved', 'InProgress', 'Suspended')
+
+
+
+
+
+
+
+
+
+
+select
+ new org.jbpm.services.task.query.DeadlineSummaryImpl(
+ t.id,
+ d.id,
+ d.date)
+from
+ TaskImpl t,
+ DeadlineImpl d
+where
+ t.archived = 0 and
+ d in elements( t.deadlines.endDeadlines ) and
+ d.escalated = 0
+order by
+ d.date
+
+
+
+
+
+
+select
+ new org.jbpm.services.task.query.DeadlineSummaryImpl(
+ t.id,
+ d.id,
+ d.date)
+from
+ TaskImpl t,
+ DeadlineImpl d
+where
+ t.archived = 0 and
+ d in elements( t.deadlines.startDeadlines ) and
+ d.escalated = 0
+order by
+ d.date
+
+
+
+
+
+select
+ t
+from
+ TaskImpl t
+where
+ t.archived = 0 and
+ t.taskData.workItemId = :workItemId
+
+
+
+
+
+ select distinct
+ new org.jbpm.services.task.query.TaskSummaryImpl(
+ t.id,
+ t.taskData.processInstanceId,
+ name.shortText,
+ subject.shortText,
+ description.shortText,
+ t.taskData.status,
+ t.priority,
+ t.taskData.skipable,
+ actualOwner,
+ createdBy,
+ t.taskData.createdOn,
+ t.taskData.activationTime,
+ t.taskData.expirationTime,
+ t.taskData.processId,
+ t.taskData.processSessionId,
+ t.subTaskStrategy,
+ t.taskData.parentId )
+ from
+ TaskImpl t
+ left join t.taskData.actualOwner as actualOwner
+ left join t.taskData.createdBy as createdBy
+ left join t.subjects as subject
+ left join t.descriptions as description
+ left join t.names as name
+ where
+ t.archived = 0 and
+ t.taskData.processInstanceId = :processInstanceId and
+ (
+ name.language = :language
+ or t.names.size = 0
+ ) and
+
+ (
+ subject.language = :language
+ or t.subjects.size = 0
+ ) and
+
+ (
+ description.language = :language
+ or t.descriptions.size = 0
+ ) and
+
+ t.taskData.status in (:status)
+
+
+
+
+
+ select distinct
+ new org.jbpm.services.task.query.TaskSummaryImpl(
+ t.id,
+ t.taskData.processInstanceId,
+ name.shortText,
+ subject.shortText,
+ description.shortText,
+ t.taskData.status,
+ t.priority,
+ t.taskData.skipable,
+ actualOwner,
+ createdBy,
+ t.taskData.createdOn,
+ t.taskData.activationTime,
+ t.taskData.expirationTime,
+ t.taskData.processId,
+ t.taskData.processSessionId,
+ t.subTaskStrategy,
+ t.taskData.parentId )
+ from
+ TaskImpl t
+ left join t.taskData.actualOwner as actualOwner
+ left join t.taskData.createdBy as createdBy
+ left join t.subjects as subject
+ left join t.descriptions as description
+ left join t.names as name
+ where
+ t.archived = 0 and
+ t.taskData.processInstanceId = :processInstanceId and
+ name.shortText = :taskName and
+ (
+ name.language = :language
+ or t.names.size = 0
+ ) and
+
+ (
+ subject.language = :language
+ or t.subjects.size = 0
+ ) and
+
+ (
+ description.language = :language
+ or t.descriptions.size = 0
+ ) and
+
+ t.taskData.status in (:status)
+ order by t.id DESC
+
+
+
+
+
+select
+ t.id
+from
+ TaskImpl t
+where
+ t.archived = 0 and
+ t.taskData.processInstanceId = :processInstanceId
+
+
+
+
\ No newline at end of file
diff --git a/jbpm-human-task/jbpm-human-task-core/src/main/resources/META-INF/services/org.kie.internal.task.api.TaskModelFactory b/jbpm-human-task/jbpm-human-task-core/src/main/resources/META-INF/services/org.kie.internal.task.api.TaskModelFactory
new file mode 100644
index 0000000000..3cda7ef186
--- /dev/null
+++ b/jbpm-human-task/jbpm-human-task-core/src/main/resources/META-INF/services/org.kie.internal.task.api.TaskModelFactory
@@ -0,0 +1 @@
+org.jbpm.services.task.persistence.JPATaskModelFactory
\ No newline at end of file
diff --git a/jbpm-human-task/jbpm-human-task-workitems/pom.xml b/jbpm-human-task/jbpm-human-task-workitems/pom.xml
index c5dba54494..8116c6bb19 100644
--- a/jbpm-human-task/jbpm-human-task-workitems/pom.xml
+++ b/jbpm-human-task/jbpm-human-task-workitems/pom.xml
@@ -76,11 +76,14 @@
logback-classic
test
+
+
diff --git a/jbpm-human-task/pom.xml b/jbpm-human-task/pom.xml
index 7fb1e6840b..80b629b594 100644
--- a/jbpm-human-task/pom.xml
+++ b/jbpm-human-task/pom.xml
@@ -16,7 +16,10 @@
jbpm-human-task-core
jbpm-human-task-workitems
jbpm-human-task-audit
+
+
diff --git a/jbpm-runtime-manager/pom.xml b/jbpm-runtime-manager/pom.xml
index b020d3a814..f38c9afac7 100644
--- a/jbpm-runtime-manager/pom.xml
+++ b/jbpm-runtime-manager/pom.xml
@@ -126,11 +126,14 @@
org.jbpm
jbpm-human-task-audit
+
+