[TRUNK][FEATURE]

- adds association class for tasks dependencies
- adds export capability for task dependencies

git-svn-id: https://svn.libreccm.org/ccm/trunk@5165 8810af33-2d31-482b-a856-94f89814c4df
master
tosmers 2017-12-12 17:43:36 +00:00
parent 6d81102967
commit a0b89a168d
8 changed files with 276 additions and 72 deletions

View File

@ -32,6 +32,7 @@ import com.arsdigita.portation.modules.core.workflow.AssignableTask;
import com.arsdigita.portation.modules.core.workflow.Task;
import com.arsdigita.portation.modules.core.workflow.TaskAssignment;
import com.arsdigita.portation.modules.core.workflow.TaskComment;
import com.arsdigita.portation.modules.core.workflow.TaskDependency;
import com.arsdigita.portation.modules.core.workflow.Workflow;
import java.util.ArrayList;
@ -62,6 +63,7 @@ public class NgCoreCollection {
public static Map<Long, TaskComment> taskComments = new HashMap<>();
public static Map<Long, Task> tasks = new HashMap<>();
public static Map<Long, AssignableTask> assignableTasks = new HashMap<>();
public static Map<Long, TaskDependency> taskDependencies = new HashMap<>();
public static Map<Long, TaskAssignment> taskAssignments = new HashMap<>();
public static Map<Long, Permission> permissions = new HashMap<>();

View File

@ -100,7 +100,8 @@ public class GroupConversion {
if (group != null && member != null) {
// create groupMemeberships
GroupMembership groupMembership = new GroupMembership(group, member);
GroupMembership groupMembership = new GroupMembership(group,
member);
// set opposed associations
group.addMembership(groupMembership);

View File

@ -28,9 +28,9 @@ import com.arsdigita.portation.modules.core.workflow.AssignableTask;
import com.arsdigita.portation.modules.core.workflow.Task;
import com.arsdigita.portation.modules.core.workflow.TaskAssignment;
import com.arsdigita.portation.modules.core.workflow.TaskComment;
import com.arsdigita.portation.modules.core.workflow.TaskDependency;
import com.arsdigita.portation.modules.core.workflow.Workflow;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@ -59,9 +59,9 @@ public class AssignableTaskConversion {
.arsdigita.workflow.simple.UserTask.getAllObjectUserTasks();
System.err.println("done.");
System.err.printf("\tConverting assignable tasks and task assignments...\n");
System.err.printf("\tConverting assignable tasks, task dependencies " +
"and task assignments...\n");
createAssignableTasksAndSetAssociations(trunkUserTasks);
setTaskRingDependencies(trunkUserTasks);
System.err.printf("\tSorting task assignments...\n");
sortAssignableTaskMap();
@ -79,11 +79,13 @@ public class AssignableTaskConversion {
*/
private static void createAssignableTasksAndSetAssociations(List<com.arsdigita
.workflow.simple.UserTask> trunkUserTasks) {
int pTasks = 0, pAssignments = 0;
int pTasks = 0, pAssignments = 0, pDependencies = 0;
for (com.arsdigita.workflow.simple.UserTask trunkUserTask :
trunkUserTasks) {
// TASK STUFF
// create assignableTask
AssignableTask assignableTask = new AssignableTask(trunkUserTask);
@ -101,6 +103,10 @@ public class AssignableTaskConversion {
}
} catch (Exception ignored) {}
// taskDependencies
pDependencies += createTaskDependencies(assignableTask,
trunkUserTask.getDependencies());
// set taskComments
Iterator commentsIt = trunkUserTask.getComments();
while (commentsIt.hasNext()) {
@ -116,6 +122,8 @@ public class AssignableTaskConversion {
}
// ASSIGNABLETASK STUFF
// set lockingUser and notificationSender
if (trunkUserTask.getLockedUser() != null) {
User lockingUser = NgCoreCollection.users.get(trunkUserTask
@ -138,11 +146,57 @@ public class AssignableTaskConversion {
groupCollection);
pTasks++;
/*System.err.printf("\t\tTasks: %d, " +
"Dependencies: %d, " +
"Assignments: %d\n",
pTasks, pDependencies, pAssignments);*/
}
System.err.printf("\t\tCreated %d assignable tasks and\n" +
"\t\tCreated %d task dependencies and\n" +
"\t\tcreated %d task assignments.\n",
pTasks, pAssignments);
pTasks, pDependencies, pAssignments);
}
/**
* Method for recreating the
* ng-{@link com.arsdigita.portation.modules.core.workflow.Task}s ring-like
* dependencies between dependentTask and dependsOn. Because all
* ng-{@link com.arsdigita.portation.modules.core.workflow.Task}s have
* already been created, it is possible e.g. to find the dependsOn-{@code
* Tasks} and bind them for association.
*
* @param assignableTask The {@link AssignableTask}
* @param dependencyIt An iterator representing all dependencies of the
* given assignableTask
*/
private static long createTaskDependencies(AssignableTask assignableTask,
Iterator dependencyIt) {
int processed = 0;
while (dependencyIt.hasNext()) {
AssignableTask dependency = NgCoreCollection
.assignableTasks
.get(((com.arsdigita.workflow.simple
.Task) dependencyIt.next())
.getID()
.longValue());
if (assignableTask != null && dependency != null) {
TaskDependency taskDependency =
new TaskDependency(assignableTask, dependency);
// set opposed associations
assignableTask.addBlockingTask(taskDependency);
dependency.addBlockedTask(taskDependency);
processed++;
}
}
return processed;
}
/**
@ -184,43 +238,6 @@ public class AssignableTaskConversion {
return processed;
}
/**
* Method for recreating the
* ng-{@link com.arsdigita.portation.modules.core.workflow.Task}s ring-like
* dependencies between dependentTask and dependsOn. Because all
* ng-{@link com.arsdigita.portation.modules.core.workflow.Task}s have
* already been created, it is possible e.g. to find the dependsOn-{@code
* Tasks} and bind them for association.
*
* @param trunkUserTasks List of all
* {@link com.arsdigita.workflow.simple.UserTask}s
* from this old trunk-system.
*/
private static void setTaskRingDependencies(List<com.arsdigita.workflow
.simple.UserTask> trunkUserTasks) {
for (com.arsdigita.workflow.simple.UserTask trunkUserTask :
trunkUserTasks) {
AssignableTask assignableTask = NgCoreCollection
.assignableTasks
.get(trunkUserTask.getID().longValue());
Iterator it = trunkUserTask.getDependencies();
while (it.hasNext()) {
AssignableTask dependency = NgCoreCollection
.assignableTasks
.get(((com.arsdigita.workflow.simple
.Task) it.next()).getID().longValue());
if (assignableTask != null && dependency != null) {
// set dependencies and opposed
assignableTask.addDependsOn(dependency);
dependency.addDependentTask(assignableTask);
}
}
}
}
/**
* Sorts values of assignable-task-map to ensure that the dependencies will
* be listed before their dependant tasks in the export file.
@ -258,16 +275,17 @@ public class AssignableTaskConversion {
*/
private static void addDependencies(ArrayList<AssignableTask> sortedList,
AssignableTask assignableTask) {
List<Task> dependencies = assignableTask.getDependsOn();
List<TaskDependency> dependencies = assignableTask.getBlockingTasks();
if (!dependencies.isEmpty()) {
for (Task dependsOnTask : dependencies) {
AssignableTask dependency = (AssignableTask) dependsOnTask;
if (dependency != null) {
addDependencies(sortedList, dependency);
for (TaskDependency dependency : dependencies) {
AssignableTask blockingTask = (AssignableTask) dependency
.getBlockingTask();
if (blockingTask != null) {
addDependencies(sortedList, blockingTask);
if (!sortedList.contains(dependency))
sortedList.add(dependency);
if (!sortedList.contains(blockingTask))
sortedList.add(blockingTask);
}
}
}

View File

@ -51,6 +51,7 @@ public class CoreExporter extends AbstractExporter {
exportWorkflows();
exportTaskComments();
exportAssignableTasks();
exportTaskDependencies();
exportTaskAssignments();
}
@ -171,6 +172,17 @@ public class CoreExporter extends AbstractExporter {
System.out.printf("\tdone.\n");
}
private static void exportTaskDependencies() {
System.out.printf("\tExporting task dependencies...");
TaskDependencyMarshaller taskDependencyMarshaller = new
TaskDependencyMarshaller();
taskDependencyMarshaller.prepare(
Format.XML, pathName, "taskDependencies", indentation);
taskDependencyMarshaller.exportList(
new ArrayList<>(NgCoreCollection.taskDependencies.values()));
System.out.printf("\tdone.\n");
}
private static void exportTaskAssignments() {
System.out.printf("\tExporting task assignments...");
TaskAssignmentMarshaller taskAssignmentMarshaller = new

View File

@ -49,9 +49,9 @@ public class Task {
@JsonIdentityReference(alwaysAsId = true)
private Workflow workflow;
@JsonIgnore
private List<Task> dependentTasks;
@JsonIdentityReference(alwaysAsId = true)
private List<Task> dependsOn;
private List<TaskDependency> blockedTasks;
@JsonIgnore
private List<TaskDependency> blockingTasks;
@JsonIdentityReference(alwaysAsId = true)
private List<TaskComment> comments;
@ -70,8 +70,8 @@ public class Task {
//this.workflow
this.dependentTasks = new ArrayList<>();
this.dependsOn = new ArrayList<>();
this.blockedTasks = new ArrayList<>();
this.blockingTasks = new ArrayList<>();
this.comments = new ArrayList<>();
NgCoreCollection.tasks.put(this.getTaskId(), this);
@ -133,37 +133,36 @@ public class Task {
this.workflow = workflow;
}
public List<Task> getDependentTasks() {
return dependentTasks;
public List<TaskDependency> getBlockedTasks() {
return blockedTasks;
}
public void setDependentTasks(final List<Task> dependentTasks) {
this.dependentTasks = dependentTasks;
public void setBlockedTasks(final List<TaskDependency> blockedTasks) {
this.blockedTasks = blockedTasks;
}
public void addDependentTask(final Task task) {
dependentTasks.add(task);
public void addBlockedTask(final TaskDependency blockedTask) {
this.blockedTasks.add(blockedTask);
}
public void removeDependentTask(final Task task) {
dependentTasks.remove(task);
public void removeBlockedTask(final TaskDependency blockedTask) {
this.blockedTasks.remove(blockedTask);
}
public List<Task> getDependsOn() {
return dependsOn;
public List<TaskDependency> getBlockingTasks() {
return blockingTasks;
}
public void setDependsOn(final List<Task> dependsOn) {
this.dependsOn = dependsOn;
public void setBlockingTasks(final List<TaskDependency> blockingTasks) {
this.blockingTasks = blockingTasks;
}
public void addDependsOn(final Task task) {
dependsOn.add(task);
public void addBlockingTask(final TaskDependency blockingTask) {
this.blockingTasks.add(blockingTask);
}
public void removeDependsOn(final Task task) {
dependsOn.remove(task);
public void removeBlockingTask(final TaskDependency blockingTask) {
this.blockingTasks.remove(blockingTask);
}
public List<TaskComment> getComments() {

View File

@ -0,0 +1,73 @@
/*
* 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 com.arsdigita.portation.modules.core.workflow;
import com.arsdigita.kernel.ACSObject;
import com.arsdigita.portation.Portable;
import com.arsdigita.portation.conversion.NgCoreCollection;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonIdentityReference;
/**
* @author <a href="mailto:tosmers@uni-bremen.de>Tobias Osmers<\a>
* @version created the 12/12/17
*/
@JsonIdentityInfo(generator = TaskDependencyIdGenerator.class,
property = "customDepId")
public class TaskDependency implements Portable {
private long taskDependencyId;
@JsonIdentityReference(alwaysAsId = true)
private Task blockedTask;
@JsonIdentityReference(alwaysAsId = true)
private Task blockingTask;
public TaskDependency(final Task blockedTask, final Task blockingTask) {
this.taskDependencyId = ACSObject.generateID().longValue();
this.blockedTask = blockedTask;
this.blockingTask = blockingTask;
NgCoreCollection.taskDependencies.put(this.taskDependencyId, this);
}
public long getTaskDependencyId() {
return taskDependencyId;
}
public void setTaskDependencyId(long taskDependencyId) {
this.taskDependencyId = taskDependencyId;
}
public Task getBlockedTask() {
return blockedTask;
}
public void setBlockedTask(Task blockedTask) {
this.blockedTask = blockedTask;
}
public Task getBlockingTask() {
return blockingTask;
}
public void setBlockingTask(Task blockingTask) {
this.blockingTask = blockingTask;
}
}

View File

@ -0,0 +1,70 @@
/*
* 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 com.arsdigita.portation.modules.core.workflow;
import com.arsdigita.portation.modules.core.security.GroupMembership;
import com.fasterxml.jackson.annotation.ObjectIdGenerator;
/**
* @author <a href="mailto:tosmers@uni-bremen.de>Tobias Osmers<\a>
* @version created the 12/12/17
*/
public class TaskDependencyIdGenerator extends ObjectIdGenerator<String> {
@Override
public Class<?> getScope() {
return TaskDependency.class;
}
@Override
public boolean canUseFor(final ObjectIdGenerator<?> objectIdGenerator) {
return objectIdGenerator instanceof TaskDependencyIdGenerator;
}
@Override
public ObjectIdGenerator<String> forScope(final Class<?> aClass) {
return this;
}
@Override
public ObjectIdGenerator<String> newForSerialization(final Object o) {
return this;
}
@Override
public IdKey key(Object key) {
if (key == null) {
return null;
}
return new IdKey(TaskDependency.class, TaskDependency.class, key);
}
@Override
public String generateId(Object forPojo) {
if (!(forPojo instanceof TaskDependency)) {
throw new IllegalArgumentException(
"Only TaskDependency instances are supported.");
}
final TaskDependency dependency = (TaskDependency) forPojo;
return String.format("{%s}{%s}",
dependency.getBlockedTask().getUuid(),
dependency.getBlockingTask().getUuid());
}
}

View File

@ -0,0 +1,29 @@
/*
* 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 com.arsdigita.portation.modules.core.workflow;
import com.arsdigita.portation.AbstractMarshaller;
/**
* @author <a href="mailto:tosmers@uni-bremen.de>Tobias Osmers<\a>
* @version created the 12/12/17
*/
public class TaskDependencyMarshaller extends
AbstractMarshaller<TaskDependency> {
}