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 getEmailHeaders() { + return emailHeaders; + } + + public void setEmailHeaders(Map 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 + +