diff --git a/ccm-core/src/main/java/org/libreccm/workflow/Task.java b/ccm-core/src/main/java/org/libreccm/workflow/Task.java new file mode 100644 index 000000000..e97c94c9b --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/workflow/Task.java @@ -0,0 +1,297 @@ +/* + * Copyright (C) 2015 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.libreccm.workflow; + +import org.libreccm.l10n.LocalizedString; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +import javax.persistence.AssociationOverride; +import javax.persistence.Column; +import javax.persistence.ElementCollection; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.Lob; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +/** + * + * @author Jens Pelzetter + */ +@Entity +@Table(name = "workflow_tasks") +@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) +public class Task implements Serializable { + + private static final long serialVersionUID = 8161343036908150426L; + + @Id + @Column(name = "task_id") + @GeneratedValue(strategy = GenerationType.AUTO) + private long taskId; + + @Embedded + @AssociationOverride( + name = "values", + joinTable = @JoinTable(name = "workflow_task_labels", + joinColumns = { + @JoinColumn(name = "task_id")})) + private LocalizedString label; + + @Embedded + @AssociationOverride( + name = "values", + joinTable = @JoinTable(name = "workflow_tasks_descriptions", + joinColumns = { + @JoinColumn(name = "task_id")})) + private LocalizedString description; + + @Column(name = "active") + private boolean active; + + @Column(name = "task_state", length = 512) + private String taskState; + + @ManyToOne + @JoinColumn(name = "workflow_id") + private Workflow workflow; + + @ManyToMany(mappedBy = "dependsOn") + private List dependentTasks; + + @ManyToMany + @JoinTable(name = "workflow_task_dependencies", + joinColumns = { + @JoinColumn(name = "depends_on_task_id")}, + inverseJoinColumns = { + @JoinColumn(name = "dependent_task_id")}) + private List dependsOn; + + @ElementCollection + @JoinTable(name = "workflow_task_comments", + joinColumns = { + @JoinColumn(name = "task_id")}) + @Column(name = "comment") + @Lob + private List comments; + + public Task() { + super(); + + label = new LocalizedString(); + description = new LocalizedString(); + dependentTasks = new ArrayList<>(); + dependsOn = new ArrayList<>(); + comments = new ArrayList<>(); + } + + public long getTaskId() { + return taskId; + } + + public void setTaskId(final long taskId) { + this.taskId = taskId; + } + + public LocalizedString getLabel() { + return label; + } + + public void setLabel(final LocalizedString label) { + this.label = label; + } + + public LocalizedString getDescription() { + return description; + } + + public void setDescription(final LocalizedString description) { + this.description = description; + } + + public boolean isActive() { + return active; + } + + public void setActive(final boolean active) { + this.active = active; + } + + public String getTaskState() { + return taskState; + } + + public void setTaskState(final String taskState) { + this.taskState = taskState; + } + + public Workflow getWorkflow() { + return workflow; + } + + protected void setWorkflow(final Workflow workflow) { + this.workflow = workflow; + } + + public List getDependentTasks() { + return Collections.unmodifiableList(dependentTasks); + } + + protected void setDependentTasks(final List dependentTasks) { + this.dependentTasks = dependentTasks; + } + + protected void addDependentTask(final Task task) { + dependentTasks.add(task); + } + + protected void removeDependentTask(final Task task) { + dependentTasks.remove(task); + } + + public List getDependsOn() { + return Collections.unmodifiableList(dependsOn); + } + + protected void setDependsOn(final List dependsOn) { + this.dependsOn = dependsOn; + } + + protected void addDependsOn(final Task task) { + dependsOn.add(task); + } + + protected void removeDependsOn(final Task task) { + dependsOn.remove(task); + } + + public List getComments() { + return Collections.unmodifiableList(comments); + } + + protected void setComments(final List comments) { + this.comments = comments; + } + + public void addComment(final String comment) { + comments.add(comment); + } + + public void removeComment(final String comment) { + comments.remove(comment); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 79 * hash + (int) (taskId ^ (taskId >>> 32)); + hash = 79 * hash + Objects.hashCode(label); + hash = 79 * hash + Objects.hashCode(description); + hash = 79 * hash + (active ? 1 : 0); + hash = 79 * hash + Objects.hashCode(taskState); + hash = 79 * hash + Objects.hashCode(workflow); + hash = 79 * hash + Objects.hashCode(dependentTasks); + hash = 79 * hash + Objects.hashCode(dependsOn); + hash = 79 * hash + Objects.hashCode(comments); + return hash; + } + + @Override + public boolean equals(final Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final Task other = (Task) obj; + if (!other.canEqual(obj)) { + return false; + } + + if (taskId != other.getTaskId()) { + return false; + } + if (!Objects.equals(label, other.getLabel())) { + return false; + } + if (!Objects.equals(description, other.getDescription())) { + return false; + } + if (active != other.isActive()) { + return false; + } + if (!Objects.equals(taskState, other.getTaskState())) { + return false; + } + if (!Objects.equals(workflow, other.getWorkflow())) { + return false; + } + if (!Objects.equals(dependentTasks, other.getDependentTasks())) { + return false; + } + if (!Objects.equals(dependsOn, other.getDependsOn())) { + return false; + } + return Objects.equals(comments, other.getComments()); + } + + public boolean canEqual(final Object obj) { + return obj instanceof Task; + } + + @Override + public final String toString() { + return toString(""); + } + + public String toString(final String data) { + return String.format("%s{ " + + "taskId = %d, " + + "label = %s, " + + "active = %b, " + + "taskState = \"%s\", " + + "workflow = %s, " + + "dependentTasks = %s, " + + "dependsOn = %s%s" + + " }", + super.toString(), + taskId, + Objects.toString(label), + active, + taskState, + Objects.toString(workflow), + Objects.toString(dependentTasks), + Objects.toString(dependsOn), + data); + } +} diff --git a/ccm-core/src/main/java/org/libreccm/workflow/UserTask.java b/ccm-core/src/main/java/org/libreccm/workflow/UserTask.java new file mode 100644 index 000000000..19132ab08 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/workflow/UserTask.java @@ -0,0 +1,244 @@ +/* + * Copyright (C) 2015 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.libreccm.workflow; + +import org.libreccm.core.User; +import org.libreccm.core.UserGroup; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Objects; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +/** + * + * @author Jens Pelzetter + */ +@Entity +@Table(name = "workflow_user_tasks") +public class UserTask extends Task implements Serializable { + + private static final long serialVersionUID = 4188064584389893019L; + + @Column(name = "locked") + private boolean locked; + + @OneToOne + @JoinColumn(name = "locking_user_id") + private User lockingUser; + + @Column(name = "start_date") + @Temporal(TemporalType.TIMESTAMP) + private Date startDate; + + @Column(name = "due_date") + @Temporal(TemporalType.TIMESTAMP) + private Date dueDate; + + @Column(name = "duration_minutes") + private long durationMinutes; + + @OneToOne + @JoinColumn(name = "notification_sender") + private User notificationSender; + + @OneToMany + @JoinTable(name = "workflow_user_task_assigned_users", + joinColumns = { + @JoinColumn(name = "user_task_id")}, + inverseJoinColumns = { + @JoinColumn(name = "assigned_user_id")}) + private List assignedUsers; + + @OneToMany + @JoinTable(name = "workflow_user_task_assigned_groups", + joinColumns = { + @JoinColumn(name = "user_task_id")}, + inverseJoinColumns = { + @JoinColumn(name = "assigned_group_id")}) + private List assignedGroups; + + public UserTask() { + super(); + assignedUsers = new ArrayList<>(); + assignedGroups = new ArrayList<>(); + } + + public boolean isLocked() { + return locked; + } + + public void setLocked(final boolean locked) { + this.locked = locked; + } + + public User getLockingUser() { + return lockingUser; + } + + public void setLockingUser(final User lockingUser) { + this.lockingUser = lockingUser; + } + + public Date getStartDate() { + return new Date(startDate.getTime()); + } + + public void setStartDate(final Date startDate) { + this.startDate = new Date(startDate.getTime()); + } + + public Date getDueDate() { + return new Date(dueDate.getTime()); + } + + public void setDueDate(final Date dueDate) { + this.dueDate = new Date(dueDate.getTime()); + } + + public long getDurationMinutes() { + return durationMinutes; + } + + public void setDurationMinutes(final long durationMinutes) { + this.durationMinutes = durationMinutes; + } + + public User getNotificationSender() { + return notificationSender; + } + + public void setNotificationSender(final User notificationSender) { + this.notificationSender = notificationSender; + } + + public List getAssignedUsers() { + return Collections.unmodifiableList(assignedUsers); + } + + protected void setAssignedUsers(final List assignedUsers) { + this.assignedUsers = assignedUsers; + } + + protected void addAssignedUser(final User user) { + assignedUsers.add(user); + } + + protected void removeAssignedUser(final User user) { + assignedUsers.remove(user); + } + + public List getAssignedGroups() { + return Collections.unmodifiableList(assignedGroups); + } + + protected void setAssignedGroups(final List assignedGroups) { + this.assignedGroups = assignedGroups; + } + + protected void addAssignedGroup(final UserGroup group) { + assignedGroups.add(group); + } + + protected void removeAssignedGroup(final UserGroup group) { + assignedGroups.remove(group); + } + + @Override + public int hashCode() { + int hash = super.hashCode(); + hash = 37 * hash + (locked ? 1 : 0); + hash = 37 * hash + Objects.hashCode(lockingUser); + hash = 37 * hash + Objects.hashCode(startDate); + hash = 37 * hash + Objects.hashCode(dueDate); + hash + = 37 * hash + (int) (durationMinutes ^ (durationMinutes >>> 32)); + hash = 37 * hash + Objects.hashCode(notificationSender); + hash = 37 * hash + Objects.hashCode(assignedUsers); + hash = 37 * hash + Objects.hashCode(assignedGroups); + return hash; + } + + @Override + public boolean equals(final Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final UserTask other = (UserTask) obj; + if (!other.canEqual(obj)) { + return false; + } + + if (locked != other.isLocked()) { + return false; + } + if (!Objects.equals(lockingUser, other.getLockingUser())) { + return false; + } + if (!Objects.equals(startDate, other.getStartDate())) { + return false; + } + if (!Objects.equals(dueDate, other.getDueDate())) { + return false; + } + if (durationMinutes != other.getDurationMinutes()) { + return false; + } + if (!Objects.equals(notificationSender, other.getNotificationSender())) { + return false; + } + if (!Objects.equals(assignedUsers, other.getAssignedUsers())) { + return false; + } + return Objects.equals(assignedGroups, other.getAssignedGroups()); + } + + @Override + public String toString(final String data) { + return super.toString(String.format(", locked = %b, " + + "lockingUser = %s, " + + "startDate = %tF %Jens Pelzetter + */ +@Entity +@Table(name = "workflows") +public class Workflow implements Serializable { + + private static final long serialVersionUID = 4322500264543325829L; + + @Id + @Column(name = "workflow_id") + @GeneratedValue(strategy = GenerationType.AUTO) + private long workflowId; + + @Embedded + @AssociationOverride( + name = "values", + joinTable = @JoinTable(name = "workflow_names", + joinColumns = { + @JoinColumn(name = "workflow_id")})) + private LocalizedString name; + + @Embedded + @AssociationOverride( + name = "values", + joinTable = @JoinTable(name = "workflow_descriptions", + joinColumns = { + @JoinColumn(name = "workflow_id") + })) + private LocalizedString description; + + @OneToMany(mappedBy = "workflow") + private List tasks; + + public Workflow() { + super(); + + name = new LocalizedString(); + description = new LocalizedString(); + tasks = new ArrayList<>(); + } + + public long getWorkflowId() { + return workflowId; + } + + public void setWorkflowId(final long workflowId) { + this.workflowId = workflowId; + } + + public LocalizedString getName() { + return name; + } + + public void setName(final LocalizedString name) { + this.name = name; + } + + public LocalizedString getDescription() { + return description; + } + + public void setDescription(final LocalizedString description) { + this.description = description; + } + + public List getTasks() { + return Collections.unmodifiableList(tasks); + } + + protected void setTasks(final List tasks) { + this.tasks = tasks; + } + + protected void addTask(final Task task) { + tasks.add(task); + } + + protected void removeTask(final Task task) { + tasks.remove(task); + } + + @Override + public int hashCode() { + int hash = 5; + hash = 79 * hash + (int) (this.workflowId ^ (this.workflowId >>> 32)); + hash = 79 * hash + Objects.hashCode(this.name); + hash = 79 * hash + Objects.hashCode(this.tasks); + return hash; + } + + @Override + public boolean equals(final Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final Workflow other = (Workflow) obj; + if (!other.canEqual(obj)) { + return false; + } + + if (this.workflowId != other.getWorkflowId()) { + return false; + } + if (!Objects.equals(this.name, other.getName())) { + return false; + } + return Objects.equals(this.tasks, other.getTasks()); + } + + public boolean canEqual(final Object obj) { + return obj instanceof Workflow; + } + + @Override + public String toString() { + return String.format("%s{ " + + "workflowId = %d, " + + "name = \"%s\"" + + " }", + super.toString(), + workflowId, + name); + } + +}