From ed824be970d5a0bdfaee8a8403a44eac9ad048c3 Mon Sep 17 00:00:00 2001 From: jensp Date: Sat, 3 Sep 2016 15:21:28 +0000 Subject: [PATCH] CCM NG: WorkflowAdminPane ported git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4253 8810af33-2d31-482b-a856-94f89814c4df --- .../cms/ui/ListOptionPrintListener.java | 2 +- .../AssignedTaskTableModelBuilder.java.off | 120 ---------- .../cms/ui/workflow/BaseTaskForm.java | 210 ++++++++++++++++++ ...ane.java.off => BaseWorkflowItemPane.java} | 142 ++++++++---- .../cms/ui/workflow/TaskAddForm.java | 138 ++++++++++++ .../cms/ui/workflow/TaskEditForm.java | 156 +++++++++++++ .../ui/workflow/TaskTableModelBuilder.java | 146 ++++++++++++ ...inPane.java.off => WorkflowAdminPane.java} | 22 +- ...temPane.java.off => WorkflowItemPane.java} | 0 .../workflow/CmsTaskTypeRepository.java | 43 ++++ 10 files changed, 809 insertions(+), 170 deletions(-) delete mode 100755 ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/AssignedTaskTableModelBuilder.java.off create mode 100755 ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/BaseTaskForm.java rename ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/{BaseWorkflowItemPane.java.off => BaseWorkflowItemPane.java} (65%) create mode 100755 ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/TaskAddForm.java create mode 100755 ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/TaskEditForm.java create mode 100755 ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/TaskTableModelBuilder.java rename ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/{WorkflowAdminPane.java.off => WorkflowAdminPane.java} (76%) rename ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/{WorkflowItemPane.java.off => WorkflowItemPane.java} (100%) create mode 100644 ccm-cms/src/main/java/org/librecms/workflow/CmsTaskTypeRepository.java diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/ListOptionPrintListener.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/ListOptionPrintListener.java index f82f39e84..bbf4de74f 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/ListOptionPrintListener.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/ListOptionPrintListener.java @@ -27,7 +27,7 @@ import com.arsdigita.bebop.form.OptionGroup; import java.util.List; /** - * Migrated from the {@code DataQueryPrintListener} in the old system. Renamed + * Migrated from the {@code DataQueryOptionPrintListener} in the old system. Renamed * and refactored to operate on a list. * * @author Jens Pelzetter diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/AssignedTaskTableModelBuilder.java.off b/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/AssignedTaskTableModelBuilder.java.off deleted file mode 100755 index 17a486dcc..000000000 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/AssignedTaskTableModelBuilder.java.off +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved. - * - * The contents of this file are subject to the CCM Public - * License (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the - * License at http://www.redhat.com/licenses/ccmpl.html. - * - * Software distributed under the License is distributed on an - * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express - * or implied. See the License for the specific language - * governing rights and limitations under the License. - * - */ -package com.arsdigita.cms.ui.workflow; - -import com.arsdigita.bebop.Label; -import com.arsdigita.bebop.PageState; -import com.arsdigita.bebop.Table; -import com.arsdigita.bebop.table.AbstractTableModelBuilder; -import com.arsdigita.bebop.table.TableModel; - -import org.librecms.workflow.CmsTask; -import org.librecms.workflow.CmsTaskType; - -import com.arsdigita.globalization.GlobalizedMessage; -import com.arsdigita.util.Assert; -import com.arsdigita.web.Web; - -import org.apache.logging.log4j.LogManager; -import org.libreccm.workflow.Workflow; - -import java.util.Collections; -import java.util.Iterator; - -import org.apache.logging.log4j.Logger; - -/** - * - * - */ -class AssignedTaskTableModelBuilder extends AbstractTableModelBuilder { - - private final WorkflowRequestLocal m_workflow; - - public AssignedTaskTableModelBuilder(final WorkflowRequestLocal workflow) { - m_workflow = workflow; - } - - @Override - public TableModel makeModel(final Table table, final PageState state) { - return new Model(m_workflow.getWorkflow(state)); - } - - private static class Model implements TableModel { - - private final Iterator m_iter; - private CmsTask m_task; - - Model(final Workflow workflow) { - Assert.exists(workflow, Workflow.class); - - if (workflow.getProcessState() == Workflow.STARTED) { - - final Engine engine = Engine.getInstance(CMSEngine.CMS_ENGINE_TYPE); - - Assert.exists(engine, Engine.class); - - m_iter = engine.getEnabledTasks(Web.getWebContext().getUser(), workflow.getID()).iterator(); - } else { - m_iter = Collections.emptyList().iterator(); - } - - } - - @Override - public final int getColumnCount() { - return 3; - } - - @Override - public final boolean nextRow() { - if (m_iter.hasNext()) { - m_task = (CmsTask) m_iter.next(); - - return true; - } else { - return false; - } - } - - public final Object getKeyAt(final int column) { - return m_task.getID(); - } - - public final Object getElementAt(final int column) { - switch (column) { - case 0: - return m_task.getLabel(); - case 1: - // SF patch [ 1587168 ] Show locking user - return m_task.isLocked() ? m_task.getLockedUser() : null; - case 2: - return m_task.getTaskType().getID().equals(CmsTaskType.DEPLOY) - ? (Object) new Label("") : // null should work as well - (Object) lz("cms.ui.workflow.task.finish"); - default: - throw new IllegalStateException(); - } - } - } - - protected final static GlobalizedMessage gz(final String key) { - return GlobalizationUtil.globalize(key); - } - - protected final static String lz(final String key) { - return (String) gz(key).localize(); - } -} 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 new file mode 100755 index 000000000..fdf6cebb0 --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/BaseTaskForm.java @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved. + * + * The contents of this file are subject to the CCM Public + * License (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the + * License at http://www.redhat.com/licenses/ccmpl.html. + * + * Software distributed under the License is distributed on an + * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express + * or implied. See the License for the specific language + * governing rights and limitations under the License. + * + */ +package com.arsdigita.cms.ui.workflow; + +import com.arsdigita.bebop.FormProcessException; +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.event.FormSectionEvent; +import com.arsdigita.bebop.event.FormValidationListener; +import com.arsdigita.bebop.form.CheckboxGroup; +import com.arsdigita.bebop.form.OptionGroup; +import com.arsdigita.bebop.form.SingleSelect; +import com.arsdigita.bebop.form.TextArea; +import com.arsdigita.bebop.form.TextField; +import com.arsdigita.bebop.parameters.IntegerParameter; +import com.arsdigita.cms.ui.BaseForm; +import com.arsdigita.cms.ui.ListOptionPrintListener; + +import org.librecms.workflow.CmsTaskType; + +import com.arsdigita.globalization.GlobalizedMessage; +import com.arsdigita.kernel.KernelConfig; + +import org.apache.logging.log4j.LogManager; +import org.libreccm.workflow.Task; +import org.apache.logging.log4j.Logger; +import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.workflow.TaskRepository; +import org.libreccm.workflow.WorkflowManager; +import org.librecms.CmsConstants; +import org.librecms.workflow.CmsTaskTypeRepository; + +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.TooManyListenersException; + +/** + * @author Jens Pelzetter + * @author Justin Ross + */ +class BaseTaskForm extends BaseForm { + + private static final Logger LOGGER = LogManager + .getLogger(BaseTaskForm.class); + + final WorkflowRequestLocal m_workflow; + + final TextField m_name; + final TextArea m_description; + final OptionGroup m_type; + final OptionGroup m_deps; + + BaseTaskForm(final String key, + final GlobalizedMessage message, + final WorkflowRequestLocal workflow) { + super(key, message); + + m_workflow = workflow; + + m_name = new Name("name", 200, true); + addField(gz("cms.ui.name"), m_name); + + m_type = new SingleSelect(new IntegerParameter("task_type")); + addField(gz("cms.ui.workflow.task.type"), m_type); + + try { + m_type.addPrintListener(new TaskTypePrintListener()); + } catch (TooManyListenersException ex) { + throw new RuntimeException(ex); + } + + m_description = new Description("desc", 4000, true); + addField(gz("cms.ui.description"), m_description); + + m_deps = new CheckboxGroup("dep"); + addField(gz("cms.ui.workflow.task.dependencies"), m_deps); + + addAction(new Finish()); + addAction(new Cancel()); + + addSecurityListener(CmsConstants.PRIVILEGE_ADMINISTER_WORKFLOW); + addValidationListener(new ValidationListener()); + } + + private class ValidationListener implements FormValidationListener { + + @Override + public final void validate(final FormSectionEvent e) + throws FormProcessException { + final String name = (String) m_name.getValue(e.getPageState()); + + // XXX do a dupe check here ala commented out code below + } + + } + + /* + protected void addValidationListener() { + addValidationListener(new DataQueryExistsListener(ERROR_MSG) { + private final String QUERY_NAME = + "com.arsdigita.workflow.simple.getTasks"; + + public void validate(FormSectionEvent event) + throws FormProcessException { + String name = (String) m_name.getValue(event.getPageState()); + if ( name != null ) { + super.validate(event); + } else { + // Do nothing. Let the NotNullValidationListener fire. + } + } + + public DataQuery getDataQuery(FormSectionEvent e) { + PageState s = e.getPageState(); + Session session = SessionManager.getSession(); + DataQuery query = session.retrieveQuery(QUERY_NAME); + Filter f = query.addFilter("lower(taskLabel) = lower(:label)"); + f.set("label", ((String) m_name.getValue(s)).trim()); + Filter parentFilter = query.addFilter("taskParentId = :parent_id"); + parentFilter.set("parent_id", m_processes.getSelectedKey(s)); + Filter itemFilter = query.addNotEqualsFilter + ("taskId", (BigDecimal)m_id.getValue(s)); + + return query; + } + }); + } + */ + // Fix this one too + private class TaskTypePrintListener extends ListOptionPrintListener { + + @Override + protected List getDataQuery(final PageState state) { + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final CmsTaskTypeRepository taskTypeRepo = cdiUtil.findBean( + CmsTaskTypeRepository.class); + + final List taskTypes = taskTypeRepo.findAll(); + + return taskTypes; + + } + + @Override + public String getKey(final CmsTaskType taskType) { + return Long.toString(taskType.getTaskTypeId()); + } + + @Override + public String getValue(final CmsTaskType taskType) { + final KernelConfig kernelConfig = KernelConfig.getConfig(); + final Locale defaultLocale = kernelConfig.getDefaultLocale(); + return taskType.getName().getValue(defaultLocale); + } + + } + + /** + * This method decides which dependencies have to be removed and which ones + * newly added. Unfortunately we cannot just do "remove all", and add the + * new ones in since it is possible that Tasks will fire events when + * dependencies are added and removed. + * + */ + final void processDependencies(final Task task, + final String[] selectedDependencies) { + final List dependencies = task.getDependentTasks(); + final Map toAdd = new HashMap<>(); + final Map toRemove = new HashMap<>(); + + // Everything is to be removed unless it is in the array. + dependencies.forEach(temp -> toRemove.put(temp.getTaskId(), temp)); + + final CdiUtil cdiUtil =CdiUtil.createCdiUtil(); + final TaskRepository taskRepo = cdiUtil.findBean(TaskRepository.class); + final WorkflowManager workflowManager = cdiUtil.findBean(WorkflowManager.class); + + Long selectedId; + Object addedTask; + if (selectedDependencies != null) { + for (String selectedDependency : selectedDependencies) { + selectedId = Long.parseLong(selectedDependency); + addedTask = toRemove.remove(selectedId); + if (addedTask == null) { + toAdd.put(selectedId, taskRepo.findById(selectedId)); + } + } + } + + toRemove.values().forEach(temp -> workflowManager.removeDependentTask( + task, temp)); + + toAdd.values().forEach(temp -> workflowManager.addDependentTask(task, + temp)); + } + +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/BaseWorkflowItemPane.java.off b/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/BaseWorkflowItemPane.java similarity index 65% rename from ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/BaseWorkflowItemPane.java.off rename to ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/BaseWorkflowItemPane.java index 1a450337c..db6f3c030 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/BaseWorkflowItemPane.java.off +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/BaseWorkflowItemPane.java @@ -32,16 +32,29 @@ import com.arsdigita.bebop.table.DefaultTableCellRenderer; import com.arsdigita.cms.ui.BaseDeleteForm; import com.arsdigita.cms.ui.BaseItemPane; import com.arsdigita.cms.ui.VisibilityComponent; +import com.arsdigita.kernel.KernelConfig; + import org.librecms.workflow.CmsTask; import org.libreccm.security.User; + import com.arsdigita.toolbox.ui.ActionGroup; import com.arsdigita.toolbox.ui.PropertyList; import com.arsdigita.toolbox.ui.Section; import com.arsdigita.util.UncheckedWrapperException; import com.arsdigita.web.Web; + +import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.security.Shiro; +import org.libreccm.workflow.Task; +import org.libreccm.workflow.TaskRepository; import org.libreccm.workflow.Workflow; +import org.libreccm.workflow.WorkflowManager; +import org.librecms.CmsConstants; +import org.librecms.workflow.CmsTaskTypeRepository; import java.math.BigDecimal; +import java.util.List; +import java.util.Locale; abstract class BaseWorkflowItemPane extends BaseItemPane { @@ -66,24 +79,23 @@ abstract class BaseWorkflowItemPane extends BaseItemPane { m_detailPane = new SimpleContainer(); // Tasks - final FinishLink taskFinishLink = new FinishLink(); - final ActionLink taskAddLink = new ActionLink - (new Label(gz("cms.ui.workflow.task.add"))); - final TaskAddForm taskAddForm = new TaskAddForm - (m_workflow, m_tasks.getRowSelectionModel()); + final ActionLink taskAddLink = new ActionLink(new Label(gz( + "cms.ui.workflow.task.add"))); + final TaskAddForm taskAddForm = new TaskAddForm(m_workflow, m_tasks + .getRowSelectionModel()); - final ActionLink taskEditLink = new ActionLink - (new Label(gz("cms.ui.workflow.task.edit"))); + final ActionLink taskEditLink = new ActionLink(new Label(gz( + "cms.ui.workflow.task.edit"))); final TaskEditForm taskEditForm = new TaskEditForm(m_workflow, m_task); - final ActionLink taskDeleteLink = new ActionLink - (new Label(gz("cms.ui.workflow.task.delete"))); + final ActionLink taskDeleteLink = new ActionLink(new Label(gz( + "cms.ui.workflow.task.delete"))); final TaskDeleteForm taskDeleteForm = new TaskDeleteForm(); - final ActionLink backLink = new ActionLink - (new Label(gz("cms.ui.workflow.task.return"))); + final ActionLink backLink = new ActionLink(new Label(gz( + "cms.ui.workflow.task.return"))); backLink.addActionListener(new ResetListener()); m_taskPane = new TaskItemPane(m_workflow, m_task, @@ -114,12 +126,15 @@ abstract class BaseWorkflowItemPane extends BaseItemPane { } protected class AdminVisible extends VisibilityComponent { + public AdminVisible(final Component child) { - super(child, SecurityManager.WORKFLOW_ADMIN); + super(child, CmsConstants.PRIVILEGE_ADMINISTER_WORKFLOW); } + } private class FinishLink extends ActionLink { + FinishLink() { super(new Label(gz("cms.ui.workflow.task.finish"))); @@ -127,27 +142,37 @@ abstract class BaseWorkflowItemPane extends BaseItemPane { addActionListener(new ResetListener()); } + @Override public final boolean isVisible(final PageState state) { - CmsTask task = m_task.getTask(state); - User lockingUser = task.getLockedUser(); - boolean visible = task.isEnabled() && - (lockingUser == null || - lockingUser.equals(Web.getWebContext().getUser())); + final CmsTask task = m_task.getTask(state); + final User lockingUser = task.getLockingUser(); + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final Shiro shiro = cdiUtil.findBean(Shiro.class); + final User currentUser = shiro.getUser(); + + boolean visible = task.isLocked() + && (lockingUser == null + || lockingUser.equals(currentUser)); return visible; } private class Listener implements ActionListener { - public final void actionPerformed(final ActionEvent e) { - final PageState state = e.getPageState(); - try { - m_task.getTask(state).finish - (Web.getWebContext().getUser()); - } catch (TaskException te) { - throw new UncheckedWrapperException(te); - } + @Override + public final void actionPerformed(final ActionEvent event) { + final PageState state = event.getPageState(); + + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final WorkflowManager workflowManager = cdiUtil.findBean( + WorkflowManager.class); + + final Task task = m_task.getTask(state); + task.setTaskState("finished"); + } + } + } public void reset(final PageState state) { @@ -157,32 +182,48 @@ abstract class BaseWorkflowItemPane extends BaseItemPane { } private class TaskDeleteForm extends BaseDeleteForm { + TaskDeleteForm() { super(new Label(gz("cms.ui.workflow.task.delete_prompt"))); - addSecurityListener(SecurityManager.WORKFLOW_ADMIN); + addSecurityListener(CmsConstants.PRIVILEGE_ADMINISTER_WORKFLOW); } - public final void process(final FormSectionEvent e) - throws FormProcessException { - final PageState state = e.getPageState(); + @Override + public final void process(final FormSectionEvent event) + throws FormProcessException { + final PageState state = event.getPageState(); - m_task.getTask(state).delete(); + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final TaskRepository taskRepo = cdiUtil.findBean( + TaskRepository.class); + + final Task task = m_task.getTask(state); + taskRepo.delete(task); m_tasks.getRowSelectionModel().clearSelection(state); } + } private class TaskSelectionRequestLocal extends TaskRequestLocal { - protected final Object initialValue(final PageState state) { - final String id = m_tasks.getRowSelectionModel().getSelectedKey - (state).toString(); - return new CmsTask(new BigDecimal(id)); + @Override + protected final Object initialValue(final PageState state) { + final String id = m_tasks.getRowSelectionModel().getSelectedKey( + state).toString(); + + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final CmsTaskTypeRepository taskRepo = cdiUtil.findBean( + CmsTaskTypeRepository.class); + + return taskRepo.findById(Long.parseLong(id)); } + } class SummarySection extends Section { + SummarySection(final ActionLink editLink, final ActionLink deleteLink) { setHeading(new Label(gz("cms.ui.workflow.details"))); @@ -200,26 +241,35 @@ abstract class BaseWorkflowItemPane extends BaseItemPane { } private class Properties extends PropertyList { - protected final java.util.List properties(final PageState state) { - final java.util.List props = super.properties(state); + + @Override + protected final List properties(final PageState state) { + @SuppressWarnings("unchecked") + final List props = super.properties(state); final Workflow flow = (Workflow) m_workflow.get(state); + final KernelConfig kernelConfig = KernelConfig.getConfig(); + final Locale defaultLocale = kernelConfig.getDefaultLocale(); + props.add(new Property(gz("cms.ui.name"), - flow.getLabel())); - props.add(new Property(gz("cms.ui.description"), - flow.getDescription())); - props.add(new Property(gz("cms.ui.workflow.current_state"), - flow.getStateString())); + flow.getName().getValue(defaultLocale))); + props.add(new Property( + gz("cms.ui.description"), + flow.getDescription().getValue(defaultLocale))); +// props.add(new Property(gz("cms.ui.workflow.current_state"), +// flow.getStateString())); props.add(new Property(gz("cms.ui.workflow.num_tasks"), - String.valueOf(flow.getTaskCount()))); + String.valueOf(flow.getTasks().size()))); return props; } + } } class TaskSection extends Section { + TaskSection(final ActionLink taskAddLink) { setHeading(new Label(gz("cms.ui.workflow.tasks"))); @@ -229,10 +279,11 @@ abstract class BaseWorkflowItemPane extends BaseItemPane { group.setSubject(m_tasks); group.addAction(new AdminVisible(taskAddLink), ActionGroup.ADD); } + } // XXX Fix this. - private static final String[] s_columns = new String[] { + private static final String[] s_columns = new String[]{ lz("cms.ui.name"), lz("cms.ui.description"), lz("cms.ui.workflow.task.dependencies"), @@ -240,14 +291,15 @@ abstract class BaseWorkflowItemPane extends BaseItemPane { }; private class TaskTable extends Table { + public TaskTable() { super(new TaskTableModelBuilder(m_workflow), s_columns); setEmptyView(new Label(gz("cms.ui.workflow.task.none"))); - getColumn(0).setCellRenderer - (new DefaultTableCellRenderer(true)); + getColumn(0).setCellRenderer(new DefaultTableCellRenderer(true)); } + } } diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/TaskAddForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/TaskAddForm.java new file mode 100755 index 000000000..0a141a20c --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/TaskAddForm.java @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.cms.ui.workflow; + +import com.arsdigita.bebop.FormProcessException; +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.SingleSelectionModel; +import com.arsdigita.bebop.event.FormProcessListener; +import com.arsdigita.bebop.event.FormSectionEvent; +import com.arsdigita.bebop.event.PrintEvent; +import com.arsdigita.bebop.event.PrintListener; +import com.arsdigita.bebop.form.Option; +import com.arsdigita.bebop.form.OptionGroup; +import com.arsdigita.kernel.KernelConfig; + +import org.librecms.workflow.CmsTask; +import org.librecms.workflow.CmsTaskType; + +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.Workflow; +import org.libreccm.workflow.WorkflowManager; +import org.librecms.workflow.CmsTaskTypeRepository; + +import java.util.List; +import java.util.Locale; +import java.util.TooManyListenersException; + +/** + * @author Jens Pelzetter + * @author Justin Ross + */ +class TaskAddForm extends BaseTaskForm { + + protected final static String ERROR_MSG + = "A workflow template with that name already exists in this content " + + "section."; + + private final SingleSelectionModel m_model; + + public TaskAddForm(final WorkflowRequestLocal workflow, + final SingleSelectionModel model) { + super("task", gz("cms.ui.workflow.task.add"), workflow); + + m_model = model; + + try { + m_deps.addPrintListener(new DependencyPrinter()); + } catch (TooManyListenersException tmle) { + throw new UncheckedWrapperException(tmle); + } + + addProcessListener(new ProcessListener()); + } + + private class DependencyPrinter implements PrintListener { + + @Override + public final void prepare(final PrintEvent event) { + final PageState state = event.getPageState(); + final List tasks = m_workflow.getWorkflow(state).getTasks(); + + final OptionGroup options = (OptionGroup) event.getTarget(); + final KernelConfig kernelConfig = KernelConfig.getConfig(); + final Locale defaultLocale = kernelConfig.getDefaultLocale(); + + tasks.forEach(task -> options.addOption(new Option( + Long.toString(task.getTaskId()), + task.getLabel().getValue(defaultLocale)))); + } + + } + + private class ProcessListener implements FormProcessListener { + + @Override + public final void process(final FormSectionEvent event) + throws FormProcessException { + + final PageState state = event.getPageState(); + + final Workflow workflow = m_workflow.getWorkflow(state); + final CmsTask task = new CmsTask(); + + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final TaskRepository taskRepo = cdiUtil.findBean( + TaskRepository.class); + final CmsTaskTypeRepository taskTypeRepo = cdiUtil.findBean(CmsTaskTypeRepository.class); + final WorkflowManager workflowManager = cdiUtil.findBean( + WorkflowManager.class); + final ConfigurationManager confManager = cdiUtil.findBean( + ConfigurationManager.class); + final KernelConfig kernelConfig = confManager.findConfiguration( + KernelConfig.class); + final Locale defaultLocale = kernelConfig.getDefaultLocale(); + + task.getLabel().addValue(defaultLocale, + ((String) m_name.getValue(state))); + task.getDescription().addValue( + defaultLocale, + ((String) m_description.getValue(state))); + + final CmsTaskType taskType = taskTypeRepo.findById((Long) m_type.getValue(state)); + task.setTaskType(taskType); + task.setActive(true); + + taskRepo.save(task); + + workflowManager.addTask(workflow, task); + + processDependencies(task, (String[]) m_deps.getValue(state)); + + m_model.setSelectedKey(state, task.getTaskId()); + } + + } + +} 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 new file mode 100755 index 000000000..24cd25a4f --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/TaskEditForm.java @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.cms.ui.workflow; + +import com.arsdigita.bebop.Form; +import com.arsdigita.bebop.FormProcessException; +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.event.FormInitListener; +import com.arsdigita.bebop.event.FormProcessListener; +import com.arsdigita.bebop.event.FormSectionEvent; +import com.arsdigita.bebop.event.PrintEvent; +import com.arsdigita.bebop.event.PrintListener; +import com.arsdigita.bebop.form.Option; +import com.arsdigita.bebop.form.OptionGroup; +import com.arsdigita.kernel.KernelConfig; + +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.librecms.workflow.CmsTaskType; +import org.librecms.workflow.CmsTaskTypeRepository; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.TooManyListenersException; + +/** + * @author Jens Pelzetter + * @author Justin Ross + */ +class TaskEditForm extends BaseTaskForm { + + private TaskRequestLocal m_task; + + public TaskEditForm(final WorkflowRequestLocal workflow, + final TaskRequestLocal task) { + super("task", gz("cms.ui.workflow.task.edit"), workflow); + + m_task = task; + + try { + m_deps.addPrintListener(new DependencyPrinter()); + } catch (TooManyListenersException tmle) { + throw new UncheckedWrapperException(tmle); + } + + addInitListener(new InitListener()); + addProcessListener(new ProcessListener()); + } + + private class DependencyPrinter implements PrintListener { + + @Override + public final void prepare(final PrintEvent event) { + final PageState state = event.getPageState(); + final List tasks = m_workflow.getWorkflow(state).getTasks(); + + final OptionGroup options = (OptionGroup) event.getTarget(); + + tasks.forEach(task -> addOption(task, state, options)); + } + + } + + private void addOption(final Task task, + final PageState state, + final OptionGroup options) { + final KernelConfig kernelConfig = KernelConfig.getConfig(); + final Locale defaultLocale = kernelConfig.getDefaultLocale(); + if (m_task.getTask(state).getTaskId() != task.getTaskId()) { + options.addOption(new Option( + Long.toString(task.getTaskId()), + task.getLabel().getValue(defaultLocale))); + } + } + + private class InitListener implements FormInitListener { + + @Override + public final void init(final FormSectionEvent event) + throws FormProcessException { + final PageState state = event.getPageState(); + final CmsTask task = m_task.getTask(state); + + m_name.setValue(state, task.getLabel()); + m_description.setValue(state, task.getDescription()); + m_type.setValue(state, Long.toString(task.getTaskType() + .getTaskTypeId())); + + final List deps = task.getDependsOn(); + final List list = new ArrayList<>(); + + deps.forEach(dep -> list.add(Long.toString(dep.getTaskId()))); + + m_deps.setValue(state, list.toArray()); + } + + } + + private class ProcessListener implements FormProcessListener { + + @Override + public final void process(final FormSectionEvent event) + throws FormProcessException { + final PageState state = event.getPageState(); + final CmsTask task = m_task.getTask(state); + + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final TaskRepository taskRepo = cdiUtil.findBean( + TaskRepository.class); + final CmsTaskTypeRepository taskTypeRepo = cdiUtil.findBean(CmsTaskTypeRepository.class); + final ConfigurationManager confManager = cdiUtil.findBean( + ConfigurationManager.class); + final KernelConfig kernelConfig = confManager.findConfiguration( + KernelConfig.class); + final Locale defaultLocale = kernelConfig.getDefaultLocale(); + + task.getLabel().addValue(defaultLocale, + (String) m_name.getValue(state)); + task.getDescription().addValue( + defaultLocale, + (String) m_description.getValue(state)); + + final CmsTaskType taskType = taskTypeRepo.findById((Long) m_type.getValue(state)); + task.setTaskType(taskType); + + taskRepo.save(task); + + processDependencies(task, (String[]) m_deps.getValue(state)); + } + + } + +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/TaskTableModelBuilder.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/TaskTableModelBuilder.java new file mode 100755 index 000000000..bed528c47 --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/TaskTableModelBuilder.java @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.cms.ui.workflow; + +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 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; + +class TaskTableModelBuilder extends AbstractTableModelBuilder { + + private static final Logger LOGGER = LogManager.getLogger( + TaskTableModelBuilder.class); + + private final WorkflowRequestLocal m_workflow; + + TaskTableModelBuilder(final WorkflowRequestLocal workflow) { + m_workflow = workflow; + } + + @Override + public final TableModel makeModel(final Table table, + final PageState state) { + LOGGER.debug("Creating a new table model for the current request"); + + return new Model(m_workflow.getWorkflow(state)); + } + + private static class Model implements TableModel { + + private Task m_task; + private Iterator m_tasks; + private Map m_dependencies = new HashMap(); + + private Model(final Workflow workflow) { + final Iterator tasksIter = workflow.getTasks().iterator(); + GraphSet g = new GraphSet(); + + while (tasksIter.hasNext()) { + Task t = tasksIter.next(); + final Iterator 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; + } + Assert.assertEquals(workflow.getTasks().size(), tasks.size()); + m_tasks = tasks.iterator(); + } + + @Override + public final int getColumnCount() { + return 4; + } + + @Override + public final boolean nextRow() { + if (m_tasks.hasNext()) { + m_task = (Task) m_tasks.next(); + return true; + } else { + return false; + } + } + + @Override + public final Object getKeyAt(final int column) { + return m_task.getTaskId(); + } + + @Override + public final Object getElementAt(final int column) { + switch (column) { + case 0: + return m_task.getLabel(); + case 1: + return m_task.getDescription(); + case 2: + return m_dependencies.get(m_task); + case 3: + return ""; +// return m_task.getStateString(); + default: + throw new IllegalStateException(); + } + } + + } + +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/WorkflowAdminPane.java.off b/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/WorkflowAdminPane.java similarity index 76% rename from ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/WorkflowAdminPane.java.off rename to ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/WorkflowAdminPane.java index c4d0d42c7..dc7c337fa 100755 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/WorkflowAdminPane.java.off +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/WorkflowAdminPane.java @@ -26,7 +26,12 @@ import com.arsdigita.cms.ui.BaseAdminPane; import com.arsdigita.cms.ui.BaseDeleteForm; import com.arsdigita.cms.ui.VisibilityComponent; +import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.workflow.Workflow; +import org.libreccm.workflow.WorkflowManager; +import org.libreccm.workflow.WorkflowRepository; import org.libreccm.workflow.WorkflowTemplate; +import org.libreccm.workflow.WorkflowTemplateRepository; import org.librecms.CmsConstants; import java.math.BigDecimal; @@ -67,11 +72,15 @@ public final class WorkflowAdminPane extends BaseAdminPane { } @Override - public final void process(final FormSectionEvent e) + public final void process(final FormSectionEvent event) throws FormProcessException { - final PageState state = e.getPageState(); + final PageState state = event.getPageState(); - m_workflow.getWorkflow(state).delete(); + final CdiUtil cdiUtil= CdiUtil.createCdiUtil(); + final WorkflowRepository workflowRepo= cdiUtil.findBean(WorkflowRepository.class); + + final Workflow workflow = m_workflow.getWorkflow(state); + workflowRepo.delete(workflow); getSelectionModel().clearSelection(state); } @@ -80,11 +89,16 @@ public final class WorkflowAdminPane extends BaseAdminPane { private class SelectionRequestLocal extends WorkflowRequestLocal { + @Override protected final Object initialValue(final PageState state) { final String id = getSelectionModel().getSelectedKey(state) .toString(); - return new WorkflowTemplate(new BigDecimal(id)); + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final WorkflowTemplateRepository templateRepo = cdiUtil.findBean( + WorkflowTemplateRepository.class); + + return templateRepo.findById(Long.parseLong(id)); } } diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/WorkflowItemPane.java.off b/ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/WorkflowItemPane.java similarity index 100% rename from ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/WorkflowItemPane.java.off rename to ccm-cms/src/main/java/com/arsdigita/cms/ui/workflow/WorkflowItemPane.java diff --git a/ccm-cms/src/main/java/org/librecms/workflow/CmsTaskTypeRepository.java b/ccm-cms/src/main/java/org/librecms/workflow/CmsTaskTypeRepository.java new file mode 100644 index 000000000..fb50cf97a --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/workflow/CmsTaskTypeRepository.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2016 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.librecms.workflow; + +import org.libreccm.core.AbstractEntityRepository; + +import javax.enterprise.context.RequestScoped; + +/** + * A repository for the {@link CmsTaskType} entity. + * + * @author Jens Pelzetter + */ +@RequestScoped +public class CmsTaskTypeRepository extends AbstractEntityRepository{ + + @Override + public Class getEntityClass() { + return CmsTaskType.class; + } + + @Override + public boolean isNew(final CmsTaskType taskType) { + return taskType.getTaskTypeId() == 0; + } + +}