From 2d900794f9f4e24ff8ec61bf6197e9df208c0749 Mon Sep 17 00:00:00 2001 From: jensp Date: Sun, 10 Dec 2017 20:19:18 +0000 Subject: [PATCH] CCM NG: Refactored dependencies between tasks from an n:m relation to two 1:n relations using an relation entity (TaskDependency). Also renamed some attributes to make the dependency relations more readable. git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@5162 8810af33-2d31-482b-a856-94f89814c4df --- ccm-cms/pom.xml | 4 +- .../com/arsdigita/cms/ui/item/Summary.java | 13 +- .../cms/ui/workflow/BaseTaskForm.java | 7 +- .../cms/ui/workflow/TaskEditForm.java | 11 +- .../cms/ui/workflow/TaskFinishForm.java | 14 +- .../cms/ui/workflow/TaskItemPane.java | 10 +- .../workflow/WorkflowAdminPaneController.java | 17 +- .../ContentItemPermissionTest.java | 2 +- .../ContentTypeRepositoryTest.java | 2 +- .../scripts/create_ccm_cms_schema.sql | 19 +- .../scripts/create_ccm_cms_schema.sql | 19 +- .../categorization/Categorization.java | 3 - .../main/java/org/libreccm/workflow/Task.java | 165 +++++++++++++----- .../org/libreccm/workflow/TaskDependency.java | 142 +++++++++++++++ .../org/libreccm/workflow/TaskManager.java | 143 +++++++++++---- .../libreccm/workflow/WorkflowManager.java | 53 ++++-- .../h2/V7_0_0_18__add_task_dependency.sql | 39 +++++ .../pgsql/V7_0_0_18__add_task_dependency.sql | 39 +++++ .../scripts/create_ccm_core_schema.sql | 19 +- .../scripts/create_ccm_core_schema.sql | 20 ++- ccm-shortcuts/pom.xml | 4 +- .../scripts/create_ccm_shortcuts_schema.sql | 56 ++++-- .../scripts/create_ccm_shortcuts_schema.sql | 58 ++++-- 23 files changed, 684 insertions(+), 175 deletions(-) create mode 100644 ccm-core/src/main/java/org/libreccm/workflow/TaskDependency.java create mode 100644 ccm-core/src/main/resources/db/migrations/org/libreccm/ccm_core/h2/V7_0_0_18__add_task_dependency.sql create mode 100644 ccm-core/src/main/resources/db/migrations/org/libreccm/ccm_core/pgsql/V7_0_0_18__add_task_dependency.sql diff --git a/ccm-cms/pom.xml b/ccm-cms/pom.xml index e869238ca..ba75c1acd 100644 --- a/ccm-cms/pom.xml +++ b/ccm-cms/pom.xml @@ -363,9 +363,9 @@ com.github.spotbugs spotbugs-maven-plugin 3.1.0-RC8 - + diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/item/Summary.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/item/Summary.java index 155237318..324b7d2c5 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/item/Summary.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/item/Summary.java @@ -58,6 +58,7 @@ import org.libreccm.categorization.CategoryManager; import org.libreccm.cdi.utils.CdiUtil; import org.libreccm.l10n.GlobalizationHelper; import org.libreccm.security.Shiro; +import org.libreccm.workflow.TaskDependency; import org.librecms.contentsection.ContentItemRepository; import org.librecms.contentsection.ContentSectionManager; import org.librecms.dispatcher.ItemResolver; @@ -171,11 +172,15 @@ public class Summary extends CMSContainer { final GraphSet graph = new GraphSet(); for (final Task task : tasks) { - final List dependsOn = task.getDependsOn(); + final List blockingTasks = task + .getBlockingTasks(); final StringBuilder builder = new StringBuilder(); - for (final Task dep : dependsOn) { - graph.addEdge(task, dep, null); - builder.append(dep.getLabel().getValue(language)); + for (final TaskDependency blocking : blockingTasks) { + graph.addEdge(task, blocking, null); + builder.append(blocking + .getBlockingTask() + .getLabel() + .getValue(language)); } final int len = builder.length(); diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/BaseTaskForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/BaseTaskForm.java index 0c4d10d1e..e70679bde 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/BaseTaskForm.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/BaseTaskForm.java @@ -35,6 +35,7 @@ import com.arsdigita.util.UncheckedWrapperException; import org.libreccm.workflow.Task; import org.libreccm.cdi.utils.CdiUtil; import org.libreccm.workflow.CircularTaskDependencyException; +import org.libreccm.workflow.TaskDependency; import org.libreccm.workflow.TaskManager; import org.libreccm.workflow.TaskRepository; import org.librecms.CmsConstants; @@ -187,10 +188,12 @@ class BaseTaskForm extends BaseForm { */ final void processDependencies(final Task task, final String[] selectedDependencies) { - final List dependencies = task.getDependentTasks(); + final List blockedTasks = task.getBlockedTasks(); final Map toAdd = new HashMap<>(); // Everything is to be removed unless it is in the array. - final Map toRemove = dependencies.stream() + final Map toRemove = blockedTasks + .stream() + .map(TaskDependency::getBlockedTask) .collect(Collectors.toMap(Task::getTaskId, dependency -> dependency)); diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/TaskEditForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/TaskEditForm.java index 101cd06df..56f298638 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/TaskEditForm.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/TaskEditForm.java @@ -34,9 +34,8 @@ import org.librecms.workflow.CmsTask; import com.arsdigita.util.UncheckedWrapperException; import org.libreccm.cdi.utils.CdiUtil; -import org.libreccm.configuration.ConfigurationManager; import org.libreccm.workflow.Task; -import org.libreccm.workflow.TaskRepository; +import org.libreccm.workflow.TaskDependency; import org.libreccm.workflow.Workflow; import org.librecms.workflow.CmsTaskType; @@ -125,9 +124,11 @@ class TaskEditForm extends BaseTaskForm { final WorkflowAdminPaneController controller = cdiUtil.findBean( WorkflowAdminPaneController.class); - final List dependencies = controller.getDependencies(task); - final List depIdList = dependencies.stream() - .map(dependency -> Long.toString(dependency.getTaskId())) + final List blockedTasks = controller.getBlockedTasks(task); + final List depIdList = blockedTasks + .stream() + .map(TaskDependency::getBlockedTask) + .map(blockedTask -> Long.toString(blockedTask.getTaskId())) .collect(Collectors.toList()); getDependenciesOptionGroup().setValue(state, depIdList.toArray()); diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/TaskFinishForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/TaskFinishForm.java index 5269f79e8..206789820 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/TaskFinishForm.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/TaskFinishForm.java @@ -29,7 +29,6 @@ import com.arsdigita.bebop.form.Option; import com.arsdigita.bebop.form.RadioGroup; import com.arsdigita.bebop.parameters.BooleanParameter; -import com.arsdigita.cms.ui.ContentItemPage; import com.arsdigita.globalization.GlobalizedMessage; import com.arsdigita.kernel.KernelConfig; import com.arsdigita.util.UncheckedWrapperException; @@ -50,6 +49,7 @@ import org.libreccm.cdi.utils.CdiUtil; import org.libreccm.configuration.ConfigurationManager; import org.libreccm.security.PermissionChecker; import org.libreccm.workflow.AssignableTask; +import org.libreccm.workflow.TaskDependency; import org.libreccm.workflow.Workflow; import org.librecms.CmsConstants; import org.librecms.contentsection.ContentItem; @@ -192,12 +192,16 @@ public final class TaskFinishForm extends CommentAddForm { + "tasks"); // Reenable the previous tasks. - for (final Task dependent : task.getDependentTasks()) { + for (final TaskDependency blockedTask : task + .getBlockedTasks()) { LOGGER.debug("Reenabling task {}", - dependent.getLabel().getValue( - kernelConfig.getDefaultLocale())); + blockedTask + .getBlockedTask() + .getLabel() + .getValue(kernelConfig + .getDefaultLocale())); - controller.enable(dependent); + controller.enable(blockedTask.getBlockedTask()); } } } else { diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/TaskItemPane.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/TaskItemPane.java index 619649323..14c65461d 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/TaskItemPane.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/TaskItemPane.java @@ -52,6 +52,7 @@ import org.libreccm.security.Shiro; import org.libreccm.workflow.Task; import org.libreccm.workflow.AssignableTask; import org.libreccm.workflow.AssignableTaskManager; +import org.libreccm.workflow.TaskDependency; import org.librecms.contentsection.privileges.AdminPrivileges; import java.util.List; @@ -340,12 +341,15 @@ final class TaskItemPane extends BaseItemPane { final WorkflowAdminPaneController controller = cdiUtil .findBean(WorkflowAdminPaneController.class); - final List dependencies = controller.getDependencies(task); + final List blockedTasks = controller + .getBlockedTasks(task); final KernelConfig kernelConfig = KernelConfig.getConfig(); final Locale defaultLocale = kernelConfig.getDefaultLocale(); - return dependencies.stream() - .map(dependency -> dependency.getLabel().getValue( + return blockedTasks + .stream() + .map(TaskDependency::getBlockedTask) + .map(blockedTask -> blockedTask.getLabel().getValue( defaultLocale)) .collect(Collectors.joining(", ")); } diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/WorkflowAdminPaneController.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/WorkflowAdminPaneController.java index 6f1c0eeaa..99335797e 100644 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/WorkflowAdminPaneController.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/WorkflowAdminPaneController.java @@ -31,6 +31,7 @@ import org.libreccm.security.RoleRepository; import org.libreccm.workflow.AssignableTaskManager; import org.libreccm.workflow.CircularTaskDependencyException; import org.libreccm.workflow.Task; +import org.libreccm.workflow.TaskDependency; import org.libreccm.workflow.TaskManager; import org.libreccm.workflow.TaskRepository; import org.libreccm.workflow.Workflow; @@ -208,10 +209,12 @@ public class WorkflowAdminPaneController { */ private void processDependencies(final Task task, final String[] selectedDependencies) { - final List dependencies = task.getDependentTasks(); + final List blockedTasks = task.getBlockedTasks(); final Map toAdd = new HashMap<>(); // Everything is to be removed unless it is in the array. - final Map toRemove = dependencies.stream() + final Map toRemove = blockedTasks + .stream() + .map(TaskDependency::getBlockedTask) .collect(Collectors.toMap(Task::getTaskId, dependency -> dependency)); @@ -241,7 +244,7 @@ public class WorkflowAdminPaneController { } @Transactional(Transactional.TxType.REQUIRED) - public List getDependencies(final Task task) { + public List getBlockedTasks(final Task task) { final Task theTask = taskRepo .findById(task.getTaskId()) @@ -249,7 +252,7 @@ public class WorkflowAdminPaneController { "No Task with ID %d in the database. Where did that ID come from?", task.getTaskId()))); - return new ArrayList<>(theTask.getDependsOn()); + return new ArrayList<>(theTask.getBlockedTasks()); } @Transactional(Transactional.TxType.REQUIRED) @@ -266,10 +269,12 @@ public class WorkflowAdminPaneController { while (tasksIter.hasNext()) { Task task = tasksIter.next(); - final Iterator deps = task.getDependsOn().iterator(); + final Iterator deps = task + .getBlockingTasks() + .iterator(); final StringBuffer buffer = new StringBuffer(); while (deps.hasNext()) { - Task dep = deps.next(); + Task dep = deps.next().getBlockingTask(); graphSet.addEdge(task, dep, null); buffer .append(dep.getLabel().getValue(defaultLocale)) diff --git a/ccm-cms/src/test/java/org/librecms/contentsection/ContentItemPermissionTest.java b/ccm-cms/src/test/java/org/librecms/contentsection/ContentItemPermissionTest.java index aa7e98469..1a72d5144 100644 --- a/ccm-cms/src/test/java/org/librecms/contentsection/ContentItemPermissionTest.java +++ b/ccm-cms/src/test/java/org/librecms/contentsection/ContentItemPermissionTest.java @@ -46,7 +46,6 @@ import org.libreccm.security.Shiro; import org.libreccm.security.User; import org.libreccm.tests.categories.IntegrationTest; -import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Optional; @@ -150,6 +149,7 @@ public class ContentItemPermissionTest { .addClass(org.libreccm.security.Relation.class) //Classes required by org.libreccm.workflow.Task.class .addClass(org.libreccm.workflow.TaskComment.class) + .addClass(org.libreccm.workflow.TaskDependency.class) .addClass(org.libreccm.workflow.TaskState.class) .addClass(org.libreccm.workflow.Workflow.class) .addClass(org.libreccm.workflow.AbstractWorkflowException.class) diff --git a/ccm-cms/src/test/java/org/librecms/contentsection/ContentTypeRepositoryTest.java b/ccm-cms/src/test/java/org/librecms/contentsection/ContentTypeRepositoryTest.java index 2ac0ca70d..8762215b8 100644 --- a/ccm-cms/src/test/java/org/librecms/contentsection/ContentTypeRepositoryTest.java +++ b/ccm-cms/src/test/java/org/librecms/contentsection/ContentTypeRepositoryTest.java @@ -52,7 +52,6 @@ import javax.inject.Inject; import org.jboss.arquillian.persistence.CleanupUsingScript; import org.jboss.arquillian.persistence.TestExecutionPhase; -import org.jboss.shrinkwrap.api.asset.EmptyAsset; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; @@ -387,6 +386,7 @@ public class ContentTypeRepositoryTest { .addClass(org.libreccm.workflow.Task.class) .addClass(org.libreccm.workflow.TaskAssignment.class) .addClass(org.libreccm.workflow.TaskComment.class) + .addClass(org.libreccm.workflow.TaskDependency.class) .addClass(org.libreccm.workflow.TaskState.class) .addClass(org.libreccm.workflow.Workflow.class) .addClass(org.libreccm.workflow.WorkflowState.class) diff --git a/ccm-cms/src/test/resources-wildfly-remote-h2-mem/scripts/create_ccm_cms_schema.sql b/ccm-cms/src/test/resources-wildfly-remote-h2-mem/scripts/create_ccm_cms_schema.sql index 5492fa8ed..09f173746 100644 --- a/ccm-cms/src/test/resources-wildfly-remote-h2-mem/scripts/create_ccm_cms_schema.sql +++ b/ccm-cms/src/test/resources-wildfly-remote-h2-mem/scripts/create_ccm_cms_schema.sql @@ -3,6 +3,7 @@ drop schema if exists CCM_CORE; drop sequence if exists HIBERNATE_SEQUENCE; + create schema CCM_CMS; create schema CCM_CORE; @@ -1432,11 +1433,11 @@ drop sequence if exists HIBERNATE_SEQUENCE; SETTING_ID bigint not null, CONFIGURATION_CLASS varchar(512) not null, NAME varchar(512) not null, - SETTING_VALUE_BOOLEAN boolean, SETTING_VALUE_DOUBLE double, + SETTING_VALUE_LONG bigint, SETTING_VALUE_BIG_DECIMAL decimal(19,2), SETTING_VALUE_STRING varchar(1024), - SETTING_VALUE_LONG bigint, + SETTING_VALUE_BOOLEAN boolean, primary key (SETTING_ID) ); @@ -1539,8 +1540,10 @@ drop sequence if exists HIBERNATE_SEQUENCE; ); create table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES ( - DEPENDS_ON_TASK_ID bigint not null, - DEPENDENT_TASK_ID bigint not null + TASK_DEPENDENCY_ID bigint not null, + BLOCKED_TASK_ID bigint, + BLOCKING_TASK_ID bigint, + primary key (TASK_DEPENDENCY_ID) ); create table CCM_CORE.WORKFLOW_TASK_DESCRIPTIONS ( @@ -2921,13 +2924,13 @@ drop sequence if exists HIBERNATE_SEQUENCE; references CCM_CORE.WORKFLOW_TASKS; alter table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES - add constraint FK1htp420ki24jaswtcum56iawe - foreign key (DEPENDENT_TASK_ID) + add constraint FKy88tppv7ihx0lsn6g64f5lfq + foreign key (BLOCKED_TASK_ID) references CCM_CORE.WORKFLOW_TASKS; alter table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES - add constraint FK8rbggnp4yjpab8quvvx800ymy - foreign key (DEPENDS_ON_TASK_ID) + add constraint FKrj80uilojn73u9a4xgk3vt0cj + foreign key (BLOCKING_TASK_ID) references CCM_CORE.WORKFLOW_TASKS; alter table CCM_CORE.WORKFLOW_TASK_DESCRIPTIONS diff --git a/ccm-cms/src/test/resources-wildfly-remote-pgsql/scripts/create_ccm_cms_schema.sql b/ccm-cms/src/test/resources-wildfly-remote-pgsql/scripts/create_ccm_cms_schema.sql index c2a31a3c9..a16b995f5 100644 --- a/ccm-cms/src/test/resources-wildfly-remote-pgsql/scripts/create_ccm_cms_schema.sql +++ b/ccm-cms/src/test/resources-wildfly-remote-pgsql/scripts/create_ccm_cms_schema.sql @@ -3,6 +3,7 @@ drop schema if exists CCM_CORE cascade; drop sequence if exists HIBERNATE_SEQUENCE; + create schema CCM_CMS; create schema CCM_CORE; @@ -1432,11 +1433,11 @@ drop sequence if exists HIBERNATE_SEQUENCE; SETTING_ID int8 not null, CONFIGURATION_CLASS varchar(512) not null, NAME varchar(512) not null, - SETTING_VALUE_BOOLEAN boolean, SETTING_VALUE_DOUBLE float8, + SETTING_VALUE_LONG int8, SETTING_VALUE_BIG_DECIMAL numeric(19, 2), SETTING_VALUE_STRING varchar(1024), - SETTING_VALUE_LONG int8, + SETTING_VALUE_BOOLEAN boolean, primary key (SETTING_ID) ); @@ -1539,8 +1540,10 @@ drop sequence if exists HIBERNATE_SEQUENCE; ); create table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES ( - DEPENDS_ON_TASK_ID int8 not null, - DEPENDENT_TASK_ID int8 not null + TASK_DEPENDENCY_ID int8 not null, + BLOCKED_TASK_ID int8, + BLOCKING_TASK_ID int8, + primary key (TASK_DEPENDENCY_ID) ); create table CCM_CORE.WORKFLOW_TASK_DESCRIPTIONS ( @@ -2921,13 +2924,13 @@ drop sequence if exists HIBERNATE_SEQUENCE; references CCM_CORE.WORKFLOW_TASKS; alter table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES - add constraint FK1htp420ki24jaswtcum56iawe - foreign key (DEPENDENT_TASK_ID) + add constraint FKy88tppv7ihx0lsn6g64f5lfq + foreign key (BLOCKED_TASK_ID) references CCM_CORE.WORKFLOW_TASKS; alter table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES - add constraint FK8rbggnp4yjpab8quvvx800ymy - foreign key (DEPENDS_ON_TASK_ID) + add constraint FKrj80uilojn73u9a4xgk3vt0cj + foreign key (BLOCKING_TASK_ID) references CCM_CORE.WORKFLOW_TASKS; alter table CCM_CORE.WORKFLOW_TASK_DESCRIPTIONS diff --git a/ccm-core/src/main/java/org/libreccm/categorization/Categorization.java b/ccm-core/src/main/java/org/libreccm/categorization/Categorization.java index 0b3a49f5b..0df61fba0 100644 --- a/ccm-core/src/main/java/org/libreccm/categorization/Categorization.java +++ b/ccm-core/src/main/java/org/libreccm/categorization/Categorization.java @@ -29,8 +29,6 @@ import java.util.Objects; import static org.libreccm.core.CoreConstants.DB_SCHEMA; -import javax.persistence.Access; -import javax.persistence.AccessType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; @@ -38,7 +36,6 @@ import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; -import javax.persistence.MappedSuperclass; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.Table; diff --git a/ccm-core/src/main/java/org/libreccm/workflow/Task.java b/ccm-core/src/main/java/org/libreccm/workflow/Task.java index ea38f6c10..127e1ff2e 100644 --- a/ccm-core/src/main/java/org/libreccm/workflow/Task.java +++ b/ccm-core/src/main/java/org/libreccm/workflow/Task.java @@ -20,14 +20,13 @@ package org.libreccm.workflow; import com.fasterxml.jackson.annotation.JsonIdentityInfo; import com.fasterxml.jackson.annotation.JsonIdentityReference; -import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.ObjectIdGenerators; import org.libreccm.core.CcmObject; import org.libreccm.core.Identifiable; import org.libreccm.l10n.LocalizedString; -import javax.persistence.*; import javax.validation.constraints.NotNull; + import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; @@ -36,6 +35,28 @@ import java.util.Objects; import static org.libreccm.core.CoreConstants.DB_SCHEMA; +import javax.persistence.AssociationOverride; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +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.ManyToOne; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; + /** * A task is part of a workflow and represents a specific step in the creation * process of an {@link CcmObject}. @@ -84,6 +105,21 @@ import static org.libreccm.core.CoreConstants.DB_SCHEMA; query = "SELECT t FROM Task t " + "WHERE t.workflow = :workflow " + "AND t.taskState = org.libreccm.workflow.TaskState.FINISHED") + , + @NamedQuery( + name = "Task.existsDependency", + query = "SELECT (CASE WHEN COUNT(d) > 0 THEN true ELSE false END) " + + "FROM TaskDependency d " + + "WHERE d.blockedTask = :blockedTask " + + "AND d.blockingTask = :blockingTask" + ) + , + @NamedQuery( + name = "Task.findDependency", + query = "SELECT d FROM TaskDependency d " + + "WHERE d.blockedTask = :blockedTask " + + "AND d.blockingTask = :blockingTask" + ) }) @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, resolver = TaskIdResolver.class, @@ -152,26 +188,34 @@ public class Task implements Identifiable, Serializable { @JsonIdentityReference(alwaysAsId = true) private Workflow workflow; - /** - * Tasks which depend on this task. - */ - @ManyToMany(mappedBy = "dependsOn", fetch = FetchType.LAZY) - @JsonIgnore - private List dependentTasks; +// /** +// * Tasks which depend on this task. +// */ +// @ManyToMany(mappedBy = "dependsOn", fetch = FetchType.LAZY) +// @JsonIgnore +// private List dependentTasks; + @OneToMany(mappedBy = "blockingTask", fetch = FetchType.LAZY) + @XmlElementWrapper(name = "blocked-tasks") + @XmlElement(name = "task-dependency") + private List blockedTasks; - /** - * The dependencies of this task. - */ - @ManyToMany(fetch = FetchType.LAZY) - @JoinTable(name = "WORKFLOW_TASK_DEPENDENCIES", - schema = DB_SCHEMA, - joinColumns = { - @JoinColumn(name = "DEPENDS_ON_TASK_ID")}, - inverseJoinColumns = { - @JoinColumn(name = "DEPENDENT_TASK_ID")}) - @JsonIdentityReference(alwaysAsId = true) - private List dependsOn; + @OneToMany(mappedBy = "blockedTask", fetch = FetchType.LAZY) + @XmlElementWrapper(name = "blocking-tasks") + @XmlElement(name = "task-dependency") + private List blockingTasks; +// /** +// * The dependencies of this task. +// */ +// @ManyToMany(fetch = FetchType.LAZY) +// @JoinTable(name = "WORKFLOW_TASK_DEPENDENCIES", +// schema = DB_SCHEMA, +// joinColumns = { +// @JoinColumn(name = "DEPENDS_ON_TASK_ID")}, +// inverseJoinColumns = { +// @JoinColumn(name = "DEPENDENT_TASK_ID")}) +// @JsonIdentityReference(alwaysAsId = true) +// private List dependsOn; /** * Comments for the task. */ @@ -185,8 +229,10 @@ public class Task implements Identifiable, Serializable { label = new LocalizedString(); description = new LocalizedString(); - dependentTasks = new ArrayList<>(); - dependsOn = new ArrayList<>(); +// dependentTasks = new ArrayList<>(); +// dependsOn = new ArrayList<>(); + blockedTasks = new ArrayList<>(); + blockingTasks = new ArrayList<>(); comments = new ArrayList<>(); active = false; } @@ -250,44 +296,83 @@ public class Task implements Identifiable, Serializable { this.workflow = workflow; } - public List getDependentTasks() { - if (dependentTasks == null) { +// public List getDependentTasks() { +// if (dependentTasks == null) { +// return null; +// } else { +// 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() { +// if (dependsOn == null) { +// return null; +// } else { +// 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 getBlockingTasks() { + if (blockingTasks == null) { return null; } else { - return Collections.unmodifiableList(dependentTasks); + return Collections.unmodifiableList(blockingTasks); } } - protected void setDependentTasks(final List dependentTasks) { - this.dependentTasks = dependentTasks; + protected void setBlockingTasks(final List blockingTasks) { + this.blockingTasks = blockingTasks; } - protected void addDependentTask(final Task task) { - dependentTasks.add(task); + protected void addBlockingTask(final TaskDependency taskDependency) { + blockingTasks.add(taskDependency); } - protected void removeDependentTask(final Task task) { - dependentTasks.remove(task); + protected void removeBlockingTask(final TaskDependency taskDependency) { + blockingTasks.remove(taskDependency); } - public List getDependsOn() { - if (dependsOn == null) { + public List getBlockedTasks() { + if (blockedTasks == null) { return null; } else { - return Collections.unmodifiableList(dependsOn); + return Collections.unmodifiableList(blockedTasks); } } - protected void setDependsOn(final List dependsOn) { - this.dependsOn = dependsOn; + protected void setBlockedTasks(final List blockedTasks) { + this.blockedTasks = blockedTasks; } - protected void addDependsOn(final Task task) { - dependsOn.add(task); + protected void addBlockedTask(final TaskDependency taskDependency) { + blockedTasks.add(taskDependency); } - protected void removeDependsOn(final Task task) { - dependsOn.remove(task); + protected void removeBlockedTask(final TaskDependency taskDependency) { + blockedTasks.remove(taskDependency); } public List getComments() { diff --git a/ccm-core/src/main/java/org/libreccm/workflow/TaskDependency.java b/ccm-core/src/main/java/org/libreccm/workflow/TaskDependency.java new file mode 100644 index 000000000..4ff2281d2 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/workflow/TaskDependency.java @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2017 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 com.fasterxml.jackson.annotation.JsonIdentityReference; +import org.libreccm.core.CoreConstants; + +import java.io.Serializable; +import java.util.Objects; + +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.ManyToOne; +import javax.persistence.Table; + +/** + * + * @author Jens Pelzetter + */ +@Entity +@Table(name = "WORKFLOW_TASK_DEPENDENCIES", schema = CoreConstants.DB_SCHEMA) +public class TaskDependency implements Serializable { + + private static final long serialVersionUID = -4383255770131633943L; + + @Id + @Column(name = "TASK_DEPENDENCY_ID") + @GeneratedValue(strategy = GenerationType.AUTO) + private long taskDependencyId; + + @ManyToOne + @JoinColumn(name = "BLOCKED_TASK_ID") + @JsonIdentityReference(alwaysAsId = true) + private Task blockedTask; + + @ManyToOne + @JoinColumn(name = "BLOCKING_TASK_ID") + @JsonIdentityReference(alwaysAsId = true) + private Task blockingTask; + + public long getTaskDependencyId() { + return taskDependencyId; + } + + public void setTaskDependencyId(final long taskDependencyId) { + this.taskDependencyId = taskDependencyId; + } + + public Task getBlockedTask() { + return blockedTask; + } + + protected void setBlockedTask(final Task blockedTask) { + this.blockedTask = blockedTask; + } + + public Task getBlockingTask() { + return blockingTask; + } + + protected void setBlockingTask(final Task blockingTask) { + this.blockingTask = blockingTask; + } + + @Override + public int hashCode() { + int hash = 7; + hash + = 89 * hash + (int) (taskDependencyId ^ (taskDependencyId >>> 32)); + hash = 89 * hash + Objects.hashCode(blockedTask); + hash = 89 * hash + Objects.hashCode(blockingTask); + return hash; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof TaskDependency)) { + return false; + } + final TaskDependency other = (TaskDependency) obj; + if (!other.canEqual(this)) { + return false; + } + if (taskDependencyId != other.getTaskDependencyId()) { + return false; + } + if (!Objects.equals(blockedTask, other.getBlockedTask())) { + return false; + } + return Objects.equals(blockingTask, other.getBlockingTask()); + } + + public boolean canEqual(final Object obj) { + return obj instanceof TaskDependency; + } + + @Override + public final String toString() { + return toString(""); + } + + public String toString(final String data) { + + return String.format("%s{ " + + "taskDependencyId = %d, " + + "blockedTask = %s, " + + "blockingTask = %s%s" + + " }", + super.toString(), + taskDependencyId, + Objects.toString(blockedTask), + Objects.toString(blockingTask), + data); + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/workflow/TaskManager.java b/ccm-core/src/main/java/org/libreccm/workflow/TaskManager.java index af6935184..2c9164ad1 100644 --- a/ccm-core/src/main/java/org/libreccm/workflow/TaskManager.java +++ b/ccm-core/src/main/java/org/libreccm/workflow/TaskManager.java @@ -26,14 +26,19 @@ import org.libreccm.security.RequiresPrivilege; import org.libreccm.security.Shiro; import org.libreccm.security.User; +import java.util.List; + import javax.enterprise.context.RequestScoped; import javax.inject.Inject; import javax.persistence.EntityManager; import javax.transaction.Transactional; + import java.util.Objects; import java.util.Optional; import java.util.UUID; +import javax.persistence.TypedQuery; + /** * Manager for {@link Task}s. The logic of some of this methods has been taken * from the old implementation without changes. @@ -94,8 +99,8 @@ public class TaskManager { /** * Adds a dependent {@link Task} to another {@code Task}. * - * @param parent The task to which the dependent task is added. - * @param task The dependent task. + * @param blockingTask The task which blocks the blocked task. + * @param blockedTask The task blocked by the blocking task. * * @throws CircularTaskDependencyException If a circular dependency is * detected. @@ -103,33 +108,81 @@ public class TaskManager { @AuthorizationRequired @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) @Transactional(Transactional.TxType.REQUIRED) - public void addDependentTask(final Task parent, final Task task) + public void addDependentTask(final Task blockingTask, + final Task blockedTask) throws CircularTaskDependencyException { - checkForCircularDependencies(parent, task); + Objects.requireNonNull(blockedTask); + Objects.requireNonNull(blockingTask); - parent.addDependentTask(task); - task.addDependsOn(parent); + LOGGER.debug("Adding a dependency between task {} (blocking task) " + + "and task {} (blocked task)...", + Objects.toString(blockingTask), + Objects.toString(blockedTask)); - taskRepo.save(task); - taskRepo.save(parent); + LOGGER.debug("Checking for circular dependencies..."); + checkForCircularDependencies(blockingTask, blockedTask); + + LOGGER.debug("Checking if dependency already exists..."); + final TypedQuery query = entityManager + .createNamedQuery("Task.existsDependency", Boolean.class); + query.setParameter("blockingTask", blockingTask); + query.setParameter("blockedTask", blockedTask); + final Boolean dependencyExists = query.getSingleResult(); + + if (dependencyExists) { + LOGGER.info("Dependency between task {} (blocking task) " + + "and task {} (blocked task) already exists.", + Objects.toString(blockingTask), + Objects.toString(blockedTask)); + return; + } + + final TaskDependency dependency = new TaskDependency(); + dependency.setBlockedTask(blockedTask); + dependency.setBlockingTask(blockingTask); + + blockingTask.addBlockedTask(dependency); + blockedTask.addBlockingTask(dependency); + +// blockingTask.addDependentTask(blockedTask); +// blockedTask.addDependsOn(blockingTask); + + entityManager.persist(dependency); + taskRepo.save(blockedTask); + taskRepo.save(blockingTask); } /** * Removes a dependent task. * - * @param parent The task from which the dependent task is removed. - * @param task The dependent task to remove. + * @param blockingTask The task which blocks the other task. + * @param blockedTask The task which is blocked by the other task. */ @AuthorizationRequired @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) @Transactional(Transactional.TxType.REQUIRED) - public void removeDependentTask(final Task parent, final Task task) { - parent.removeDependentTask(task); - task.removeDependsOn(parent); + public void removeDependentTask(final Task blockingTask, + final Task blockedTask) { - taskRepo.save(task); - taskRepo.save(parent); + final TypedQuery query = entityManager + .createNamedQuery("Task.findDependency", TaskDependency.class); + query.setParameter("blockedTask", blockedTask); + query.setParameter("blockingTask", blockingTask); + final List dependencies = query.getResultList(); + + for(final TaskDependency dependency : dependencies) { + + entityManager.remove(dependency); + blockingTask.removeBlockedTask(dependency); + blockedTask.removeBlockingTask(dependency); + } + +// blockingTask.removeDependentTask(blockedTask); +// blockedTask.removeDependsOn(blockingTask); + + taskRepo.save(blockedTask); + taskRepo.save(blockingTask); } /** @@ -149,19 +202,27 @@ public class TaskManager { } } - private boolean dependsOn(final Task task, final Task dependsOn) { - for (final Task current : task.getDependsOn()) { - if (current.equals(dependsOn)) { - return true; - } - - if (current.getDependsOn() != null - && !current.getDependsOn().isEmpty()) { - return dependsOn(current, dependsOn); - } - } - - return false; + private boolean dependsOn(final Task blockingTask, final Task blockedTask) { + + final TypedQuery query = entityManager + .createNamedQuery("Task.existsDependency", Boolean.class); + query.setParameter("blockingTask", blockingTask); + query.setParameter("blockedTask", blockedTask); + + return query.getSingleResult(); + +// for (final Task current : blockingTask.getDependsOn()) { +// if (current.equals(blockedTask)) { +// return true; +// } +// +// if (current.getDependsOn() != null +// && !current.getDependsOn().isEmpty()) { +// return dependsOn(current, blockedTask); +// } +// } +// +// return false; } /** @@ -252,10 +313,9 @@ public class TaskManager { * @param task The task to finish. */ public void finish(final Task task) { - if (task == null) { - throw new IllegalArgumentException("Can't finished null..."); - } - + + Objects.requireNonNull(task, "Can't finished null..."); + if (task.getTaskState() != TaskState.ENABLED) { throw new IllegalArgumentException(String.format( "Task %s is not enabled.", @@ -265,7 +325,11 @@ public class TaskManager { task.setTaskState(TaskState.FINISHED); taskRepo.save(task); - task.getDependentTasks().forEach(dependent -> updateState(dependent)); + task + .getBlockedTasks() + .stream() + .map(TaskDependency::getBlockedTask) + .forEach(this::updateState); } /** @@ -276,6 +340,9 @@ public class TaskManager { * @param task */ protected void updateState(final Task task) { + + Objects.requireNonNull(task); + LOGGER.debug("Updating state for task {}...", Objects.toString(task)); @@ -285,11 +352,13 @@ public class TaskManager { return; } - for (final Task dependsOnTask : task.getDependsOn()) { + for (final TaskDependency blockingTaskDependency : task.getBlockingTasks()) { + + final Task blockingTask = blockingTaskDependency.getBlockingTask(); LOGGER.debug("Checking dependency {}...", - Objects.toString(dependsOnTask)); - if (dependsOnTask.getTaskState() != TaskState.FINISHED - && dependsOnTask.isActive()) { + Objects.toString(blockingTask)); + if (blockingTask.getTaskState() != TaskState.FINISHED + && blockingTask.isActive()) { LOGGER.debug("Dependency is not yet satisfied."); diff --git a/ccm-core/src/main/java/org/libreccm/workflow/WorkflowManager.java b/ccm-core/src/main/java/org/libreccm/workflow/WorkflowManager.java index b5059293a..9bc39f725 100644 --- a/ccm-core/src/main/java/org/libreccm/workflow/WorkflowManager.java +++ b/ccm-core/src/main/java/org/libreccm/workflow/WorkflowManager.java @@ -26,6 +26,7 @@ import org.apache.shiro.subject.Subject; import org.libreccm.configuration.ConfigurationManager; import org.libreccm.core.CcmObject; import org.libreccm.core.CoreConstants; +import org.libreccm.core.UnexpectedErrorException; import org.libreccm.l10n.LocalizedString; import org.libreccm.security.AuthorizationRequired; import org.libreccm.security.RequiresPrivilege; @@ -54,7 +55,6 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; - /** * Manager for {@link Workflow}s. The logic of some of these classes has been * ported from the workflow implementation. The methods have only been edited to @@ -128,9 +128,9 @@ public class WorkflowManager { "The provided template is not an abstract workflow"); } - Objects.requireNonNull(object, + Objects.requireNonNull(object, "Can't create a workflow without an object."); - + final Workflow workflow = new Workflow(); final LocalizedString name = new LocalizedString(); @@ -267,17 +267,48 @@ public class WorkflowManager { private void fixTaskDependencies(final Task template, final Task task, final Map tasks) { - if (template.getDependentTasks() != null - && !template.getDependentTasks().isEmpty()) { - template.getDependentTasks().forEach(dependent - -> task.addDependentTask(tasks.get(dependent.getTaskId()))); + + if (template.getBlockedTasks() != null + && !template.getBlockedTasks().isEmpty()) { + + for (final TaskDependency blocked : template.getBlockedTasks()) { + + final Task blockingTask = tasks + .get(blocked.getBlockingTask().getTaskId()); + final Task blockedTask = tasks + .get(blocked.getBlockedTask().getTaskId()); + try { + taskManager.addDependentTask(blockingTask, blockedTask); + } catch (CircularTaskDependencyException ex) { + throw new UnexpectedErrorException(ex); + } + } } - if (template.getDependsOn() != null - && !template.getDependsOn().isEmpty()) { - template.getDependsOn().forEach(dependsOn - -> task.addDependsOn(tasks.get(dependsOn.getTaskId()))); +// if (template.getDependentTasks() != null +// && !template.getDependentTasks().isEmpty()) { +// template.getDependentTasks().forEach(dependent +// -> task.addDependentTask(tasks.get(dependent.getTaskId()))); +// } + for (final TaskDependency blocking : template.getBlockingTasks()) { + + final Task blockingTask = tasks + .get(blocking.getBlockingTask().getTaskId()); + final Task blockedTask = tasks + .get(blocking.getBlockedTask().getTaskId()); + try { + taskManager.addDependentTask(blockingTask, blockedTask); + } catch(CircularTaskDependencyException ex) { + throw new UnexpectedErrorException(ex); + } + } + +// if (template.getDependsOn() != null +// && !template.getDependsOn().isEmpty()) { +// template.getDependsOn().forEach(dependsOn +// -> task.addDependsOn(tasks.get(dependsOn.getTaskId()))); +// } } /** diff --git a/ccm-core/src/main/resources/db/migrations/org/libreccm/ccm_core/h2/V7_0_0_18__add_task_dependency.sql b/ccm-core/src/main/resources/db/migrations/org/libreccm/ccm_core/h2/V7_0_0_18__add_task_dependency.sql new file mode 100644 index 000000000..f73fa460c --- /dev/null +++ b/ccm-core/src/main/resources/db/migrations/org/libreccm/ccm_core/h2/V7_0_0_18__add_task_dependency.sql @@ -0,0 +1,39 @@ +alter table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES + drop constraint if exists FK1htp420ki24jaswtcum56iawe; + +alter table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES + drop constraint if exists FK8rbggnp4yjpab8quvvx800ymy; + +create table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES_ ( + TASK_DEPENDENCY_ID bigint, + BLOCKED_TASK_ID bigint, + BLOCKING_TASK_ID bigint +); + +insert into CCM_CORE.WORKFLOW_TASK_DEPENDENCIES_ (BLOCKED_TASK_ID, BLOCKING_TASK_ID) + (select DEPENDENT_TASK_ID, DEPENDS_ON_TASK_ID + from CCM_CORE.WORKFLOW_TASK_DEPENDENCIES); + +update CCM_CORE.WORKFLOW_TASK_DEPENDENCIES_ + set TASK_DEPENDENCY_ID = nextval('hibernate_sequence'); + +alter table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES_ + alter column TASK_DEPENDENCY_ID set not null; + +alter table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES_ + add primary key(TASK_DEPENDENCY_ID); + +drop table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES; + +alter table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES_ + rename to CCM_CORE.WORKFLOW_TASK_DEPENDENCIES; + +alter table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES + add constraint FKci4hwj0evq82m4nyvux1bwc73 + foreign key (BLOCKED_TASK_ID) + references CCM_CORE.WORKFLOW_TASKS; + +alter table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES + add constraint FKkmrbcm2fbbrb43l5j7supp7eg + foreign key (BLOCKING_TASK_ID) + references CCM_CORE.WORKFLOW_TASKS; diff --git a/ccm-core/src/main/resources/db/migrations/org/libreccm/ccm_core/pgsql/V7_0_0_18__add_task_dependency.sql b/ccm-core/src/main/resources/db/migrations/org/libreccm/ccm_core/pgsql/V7_0_0_18__add_task_dependency.sql new file mode 100644 index 000000000..50c10ea1d --- /dev/null +++ b/ccm-core/src/main/resources/db/migrations/org/libreccm/ccm_core/pgsql/V7_0_0_18__add_task_dependency.sql @@ -0,0 +1,39 @@ +alter table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES + drop constraint if exists FK1htp420ki24jaswtcum56iawe; + +alter table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES + drop constraint if exists FK8rbggnp4yjpab8quvvx800ymy; + +create table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES_ ( + TASK_DEPENDENCY_ID bigint, + BLOCKED_TASK_ID bigint, + BLOCKING_TASK_ID bigint +); + +insert into CCM_CORE.WORKFLOW_TASK_DEPENDENCIES_ (BLOCKED_TASK_ID, BLOCKING_TASK_ID) + (select DEPENDENT_TASK_ID, DEPENDS_ON_TASK_ID + from CCM_CORE.WORKFLOW_TASK_DEPENDENCIES); + +update CCM_CORE.WORKFLOW_TASK_DEPENDENCIES_ + set TASK_DEPENDENCY_ID = nextval('hibernate_sequence'); + +alter table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES_ + alter column TASK_DEPENDENCY_ID set not null; + +alter table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES_ + add primary key(TASK_DEPENDENCY_ID); + +drop table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES; + +alter table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES_ + rename to WORKFLOW_TASK_DEPENDENCIES; + +alter table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES + add constraint FKci4hwj0evq82m4nyvux1bwc73 + foreign key (BLOCKED_TASK_ID) + references CCM_CORE.WORKFLOW_TASKS; + +alter table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES + add constraint FKkmrbcm2fbbrb43l5j7supp7eg + foreign key (BLOCKING_TASK_ID) + references CCM_CORE.WORKFLOW_TASKS; diff --git a/ccm-core/src/test/resources-wildfly-remote-h2-mem/scripts/create_ccm_core_schema.sql b/ccm-core/src/test/resources-wildfly-remote-h2-mem/scripts/create_ccm_core_schema.sql index 4504a9d29..051b92d3a 100644 --- a/ccm-core/src/test/resources-wildfly-remote-h2-mem/scripts/create_ccm_core_schema.sql +++ b/ccm-core/src/test/resources-wildfly-remote-h2-mem/scripts/create_ccm_core_schema.sql @@ -2,6 +2,7 @@ drop schema if exists CCM_CORE; drop sequence if exists HIBERNATE_SEQUENCE; + create schema CCM_CORE; create table CCM_CORE.APPLICATIONS ( @@ -530,10 +531,10 @@ drop sequence if exists HIBERNATE_SEQUENCE; CONFIGURATION_CLASS varchar(512) not null, NAME varchar(512) not null, SETTING_VALUE_STRING varchar(1024), - SETTING_VALUE_BOOLEAN boolean, SETTING_VALUE_DOUBLE double, - SETTING_VALUE_BIG_DECIMAL decimal(19,2), SETTING_VALUE_LONG bigint, + SETTING_VALUE_BOOLEAN boolean, + SETTING_VALUE_BIG_DECIMAL decimal(19,2), primary key (SETTING_ID) ); @@ -636,8 +637,10 @@ drop sequence if exists HIBERNATE_SEQUENCE; ); create table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES ( - DEPENDS_ON_TASK_ID bigint not null, - DEPENDENT_TASK_ID bigint not null + TASK_DEPENDENCY_ID bigint not null, + BLOCKED_TASK_ID bigint, + BLOCKING_TASK_ID bigint, + primary key (TASK_DEPENDENCY_ID) ); create table CCM_CORE.WORKFLOW_TASK_DESCRIPTIONS ( @@ -1203,13 +1206,13 @@ drop sequence if exists HIBERNATE_SEQUENCE; references CCM_CORE.WORKFLOW_TASKS; alter table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES - add constraint FK1htp420ki24jaswtcum56iawe - foreign key (DEPENDENT_TASK_ID) + add constraint FKy88tppv7ihx0lsn6g64f5lfq + foreign key (BLOCKED_TASK_ID) references CCM_CORE.WORKFLOW_TASKS; alter table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES - add constraint FK8rbggnp4yjpab8quvvx800ymy - foreign key (DEPENDS_ON_TASK_ID) + add constraint FKrj80uilojn73u9a4xgk3vt0cj + foreign key (BLOCKING_TASK_ID) references CCM_CORE.WORKFLOW_TASKS; alter table CCM_CORE.WORKFLOW_TASK_DESCRIPTIONS diff --git a/ccm-core/src/test/resources-wildfly-remote-pgsql/scripts/create_ccm_core_schema.sql b/ccm-core/src/test/resources-wildfly-remote-pgsql/scripts/create_ccm_core_schema.sql index 412668b40..0e42defde 100644 --- a/ccm-core/src/test/resources-wildfly-remote-pgsql/scripts/create_ccm_core_schema.sql +++ b/ccm-core/src/test/resources-wildfly-remote-pgsql/scripts/create_ccm_core_schema.sql @@ -2,6 +2,8 @@ drop schema if exists CCM_CORE cascade; drop sequence if exists HIBERNATE_SEQUENCE; + + create schema CCM_CORE; create table CCM_CORE.APPLICATIONS ( @@ -530,10 +532,10 @@ drop sequence if exists HIBERNATE_SEQUENCE; CONFIGURATION_CLASS varchar(512) not null, NAME varchar(512) not null, SETTING_VALUE_STRING varchar(1024), - SETTING_VALUE_BOOLEAN boolean, SETTING_VALUE_DOUBLE float8, - SETTING_VALUE_BIG_DECIMAL numeric(19, 2), SETTING_VALUE_LONG int8, + SETTING_VALUE_BOOLEAN boolean, + SETTING_VALUE_BIG_DECIMAL numeric(19, 2), primary key (SETTING_ID) ); @@ -636,8 +638,10 @@ drop sequence if exists HIBERNATE_SEQUENCE; ); create table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES ( - DEPENDS_ON_TASK_ID int8 not null, - DEPENDENT_TASK_ID int8 not null + TASK_DEPENDENCY_ID int8 not null, + BLOCKED_TASK_ID int8, + BLOCKING_TASK_ID int8, + primary key (TASK_DEPENDENCY_ID) ); create table CCM_CORE.WORKFLOW_TASK_DESCRIPTIONS ( @@ -1203,13 +1207,13 @@ drop sequence if exists HIBERNATE_SEQUENCE; references CCM_CORE.WORKFLOW_TASKS; alter table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES - add constraint FK1htp420ki24jaswtcum56iawe - foreign key (DEPENDENT_TASK_ID) + add constraint FKy88tppv7ihx0lsn6g64f5lfq + foreign key (BLOCKED_TASK_ID) references CCM_CORE.WORKFLOW_TASKS; alter table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES - add constraint FK8rbggnp4yjpab8quvvx800ymy - foreign key (DEPENDS_ON_TASK_ID) + add constraint FKrj80uilojn73u9a4xgk3vt0cj + foreign key (BLOCKING_TASK_ID) references CCM_CORE.WORKFLOW_TASKS; alter table CCM_CORE.WORKFLOW_TASK_DESCRIPTIONS diff --git a/ccm-shortcuts/pom.xml b/ccm-shortcuts/pom.xml index 0a127e0e8..f4fa41a4d 100644 --- a/ccm-shortcuts/pom.xml +++ b/ccm-shortcuts/pom.xml @@ -312,9 +312,9 @@ com.github.spotbugs spotbugs-maven-plugin 3.1.0-RC8 - + diff --git a/ccm-shortcuts/src/test/resources-wildfly-remote-h2-mem/scripts/create_ccm_shortcuts_schema.sql b/ccm-shortcuts/src/test/resources-wildfly-remote-h2-mem/scripts/create_ccm_shortcuts_schema.sql index 79d21a5df..72fb9bce8 100644 --- a/ccm-shortcuts/src/test/resources-wildfly-remote-h2-mem/scripts/create_ccm_shortcuts_schema.sql +++ b/ccm-shortcuts/src/test/resources-wildfly-remote-h2-mem/scripts/create_ccm_shortcuts_schema.sql @@ -3,8 +3,10 @@ DROP SCHEMA IF EXISTS ccm_core; DROP SEQUENCE IF EXISTS hibernate_sequence; -CREATE SCHEMA ccm_core; -CREATE SCHEMA ccm_shortcuts; + + create schema CCM_CORE; + + create schema CCM_SHORTCUTS; create table CCM_CORE.APPLICATIONS ( APPLICATION_TYPE varchar(1024) not null, @@ -530,10 +532,10 @@ CREATE SCHEMA ccm_shortcuts; SETTING_ID bigint not null, CONFIGURATION_CLASS varchar(512) not null, NAME varchar(512) not null, - SETTING_VALUE_DOUBLE double, SETTING_VALUE_STRING varchar(1024), - SETTING_VALUE_BOOLEAN boolean, + SETTING_VALUE_DOUBLE double, SETTING_VALUE_LONG bigint, + SETTING_VALUE_BOOLEAN boolean, SETTING_VALUE_BIG_DECIMAL decimal(19,2), primary key (SETTING_ID) ); @@ -555,6 +557,20 @@ CREATE SCHEMA ccm_shortcuts; value varchar(255) ); + create table CCM_CORE.SITE_AWARE_APPLICATIONS ( + OBJECT_ID bigint not null, + SITE_ID bigint, + primary key (OBJECT_ID) + ); + + create table CCM_CORE.SITES ( + DEFAULT_SITE boolean, + DEFAULT_THEME varchar(255), + DOMAIN_OF_SITE varchar(255), + OBJECT_ID bigint not null, + primary key (OBJECT_ID) + ); + create table CCM_CORE.THREADS ( OBJECT_ID bigint not null, ROOT_ID bigint, @@ -623,8 +639,10 @@ CREATE SCHEMA ccm_shortcuts; ); create table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES ( - DEPENDS_ON_TASK_ID bigint not null, - DEPENDENT_TASK_ID bigint not null + TASK_DEPENDENCY_ID bigint not null, + BLOCKED_TASK_ID bigint, + BLOCKING_TASK_ID bigint, + primary key (TASK_DEPENDENCY_ID) ); create table CCM_CORE.WORKFLOW_TASK_DESCRIPTIONS ( @@ -680,6 +698,9 @@ CREATE SCHEMA ccm_shortcuts; alter table CCM_CORE.SETTINGS add constraint UK5whinfxdaepqs09e5ia9y71uk unique (CONFIGURATION_CLASS, NAME); + alter table CCM_CORE.SITES + add constraint UK_kou1h4y4st2m173he44yy8grx unique (DOMAIN_OF_SITE); + alter table CCM_CORE.WORKFLOW_TASK_COMMENTS add constraint UK_4nnedf08odyjxalfkg16fmjoi unique (UUID); @@ -1111,6 +1132,21 @@ CREATE SCHEMA ccm_shortcuts; foreign key (LIST_ID) references CCM_CORE.SETTINGS; + alter table CCM_CORE.SITE_AWARE_APPLICATIONS + add constraint FKopo91c29jaunpcusjwlphhxkd + foreign key (SITE_ID) + references CCM_CORE.SITES; + + alter table CCM_CORE.SITE_AWARE_APPLICATIONS + add constraint FKslbu2qagg23dmdu01lun7oh7x + foreign key (OBJECT_ID) + references CCM_CORE.APPLICATIONS; + + alter table CCM_CORE.SITES + add constraint FKrca95c6p023men53b8ayu26kp + foreign key (OBJECT_ID) + references CCM_CORE.CCM_OBJECTS; + alter table CCM_CORE.THREADS add constraint FKsx08mpwvwnw97uwdgjs76q39g foreign key (ROOT_ID) @@ -1177,13 +1213,13 @@ CREATE SCHEMA ccm_shortcuts; references CCM_CORE.WORKFLOW_TASKS; alter table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES - add constraint FK1htp420ki24jaswtcum56iawe - foreign key (DEPENDENT_TASK_ID) + add constraint FKy88tppv7ihx0lsn6g64f5lfq + foreign key (BLOCKED_TASK_ID) references CCM_CORE.WORKFLOW_TASKS; alter table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES - add constraint FK8rbggnp4yjpab8quvvx800ymy - foreign key (DEPENDS_ON_TASK_ID) + add constraint FKrj80uilojn73u9a4xgk3vt0cj + foreign key (BLOCKING_TASK_ID) references CCM_CORE.WORKFLOW_TASKS; alter table CCM_CORE.WORKFLOW_TASK_DESCRIPTIONS diff --git a/ccm-shortcuts/src/test/resources-wildfly-remote-pgsql/scripts/create_ccm_shortcuts_schema.sql b/ccm-shortcuts/src/test/resources-wildfly-remote-pgsql/scripts/create_ccm_shortcuts_schema.sql index 8201effaa..76a83b5a8 100644 --- a/ccm-shortcuts/src/test/resources-wildfly-remote-pgsql/scripts/create_ccm_shortcuts_schema.sql +++ b/ccm-shortcuts/src/test/resources-wildfly-remote-pgsql/scripts/create_ccm_shortcuts_schema.sql @@ -3,10 +3,12 @@ DROP SCHEMA IF EXISTS ccm_core CASCADE; DROP SEQUENCE IF EXISTS hibernate_sequence; -CREATE SCHEMA ccm_core; -CREATE SCHEMA ccm_shortcuts; -create table CCM_CORE.APPLICATIONS ( + create schema CCM_CORE; + + create schema CCM_SHORTCUTS; + + create table CCM_CORE.APPLICATIONS ( APPLICATION_TYPE varchar(1024) not null, PRIMARY_URL varchar(1024) not null, OBJECT_ID int8 not null, @@ -530,10 +532,10 @@ create table CCM_CORE.APPLICATIONS ( SETTING_ID int8 not null, CONFIGURATION_CLASS varchar(512) not null, NAME varchar(512) not null, - SETTING_VALUE_DOUBLE float8, SETTING_VALUE_STRING varchar(1024), - SETTING_VALUE_BOOLEAN boolean, + SETTING_VALUE_DOUBLE float8, SETTING_VALUE_LONG int8, + SETTING_VALUE_BOOLEAN boolean, SETTING_VALUE_BIG_DECIMAL numeric(19, 2), primary key (SETTING_ID) ); @@ -555,6 +557,20 @@ create table CCM_CORE.APPLICATIONS ( value varchar(255) ); + create table CCM_CORE.SITE_AWARE_APPLICATIONS ( + OBJECT_ID int8 not null, + SITE_ID int8, + primary key (OBJECT_ID) + ); + + create table CCM_CORE.SITES ( + DEFAULT_SITE boolean, + DEFAULT_THEME varchar(255), + DOMAIN_OF_SITE varchar(255), + OBJECT_ID int8 not null, + primary key (OBJECT_ID) + ); + create table CCM_CORE.THREADS ( OBJECT_ID int8 not null, ROOT_ID int8, @@ -623,8 +639,10 @@ create table CCM_CORE.APPLICATIONS ( ); create table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES ( - DEPENDS_ON_TASK_ID int8 not null, - DEPENDENT_TASK_ID int8 not null + TASK_DEPENDENCY_ID int8 not null, + BLOCKED_TASK_ID int8, + BLOCKING_TASK_ID int8, + primary key (TASK_DEPENDENCY_ID) ); create table CCM_CORE.WORKFLOW_TASK_DESCRIPTIONS ( @@ -680,6 +698,9 @@ create table CCM_CORE.APPLICATIONS ( alter table CCM_CORE.SETTINGS add constraint UK5whinfxdaepqs09e5ia9y71uk unique (CONFIGURATION_CLASS, NAME); + alter table CCM_CORE.SITES + add constraint UK_kou1h4y4st2m173he44yy8grx unique (DOMAIN_OF_SITE); + alter table CCM_CORE.WORKFLOW_TASK_COMMENTS add constraint UK_4nnedf08odyjxalfkg16fmjoi unique (UUID); @@ -1111,6 +1132,21 @@ create table CCM_CORE.APPLICATIONS ( foreign key (LIST_ID) references CCM_CORE.SETTINGS; + alter table CCM_CORE.SITE_AWARE_APPLICATIONS + add constraint FKopo91c29jaunpcusjwlphhxkd + foreign key (SITE_ID) + references CCM_CORE.SITES; + + alter table CCM_CORE.SITE_AWARE_APPLICATIONS + add constraint FKslbu2qagg23dmdu01lun7oh7x + foreign key (OBJECT_ID) + references CCM_CORE.APPLICATIONS; + + alter table CCM_CORE.SITES + add constraint FKrca95c6p023men53b8ayu26kp + foreign key (OBJECT_ID) + references CCM_CORE.CCM_OBJECTS; + alter table CCM_CORE.THREADS add constraint FKsx08mpwvwnw97uwdgjs76q39g foreign key (ROOT_ID) @@ -1177,13 +1213,13 @@ create table CCM_CORE.APPLICATIONS ( references CCM_CORE.WORKFLOW_TASKS; alter table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES - add constraint FK1htp420ki24jaswtcum56iawe - foreign key (DEPENDENT_TASK_ID) + add constraint FKy88tppv7ihx0lsn6g64f5lfq + foreign key (BLOCKED_TASK_ID) references CCM_CORE.WORKFLOW_TASKS; alter table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES - add constraint FK8rbggnp4yjpab8quvvx800ymy - foreign key (DEPENDS_ON_TASK_ID) + add constraint FKrj80uilojn73u9a4xgk3vt0cj + foreign key (BLOCKING_TASK_ID) references CCM_CORE.WORKFLOW_TASKS; alter table CCM_CORE.WORKFLOW_TASK_DESCRIPTIONS