CCM NG: JavaDoc for Workflow and related classes
git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4444 8810af33-2d31-482b-a856-94f89814c4dfpull/2/head
parent
17a2157b5c
commit
2ae87e3353
|
|
@ -19,6 +19,7 @@
|
||||||
package org.librecms.workflow;
|
package org.librecms.workflow;
|
||||||
|
|
||||||
import org.libreccm.workflow.AssignableTask;
|
import org.libreccm.workflow.AssignableTask;
|
||||||
|
import org.librecms.contentsection.ContentItem;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
@ -32,7 +33,8 @@ import javax.persistence.Table;
|
||||||
import static org.librecms.CmsConstants.*;
|
import static org.librecms.CmsConstants.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* A special tasks for {@link ContentItem}s.
|
||||||
|
*
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
|
|
@ -41,6 +43,9 @@ public class CmsTask extends AssignableTask implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = -3988352366529930659L;
|
private static final long serialVersionUID = -3988352366529930659L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of the task.
|
||||||
|
*/
|
||||||
@Column(name = "TASK_TYPE")
|
@Column(name = "TASK_TYPE")
|
||||||
@Enumerated(EnumType.STRING)
|
@Enumerated(EnumType.STRING)
|
||||||
private CmsTaskType taskType;
|
private CmsTaskType taskType;
|
||||||
|
|
|
||||||
|
|
@ -21,18 +21,25 @@ package org.librecms.workflow;
|
||||||
import com.arsdigita.cms.workflow.TaskURLGenerator;
|
import com.arsdigita.cms.workflow.TaskURLGenerator;
|
||||||
import com.arsdigita.util.UncheckedWrapperException;
|
import com.arsdigita.util.UncheckedWrapperException;
|
||||||
|
|
||||||
import org.libreccm.workflow.AssignableTaskManager;
|
|
||||||
import org.librecms.contentsection.ContentItem;
|
import org.librecms.contentsection.ContentItem;
|
||||||
|
|
||||||
import javax.enterprise.context.RequestScoped;
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Manager for {@link CmsTask}s.
|
||||||
|
*
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@RequestScoped
|
@RequestScoped
|
||||||
public class CmsTaskManager extends AssignableTaskManager {
|
public class CmsTaskManager {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the URL for finishing the task for a certain {@link ContentItem}.
|
||||||
|
*
|
||||||
|
* @param item The item.
|
||||||
|
* @param task The task.
|
||||||
|
* @return The finish URL.
|
||||||
|
*/
|
||||||
public String getFinishUrl(final ContentItem item, final CmsTask task) {
|
public String getFinishUrl(final ContentItem item, final CmsTask task) {
|
||||||
final Class<? extends TaskURLGenerator> urlGeneratorClass = task
|
final Class<? extends TaskURLGenerator> urlGeneratorClass = task
|
||||||
.getTaskType().getUrlGenerator();
|
.getTaskType().getUrlGenerator();
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,8 @@ import com.arsdigita.cms.workflow.TaskURLGenerator;
|
||||||
import org.librecms.contentsection.privileges.ItemPrivileges;
|
import org.librecms.contentsection.privileges.ItemPrivileges;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Possible types of a {@link CmsTask}.
|
||||||
|
*
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
public enum CmsTaskType {
|
public enum CmsTaskType {
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ import org.librecms.lifecycle.LifecycleDefinition;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
@ -124,30 +125,32 @@ public class EqualsAndHashCodeTest extends EqualsVerifier {
|
||||||
|
|
||||||
final CcmApplication application2 = new CcmApplication();
|
final CcmApplication application2 = new CcmApplication();
|
||||||
application2.setDisplayName("Application 2");
|
application2.setDisplayName("Application 2");
|
||||||
|
|
||||||
final Domain domain1 = new Domain();
|
final Domain domain1 = new Domain();
|
||||||
domain1.setDisplayName("Domain 1");
|
domain1.setDisplayName("Domain 1");
|
||||||
|
|
||||||
final Domain domain2 = new Domain();
|
final Domain domain2 = new Domain();
|
||||||
domain2.setDisplayName("Domain 2");
|
domain2.setDisplayName("Domain 2");
|
||||||
|
|
||||||
final Resource resource1 = new Resource();
|
final Resource resource1 = new Resource();
|
||||||
resource1.setDisplayName("Resource 1");
|
resource1.setDisplayName("Resource 1");
|
||||||
|
|
||||||
final Resource resource2 = new Resource();
|
final Resource resource2 = new Resource();
|
||||||
resource2.setDisplayName("Resource 2");
|
resource2.setDisplayName("Resource 2");
|
||||||
|
|
||||||
final LifecycleDefinition lifecycleDef1 = new LifecycleDefinition();
|
final LifecycleDefinition lifecycleDef1 = new LifecycleDefinition();
|
||||||
lifecycleDef1.setDefinitionId(-100);
|
lifecycleDef1.setDefinitionId(-100);
|
||||||
|
|
||||||
final LifecycleDefinition lifecycleDef2 = new LifecycleDefinition();
|
final LifecycleDefinition lifecycleDef2 = new LifecycleDefinition();
|
||||||
lifecycleDef2.setDefinitionId(-110);
|
lifecycleDef2.setDefinitionId(-110);
|
||||||
|
|
||||||
final WorkflowTemplate workflowTemplate1 = new WorkflowTemplate();
|
final WorkflowTemplate workflowTemplate1 = new WorkflowTemplate();
|
||||||
workflowTemplate1.setWorkflowId(-200);
|
workflowTemplate1.getName().addValue(Locale.ENGLISH,
|
||||||
|
"Workflow Template 1");
|
||||||
|
|
||||||
final WorkflowTemplate workflowTemplate2 = new WorkflowTemplate();
|
final WorkflowTemplate workflowTemplate2 = new WorkflowTemplate();
|
||||||
workflowTemplate2.setWorkflowId(-210);
|
workflowTemplate2.getName().addValue(Locale.ENGLISH,
|
||||||
|
"Workflow Template 2");
|
||||||
|
|
||||||
verifier
|
verifier
|
||||||
.withPrefabValues(ContentItem.class, item1, item2)
|
.withPrefabValues(ContentItem.class, item1, item2)
|
||||||
|
|
@ -161,11 +164,11 @@ public class EqualsAndHashCodeTest extends EqualsVerifier {
|
||||||
.withPrefabValues(CcmApplication.class, application1, application2)
|
.withPrefabValues(CcmApplication.class, application1, application2)
|
||||||
.withPrefabValues(Domain.class, domain1, domain2)
|
.withPrefabValues(Domain.class, domain1, domain2)
|
||||||
.withPrefabValues(Resource.class, resource1, resource2)
|
.withPrefabValues(Resource.class, resource1, resource2)
|
||||||
.withPrefabValues(LifecycleDefinition.class,
|
.withPrefabValues(LifecycleDefinition.class,
|
||||||
lifecycleDef1,
|
lifecycleDef1,
|
||||||
lifecycleDef2)
|
lifecycleDef2)
|
||||||
.withPrefabValues(WorkflowTemplate.class,
|
.withPrefabValues(WorkflowTemplate.class,
|
||||||
workflowTemplate1,
|
workflowTemplate1,
|
||||||
workflowTemplate2);
|
workflowTemplate2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -297,7 +297,7 @@ public abstract class AbstractEntityRepository<K, E> {
|
||||||
*
|
*
|
||||||
* @param entity The entity to init.
|
* @param entity The entity to init.
|
||||||
*/
|
*/
|
||||||
public void initNewEntity(final E entity) {
|
protected void initNewEntity(final E entity) {
|
||||||
//Empty default implementation
|
//Empty default implementation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,10 @@ import javax.persistence.Temporal;
|
||||||
import javax.persistence.TemporalType;
|
import javax.persistence.TemporalType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* A task which can be assigned to a user. Also a {@code AssignableTask} can be
|
||||||
|
* locked by a user to indicate that the user is currently working on the
|
||||||
|
* object to which the workflow to which the task belongs is assigned.
|
||||||
|
*
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
|
|
@ -79,29 +82,50 @@ public class AssignableTask extends Task implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 4188064584389893019L;
|
private static final long serialVersionUID = 4188064584389893019L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the task locked?
|
||||||
|
*/
|
||||||
@Column(name = "LOCKED")
|
@Column(name = "LOCKED")
|
||||||
private boolean locked;
|
private boolean locked;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user which has locked the task (if the task is locked).
|
||||||
|
*/
|
||||||
@OneToOne
|
@OneToOne
|
||||||
@JoinColumn(name = "LOCKING_USER_ID")
|
@JoinColumn(name = "LOCKING_USER_ID")
|
||||||
private User lockingUser;
|
private User lockingUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The date on which the task was started.
|
||||||
|
*/
|
||||||
@Column(name = "START_DATE")
|
@Column(name = "START_DATE")
|
||||||
@Temporal(TemporalType.TIMESTAMP)
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
private Date startDate;
|
private Date startDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The date on which the task should be finished.
|
||||||
|
*/
|
||||||
@Column(name = "DUE_DATE")
|
@Column(name = "DUE_DATE")
|
||||||
@Temporal(TemporalType.TIMESTAMP)
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
private Date dueDate;
|
private Date dueDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How long did it take to complete the task?
|
||||||
|
*/
|
||||||
@Column(name = "DURATION_MINUTES")
|
@Column(name = "DURATION_MINUTES")
|
||||||
private long durationMinutes;
|
private long durationMinutes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Which user should be used as sender of notification emails for the task?
|
||||||
|
*/
|
||||||
@OneToOne
|
@OneToOne
|
||||||
@JoinColumn(name = "NOTIFICATION_SENDER")
|
@JoinColumn(name = "NOTIFICATION_SENDER")
|
||||||
@SuppressWarnings("PMD.LongVariable") //Shorter name would not be descriptive
|
@SuppressWarnings("PMD.LongVariable") //Shorter name would not be descriptive
|
||||||
private User notificationSender;
|
private User notificationSender;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The roles to which task is assigned.
|
||||||
|
*/
|
||||||
@OneToMany(mappedBy = "task")
|
@OneToMany(mappedBy = "task")
|
||||||
private List<TaskAssignment> assignments;
|
private List<TaskAssignment> assignments;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,16 +41,16 @@ import javax.transaction.Transactional;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@RequestScoped
|
@RequestScoped
|
||||||
public class AssignableTaskManager extends TaskManager {
|
public class AssignableTaskManager {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private EntityManager entityManager;
|
private EntityManager entityManager;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private WorkflowRepository workflowRepo;
|
private TaskRepository taskRepo;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private TaskRepository taskRepo;
|
private TaskManager taskManager;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private RoleRepository roleRepo;
|
private RoleRepository roleRepo;
|
||||||
|
|
@ -58,10 +58,26 @@ public class AssignableTaskManager extends TaskManager {
|
||||||
@Inject
|
@Inject
|
||||||
private Shiro shiro;
|
private Shiro shiro;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assigns a task to role.
|
||||||
|
*
|
||||||
|
* @param task The task to assign.
|
||||||
|
* @param role The role to which the task is assigned.
|
||||||
|
*/
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public void assignTask(final AssignableTask task, final Role role) {
|
public void assignTask(final AssignableTask task, final Role role) {
|
||||||
|
if (task == null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Can't assign task null to a role.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (role == null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Can't assign a task to role null.");
|
||||||
|
}
|
||||||
|
|
||||||
final TaskAssignment assignment = new TaskAssignment();
|
final TaskAssignment assignment = new TaskAssignment();
|
||||||
assignment.setTask(task);
|
assignment.setTask(task);
|
||||||
assignment.setRole(role);
|
assignment.setRole(role);
|
||||||
|
|
@ -74,10 +90,26 @@ public class AssignableTaskManager extends TaskManager {
|
||||||
roleRepo.save(role);
|
roleRepo.save(role);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a task assignments.
|
||||||
|
*
|
||||||
|
* @param task
|
||||||
|
* @param role
|
||||||
|
*/
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public void retractTask(final AssignableTask task, final Role role) {
|
public void retractTask(final AssignableTask task, final Role role) {
|
||||||
|
if (task == null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Can't retract task null from a role.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (role == null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Can't retract a task from role null.");
|
||||||
|
}
|
||||||
|
|
||||||
final List<TaskAssignment> result = task.getAssignments().stream()
|
final List<TaskAssignment> result = task.getAssignments().stream()
|
||||||
.filter(assigned -> role.equals(assigned.getRole()))
|
.filter(assigned -> role.equals(assigned.getRole()))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
@ -90,30 +122,65 @@ public class AssignableTaskManager extends TaskManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param task
|
||||||
|
*/
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public void lockTask(final AssignableTask task) {
|
public void lockTask(final AssignableTask task) {
|
||||||
|
if (task == null) {
|
||||||
|
throw new IllegalArgumentException("Can't lock task null.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (task.isLocked()) {
|
||||||
|
throw new IllegalArgumentException(String.format(
|
||||||
|
"Task %s is already locked by user \"%s\".",
|
||||||
|
Objects.toString(task),
|
||||||
|
task.getLockingUser().getName()));
|
||||||
|
}
|
||||||
|
|
||||||
task.setLocked(true);
|
task.setLocked(true);
|
||||||
task.setLockingUser(shiro.getUser());
|
task.setLockingUser(shiro.getUser());
|
||||||
|
|
||||||
taskRepo.save(task);
|
taskRepo.save(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlocks a task.
|
||||||
|
*
|
||||||
|
* @param task The task to unlock.
|
||||||
|
*/
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public void unlockTask(final AssignableTask task) {
|
public void unlockTask(final AssignableTask task) {
|
||||||
|
if (task == null) {
|
||||||
|
throw new IllegalArgumentException("Can't unlock task null.");
|
||||||
|
}
|
||||||
|
|
||||||
task.setLocked(false);
|
task.setLocked(false);
|
||||||
task.setLockingUser(null);
|
task.setLockingUser(null);
|
||||||
|
|
||||||
taskRepo.save(task);
|
taskRepo.save(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a list of all tasks locked by a specific user.
|
||||||
|
*
|
||||||
|
* @param user The user which locks the tasks.
|
||||||
|
* @return A list with all tasks locked by the specified user.
|
||||||
|
*/
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public List<AssignableTask> lockedBy(final User user) {
|
public List<AssignableTask> lockedBy(final User user) {
|
||||||
|
|
||||||
|
if (user == null) {
|
||||||
|
throw new IllegalArgumentException("user can't be null.");
|
||||||
|
}
|
||||||
|
|
||||||
final TypedQuery<AssignableTask> query = entityManager.createNamedQuery(
|
final TypedQuery<AssignableTask> query = entityManager.createNamedQuery(
|
||||||
"UserTask.findLockedBy", AssignableTask.class);
|
"UserTask.findLockedBy", AssignableTask.class);
|
||||||
query.setParameter("user", user);
|
query.setParameter("user", user);
|
||||||
|
|
@ -121,12 +188,17 @@ public class AssignableTaskManager extends TaskManager {
|
||||||
return query.getResultList();
|
return query.getResultList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finishes a {@link AssignableTask}.
|
||||||
|
*
|
||||||
|
* @param task The task to finish.
|
||||||
|
*/
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public void finish(final AssignableTask task) {
|
public void finish(final AssignableTask task) {
|
||||||
final User currentUser = shiro.getUser();
|
final User currentUser = shiro.getUser();
|
||||||
|
|
||||||
if (!currentUser.equals(task.getLockingUser())) {
|
if (!currentUser.equals(task.getLockingUser())) {
|
||||||
throw new IllegalArgumentException(String.format(
|
throw new IllegalArgumentException(String.format(
|
||||||
"Current user %s is not locking user for task %s. Task is"
|
"Current user %s is not locking user for task %s. Task is"
|
||||||
|
|
@ -135,18 +207,23 @@ public class AssignableTaskManager extends TaskManager {
|
||||||
Objects.toString(task),
|
Objects.toString(task),
|
||||||
Objects.toString(task.getLockingUser())));
|
Objects.toString(task.getLockingUser())));
|
||||||
}
|
}
|
||||||
|
|
||||||
super.finish(task);
|
taskManager.finish(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finishes a {@link AssignableTask} with a comment.
|
||||||
|
*
|
||||||
|
* @param task The task to finish.
|
||||||
|
* @param comment The comment to add to the task.
|
||||||
|
*/
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public void finish(final AssignableTask task,
|
public void finish(final AssignableTask task,
|
||||||
final String comment) {
|
final String comment) {
|
||||||
addComment(task, comment);
|
taskManager.addComment(task, comment);
|
||||||
finish(task);
|
finish(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,8 @@ import javax.enterprise.context.RequestScoped;
|
||||||
import javax.persistence.TypedQuery;
|
import javax.persistence.TypedQuery;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Repository for assignable tasks.
|
||||||
|
*
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@RequestScoped
|
@RequestScoped
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,8 @@
|
||||||
package org.libreccm.workflow;
|
package org.libreccm.workflow;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Thrown when a circular task dependency is detected.
|
||||||
|
*
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
public class CircularTaskDependencyException extends Exception {
|
public class CircularTaskDependencyException extends Exception {
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@ package org.libreccm.workflow;
|
||||||
|
|
||||||
import static org.libreccm.core.CoreConstants.*;
|
import static org.libreccm.core.CoreConstants.*;
|
||||||
|
|
||||||
|
import org.libreccm.core.CcmObject;
|
||||||
|
import org.libreccm.core.Identifiable;
|
||||||
import org.libreccm.l10n.LocalizedString;
|
import org.libreccm.l10n.LocalizedString;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
@ -47,8 +49,11 @@ import javax.persistence.NamedQueries;
|
||||||
import javax.persistence.NamedQuery;
|
import javax.persistence.NamedQuery;
|
||||||
import javax.persistence.OneToMany;
|
import javax.persistence.OneToMany;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* A task is part of a workflow and represents a specific step in the creation
|
||||||
|
* process of an {@link CcmObject}.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
|
|
@ -91,15 +96,28 @@ import javax.persistence.Table;
|
||||||
+ "WHERE t.workflow = :workflow "
|
+ "WHERE t.workflow = :workflow "
|
||||||
+ "AND t.taskState = org.libreccm.workflow.TaskState.FINISHED")
|
+ "AND t.taskState = org.libreccm.workflow.TaskState.FINISHED")
|
||||||
})
|
})
|
||||||
public class Task implements Serializable {
|
public class Task implements Identifiable, Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 8161343036908150426L;
|
private static final long serialVersionUID = 8161343036908150426L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database ID of the task.
|
||||||
|
*/
|
||||||
@Id
|
@Id
|
||||||
@Column(name = "TASK_ID")
|
@Column(name = "TASK_ID")
|
||||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
private long taskId;
|
private long taskId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The UUID of the task.
|
||||||
|
*/
|
||||||
|
@Column(name = "UUID", unique = true, nullable = false)
|
||||||
|
@NotNull
|
||||||
|
private String uuid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A human readable, localisable label for the task.
|
||||||
|
*/
|
||||||
@Embedded
|
@Embedded
|
||||||
@AssociationOverride(
|
@AssociationOverride(
|
||||||
name = "values",
|
name = "values",
|
||||||
|
|
@ -109,6 +127,9 @@ public class Task implements Serializable {
|
||||||
@JoinColumn(name = "TASK_ID")}))
|
@JoinColumn(name = "TASK_ID")}))
|
||||||
private LocalizedString label;
|
private LocalizedString label;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A description of the task.
|
||||||
|
*/
|
||||||
@Embedded
|
@Embedded
|
||||||
@AssociationOverride(
|
@AssociationOverride(
|
||||||
name = "values",
|
name = "values",
|
||||||
|
|
@ -118,20 +139,35 @@ public class Task implements Serializable {
|
||||||
@JoinColumn(name = "TASK_ID")}))
|
@JoinColumn(name = "TASK_ID")}))
|
||||||
private LocalizedString description;
|
private LocalizedString description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the task active?
|
||||||
|
*/
|
||||||
@Column(name = "ACTIVE")
|
@Column(name = "ACTIVE")
|
||||||
private boolean active;
|
private boolean active;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The state of the task.
|
||||||
|
*/
|
||||||
@Column(name = "TASK_STATE", length = 512)
|
@Column(name = "TASK_STATE", length = 512)
|
||||||
@Enumerated(EnumType.STRING)
|
@Enumerated(EnumType.STRING)
|
||||||
private TaskState taskState;
|
private TaskState taskState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The workflow to which the task belongs.
|
||||||
|
*/
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "WORKFLOW_ID")
|
@JoinColumn(name = "WORKFLOW_ID")
|
||||||
private Workflow workflow;
|
private Workflow workflow;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tasks which the depends of this task.
|
||||||
|
*/
|
||||||
@ManyToMany(mappedBy = "dependsOn")
|
@ManyToMany(mappedBy = "dependsOn")
|
||||||
private List<Task> dependentTasks;
|
private List<Task> dependentTasks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The task of this task depends.
|
||||||
|
*/
|
||||||
@ManyToMany
|
@ManyToMany
|
||||||
@JoinTable(name = "WORKFLOW_TASK_DEPENDENCIES",
|
@JoinTable(name = "WORKFLOW_TASK_DEPENDENCIES",
|
||||||
schema = DB_SCHEMA,
|
schema = DB_SCHEMA,
|
||||||
|
|
@ -141,6 +177,9 @@ public class Task implements Serializable {
|
||||||
@JoinColumn(name = "DEPENDENT_TASK_ID")})
|
@JoinColumn(name = "DEPENDENT_TASK_ID")})
|
||||||
private List<Task> dependsOn;
|
private List<Task> dependsOn;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Comments for the task.
|
||||||
|
*/
|
||||||
@OneToMany
|
@OneToMany
|
||||||
@JoinColumn(name = "TASK_ID")
|
@JoinColumn(name = "TASK_ID")
|
||||||
private List<TaskComment> comments;
|
private List<TaskComment> comments;
|
||||||
|
|
@ -159,10 +198,18 @@ public class Task implements Serializable {
|
||||||
return taskId;
|
return taskId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTaskId(final long taskId) {
|
protected void setTaskId(final long taskId) {
|
||||||
this.taskId = taskId;
|
this.taskId = taskId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getUuid() {
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setUuid(final String uuid) {
|
||||||
|
this.uuid = uuid;
|
||||||
|
}
|
||||||
|
|
||||||
public LocalizedString getLabel() {
|
public LocalizedString getLabel() {
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
|
@ -267,6 +314,7 @@ public class Task implements Serializable {
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int hash = 7;
|
int hash = 7;
|
||||||
hash = 79 * hash + (int) (taskId ^ (taskId >>> 32));
|
hash = 79 * hash + (int) (taskId ^ (taskId >>> 32));
|
||||||
|
hash = 79 * hash + Objects.hashCode(uuid);
|
||||||
hash = 79 * hash + Objects.hashCode(label);
|
hash = 79 * hash + Objects.hashCode(label);
|
||||||
hash = 79 * hash + Objects.hashCode(description);
|
hash = 79 * hash + Objects.hashCode(description);
|
||||||
hash = 79 * hash + (active ? 1 : 0);
|
hash = 79 * hash + (active ? 1 : 0);
|
||||||
|
|
@ -296,6 +344,9 @@ public class Task implements Serializable {
|
||||||
if (taskId != other.getTaskId()) {
|
if (taskId != other.getTaskId()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!Objects.equals(uuid, other.getUuid())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (!Objects.equals(label, other.getLabel())) {
|
if (!Objects.equals(label, other.getLabel())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -323,6 +374,7 @@ public class Task implements Serializable {
|
||||||
public String toString(final String data) {
|
public String toString(final String data) {
|
||||||
return String.format("%s{ "
|
return String.format("%s{ "
|
||||||
+ "taskId = %d, "
|
+ "taskId = %d, "
|
||||||
|
+ "uuid = \"%s\", "
|
||||||
+ "label = %s, "
|
+ "label = %s, "
|
||||||
+ "active = %b, "
|
+ "active = %b, "
|
||||||
+ "taskState = \"%s\", "
|
+ "taskState = \"%s\", "
|
||||||
|
|
@ -332,6 +384,7 @@ public class Task implements Serializable {
|
||||||
+ " }",
|
+ " }",
|
||||||
super.toString(),
|
super.toString(),
|
||||||
taskId,
|
taskId,
|
||||||
|
uuid,
|
||||||
Objects.toString(label),
|
Objects.toString(label),
|
||||||
active,
|
active,
|
||||||
taskState,
|
taskState,
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,8 @@ import javax.persistence.ManyToOne;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Represents the assignment of a {@link AssignableTask} to a {@link Role}.
|
||||||
|
*
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
|
|
@ -44,15 +45,24 @@ public class TaskAssignment implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = -4427537363301565707L;
|
private static final long serialVersionUID = -4427537363301565707L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database ID of the entity.
|
||||||
|
*/
|
||||||
@Id
|
@Id
|
||||||
@Column(name = "TASK_ASSIGNMENT_ID")
|
@Column(name = "TASK_ASSIGNMENT_ID")
|
||||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
private long taskAssignmentId;
|
private long taskAssignmentId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The task.
|
||||||
|
*/
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "TASK_ID")
|
@JoinColumn(name = "TASK_ID")
|
||||||
private AssignableTask task;
|
private AssignableTask task;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The role to which the task is assigned.
|
||||||
|
*/
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "ROLE_ID")
|
@JoinColumn(name = "ROLE_ID")
|
||||||
private Role role;
|
private Role role;
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ public class TaskComment implements Identifiable, Serializable {
|
||||||
/**
|
/**
|
||||||
* The UUID of the comment.
|
* The UUID of the comment.
|
||||||
*/
|
*/
|
||||||
@Column(name = "uuid", unique = true, nullable = false)
|
@Column(name = "UUID", unique = true, nullable = false)
|
||||||
@NotNull
|
@NotNull
|
||||||
private String uuid;
|
private String uuid;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@ package org.libreccm.workflow;
|
||||||
|
|
||||||
import org.libreccm.core.AbstractEntityRepository;
|
import org.libreccm.core.AbstractEntityRepository;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import javax.enterprise.context.RequestScoped;
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -39,5 +41,10 @@ public class TaskRepository extends AbstractEntityRepository<Long, Task> {
|
||||||
public boolean isNew(final Task task) {
|
public boolean isNew(final Task task) {
|
||||||
return task.getTaskId() == 0;
|
return task.getTaskId() == 0;
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
protected void initNewEntity(final Task task) {
|
||||||
|
super.initNewEntity(task);
|
||||||
|
task.setUuid(UUID.randomUUID().toString());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ public class Workflow implements Identifiable, Serializable {
|
||||||
/**
|
/**
|
||||||
* UUID of the workflow.
|
* UUID of the workflow.
|
||||||
*/
|
*/
|
||||||
@Column(name = "uuid", unique = true, nullable = false)
|
@Column(name = "UUID", unique = true, nullable = false)
|
||||||
@NotNull
|
@NotNull
|
||||||
private String uuid;
|
private String uuid;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,8 @@ public class WorkflowRepository extends AbstractEntityRepository<Long, Workflow>
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initNewEntity(final Workflow workflow) {
|
protected void initNewEntity(final Workflow workflow) {
|
||||||
|
super.initNewEntity(workflow);
|
||||||
workflow.setUuid(UUID.randomUUID().toString());
|
workflow.setUuid(UUID.randomUUID().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import org.libreccm.workflow.AssignableTask;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
@ -89,10 +90,10 @@ public class EqualsAndHashCodeTest extends EqualsVerifier {
|
||||||
ccmObject1.setDisplayName("Object 2");
|
ccmObject1.setDisplayName("Object 2");
|
||||||
|
|
||||||
final AssignableTask task1 = new AssignableTask();
|
final AssignableTask task1 = new AssignableTask();
|
||||||
task1.setTaskId(-10);
|
task1.getLabel().addValue(Locale.ENGLISH, "Task 1");
|
||||||
|
|
||||||
final AssignableTask task2 = new AssignableTask();
|
final AssignableTask task2 = new AssignableTask();
|
||||||
task2.setTaskId(-20);
|
task2.getLabel().addValue(Locale.ENGLISH, "Task 2");
|
||||||
|
|
||||||
verifier
|
verifier
|
||||||
.withPrefabValues(Group.class, group1, group2)
|
.withPrefabValues(Group.class, group1, group2)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue