CCM NG/ccm-cms: Workflow tab

git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4626 8810af33-2d31-482b-a856-94f89814c4df
jensp 2017-03-13 19:13:08 +00:00
parent 45f9e5bda0
commit 96b150582c
9 changed files with 210 additions and 74 deletions

View File

@ -293,10 +293,9 @@ abstract class BaseWorkflowItemPane extends BaseItemPane {
}
// XXX Fix this.
private static final String[] s_columns = new String[]{
lz("cms.ui.name"),
lz("cms.ui.description"),
private static final String[] COLUMNS = new String[]{
lz("cms.ui.workflow.task.name"),
lz("cms.ui.workflow.task.description"),
lz("cms.ui.workflow.task.dependencies"),
lz("cms.ui.workflow.task.state")
};
@ -304,7 +303,7 @@ abstract class BaseWorkflowItemPane extends BaseItemPane {
private class TaskTable extends Table {
public TaskTable() {
super(new TaskTableModelBuilder(workflowRequestLocal), s_columns);
super(new TaskTableModelBuilder(workflowRequestLocal), COLUMNS);
setEmptyView(new Label(gz("cms.ui.workflow.task.none")));

View File

@ -440,9 +440,11 @@ final class TaskItemPane extends BaseItemPane {
private int index = -1;
private Model(final CmsTask task) {
roles = task.getAssignments().stream()
.map(assignment -> assignment.getRole())
.collect(Collectors.toList());
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final WorkflowAdminPaneController controller = cdiUtil.findBean(
WorkflowAdminPaneController.class);
roles = controller.findAssignees(task);
}
@Override

View File

@ -22,32 +22,29 @@ import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.Table;
import com.arsdigita.bebop.table.AbstractTableModelBuilder;
import com.arsdigita.bebop.table.TableModel;
import com.arsdigita.util.Assert;
import com.arsdigita.util.GraphSet;
import com.arsdigita.util.Graphs;
import com.arsdigita.kernel.KernelConfig;
import org.apache.logging.log4j.LogManager;
import org.libreccm.workflow.Task;
import org.libreccm.workflow.Workflow;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.logging.log4j.Logger;
import org.libreccm.cdi.utils.CdiUtil;
import java.util.Locale;
class TaskTableModelBuilder extends AbstractTableModelBuilder {
private static final Logger LOGGER = LogManager.getLogger(
TaskTableModelBuilder.class);
private final WorkflowRequestLocal m_workflow;
private final WorkflowRequestLocal workflow;
TaskTableModelBuilder(final WorkflowRequestLocal workflow) {
m_workflow = workflow;
this.workflow = workflow;
}
@Override
@ -55,14 +52,14 @@ class TaskTableModelBuilder extends AbstractTableModelBuilder {
final PageState state) {
LOGGER.debug("Creating a new table model for the current request");
return new Model(m_workflow.getWorkflow(state));
return new Model(workflow.getWorkflow(state));
}
private static class Model implements TableModel {
private Task m_task;
private Iterator m_tasks;
private Map m_dependencies = new HashMap();
private Task currentTask;
private Iterator<Task> tasksIterator;
private Map<Task, String> dependencies;
private Model(final Workflow workflow) {
@ -70,46 +67,54 @@ class TaskTableModelBuilder extends AbstractTableModelBuilder {
final WorkflowAdminPaneController controller = cdiUtil.findBean(
WorkflowAdminPaneController.class);
final Iterator<Task> tasksIter = controller
.getTasksForWorkflow(workflow)
.iterator();
GraphSet g = new GraphSet();
final TaskTableModelData data = controller
.getTaskTableModelData(workflow);
tasksIterator = data.getTasks();
dependencies = data.getDependencies();
while (tasksIter.hasNext()) {
Task t = tasksIter.next();
final Iterator<Task> deps = t.getDependsOn().iterator();
final StringBuffer buffer = new StringBuffer();
while (deps.hasNext()) {
Task dep = deps.next();
g.addEdge(t, dep, null);
buffer.append(dep.getLabel() + ", ");
}
final int len = buffer.length();
if (len >= 2) {
buffer.setLength(len - 2);
} else {
g.addNode(t);
}
m_dependencies.put(t, buffer.toString());
}
List tasks = new ArrayList();
outer:
while (g.nodeCount() > 0) {
List l = Graphs.getSinkNodes(g);
for (Iterator it = l.iterator(); it.hasNext();) {
Task t = (Task) it.next();
tasks.add(t);
g.removeNode(t);
continue outer;
}
// break loop if no nodes removed
LOGGER.error("found possible loop in tasks for " + workflow);
break;
}
m_tasks = tasks.iterator();
// final Iterator<Task> tasksIter = controller
// .getTasksForWorkflow(workflow)
// .iterator();
// GraphSet graphSet = new GraphSet();
//
// while (tasksIter.hasNext()) {
// Task task = tasksIter.next();
// final Iterator<Task> deps = task.getDependsOn().iterator();
// final StringBuffer buffer = new StringBuffer();
// while (deps.hasNext()) {
// Task dep = deps.next();
// graphSet.addEdge(task, dep, null);
// buffer
// .append(dep.getLabel())
// .append(", ");
// }
//
// final int len = buffer.length();
// if (len >= 2) {
// buffer.setLength(len - 2);
// } else {
// graphSet.addNode(task);
// }
// m_dependencies.put(task, buffer.toString());
// }
//
// List tasks = new ArrayList();
// outer:
// while (graphSet.nodeCount() > 0) {
// List list = Graphs.getSinkNodes(graphSet);
// for (Iterator it = list.iterator(); it.hasNext();) {
// Task t = (Task) it.next();
// tasks.add(t);
// graphSet.removeNode(t);
// continue outer;
// }
// // break loop if no nodes removed
// LOGGER.error("found possible loop in tasks for " + workflow);
// break;
// }
//
// m_tasks = tasks.iterator();
}
@Override
@ -119,8 +124,8 @@ class TaskTableModelBuilder extends AbstractTableModelBuilder {
@Override
public final boolean nextRow() {
if (m_tasks.hasNext()) {
m_task = (Task) m_tasks.next();
if (tasksIterator.hasNext()) {
currentTask = tasksIterator.next();
return true;
} else {
return false;
@ -129,18 +134,20 @@ class TaskTableModelBuilder extends AbstractTableModelBuilder {
@Override
public final Object getKeyAt(final int column) {
return m_task.getTaskId();
return currentTask.getTaskId();
}
@Override
public final Object getElementAt(final int column) {
final Locale defaultLocale = KernelConfig.getConfig().getDefaultLocale();
switch (column) {
case 0:
return m_task.getLabel();
return currentTask.getLabel().getValue(defaultLocale);
case 1:
return m_task.getDescription();
return currentTask.getDescription().getValue(defaultLocale);
case 2:
return m_dependencies.get(m_task);
return dependencies.get(currentTask);
case 3:
return "";
// return m_task.getStateString();

View File

@ -0,0 +1,51 @@
/*
* 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 com.arsdigita.cms.ui.workflow;
import org.libreccm.workflow.Task;
import java.util.Iterator;
import java.util.Map;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
class TaskTableModelData {
private final Iterator<Task> tasks;
private final Map<Task, String> dependencies;
protected TaskTableModelData(final Iterator<Task> tasks,
final Map<Task, String> dependencies) {
this.tasks = tasks;
this.dependencies = dependencies;
}
public Iterator<Task> getTasks() {
return tasks;
}
public Map<Task, String> getDependencies() {
return dependencies;
}
}

View File

@ -19,10 +19,15 @@
package com.arsdigita.cms.ui.workflow;
import com.arsdigita.kernel.KernelConfig;
import com.arsdigita.util.GraphSet;
import com.arsdigita.util.Graphs;
import com.arsdigita.util.UncheckedWrapperException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.configuration.ConfigurationManager;
import org.libreccm.security.Role;
import org.libreccm.workflow.CircularTaskDependencyException;
import org.libreccm.workflow.Task;
import org.libreccm.workflow.TaskManager;
@ -40,6 +45,7 @@ import org.librecms.workflow.CmsTaskType;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@ -56,6 +62,9 @@ import javax.transaction.Transactional;
@RequestScoped
public class WorkflowAdminPaneController {
private static final Logger LOGGER = LogManager
.getLogger(WorkflowAdminPaneController.class);
@Inject
private ConfigurationManager confManager;
@ -215,4 +224,69 @@ public class WorkflowAdminPaneController {
return new ArrayList<>(theTask.getDependsOn());
}
@Transactional(Transactional.TxType.REQUIRED)
TaskTableModelData getTaskTableModelData(final Workflow workflow) {
final Map<Task, String> dependencies = new HashMap<>();
final Iterator<Task> tasksIter = getTasksForWorkflow(workflow)
.iterator();
final GraphSet graphSet = new GraphSet();
while (tasksIter.hasNext()) {
Task task = tasksIter.next();
final Iterator<Task> deps = task.getDependsOn().iterator();
final StringBuffer buffer = new StringBuffer();
while (deps.hasNext()) {
Task dep = deps.next();
graphSet.addEdge(task, dep, null);
buffer
.append(dep.getLabel())
.append(", ");
}
final int len = buffer.length();
if (len >= 2) {
buffer.setLength(len - 2);
} else {
graphSet.addNode(task);
}
dependencies.put(task, buffer.toString());
}
final List<Task> tasks = new ArrayList<>();
outer:
while (graphSet.nodeCount() > 0) {
@SuppressWarnings("unchecked")
final List<Task> list = Graphs.getSinkNodes(graphSet);
for (final Iterator<Task> it = list.iterator(); it.hasNext();) {
final Task currentTask = it.next();
tasks.add(currentTask);
graphSet.removeNode(currentTask);
continue outer;
}
// break loop if no nodes removed
LOGGER.error("found possible loop in tasks for " + workflow);
break;
}
final Iterator<Task> taskIterator = tasks.iterator();
return new TaskTableModelData(taskIterator, dependencies);
}
@Transactional(Transactional.TxType.REQUIRED)
public List<Role> findAssignees(final CmsTask task) {
final CmsTask theTask = (CmsTask) taskRepo
.findById(task.getTaskId())
.orElseThrow(() -> new IllegalArgumentException(String.format(
"No Task with ID %d in the database. Where did that ID come from?",
task.getTaskId())));
return theTask
.getAssignments()
.stream()
.map(assignment -> assignment.getRole())
.collect(Collectors.toList());
}
}

View File

@ -165,3 +165,4 @@ cms.ui.workflow.task.dependencies=Dependencies
cms.workflow.task_type.AUTHOR=Author
cms.workflow.task_type.EDIT=Edit
cms.workflow.task_type.DEPLOY=Deploy
cms.ui.workflow.task.state=Status

View File

@ -164,3 +164,4 @@ cms.ui.workflow.task.dependencies=Abh\u00e4ngigkeiten
cms.workflow.task_type.AUTHOR=Verfassen
cms.workflow.task_type.EDIT=Bearbeiten
cms.workflow.task_type.DEPLOY=Ver\u00f6ffentlichen
cms.ui.workflow.task.state=Status

View File

@ -133,3 +133,4 @@ cms.ui.workflow.task.dependencies=Dependencies
cms.workflow.task_type.AUTHOR=Author
cms.workflow.task_type.EDIT=Edit
cms.workflow.task_type.DEPLOY=Deploy
cms.ui.workflow.task.state=Status

View File

@ -189,7 +189,7 @@ public class AssignableTaskManager {
}
final TypedQuery<AssignableTask> query = entityManager.createNamedQuery(
"UserTask.findLockedBy", AssignableTask.class);
"AssignableTask.findLockedBy", AssignableTask.class);
query.setParameter("user", user);
return query.getResultList();