CCM NG/ccm-core,ccm-cms: Some changes to Workflow, Task etc. Primarly some missing features/methods required by Workflow UI in CCM CMS.
git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4441 8810af33-2d31-482b-a856-94f89814c4dfpull/2/head
parent
7430901acc
commit
48dea0fb14
|
|
@ -436,7 +436,7 @@ public class ContentItemPage extends CMSPage implements ActionListener {
|
|||
* @param itemId the id of the ContentItem object to display
|
||||
* @param tab The index of the tab to display
|
||||
*/
|
||||
public static String getItemURL(BigDecimal itemId, int tab) {
|
||||
public static String getItemURL(long itemId, int tab) {
|
||||
final ContentItem item =
|
||||
(ContentItem) DomainObjectFactory.newInstance(new OID(
|
||||
ContentItem.BASE_DATA_OBJECT_TYPE, itemId));
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ import com.arsdigita.toolbox.ui.Section;
|
|||
import com.arsdigita.util.Assert;
|
||||
import com.arsdigita.util.SequentialMap;
|
||||
import com.arsdigita.util.UncheckedWrapperException;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
|
@ -66,6 +66,9 @@ import java.util.Collection;
|
|||
import java.util.Iterator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.librecms.contenttypes.AuthoringKitInfo;
|
||||
import org.librecms.contenttypes.ContentTypeInfo;
|
||||
|
||||
/**
|
||||
* This class represents a single authoring kit. The wizard accepts a
|
||||
|
|
@ -83,12 +86,11 @@ import java.util.Collections;
|
|||
* This constructor will be called when the component is automatically
|
||||
* instantiated by the <code>AuthoringKitWizard</code>.</p>
|
||||
*
|
||||
* @version $Id: AuthoringKitWizard.java 2140 2011-01-16 12:04:20Z pboy $
|
||||
*/
|
||||
public class AuthoringKitWizard extends LayoutPanel implements Resettable {
|
||||
|
||||
/** Private Logger instance for this class */
|
||||
private static final Logger s_log = Logger.getLogger(
|
||||
private static final Logger LOGGER = LogManager.getLogger(
|
||||
AuthoringKitWizard.class);
|
||||
private static Class[] s_args = new Class[]{
|
||||
ItemSelectionModel.class,
|
||||
|
|
@ -103,8 +105,8 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
|
|||
private static final java.util.List<AssetStepEntry> s_assets = new
|
||||
ArrayList<AssetStepEntry>();
|
||||
private final Object[] m_vals;
|
||||
private final ContentType m_type;
|
||||
private final AuthoringKit m_kit;
|
||||
private final ContentTypeInfo m_type;
|
||||
private final AuthoringKitInfo m_kit;
|
||||
private final ItemSelectionModel m_sel;
|
||||
private final WorkflowRequestLocal m_workflow;
|
||||
private final AssignedTaskTable m_tasks;
|
||||
|
|
@ -131,14 +133,12 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
|
|||
*
|
||||
* @param type The content type of the items that this wizard will
|
||||
* handle
|
||||
*
|
||||
* @param itemModel The item selection model which will supply
|
||||
* this wizard with the content item object
|
||||
* @param model
|
||||
*/
|
||||
public AuthoringKitWizard(final ContentType type,
|
||||
public AuthoringKitWizard(final ContentTypeInfo type,
|
||||
final ItemSelectionModel model) {
|
||||
if (s_log.isDebugEnabled()) {
|
||||
s_log.debug("Authoring kit wizard for type " + type + " "
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Authoring kit wizard for type " + type + " "
|
||||
+ "undergoing creation");
|
||||
}
|
||||
|
||||
|
|
@ -262,9 +262,9 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
|
|||
Collection skipSteps = ContentSection.getConfig().getAssetStepsToSkip(
|
||||
type);
|
||||
Iterator it = skipSteps.iterator();
|
||||
if (s_log.isDebugEnabled()) {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
while (it.hasNext()) {
|
||||
s_log.debug("skip step " + it.next());
|
||||
LOGGER.debug("skip step " + it.next());
|
||||
}
|
||||
}
|
||||
//Iterator assets = s_assets.iterator();
|
||||
|
|
@ -276,7 +276,7 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
|
|||
final String baseObjectType = data.getBaseDataObjectType();
|
||||
//Class step = (Class) data[1];
|
||||
Class step = data.getStep();
|
||||
s_log.debug("possibly adding asset step " + step.getName());
|
||||
LOGGER.debug("possibly adding asset step " + step.getName());
|
||||
if (!skipSteps.contains(step.getName())) {
|
||||
//GlobalizedMessage label = (GlobalizedMessage) data[2];
|
||||
GlobalizedMessage label = data.getLabel();
|
||||
|
|
@ -423,7 +423,7 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
|
|||
// registered, but I needed the image step to use a different step class if the specialised
|
||||
// image step application was loaded. Solution is to ensure initialiser in new project
|
||||
// runs after original ccm-ldn-image-step initializer and override the registered step here
|
||||
s_log.debug(
|
||||
LOGGER.debug(
|
||||
"registering asset step - label: "
|
||||
+ label.localize()
|
||||
+ " step class: "
|
||||
|
|
@ -451,7 +451,7 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
|
|||
*/
|
||||
if ((thisObjectType.equals(baseObjectType))
|
||||
&& (thisLabel.localize().equals(label.localize()))) {
|
||||
s_log.debug(
|
||||
LOGGER.debug(
|
||||
"registering authoring step with same label as previously registered step");
|
||||
s_assets.remove(data);
|
||||
break;
|
||||
|
|
@ -570,8 +570,8 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
|
|||
* @param className The Java class name of the step
|
||||
*/
|
||||
protected Component instantiateStep(String name) {
|
||||
if (s_log.isDebugEnabled()) {
|
||||
s_log.debug("Instantiating kit wizard '" + name + "' with "
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Instantiating kit wizard '" + name + "' with "
|
||||
+ "arguments " + s_args);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
package com.arsdigita.cms.ui.authoring;
|
||||
|
||||
|
||||
import com.arsdigita.bebop.Component;
|
||||
import com.arsdigita.bebop.PageState;
|
||||
import com.arsdigita.bebop.Resettable;
|
||||
|
|
@ -33,6 +32,7 @@ import org.librecms.contentsection.ContentType;
|
|||
|
||||
import com.arsdigita.cms.ItemSelectionModel;
|
||||
import com.arsdigita.toolbox.ui.LayoutPanel;
|
||||
import com.arsdigita.util.UncheckedWrapperException;
|
||||
import com.arsdigita.xml.Element;
|
||||
|
||||
import oracle.jrockit.jfr.events.ContentTypeImpl;
|
||||
|
|
@ -42,37 +42,36 @@ import org.librecms.contenttypes.ContentTypeInfo;
|
|||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
|
||||
/**
|
||||
* An invisible component which contains all the possible authoring kits.
|
||||
* The kits are loaded from the database at construction time. The selector
|
||||
* chooses which kit to display at page rendering time based on the value
|
||||
* of the content_type state parameter.
|
||||
*
|
||||
* Essentially, this component is a hack which is used to get around
|
||||
* the fact that we cannot instantiate stateful components dynamically.
|
||||
* An invisible component which contains all the possible authoring kits. The
|
||||
* kits are loaded from the database at construction time. The selector chooses
|
||||
* which kit to display at page rendering time based on the value of the
|
||||
* content_type state parameter.
|
||||
*
|
||||
* Essentially, this component is a hack which is used to get around the fact
|
||||
* that we cannot instantiate stateful components dynamically.
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
* @author unknown
|
||||
*/
|
||||
public class WizardSelector extends AuthoringKitSelector
|
||||
implements Resettable {
|
||||
implements Resettable {
|
||||
|
||||
private ItemSelectionModel itemSelectionModel;
|
||||
|
||||
/**
|
||||
* Construct a new WizardSelector. Load all the possible authoring kits
|
||||
* from the database and construct wizards for them.
|
||||
* Construct a new WizardSelector. Load all the possible authoring kits from
|
||||
* the database and construct wizards for them.
|
||||
*
|
||||
* @param model the {@link ItemSelectionModel} which will
|
||||
* supply the wizard with its item
|
||||
* @param model the {@link ItemSelectionModel} which will supply the wizard
|
||||
* with its item
|
||||
*
|
||||
* @param typeModel the {@link ACSObjectSelectionModel} which will
|
||||
* supply the default content type
|
||||
* @param typeModel the {@link ACSObjectSelectionModel} which will supply
|
||||
* the default content type
|
||||
*
|
||||
* @pre itemModel != null
|
||||
*/
|
||||
public WizardSelector(final ItemSelectionModel model,
|
||||
public WizardSelector(final ItemSelectionModel model,
|
||||
final SingleSelectionModel<String> typeModel) {
|
||||
super(typeModel);
|
||||
itemSelectionModel = model;
|
||||
|
|
@ -81,18 +80,19 @@ public class WizardSelector extends AuthoringKitSelector
|
|||
|
||||
/**
|
||||
* Get the wizard for the given kit.
|
||||
*
|
||||
* @param kit
|
||||
* @param type
|
||||
* @return
|
||||
* @return
|
||||
*/
|
||||
public Component instantiateKitComponent(final AuthoringKitInfo kit,
|
||||
@Override
|
||||
public Component instantiateKitComponent(final AuthoringKitInfo kit,
|
||||
final ContentTypeInfo type) {
|
||||
|
||||
final ItemSelectionModel itemModel = new
|
||||
ItemSelectionModel(type,
|
||||
(LongParameter)itemSelectionModel.getStateParameter());
|
||||
final ItemSelectionModel itemModel = new ItemSelectionModel(
|
||||
type, (LongParameter) itemSelectionModel.getStateParameter());
|
||||
|
||||
final AuthoringKitWizard wizard = new AuthoringKitWizard(type, itemModel);
|
||||
final AuthoringKitWizard wizard = new AuthoringKitWizard(type, itemModel);
|
||||
return wizard;
|
||||
}
|
||||
|
||||
|
|
@ -107,54 +107,51 @@ public class WizardSelector extends AuthoringKitSelector
|
|||
private Component getCurrentWizard(PageState state) {
|
||||
|
||||
// Get the current item and extract its content type
|
||||
if(!itemSelectionModel.isSelected(state))
|
||||
throw new RuntimeException( (String) GlobalizationUtil.globalize(
|
||||
"cms.ui.authoring.missing_item_id")
|
||||
.localize());
|
||||
if (!itemSelectionModel.isSelected(state)) {
|
||||
throw new UncheckedWrapperException("No item selected.");
|
||||
}
|
||||
|
||||
ContentItem item =
|
||||
(ContentItem)itemSelectionModel.getSelectedObject(state);
|
||||
final ContentItem item = (ContentItem) itemSelectionModel
|
||||
.getSelectedObject(state);
|
||||
|
||||
ContentType type = item.getContentType();
|
||||
BigDecimal typeId;
|
||||
final ContentType type = item.getContentType();
|
||||
final String typeClass;
|
||||
|
||||
if(type == null) {
|
||||
if (type == null) {
|
||||
// Try to get the default content type
|
||||
typeId = (BigDecimal)getComponentSelectionModel().getSelectedKey(state);
|
||||
if(typeId == null) {
|
||||
throw new RuntimeException((String) GlobalizationUtil.globalize(
|
||||
"cms.ui.authoring.missing_content_type")
|
||||
.localize());
|
||||
typeClass = getComponentSelectionModel().getSelectedKey(state);
|
||||
if (typeClass == null || typeClass.isEmpty()) {
|
||||
throw new UncheckedWrapperException("Content type is missing");
|
||||
}
|
||||
} else {
|
||||
typeId = type.getID();
|
||||
typeClass = type.getContentItemClass();
|
||||
}
|
||||
|
||||
|
||||
// Return the selected wizard
|
||||
return (Component)getComponent(typeId);
|
||||
return (Component) getComponent(typeClass);
|
||||
}
|
||||
|
||||
// Choose the right wizard and run it
|
||||
public void generateXML(PageState state, Element parent) {
|
||||
@Override
|
||||
public void generateXML(final PageState state, final Element parent) {
|
||||
|
||||
Component c = getCurrentWizard(state);
|
||||
final Component component = getCurrentWizard(state);
|
||||
|
||||
if(c == null) {
|
||||
throw new RuntimeException( (String) GlobalizationUtil.globalize(
|
||||
"cms.ui.authoring.no_current_wizard")
|
||||
.localize());
|
||||
if (component == null) {
|
||||
throw new UncheckedWrapperException("No Wizard.");
|
||||
}
|
||||
|
||||
c.generateXML(state, parent);
|
||||
component.generateXML(state, parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the state of the current wizard
|
||||
*/
|
||||
public void reset(PageState state) {
|
||||
Resettable r = (Resettable)getCurrentWizard(state);
|
||||
if(r != null) r.reset(state);
|
||||
public void reset(final PageState state) {
|
||||
final Resettable resettable = (Resettable) getCurrentWizard(state);
|
||||
if (resettable != null) {
|
||||
resettable.reset(state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ import com.arsdigita.kernel.KernelConfig;
|
|||
import org.libreccm.configuration.ConfigurationManager;
|
||||
import org.libreccm.security.Shiro;
|
||||
import org.libreccm.security.User;
|
||||
import org.libreccm.workflow.UserTask;
|
||||
import org.libreccm.workflow.UserTaskRepository;
|
||||
import org.libreccm.workflow.AssignableTask;
|
||||
import org.libreccm.workflow.AssignableTaskRepository;
|
||||
import org.libreccm.workflow.Workflow;
|
||||
import org.libreccm.workflow.WorkflowManager;
|
||||
|
||||
|
|
@ -50,7 +50,7 @@ public class AssignedTaskController {
|
|||
private WorkflowManager workflowManager;
|
||||
|
||||
@Inject
|
||||
private UserTaskRepository userTaskRepo;
|
||||
private AssignableTaskRepository userTaskRepo;
|
||||
|
||||
@Inject
|
||||
private Shiro shiro;
|
||||
|
|
@ -71,7 +71,7 @@ public class AssignedTaskController {
|
|||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public List<RowData<Long>> getAssignedTasks(final Workflow workflow) {
|
||||
final User user = shiro.getUser();
|
||||
final List<UserTask> tasks = userTaskRepo.getAssignedTasks(user,
|
||||
final List<AssignableTask> tasks = userTaskRepo.getAssignedTasks(user,
|
||||
workflow);
|
||||
|
||||
return tasks
|
||||
|
|
@ -81,7 +81,7 @@ public class AssignedTaskController {
|
|||
|
||||
}
|
||||
|
||||
private RowData<Long> createRowData(final UserTask task) {
|
||||
private RowData<Long> createRowData(final AssignableTask task) {
|
||||
|
||||
|
||||
final RowData<Long> rowData = new RowData<>(3);
|
||||
|
|
|
|||
|
|
@ -39,14 +39,14 @@ import org.apache.log4j.Logger;
|
|||
import org.libreccm.cdi.utils.CdiUtil;
|
||||
import org.libreccm.security.Shiro;
|
||||
import org.libreccm.workflow.Task;
|
||||
import org.libreccm.workflow.UserTask;
|
||||
import org.libreccm.workflow.UserTaskRepository;
|
||||
import org.libreccm.workflow.AssignableTask;
|
||||
import org.libreccm.workflow.AssignableTaskRepository;
|
||||
import org.libreccm.workflow.WorkflowConstants;
|
||||
import org.libreccm.workflow.WorkflowManager;
|
||||
import org.libreccm.workflow.WorkflowRepository;
|
||||
import org.librecms.CmsConstants;
|
||||
import org.librecms.workflow.CmsTask;
|
||||
import org.librecms.workflow.CmsTaskType;
|
||||
import org.librecms.workflow.CmsTaskTypeOld;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -177,16 +177,15 @@ public final class AssignedTaskSection extends Section {
|
|||
protected final Object initialValue(final PageState state) {
|
||||
final Workflow workflow = m_flow.getWorkflow(state);
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final UserTaskRepository userTaskRepo = cdiUtil.findBean(
|
||||
UserTaskRepository.class);
|
||||
final AssignableTaskRepository userTaskRepo = cdiUtil.findBean(AssignableTaskRepository.class);
|
||||
final Shiro shiro = cdiUtil.findBean(Shiro.class);
|
||||
return userTaskRepo.findEnabledTasksForWorkflow(shiro.getUser(),
|
||||
workflow);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
final List<UserTask> getTasks(final PageState state) {
|
||||
return (ArrayList<UserTask>) get(state);
|
||||
final List<AssignableTask> getTasks(final PageState state) {
|
||||
return (ArrayList<AssignableTask>) get(state);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -208,7 +207,7 @@ public final class AssignedTaskSection extends Section {
|
|||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final WorkflowManager workflowManager = cdiUtil.findBean(WorkflowManager.class);
|
||||
|
||||
for(final UserTask task : m_tasks.getTasks(state)) {
|
||||
for(final AssignableTask task : m_tasks.getTasks(state)) {
|
||||
if (relevant(task) && !task.isLocked()) {
|
||||
workflowManager.lockTask(task);
|
||||
}
|
||||
|
|
@ -219,7 +218,7 @@ public final class AssignedTaskSection extends Section {
|
|||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final WorkflowManager workflowManager = cdiUtil.findBean(WorkflowManager.class);
|
||||
|
||||
for(final UserTask task : m_tasks.getTasks(state)) {
|
||||
for(final AssignableTask task : m_tasks.getTasks(state)) {
|
||||
if (relevant(task) && task.isLocked()) {
|
||||
workflowManager.unlockTask(task);
|
||||
}
|
||||
|
|
@ -227,7 +226,7 @@ public final class AssignedTaskSection extends Section {
|
|||
}
|
||||
|
||||
final boolean tasksLocked(final PageState state) {
|
||||
for(final UserTask task : m_tasks.getTasks(state)) {
|
||||
for(final AssignableTask task : m_tasks.getTasks(state)) {
|
||||
if (relevant(task) && !task.isLocked()) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -248,7 +247,7 @@ public final class AssignedTaskSection extends Section {
|
|||
return !m_tasks.getTasks(state).isEmpty();
|
||||
}
|
||||
|
||||
private boolean relevant(final UserTask task) {
|
||||
private boolean relevant(final AssignableTask task) {
|
||||
return true;
|
||||
|
||||
// ToDo
|
||||
|
|
@ -40,8 +40,8 @@ import org.apache.log4j.Logger;
|
|||
import org.libreccm.cdi.utils.CdiUtil;
|
||||
import org.libreccm.security.Shiro;
|
||||
import org.libreccm.security.User;
|
||||
import org.libreccm.workflow.UserTask;
|
||||
import org.libreccm.workflow.UserTaskRepository;
|
||||
import org.libreccm.workflow.AssignableTask;
|
||||
import org.libreccm.workflow.AssignableTaskRepository;
|
||||
import org.libreccm.workflow.WorkflowManager;
|
||||
import org.librecms.CmsConstants;
|
||||
import org.librecms.workflow.CmsTaskTypeRepository;
|
||||
|
|
@ -70,13 +70,12 @@ public final class AssignedTaskTable extends Table {
|
|||
final int column = event.getColumn();
|
||||
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final UserTaskRepository userTaskRepo = cdiUtil.findBean(
|
||||
UserTaskRepository.class);
|
||||
final AssignableTaskRepository userTaskRepo = cdiUtil.findBean(AssignableTaskRepository.class);
|
||||
final WorkflowManager workflowManager = cdiUtil.findBean(WorkflowManager.class);
|
||||
final Shiro shiro = cdiUtil.findBean(Shiro.class);
|
||||
|
||||
if (column == 1) {
|
||||
final UserTask task = userTaskRepo.findById((Long) event
|
||||
final AssignableTask task = userTaskRepo.findById((Long) event
|
||||
.getRowKey());
|
||||
final User currentUser = shiro.getUser();
|
||||
final User lockingUser = task.getLockingUser();
|
||||
|
|
@ -27,7 +27,7 @@ import com.arsdigita.bebop.parameters.IntegerParameter;
|
|||
import com.arsdigita.cms.ui.BaseForm;
|
||||
import com.arsdigita.cms.ui.ListOptionPrintListener;
|
||||
|
||||
import org.librecms.workflow.CmsTaskType;
|
||||
import org.librecms.workflow.CmsTaskTypeOld;
|
||||
|
||||
import com.arsdigita.globalization.GlobalizedMessage;
|
||||
import com.arsdigita.kernel.KernelConfig;
|
||||
|
|
@ -142,27 +142,27 @@ class BaseTaskForm extends BaseForm {
|
|||
}
|
||||
*/
|
||||
// Fix this one too
|
||||
private class TaskTypePrintListener extends ListOptionPrintListener<CmsTaskType> {
|
||||
private class TaskTypePrintListener extends ListOptionPrintListener<CmsTaskTypeOld> {
|
||||
|
||||
@Override
|
||||
protected List<CmsTaskType> getDataQuery(final PageState state) {
|
||||
protected List<CmsTaskTypeOld> getDataQuery(final PageState state) {
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final CmsTaskTypeRepository taskTypeRepo = cdiUtil.findBean(
|
||||
CmsTaskTypeRepository.class);
|
||||
|
||||
final List<CmsTaskType> taskTypes = taskTypeRepo.findAll();
|
||||
final List<CmsTaskTypeOld> taskTypes = taskTypeRepo.findAll();
|
||||
|
||||
return taskTypes;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey(final CmsTaskType taskType) {
|
||||
public String getKey(final CmsTaskTypeOld taskType) {
|
||||
return Long.toString(taskType.getTaskTypeId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue(final CmsTaskType taskType) {
|
||||
public String getValue(final CmsTaskTypeOld taskType) {
|
||||
final KernelConfig kernelConfig = KernelConfig.getConfig();
|
||||
final Locale defaultLocale = kernelConfig.getDefaultLocale();
|
||||
return taskType.getName().getValue(defaultLocale);
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* 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.event.FormProcessListener;
|
||||
import com.arsdigita.bebop.event.FormSectionEvent;
|
||||
import com.arsdigita.bebop.form.TextArea;
|
||||
import com.arsdigita.cms.ui.BaseForm;
|
||||
import org.librecms.workflow.CmsTask;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.libreccm.cdi.utils.CdiUtil;
|
||||
import org.libreccm.workflow.TaskRepository;
|
||||
|
||||
/**
|
||||
* @author Justin Ross
|
||||
* @author <a href="mailto:jens.pelzetter">Jens Pelzetter</a>
|
||||
*/
|
||||
class CommentAddForm extends BaseForm {
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger(CommentAddForm.class);
|
||||
|
||||
private final TaskRequestLocal selectedTask;
|
||||
private final TextArea comment;
|
||||
|
||||
public CommentAddForm(final TaskRequestLocal task) {
|
||||
super("addComment", gz("cms.ui.workflow.task.comment.add"));
|
||||
|
||||
this.selectedTask = task;
|
||||
|
||||
comment = new TextArea("Comment");
|
||||
comment.setWrap(TextArea.SOFT);
|
||||
comment.setRows(5);
|
||||
comment.setCols(40);
|
||||
|
||||
addComponent(comment);
|
||||
|
||||
addAction(new Finish());
|
||||
addAction(new Cancel());
|
||||
|
||||
addProcessListener(new ProcessListener());
|
||||
}
|
||||
|
||||
private class ProcessListener implements FormProcessListener {
|
||||
@Override
|
||||
public final void process(final FormSectionEvent event)
|
||||
throws FormProcessException {
|
||||
LOGGER.debug("Processing comment add");
|
||||
|
||||
final PageState state = event.getPageState();
|
||||
final CmsTask task = selectedTask.getTask(state);
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final TaskRepository taskRepo = cdiUtil.findBean(TaskRepository.class);
|
||||
|
||||
task.addComment((String)comment.getValue(state));
|
||||
taskRepo.save(task);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -30,7 +30,7 @@ import com.arsdigita.bebop.form.OptionGroup;
|
|||
import com.arsdigita.kernel.KernelConfig;
|
||||
|
||||
import org.librecms.workflow.CmsTask;
|
||||
import org.librecms.workflow.CmsTaskType;
|
||||
import org.librecms.workflow.CmsTaskTypeOld;
|
||||
|
||||
import com.arsdigita.util.UncheckedWrapperException;
|
||||
|
||||
|
|
@ -120,7 +120,7 @@ class TaskAddForm extends BaseTaskForm {
|
|||
defaultLocale,
|
||||
((String) m_description.getValue(state)));
|
||||
|
||||
final CmsTaskType taskType = taskTypeRepo.findById((Long) m_type.getValue(state));
|
||||
final CmsTaskTypeOld taskType = taskTypeRepo.findById((Long) m_type.getValue(state));
|
||||
task.setTaskType(taskType);
|
||||
task.setActive(true);
|
||||
|
||||
|
|
@ -30,7 +30,7 @@ import com.arsdigita.cms.ui.UserSearchForm;
|
|||
import com.arsdigita.globalization.GlobalizedMessage;
|
||||
|
||||
import org.libreccm.security.User;
|
||||
import org.libreccm.workflow.UserTask;
|
||||
import org.libreccm.workflow.AssignableTask;
|
||||
|
||||
import com.arsdigita.xml.Element;
|
||||
|
||||
|
|
@ -146,7 +146,7 @@ class TaskAddUser extends SimpleContainer {
|
|||
WorkflowManager.class);
|
||||
final UserRepository userRepo = cdiUtil.findBean(UserRepository.class);
|
||||
|
||||
final UserTask task = m_task.getTask(state);
|
||||
final AssignableTask task = m_task.getTask(state);
|
||||
User user;
|
||||
|
||||
for (int i = 0; i < users.length; i++) {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ 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.CmsTaskTypeOld;
|
||||
import org.librecms.workflow.CmsTaskTypeRepository;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -144,7 +144,7 @@ class TaskEditForm extends BaseTaskForm {
|
|||
defaultLocale,
|
||||
(String) m_description.getValue(state));
|
||||
|
||||
final CmsTaskType taskType = taskTypeRepo.findById((Long) m_type
|
||||
final CmsTaskTypeOld taskType = taskTypeRepo.findById((Long) m_type
|
||||
.getValue(state));
|
||||
task.setTaskType(taskType);
|
||||
|
||||
|
|
@ -0,0 +1,253 @@
|
|||
/*
|
||||
* 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.Label;
|
||||
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.FormValidationListener;
|
||||
import com.arsdigita.bebop.form.Option;
|
||||
import com.arsdigita.bebop.form.RadioGroup;
|
||||
import com.arsdigita.bebop.parameters.BooleanParameter;
|
||||
|
||||
import org.librecms.contentsection.ContentSection;
|
||||
|
||||
import com.arsdigita.cms.ContentCenter;
|
||||
import com.arsdigita.cms.ui.ContentItemPage;
|
||||
import com.arsdigita.globalization.GlobalizedMessage;
|
||||
import com.arsdigita.util.UncheckedWrapperException;
|
||||
|
||||
import org.librecms.workflow.CmsTask;
|
||||
import org.librecms.workflow.CmsTaskTypeOld;
|
||||
|
||||
import com.arsdigita.web.RedirectSignal;
|
||||
import com.arsdigita.web.URL;
|
||||
import com.arsdigita.web.Web;
|
||||
|
||||
import org.libreccm.workflow.Task;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.libreccm.cdi.utils.CdiUtil;
|
||||
import org.libreccm.security.PermissionChecker;
|
||||
import org.libreccm.security.Shiro;
|
||||
import org.libreccm.workflow.TaskRepository;
|
||||
import org.libreccm.workflow.WorkflowManager;
|
||||
import org.libreccm.workflow.WorkflowRepository;
|
||||
import org.librecms.CmsConstants;
|
||||
import org.librecms.contentsection.ContentItem;
|
||||
import org.librecms.contentsection.ContentItemRepository;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* A form that prompts the user to comment on and approve tasks and then
|
||||
* finishes the task if it was approved.</p>
|
||||
*
|
||||
* @author Justin Ross <jross@redhat.com>
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public final class TaskFinishForm extends CommentAddForm {
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger(
|
||||
TaskFinishForm.class);
|
||||
private final TaskRequestLocal m_task;
|
||||
private final Label m_approvePrompt;
|
||||
private final RadioGroup m_approve;
|
||||
|
||||
public TaskFinishForm(final TaskRequestLocal task) {
|
||||
super(task);
|
||||
|
||||
m_task = task;
|
||||
|
||||
m_approve = new RadioGroup(new BooleanParameter("approve"));
|
||||
m_approve.addOption(new Option("true",
|
||||
lz("cms.ui.workflow.task.approve")));
|
||||
m_approve.addOption(new Option("false",
|
||||
lz("cms.ui.workflow.task.reject")));
|
||||
|
||||
m_approvePrompt = new Label(gz("cms.ui.workflow.task.approve_prompt"));
|
||||
|
||||
addComponent(m_approvePrompt);
|
||||
addComponent(m_approve);
|
||||
|
||||
addInitListener(new InitListener());
|
||||
addValidationListener(new ValidationListener());
|
||||
addProcessListener(new ProcessListener());
|
||||
}
|
||||
|
||||
private class InitListener implements FormInitListener {
|
||||
|
||||
@Override
|
||||
public final void init(final FormSectionEvent e) {
|
||||
LOGGER.debug("Initializing task finish");
|
||||
|
||||
final PageState state = e.getPageState();
|
||||
|
||||
if (isVisible(state)) {
|
||||
final CmsTask task = m_task.getTask(state);
|
||||
|
||||
if (requiresApproval(task)) {
|
||||
m_approvePrompt.setVisible(state, true);
|
||||
m_approve.setVisible(state, true);
|
||||
} else {
|
||||
m_approvePrompt.setVisible(state, false);
|
||||
m_approve.setVisible(state, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ValidationListener implements FormValidationListener {
|
||||
|
||||
@Override
|
||||
public final void validate(final FormSectionEvent e)
|
||||
throws FormProcessException {
|
||||
LOGGER.debug("Validating task finish");
|
||||
|
||||
final PageState state = e.getPageState();
|
||||
final CmsTask task = m_task.getTask(state);
|
||||
|
||||
if (requiresApproval(task) && m_approve.getValue(state) == null) {
|
||||
throw new FormProcessException(new GlobalizedMessage(
|
||||
"cms.ui.workflow.task.approval_or_reject_required",
|
||||
CmsConstants.CMS_BUNDLE));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ProcessListener implements FormProcessListener {
|
||||
|
||||
@Override
|
||||
public final void process(final FormSectionEvent event)
|
||||
throws FormProcessException {
|
||||
LOGGER.debug("Processing task finish");
|
||||
|
||||
final PageState state = event.getPageState();
|
||||
final CmsTask task = m_task.getTask(state);
|
||||
boolean finishedTask = false;
|
||||
|
||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||
final PermissionChecker permissionChecker = cdiUtil.findBean(
|
||||
PermissionChecker.class);
|
||||
final ContentItemRepository itemRepo = cdiUtil.findBean(
|
||||
ContentItemRepository.class);
|
||||
final Optional<ContentItem> item = itemRepo.findItemWithWorkflow(
|
||||
task.getWorkflow());
|
||||
|
||||
if (!item.isPresent()) {
|
||||
throw new UncheckedWrapperException(
|
||||
"Workflow not assigned to an item");
|
||||
}
|
||||
|
||||
permissionChecker.checkPermission(task.getTaskType().getPrivilege(),
|
||||
item.get());
|
||||
|
||||
final TaskRepository taskRepo = cdiUtil.findBean(
|
||||
TaskRepository.class);
|
||||
|
||||
if (requiresApproval(task)) {
|
||||
LOGGER.debug("The task requires approval; checking to see "
|
||||
+ "if it's approved");
|
||||
|
||||
// XXX I think the fact that this returns a Boolean is
|
||||
// the effect of broken parameter marshalling in
|
||||
// Bebop.
|
||||
final Boolean isApproved = (Boolean) m_approve.getValue(state);
|
||||
|
||||
if (isApproved.equals(Boolean.TRUE)) {
|
||||
LOGGER.debug("The task is approved; finishing the task");
|
||||
|
||||
final Shiro shiro = cdiUtil.findBean(Shiro.class);
|
||||
final WorkflowManager workflowManager = cdiUtil.findBean(
|
||||
WorkflowManager.class);
|
||||
|
||||
task.setActive(false);
|
||||
finishedTask = true;
|
||||
} else {
|
||||
LOGGER.debug("The task is rejected; reenabling dependent "
|
||||
+ "tasks");
|
||||
|
||||
// Reenable the previous tasks.
|
||||
final Iterator<Task> iter = task.getDependentTasks().
|
||||
iterator();
|
||||
|
||||
while (iter.hasNext()) {
|
||||
final Task dependent = (Task) iter.next();
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Reenabling task " + dependent.
|
||||
getLabel());
|
||||
}
|
||||
|
||||
dependent.setActive(true);
|
||||
|
||||
taskRepo.save(dependent);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LOGGER.debug("The task does not require approval; finishing "
|
||||
+ "it");
|
||||
|
||||
task.setActive(false);
|
||||
taskRepo.save(task);
|
||||
}
|
||||
if (finishedTask) {
|
||||
Iterator tasks = Engine.getInstance(CMSEngine.CMS_ENGINE_TYPE).
|
||||
getEnabledTasks(Web.getWebContext().getUser(),
|
||||
task.getParentID()).iterator();
|
||||
if (tasks.hasNext()) {
|
||||
CmsTask thisTask = (CmsTask) tasks.next();
|
||||
PermissionDescriptor thisTaskAccess = new PermissionDescriptor(
|
||||
thisTask.getTaskType().getPrivilege(), task.
|
||||
getWorkflow().getObject(), user);
|
||||
if (PermissionService.checkPermission(thisTaskAccess)) {
|
||||
|
||||
// Lock task for user
|
||||
thisTask.lock((User) user);
|
||||
int targetTab = (thisTask.getTaskType().getID().equals(CmsTaskTypeOld.DEPLOY)) ? ContentItemPage.PUBLISHING_TAB : ContentItemPage.AUTHORING_TAB;
|
||||
throw new RedirectSignal(URL.there(state.getRequest(),
|
||||
ContentItemPage.
|
||||
getItemURL(
|
||||
task.
|
||||
getItem(),
|
||||
targetTab)),
|
||||
true);
|
||||
}
|
||||
}
|
||||
// redirect to /content-center if streamlined creation mode is active.
|
||||
if (ContentSection.getConfig().getUseStreamlinedCreation()) {
|
||||
throw new RedirectSignal(URL.there(state.getRequest(),
|
||||
ContentCenter.getURL()),
|
||||
true);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean requiresApproval(final CmsTask task) {
|
||||
return !task.getTaskType().getID().equals(CmsTaskTypeOld.AUTHOR);
|
||||
}
|
||||
}
|
||||
|
|
@ -49,7 +49,7 @@ import org.libreccm.security.Role;
|
|||
import org.libreccm.security.RoleRepository;
|
||||
import org.libreccm.security.Shiro;
|
||||
import org.libreccm.workflow.Task;
|
||||
import org.libreccm.workflow.UserTask;
|
||||
import org.libreccm.workflow.AssignableTask;
|
||||
import org.libreccm.workflow.WorkflowManager;
|
||||
import org.librecms.CmsConstants;
|
||||
import org.librecms.contentsection.privileges.AdminPrivileges;
|
||||
|
|
@ -173,7 +173,7 @@ final class TaskItemPane extends BaseItemPane {
|
|||
|
||||
final User user = shiro.getUser();
|
||||
|
||||
final List<UserTask> tasks = workflowManager.lockedBy(user);
|
||||
final List<AssignableTask> tasks = workflowManager.lockedBy(user);
|
||||
|
||||
return tasks.contains(task);
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (C) 2001-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.workflow;
|
||||
|
||||
/**
|
||||
* Class for generating a URL to the Authoring kit given the ID of the
|
||||
* ContentItem and the Task.
|
||||
*
|
||||
* @author Uday Mathur (umathur@arsdigita.com)
|
||||
* @author <a href="mail:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
* */
|
||||
|
||||
public class AuthoringTaskURLGenerator implements TaskURLGenerator {
|
||||
|
||||
public AuthoringTaskURLGenerator() {}
|
||||
|
||||
/**
|
||||
* Generates a Link to the Authoring Kit in the Item Management part
|
||||
* of the CMS UI.
|
||||
*
|
||||
* @param itemId id of the item in question
|
||||
* @param taskId this param is ignored.
|
||||
* @return
|
||||
* */
|
||||
@Override
|
||||
public String generateURL(final long itemId, final long taskId) {
|
||||
throw new UnsupportedOperationException("ToDo");
|
||||
// return ContentItemPage.getItemURL(itemId,
|
||||
// ContentItemPage.AUTHORING_TAB);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (C) 2001-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.workflow;
|
||||
|
||||
/**
|
||||
* Generates a Link to the Deploy Task Panel under the Workflow Tab in the Item
|
||||
* Management part of the CMS UI.
|
||||
*
|
||||
* @author Uday Mathur (umathur@arsdigita.com)
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*
|
||||
*/
|
||||
public class DeployTaskURLGenerator implements TaskURLGenerator {
|
||||
|
||||
public DeployTaskURLGenerator() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a Link to the Finish Task Panel under the Workflow Tab in the
|
||||
* Item Management part of the CMS UI.
|
||||
*
|
||||
* @param itemId id of the item in question
|
||||
* @param taskId id of the task to finish
|
||||
* @return
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public String generateURL(final long itemId, final long taskId) {
|
||||
// String url = ContentItemPage.getItemURL(itemId, ContentItemPage.PUBLISHING_TAB);
|
||||
// return url;
|
||||
throw new UnsupportedOperationException("ToDo");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (C) 2001-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.workflow;
|
||||
|
||||
/**
|
||||
* Class for generating a URL to the Authoring kit given the ID of the
|
||||
* ContentItem and the Task. Eventually we may have a separate kit for editors,
|
||||
* hence this is a separate class and has its own TaskType
|
||||
*
|
||||
* @author Uday Mathur (umathur@arsdigita.com)
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*
|
||||
*/
|
||||
public class EditingTaskURLGenerator implements TaskURLGenerator {
|
||||
|
||||
public EditingTaskURLGenerator() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a Link to the Workflow Tab in the Item Management part of the
|
||||
* CMS UI.
|
||||
*
|
||||
* @param itemId id of the item in question
|
||||
* @param taskId this param is ignored.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public String generateURL(final long itemId, final long taskId) {
|
||||
// final StringBuffer url = new StringBuffer
|
||||
// (ContentItemPage.getItemURL(itemId, ContentItemPage.WORKFLOW_TAB));
|
||||
//
|
||||
// // XXX task, approve, and action were constants; restore them
|
||||
// url.append("&action=approve&task=").append(taskId.toString());
|
||||
//
|
||||
// return url.toString();
|
||||
throw new UnsupportedOperationException("ToDo");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (C) 2001-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.workflow;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* Interface for generating a URL for a Task given the ID of the
|
||||
* ContentItem and the Task.
|
||||
*
|
||||
* @author Uday Mathur (umathur@arsdigita.com)
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
* */
|
||||
|
||||
public interface TaskURLGenerator {
|
||||
|
||||
String generateURL(long item_id, long task_id);
|
||||
}
|
||||
|
|
@ -65,67 +65,77 @@ import static org.librecms.CmsConstants.*;
|
|||
@Table(name = "CONTENT_ITEMS", schema = DB_SCHEMA)
|
||||
@NamedQueries({
|
||||
@NamedQuery(
|
||||
name = "ContentItem.findByType",
|
||||
query = "SELECT i FROM ContentItem i WHERE TYPE(i) = :type")
|
||||
name = "ContentItem.findByType",
|
||||
query = "SELECT i FROM ContentItem i WHERE TYPE(i) = :type")
|
||||
,
|
||||
@NamedQuery(
|
||||
name = "ContentItem.findByFolder",
|
||||
query = "SELECT i FROM ContentItem i "
|
||||
+ "JOIN i.categories c "
|
||||
+ "WHERE c.category = :folder "
|
||||
+ "AND c.type = '" + CATEGORIZATION_TYPE_FOLDER + "'")
|
||||
name = "ContentItem.findByFolder",
|
||||
query = "SELECT i FROM ContentItem i "
|
||||
+ "JOIN i.categories c "
|
||||
+ "WHERE c.category = :folder "
|
||||
+ "AND c.type = '" + CATEGORIZATION_TYPE_FOLDER
|
||||
+ "'")
|
||||
,
|
||||
@NamedQuery(
|
||||
name = "ContentItem.countItemsInFolder",
|
||||
query = "SELECT count(i) FROM ContentItem i "
|
||||
+ "JOIN i.categories c "
|
||||
+ "WHERE c.category = :folder "
|
||||
+ "AND c.type = '" + CATEGORIZATION_TYPE_FOLDER + "'")
|
||||
name = "ContentItem.countItemsInFolder",
|
||||
query = "SELECT count(i) FROM ContentItem i "
|
||||
+ "JOIN i.categories c "
|
||||
+ "WHERE c.category = :folder "
|
||||
+ "AND c.type = '" + CATEGORIZATION_TYPE_FOLDER
|
||||
+ "'")
|
||||
,
|
||||
@NamedQuery(
|
||||
name = "ContentItem.countByNameInFolder",
|
||||
query = "SELECT COUNT(i) FROM ContentItem i "
|
||||
+ "JOIN i.categories c "
|
||||
+ "WHERE c.category = :folder "
|
||||
+ "AND c.type = '" + CATEGORIZATION_TYPE_FOLDER + "' "
|
||||
+ "AND i.displayName = :name")
|
||||
name = "ContentItem.countByNameInFolder",
|
||||
query = "SELECT COUNT(i) FROM ContentItem i "
|
||||
+ "JOIN i.categories c "
|
||||
+ "WHERE c.category = :folder "
|
||||
+ "AND c.type = '" + CATEGORIZATION_TYPE_FOLDER
|
||||
+ "' "
|
||||
+ "AND i.displayName = :name")
|
||||
,
|
||||
@NamedQuery(
|
||||
name = "ContentItem.filterByFolderAndName",
|
||||
query = "SELECT i FROM ContentItem i "
|
||||
+ "JOIN i.categories c "
|
||||
+ "WHERE c.category = :folder "
|
||||
+ "AND c.type = '" + CATEGORIZATION_TYPE_FOLDER + "' "
|
||||
+ "AND LOWER(i.displayName) LIKE CONCAT(LOWER(:name), '%')")
|
||||
name = "ContentItem.filterByFolderAndName",
|
||||
query = "SELECT i FROM ContentItem i "
|
||||
+ "JOIN i.categories c "
|
||||
+ "WHERE c.category = :folder "
|
||||
+ "AND c.type = '" + CATEGORIZATION_TYPE_FOLDER
|
||||
+ "' "
|
||||
+ "AND LOWER(i.displayName) LIKE CONCAT(LOWER(:name), '%')")
|
||||
,
|
||||
@NamedQuery(
|
||||
name = "ContentItem.countFilterByFolderAndName",
|
||||
query = "SELECT COUNT(i) FROM ContentItem i "
|
||||
+ "JOIN i.categories c "
|
||||
+ "WHERE c.category = :folder "
|
||||
+ "AND c.type = '" + CATEGORIZATION_TYPE_FOLDER + "' "
|
||||
+ "AND LOWER(i.displayName) LIKE CONCAT(LOWER(:name), '%')"
|
||||
name = "ContentItem.countFilterByFolderAndName",
|
||||
query = "SELECT COUNT(i) FROM ContentItem i "
|
||||
+ "JOIN i.categories c "
|
||||
+ "WHERE c.category = :folder "
|
||||
+ "AND c.type = '" + CATEGORIZATION_TYPE_FOLDER
|
||||
+ "' "
|
||||
+ "AND LOWER(i.displayName) LIKE CONCAT(LOWER(:name), '%')"
|
||||
)
|
||||
,
|
||||
@NamedQuery(
|
||||
name = "ContentItem.hasLiveVersion",
|
||||
query = "SELECT (CASE WHEN COUNT(i) > 0 THEN true ELSE false END) "
|
||||
+ "FROM ContentItem i "
|
||||
+ "WHERE i.itemUuid = :uuid "
|
||||
+ "AND i.version = org.librecms.contentsection.ContentItemVersion.LIVE")
|
||||
name = "ContentItem.hasLiveVersion",
|
||||
query = "SELECT (CASE WHEN COUNT(i) > 0 THEN true ELSE false END) "
|
||||
+ "FROM ContentItem i "
|
||||
+ "WHERE i.itemUuid = :uuid "
|
||||
+ "AND i.version = org.librecms.contentsection.ContentItemVersion.LIVE")
|
||||
,
|
||||
@NamedQuery(
|
||||
name = "ContentItem.findDraftVersion",
|
||||
query = "SELECT i FROM ContentItem i "
|
||||
+ "WHERE i.itemUuid = :uuid "
|
||||
+ "AND i.version = org.librecms.contentsection.ContentItemVersion.DRAFT")
|
||||
name = "ContentItem.findDraftVersion",
|
||||
query = "SELECT i FROM ContentItem i "
|
||||
+ "WHERE i.itemUuid = :uuid "
|
||||
+ "AND i.version = org.librecms.contentsection.ContentItemVersion.DRAFT")
|
||||
,
|
||||
@NamedQuery(
|
||||
name = "ContentItem.findLiveVersion",
|
||||
query = "SELECT i FROM ContentItem i "
|
||||
+ "WHERE i.itemUuid = :uuid "
|
||||
+ "AND i.version = org.librecms.contentsection.ContentItemVersion.LIVE")
|
||||
|
||||
name = "ContentItem.findLiveVersion",
|
||||
query = "SELECT i FROM ContentItem i "
|
||||
+ "WHERE i.itemUuid = :uuid "
|
||||
+ "AND i.version = org.librecms.contentsection.ContentItemVersion.LIVE")
|
||||
,
|
||||
@NamedQuery(
|
||||
name = "ContentItem.findItemWithWorkflow",
|
||||
query = "SELECT i FROM ContentItem i "
|
||||
+ "WHERE i.workflow = :workflow"
|
||||
)
|
||||
})
|
||||
public class ContentItem extends CcmObject implements Serializable,
|
||||
InheritsPermissions {
|
||||
|
|
@ -143,13 +153,13 @@ public class ContentItem extends CcmObject implements Serializable,
|
|||
*/
|
||||
@Embedded
|
||||
@AssociationOverride(
|
||||
name = "values",
|
||||
joinTable = @JoinTable(name = "CONTENT_ITEM_NAMES",
|
||||
schema = DB_SCHEMA,
|
||||
joinColumns = {
|
||||
@JoinColumn(name = "OBJECT_ID")
|
||||
}
|
||||
)
|
||||
name = "values",
|
||||
joinTable = @JoinTable(name = "CONTENT_ITEM_NAMES",
|
||||
schema = DB_SCHEMA,
|
||||
joinColumns = {
|
||||
@JoinColumn(name = "OBJECT_ID")
|
||||
}
|
||||
)
|
||||
)
|
||||
private LocalizedString name;
|
||||
|
||||
|
|
@ -166,13 +176,13 @@ public class ContentItem extends CcmObject implements Serializable,
|
|||
*/
|
||||
@Embedded
|
||||
@AssociationOverride(
|
||||
name = "values",
|
||||
joinTable = @JoinTable(name = "CONTENT_ITEM_TITLES",
|
||||
schema = DB_SCHEMA,
|
||||
joinColumns = {
|
||||
@JoinColumn(name = "OBJECT_ID")
|
||||
}
|
||||
)
|
||||
name = "values",
|
||||
joinTable = @JoinTable(name = "CONTENT_ITEM_TITLES",
|
||||
schema = DB_SCHEMA,
|
||||
joinColumns = {
|
||||
@JoinColumn(name = "OBJECT_ID")
|
||||
}
|
||||
)
|
||||
)
|
||||
private LocalizedString title;
|
||||
|
||||
|
|
@ -181,12 +191,12 @@ public class ContentItem extends CcmObject implements Serializable,
|
|||
*/
|
||||
@Embedded
|
||||
@AssociationOverride(
|
||||
name = "values",
|
||||
joinTable = @JoinTable(name = "CONTENT_ITEM_DESCRIPTIONS",
|
||||
schema = DB_SCHEMA,
|
||||
joinColumns = {
|
||||
@JoinColumn(name = "OBJECT_ID")}
|
||||
))
|
||||
name = "values",
|
||||
joinTable = @JoinTable(name = "CONTENT_ITEM_DESCRIPTIONS",
|
||||
schema = DB_SCHEMA,
|
||||
joinColumns = {
|
||||
@JoinColumn(name = "OBJECT_ID")}
|
||||
))
|
||||
private LocalizedString description;
|
||||
|
||||
/**
|
||||
|
|
@ -342,10 +352,10 @@ public class ContentItem extends CcmObject implements Serializable,
|
|||
@Override
|
||||
public Optional<CcmObject> getParent() {
|
||||
final List<Categorization> result = getCategories().stream().filter(
|
||||
categorization -> CmsConstants.CATEGORIZATION_TYPE_FOLDER.
|
||||
equals(
|
||||
categorization.getType()))
|
||||
.collect(Collectors.toList());
|
||||
categorization -> CmsConstants.CATEGORIZATION_TYPE_FOLDER.
|
||||
equals(
|
||||
categorization.getType()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (result.isEmpty()) {
|
||||
return Optional.empty();
|
||||
|
|
@ -424,15 +434,15 @@ public class ContentItem extends CcmObject implements Serializable,
|
|||
@Override
|
||||
public String toString(final String data) {
|
||||
return super.toString(String.format(", itemUuid = %s, "
|
||||
+ "name = %s, "
|
||||
+ "contentType = { %s }, "
|
||||
+ "title = %s, "
|
||||
+ "description = %s, "
|
||||
+ "version = %s, "
|
||||
+ "launchDate = %s, "
|
||||
+ "lifecycle = { %s }, "
|
||||
+ "workflow = { %s }"
|
||||
+ "%s",
|
||||
+ "name = %s, "
|
||||
+ "contentType = { %s }, "
|
||||
+ "title = %s, "
|
||||
+ "description = %s, "
|
||||
+ "version = %s, "
|
||||
+ "launchDate = %s, "
|
||||
+ "lifecycle = { %s }, "
|
||||
+ "workflow = { %s }"
|
||||
+ "%s",
|
||||
itemUuid,
|
||||
Objects.toString(name),
|
||||
Objects.toString(contentType),
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -29,7 +29,9 @@ import java.util.UUID;
|
|||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.NoResultException;
|
||||
import javax.persistence.TypedQuery;
|
||||
import org.libreccm.workflow.Workflow;
|
||||
|
||||
/**
|
||||
* Repository for content items.
|
||||
|
|
@ -251,4 +253,17 @@ public class ContentItemRepository
|
|||
return query.getSingleResult();
|
||||
}
|
||||
|
||||
public Optional<ContentItem> findItemWithWorkflow(final Workflow workflow) {
|
||||
final TypedQuery<ContentItem> query = getEntityManager()
|
||||
.createNamedQuery("ContentItem.findItemWithWorkflow",
|
||||
ContentItem.class);
|
||||
query.setParameter("workflow", workflow);
|
||||
|
||||
try {
|
||||
return Optional.of(query.getSingleResult());
|
||||
} catch(NoResultException ex) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,14 +18,15 @@
|
|||
*/
|
||||
package org.librecms.workflow;
|
||||
|
||||
import org.libreccm.workflow.UserTask;
|
||||
import org.libreccm.workflow.AssignableTask;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import static org.librecms.CmsConstants.*;
|
||||
|
|
@ -36,12 +37,12 @@ import static org.librecms.CmsConstants.*;
|
|||
*/
|
||||
@Entity
|
||||
@Table(name = "WORKFLOW_TASKS", schema = DB_SCHEMA)
|
||||
public class CmsTask extends UserTask implements Serializable {
|
||||
public class CmsTask extends AssignableTask implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -3988352366529930659L;
|
||||
|
||||
@OneToOne
|
||||
@JoinColumn(name = "TASK_TYPE_ID")
|
||||
@Column(name = "TASK_TYPE")
|
||||
@Enumerated(EnumType.STRING)
|
||||
private CmsTaskType taskType;
|
||||
|
||||
public CmsTaskType getTaskType() {
|
||||
|
|
@ -79,7 +80,7 @@ public class CmsTask extends UserTask implements Serializable {
|
|||
return false;
|
||||
}
|
||||
|
||||
return Objects.equals(taskType, other.taskType);
|
||||
return Objects.equals(taskType, other.getTaskType());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2015 LibreCCM Foundation.
|
||||
* 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
|
||||
|
|
@ -18,188 +18,38 @@
|
|||
*/
|
||||
package org.librecms.workflow;
|
||||
|
||||
import org.libreccm.l10n.LocalizedString;
|
||||
import com.arsdigita.cms.workflow.AuthoringTaskURLGenerator;
|
||||
import com.arsdigita.cms.workflow.DeployTaskURLGenerator;
|
||||
import com.arsdigita.cms.workflow.EditingTaskURLGenerator;
|
||||
import com.arsdigita.cms.workflow.TaskURLGenerator;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.AssociationOverride;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Embedded;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.JoinTable;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import static org.librecms.CmsConstants.*;
|
||||
import org.librecms.contentsection.privileges.ItemPrivileges;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "WORKFLOW_TASK_TYPES", schema = DB_SCHEMA)
|
||||
public class CmsTaskType implements Serializable {
|
||||
public enum CmsTaskType {
|
||||
|
||||
private static final long serialVersionUID = -4326031746212785970L;
|
||||
AUTHOR(AuthoringTaskURLGenerator.class, ItemPrivileges.EDIT),
|
||||
EDIT(EditingTaskURLGenerator.class, ItemPrivileges.APPROVE),
|
||||
DEPLOY(DeployTaskURLGenerator.class, ItemPrivileges.PUBLISH);
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
@Column(name = "TASK_TYPE_ID")
|
||||
private long taskTypeId;
|
||||
private final Class<? extends TaskURLGenerator> urlGenerator;
|
||||
private final String privilege;
|
||||
|
||||
@Embedded
|
||||
@AssociationOverride(
|
||||
name = "values",
|
||||
joinTable = @JoinTable(name = "ARTICLE_LEADS",
|
||||
schema = DB_SCHEMA,
|
||||
joinColumns = {
|
||||
@JoinColumn(name = "OBJECT_ID")}
|
||||
))
|
||||
private LocalizedString name;
|
||||
|
||||
@Column(name = "DEFAULT_URL_GENERATOR_CLASS", length = 1024)
|
||||
private String defaultUrlGeneratorClass;
|
||||
|
||||
@Column(name = "PRIVILEGE", length = 256)
|
||||
private String privilege;
|
||||
|
||||
@OneToMany
|
||||
@JoinColumn(name = "TASK_TYPE_ID")
|
||||
private Set<TaskEventUrlGenerator> generators;
|
||||
|
||||
public CmsTaskType() {
|
||||
generators = new HashSet<>();
|
||||
}
|
||||
|
||||
public long getTaskTypeId() {
|
||||
return taskTypeId;
|
||||
}
|
||||
|
||||
protected void setTaskTypeId(final long taskTypeId) {
|
||||
this.taskTypeId = taskTypeId;
|
||||
}
|
||||
|
||||
public LocalizedString getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(final LocalizedString name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getDefaultUrlGeneratorClass() {
|
||||
return defaultUrlGeneratorClass;
|
||||
}
|
||||
|
||||
public void setDefaultUrlGeneratorClass(
|
||||
final String defaultUrlGeneratorClass) {
|
||||
this.defaultUrlGeneratorClass = defaultUrlGeneratorClass;
|
||||
}
|
||||
|
||||
public String getPrivilege() {
|
||||
return privilege;
|
||||
}
|
||||
|
||||
public void setPrivilege(final String privilege) {
|
||||
private CmsTaskType(final Class<? extends TaskURLGenerator> urlGenerator,
|
||||
final String privilege) {
|
||||
this.urlGenerator = urlGenerator;
|
||||
this.privilege = privilege;
|
||||
}
|
||||
|
||||
public Set<TaskEventUrlGenerator> getGenerators() {
|
||||
if (generators == null) {
|
||||
return null;
|
||||
} else {
|
||||
return Collections.unmodifiableSet(generators);
|
||||
}
|
||||
public Class<? extends TaskURLGenerator> getUrlGenerator() {
|
||||
return urlGenerator;
|
||||
}
|
||||
|
||||
protected void setGenerators(final Set<TaskEventUrlGenerator> generators) {
|
||||
this.generators = generators;
|
||||
|
||||
public String getPrivilege() {
|
||||
return privilege;
|
||||
}
|
||||
|
||||
public void addGenerator(final TaskEventUrlGenerator generator) {
|
||||
generators.add(generator);
|
||||
}
|
||||
|
||||
public void removeGenerator(final TaskEventUrlGenerator generator) {
|
||||
generators.remove(generator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 5;
|
||||
hash = 79 * hash + (int) (taskTypeId ^ (taskTypeId >>> 32));
|
||||
hash = 79 * hash + Objects.hashCode(name);
|
||||
hash = 79 * hash + Objects.hashCode(defaultUrlGeneratorClass);
|
||||
hash = 79 * hash + Objects.hashCode(privilege);
|
||||
hash = 79 * hash + Objects.hashCode(generators);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (obj instanceof CmsTaskType) {
|
||||
return false;
|
||||
}
|
||||
final CmsTaskType other = (CmsTaskType) obj;
|
||||
if (!other.canEqual(this)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (taskTypeId != other.getTaskTypeId()) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(defaultUrlGeneratorClass,
|
||||
other.getDefaultUrlGeneratorClass())) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(privilege, other.getPrivilege())) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(name, other.getName())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Objects.equals(generators, other.getGenerators());
|
||||
}
|
||||
|
||||
public boolean canEqual(final Object obj) {
|
||||
return obj instanceof CmsTaskType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String toString() {
|
||||
return toString("");
|
||||
}
|
||||
|
||||
public String toString(final String data) {
|
||||
return String.format("%s{ "
|
||||
+ "taskTypeId = %d, "
|
||||
+ "name = %s, "
|
||||
+ "defaultUrlGeneratorClass = \"%s\", "
|
||||
+ "privilege = \"%s\","
|
||||
+ "generators = { %s }%s"
|
||||
+ " }",
|
||||
super.toString(),
|
||||
taskTypeId,
|
||||
Objects.toString(name),
|
||||
defaultUrlGeneratorClass,
|
||||
privilege,
|
||||
Objects.toString(generators),
|
||||
data);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* 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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@RequestScoped
|
||||
public class CmsTaskTypeRepository extends AbstractEntityRepository<Long, CmsTaskType>{
|
||||
|
||||
@Override
|
||||
public Class<CmsTaskType> getEntityClass() {
|
||||
return CmsTaskType.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNew(final CmsTaskType taskType) {
|
||||
return taskType.getTaskTypeId() == 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,156 +0,0 @@
|
|||
/*
|
||||
* 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.librecms.contentsection.ContentType;
|
||||
|
||||
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.OneToOne;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import static org.librecms.CmsConstants.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "TASK_EVENT_URL_GENERATOR", schema = DB_SCHEMA)
|
||||
public class TaskEventUrlGenerator implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -1861545657474968084L;
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
@Column(name = "GENERATOR_ID")
|
||||
private long generatorId;
|
||||
|
||||
@Column(name = "EVENT", length = 256)
|
||||
private String event;
|
||||
|
||||
@OneToOne
|
||||
@JoinColumn(name = "CONTENT_TYPE_ID")
|
||||
private ContentType contentType;
|
||||
|
||||
@Column(name = "URL_GENERATOR_CLASS", length = 1024)
|
||||
private String urlGeneratorClass;
|
||||
|
||||
public long getGeneratorId() {
|
||||
return generatorId;
|
||||
}
|
||||
|
||||
public void setGeneratorId(final long generatorId) {
|
||||
this.generatorId = generatorId;
|
||||
}
|
||||
|
||||
public String getEvent() {
|
||||
return event;
|
||||
}
|
||||
|
||||
public void setEvent(final String event) {
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
public ContentType getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
public void setContentType(final ContentType contentType) {
|
||||
this.contentType = contentType;
|
||||
}
|
||||
|
||||
public String getUrlGeneratorClass() {
|
||||
return urlGeneratorClass;
|
||||
}
|
||||
|
||||
public void setUrlGeneratorClass(final String urlGeneratorClass) {
|
||||
this.urlGeneratorClass = urlGeneratorClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 3;
|
||||
hash = 47 * hash + (int) (generatorId ^ (generatorId >>> 32));
|
||||
hash = 47 * hash + Objects.hashCode(event);
|
||||
hash = 47 * hash + Objects.hashCode(contentType);
|
||||
hash = 47 * hash + Objects.hashCode(urlGeneratorClass);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (obj instanceof TaskEventUrlGenerator) {
|
||||
return false;
|
||||
}
|
||||
final TaskEventUrlGenerator other = (TaskEventUrlGenerator) obj;
|
||||
if (!(other.canEqual(this))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (generatorId != other.getGeneratorId()) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(event, other.getEvent())) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(urlGeneratorClass, other.getUrlGeneratorClass())) {
|
||||
return false;
|
||||
}
|
||||
return Objects.equals(contentType, other.getContentType());
|
||||
}
|
||||
|
||||
public boolean canEqual(final Object obj) {
|
||||
return obj instanceof TaskEventUrlGenerator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String toString() {
|
||||
return toString("");
|
||||
}
|
||||
|
||||
public String toString(final String data) {
|
||||
return String.format("%s{ "
|
||||
+ "generatorId = %d, "
|
||||
+ "event = \"%s\", "
|
||||
+ "contentType = %s, "
|
||||
+ "urlGeneratorClass = \"%s\"%s"
|
||||
+ " }",
|
||||
super.toString(),
|
||||
generatorId,
|
||||
event,
|
||||
Objects.toString(contentType),
|
||||
urlGeneratorClass,
|
||||
data);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -45,31 +45,37 @@ import javax.persistence.TemporalType;
|
|||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "WORKFLOW_USER_TASKS", schema = DB_SCHEMA)
|
||||
@Table(name = "WORKFLOW_ASSIGNABLE_TASKS", schema = DB_SCHEMA)
|
||||
@NamedQueries({
|
||||
@NamedQuery(
|
||||
name = "UserTask.findLockedBy",
|
||||
query = "SELECT t FROM UserTask t WHERE t.lockingUser = :user")
|
||||
name = "AssignableTask.findLockedBy",
|
||||
query = "SELECT t FROM AssignableTask t WHERE t.lockingUser = :user")
|
||||
,
|
||||
@NamedQuery(
|
||||
name = "UserTask.findEnabledTasksForWorkflow",
|
||||
query = "SELECT t FROM UserTask t "
|
||||
name = "AssignableTask.findEnabledTasksForWorkflow",
|
||||
query = "SELECT t FROM AssignableTask t "
|
||||
+ "WHERE t.lockingUser = :user "
|
||||
+ "AND t.workflow = :workflow"
|
||||
)
|
||||
,
|
||||
@NamedQuery(
|
||||
name = "UserTask.findAssignedTasks",
|
||||
query = "SELECT t FROM UserTask t "
|
||||
name = "AssignableTask.findAssignedTasks",
|
||||
query = "SELECT t FROM AssignableTask t "
|
||||
+ "WHERE t.assignments.role IN :roles "
|
||||
+ "AND t.assignments.workflow = :workflow "
|
||||
+ "AND t.active = true")
|
||||
,
|
||||
@NamedQuery(
|
||||
name = "AssignableTask.findOverdueTasks",
|
||||
query = "SELECT t FROM AssignableTask t "
|
||||
+ "WHERE t.workflow = :workflow "
|
||||
+ "AND t.dueDate < :now")
|
||||
})
|
||||
//Can't reduce complexity yet
|
||||
@SuppressWarnings({"PMD.CyclomaticComplexity",
|
||||
"PMD.StdCyclomaticComplexity",
|
||||
"PMD.ModifiedCyclomaticComplexity"})
|
||||
public class UserTask extends Task implements Serializable {
|
||||
public class AssignableTask extends Task implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 4188064584389893019L;
|
||||
|
||||
|
|
@ -99,7 +105,7 @@ public class UserTask extends Task implements Serializable {
|
|||
@OneToMany(mappedBy = "task")
|
||||
private List<TaskAssignment> assignments;
|
||||
|
||||
public UserTask() {
|
||||
public AssignableTask() {
|
||||
super();
|
||||
assignments = new ArrayList<>();
|
||||
}
|
||||
|
|
@ -217,10 +223,10 @@ public class UserTask extends Task implements Serializable {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!(obj instanceof UserTask)) {
|
||||
if (!(obj instanceof AssignableTask)) {
|
||||
return false;
|
||||
}
|
||||
final UserTask other = (UserTask) obj;
|
||||
final AssignableTask other = (AssignableTask) obj;
|
||||
if (!other.canEqual(this)) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -245,7 +251,7 @@ public class UserTask extends Task implements Serializable {
|
|||
|
||||
@Override
|
||||
public boolean canEqual(final Object obj) {
|
||||
return obj instanceof UserTask;
|
||||
return obj instanceof AssignableTask;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -33,40 +33,43 @@ import javax.persistence.TypedQuery;
|
|||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@RequestScoped
|
||||
public class UserTaskRepository extends AbstractEntityRepository<Long, UserTask> {
|
||||
public class AssignableTaskRepository
|
||||
extends AbstractEntityRepository<Long, AssignableTask> {
|
||||
|
||||
@Override
|
||||
public Class<UserTask> getEntityClass() {
|
||||
return UserTask.class;
|
||||
public Class<AssignableTask> getEntityClass() {
|
||||
return AssignableTask.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNew(final UserTask task) {
|
||||
public boolean isNew(final AssignableTask task) {
|
||||
return task.getTaskId() == 0;
|
||||
}
|
||||
|
||||
public List<UserTask> findEnabledTasksForWorkflow(final User user,
|
||||
final Workflow workflow) {
|
||||
final TypedQuery<UserTask> query = getEntityManager().createNamedQuery(
|
||||
"UserTask.findEnabledTasksForWorkflow", UserTask.class);
|
||||
public List<AssignableTask> findEnabledTasksForWorkflow(
|
||||
final User user, final Workflow workflow) {
|
||||
final TypedQuery<AssignableTask> query = getEntityManager()
|
||||
.createNamedQuery(
|
||||
"UserTask.findEnabledTasksForWorkflow", AssignableTask.class);
|
||||
query.setParameter("user", user);
|
||||
query.setParameter("workflow", workflow);
|
||||
|
||||
return query.getResultList();
|
||||
}
|
||||
|
||||
public List<UserTask> getAssignedTasks(final User user,
|
||||
final Workflow workflow) {
|
||||
final TypedQuery<UserTask> query = getEntityManager().createNamedQuery(
|
||||
"UserTask.findAssignedTasks", UserTask.class);
|
||||
|
||||
public List<AssignableTask> getAssignedTasks(final User user,
|
||||
final Workflow workflow) {
|
||||
final TypedQuery<AssignableTask> query = getEntityManager()
|
||||
.createNamedQuery(
|
||||
"UserTask.findAssignedTasks", AssignableTask.class);
|
||||
final List<Role> roles = user.getRoleMemberships()
|
||||
.stream()
|
||||
.map(membership -> membership.getRole())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
query.setParameter("roles", roles );
|
||||
.stream()
|
||||
.map(membership -> membership.getRole())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
query.setParameter("roles", roles);
|
||||
query.setParameter("workflow", workflow);
|
||||
|
||||
|
||||
return query.getResultList();
|
||||
}
|
||||
|
||||
|
|
@ -30,9 +30,10 @@ import java.util.Objects;
|
|||
|
||||
import javax.persistence.AssociationOverride;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.ElementCollection;
|
||||
import javax.persistence.Embedded;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
|
|
@ -40,9 +41,11 @@ import javax.persistence.Inheritance;
|
|||
import javax.persistence.InheritanceType;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.JoinTable;
|
||||
import javax.persistence.Lob;
|
||||
import javax.persistence.ManyToMany;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
|
||||
/**
|
||||
|
|
@ -59,6 +62,35 @@ import javax.persistence.Table;
|
|||
"PMD.ShortClassName",
|
||||
"PMD.TooManyMethods",
|
||||
"PMD.AvoidDuplicateLiterals"})
|
||||
@NamedQueries({
|
||||
@NamedQuery(
|
||||
name = "Task.countUnfinishedAndActiveTasksForWorkflow",
|
||||
query = "SELECT COUNT(t) FROM Task t "
|
||||
+ "WHERE t.taskState != org.libreccm.workflow.TaskState.FINISHED "
|
||||
+ "AND t.active = true "
|
||||
+ "AND t.workflow = :workflow")
|
||||
,
|
||||
@NamedQuery(
|
||||
name = "Task.countUnfinishedTasksForWorkflow",
|
||||
query = "SELECT COUNT(t) FROM Task t "
|
||||
+ "WHERE t.taskState != org.libreccm.workflow.TaskState.FINISHED "
|
||||
+ "AND t.workflow = :workflow"
|
||||
)
|
||||
,
|
||||
@NamedQuery(
|
||||
name = "Task.findEnabledTasks",
|
||||
query = "SELECT t FROM Task t "
|
||||
+ "WHERE t.workflow = :workflow "
|
||||
+ "AND t.taskState = org.libreccm.workflow.TaskState.ENABLED "
|
||||
+ "AND t.active = true"
|
||||
)
|
||||
,
|
||||
@NamedQuery(
|
||||
name = "Task.findFinishedTasks",
|
||||
query = "SELECT t FROM Task t "
|
||||
+ "WHERE t.workflow = :workflow "
|
||||
+ "AND t.taskState = org.libreccm.workflow.TaskState.FINISHED")
|
||||
})
|
||||
public class Task implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 8161343036908150426L;
|
||||
|
|
@ -70,27 +102,28 @@ public class Task implements Serializable {
|
|||
|
||||
@Embedded
|
||||
@AssociationOverride(
|
||||
name = "values",
|
||||
joinTable = @JoinTable(name = "WORKFLOW_TASK_LABELS",
|
||||
schema = DB_SCHEMA,
|
||||
joinColumns = {
|
||||
@JoinColumn(name = "TASK_ID")}))
|
||||
name = "values",
|
||||
joinTable = @JoinTable(name = "WORKFLOW_TASK_LABELS",
|
||||
schema = DB_SCHEMA,
|
||||
joinColumns = {
|
||||
@JoinColumn(name = "TASK_ID")}))
|
||||
private LocalizedString label;
|
||||
|
||||
@Embedded
|
||||
@AssociationOverride(
|
||||
name = "values",
|
||||
joinTable = @JoinTable(name = "WORKFLOW_TASKS_DESCRIPTIONS",
|
||||
schema = DB_SCHEMA,
|
||||
joinColumns = {
|
||||
@JoinColumn(name = "TASK_ID")}))
|
||||
name = "values",
|
||||
joinTable = @JoinTable(name = "WORKFLOW_TASKS_DESCRIPTIONS",
|
||||
schema = DB_SCHEMA,
|
||||
joinColumns = {
|
||||
@JoinColumn(name = "TASK_ID")}))
|
||||
private LocalizedString description;
|
||||
|
||||
@Column(name = "ACTIVE")
|
||||
private boolean active;
|
||||
|
||||
@Column(name = "TASK_STATE", length = 512)
|
||||
private String taskState;
|
||||
@Enumerated(EnumType.STRING)
|
||||
private TaskState taskState;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "WORKFLOW_ID")
|
||||
|
|
@ -108,14 +141,9 @@ public class Task implements Serializable {
|
|||
@JoinColumn(name = "DEPENDENT_TASK_ID")})
|
||||
private List<Task> dependsOn;
|
||||
|
||||
@ElementCollection
|
||||
@JoinTable(name = "WORKFLOW_TASK_COMMENTS",
|
||||
schema = DB_SCHEMA,
|
||||
joinColumns = {
|
||||
@JoinColumn(name = "TASK_ID")})
|
||||
@Column(name = "COMMENT")
|
||||
@Lob
|
||||
private List<String> comments;
|
||||
@OneToMany
|
||||
@JoinColumn(name = "TASK_ID")
|
||||
private List<TaskComment> comments;
|
||||
|
||||
public Task() {
|
||||
super();
|
||||
|
|
@ -159,11 +187,11 @@ public class Task implements Serializable {
|
|||
this.active = active;
|
||||
}
|
||||
|
||||
public String getTaskState() {
|
||||
public TaskState getTaskState() {
|
||||
return taskState;
|
||||
}
|
||||
|
||||
public void setTaskState(final String taskState) {
|
||||
protected void setTaskState(final TaskState taskState) {
|
||||
this.taskState = taskState;
|
||||
}
|
||||
|
||||
|
|
@ -215,7 +243,7 @@ public class Task implements Serializable {
|
|||
dependsOn.remove(task);
|
||||
}
|
||||
|
||||
public List<String> getComments() {
|
||||
public List<TaskComment> getComments() {
|
||||
if (comments == null) {
|
||||
return null;
|
||||
} else {
|
||||
|
|
@ -223,15 +251,15 @@ public class Task implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
protected void setComments(final List<String> comments) {
|
||||
protected void setComments(final List<TaskComment> comments) {
|
||||
this.comments = comments;
|
||||
}
|
||||
|
||||
public void addComment(final String comment) {
|
||||
public void addComment(final TaskComment comment) {
|
||||
comments.add(comment);
|
||||
}
|
||||
|
||||
public void removeComment(final String comment) {
|
||||
public void removeComment(final TaskComment comment) {
|
||||
comments.remove(comment);
|
||||
}
|
||||
|
||||
|
|
@ -294,14 +322,14 @@ public class Task implements Serializable {
|
|||
|
||||
public String toString(final String data) {
|
||||
return String.format("%s{ "
|
||||
+ "taskId = %d, "
|
||||
+ "label = %s, "
|
||||
+ "active = %b, "
|
||||
+ "taskState = \"%s\", "
|
||||
+ "workflow = %s, "
|
||||
+ "dependentTasks = %s, "
|
||||
+ "dependsOn = %s%s"
|
||||
+ " }",
|
||||
+ "taskId = %d, "
|
||||
+ "label = %s, "
|
||||
+ "active = %b, "
|
||||
+ "taskState = \"%s\", "
|
||||
+ "workflow = %s, "
|
||||
+ "dependentTasks = %s, "
|
||||
+ "dependsOn = %s%s"
|
||||
+ " }",
|
||||
super.toString(),
|
||||
taskId,
|
||||
Objects.toString(label),
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ public class TaskAssignment implements Serializable {
|
|||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "TASK_ID")
|
||||
private UserTask task;
|
||||
private AssignableTask task;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "ROLE_ID")
|
||||
|
|
@ -65,11 +65,11 @@ public class TaskAssignment implements Serializable {
|
|||
this.taskAssignmentId = taskAssignmentId;
|
||||
}
|
||||
|
||||
public UserTask getTask() {
|
||||
public AssignableTask getTask() {
|
||||
return task;
|
||||
}
|
||||
|
||||
protected void setTask(final UserTask task) {
|
||||
protected void setTask(final AssignableTask task) {
|
||||
this.task = task;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ package org.libreccm.workflow;
|
|||
|
||||
import static org.libreccm.core.CoreConstants.*;
|
||||
|
||||
import org.libreccm.core.CcmObject;
|
||||
import org.libreccm.l10n.LocalizedString;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
|
@ -32,6 +33,8 @@ 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.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
|
|
@ -40,7 +43,10 @@ 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.OneToOne;
|
||||
import javax.persistence.Table;
|
||||
|
||||
/**
|
||||
|
|
@ -50,6 +56,12 @@ import javax.persistence.Table;
|
|||
@Entity
|
||||
@Table(name = "WORKFLOWS", schema = DB_SCHEMA)
|
||||
@Inheritance(strategy = InheritanceType.JOINED)
|
||||
@NamedQueries({
|
||||
@NamedQuery(
|
||||
name = "Workflow.findForObject",
|
||||
query = "SELECT w FROM Workflow w "
|
||||
+ "WHERE W.object = :object")
|
||||
})
|
||||
public class Workflow implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 4322500264543325829L;
|
||||
|
|
@ -62,7 +74,7 @@ public class Workflow implements Serializable {
|
|||
@ManyToOne
|
||||
@JoinColumn(name = "TEMPLATE_ID")
|
||||
private WorkflowTemplate template;
|
||||
|
||||
|
||||
@Embedded
|
||||
@AssociationOverride(
|
||||
name = "values",
|
||||
|
|
@ -82,6 +94,21 @@ public class Workflow implements Serializable {
|
|||
}))
|
||||
private LocalizedString description;
|
||||
|
||||
@Column(name = "WORKFLOW_STATE")
|
||||
@Enumerated(EnumType.STRING)
|
||||
private WorkflowState state;
|
||||
|
||||
@Column(name = "ACTIVE")
|
||||
private boolean active;
|
||||
|
||||
@Column(name = "TASKS_STATE")
|
||||
@Enumerated(EnumType.STRING)
|
||||
private TaskState tasksState;
|
||||
|
||||
@OneToOne
|
||||
@JoinColumn(name = "OBJECT_ID")
|
||||
private CcmObject object;
|
||||
|
||||
@OneToMany(mappedBy = "workflow")
|
||||
private List<Task> tasks;
|
||||
|
||||
|
|
@ -100,11 +127,11 @@ public class Workflow implements Serializable {
|
|||
public void setWorkflowId(final long workflowId) {
|
||||
this.workflowId = workflowId;
|
||||
}
|
||||
|
||||
|
||||
public WorkflowTemplate getTemplate() {
|
||||
return template;
|
||||
}
|
||||
|
||||
|
||||
protected void setTemplate(final WorkflowTemplate template) {
|
||||
this.template = template;
|
||||
}
|
||||
|
|
@ -125,6 +152,38 @@ public class Workflow implements Serializable {
|
|||
this.description = description;
|
||||
}
|
||||
|
||||
public WorkflowState getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
protected void setState(final WorkflowState state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
protected void setActive(final boolean active) {
|
||||
this.active = active;
|
||||
}
|
||||
|
||||
public TaskState getTasksState() {
|
||||
return tasksState;
|
||||
}
|
||||
|
||||
protected void setTasksState(final TaskState tasksState) {
|
||||
this.tasksState = tasksState;
|
||||
}
|
||||
|
||||
public CcmObject getObject() {
|
||||
return object;
|
||||
}
|
||||
|
||||
protected void setObject(final CcmObject object) {
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
public List<Task> getTasks() {
|
||||
if (tasks == null) {
|
||||
return null;
|
||||
|
|
@ -150,6 +209,11 @@ public class Workflow implements Serializable {
|
|||
int hash = 5;
|
||||
hash = 79 * hash + (int) (this.workflowId ^ (this.workflowId >>> 32));
|
||||
hash = 79 * hash + Objects.hashCode(this.name);
|
||||
hash = 79 * hash + Objects.hashCode(description);
|
||||
hash = 79 * hash + Objects.hashCode(state);
|
||||
hash = 79 * hash + (active ? 1 : 0);
|
||||
hash = 79 * hash + Objects.hashCode(tasksState);
|
||||
hash = 79 * hash + Objects.hashCode(object);
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
|
@ -166,11 +230,32 @@ public class Workflow implements Serializable {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (this.workflowId != other.getWorkflowId()) {
|
||||
if (workflowId != other.getWorkflowId()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Objects.equals(name, other.getName())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Objects.equals(description, other.getDescription())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Objects.equals(state, other.getState())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (active != other.isActive()) {
|
||||
return false;
|
||||
}
|
||||
return Objects.equals(this.name, other.getName());
|
||||
|
||||
if (!Objects.equals(tasksState, other.getTasksState())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Objects.equals(object, other.getObject());
|
||||
|
||||
}
|
||||
|
||||
public boolean canEqual(final Object obj) {
|
||||
|
|
@ -185,12 +270,20 @@ public class Workflow implements Serializable {
|
|||
public String toString(final String data) {
|
||||
return String.format("%s{ "
|
||||
+ "workflowId = %d, "
|
||||
+ "name = \"%s\"%s"
|
||||
+ "name = \"%s\", "
|
||||
+ "description = \"%s\", "
|
||||
+ "state = \"%s\", "
|
||||
+ "active = %b"
|
||||
+ "object = \"%s\"%s"
|
||||
+ " }",
|
||||
super.toString(),
|
||||
workflowId,
|
||||
name,
|
||||
Objects.toString(name),
|
||||
Objects.toString(description),
|
||||
Objects.toString(state),
|
||||
active,
|
||||
Objects.toString(object),
|
||||
data);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,14 +18,17 @@
|
|||
*/
|
||||
package org.libreccm.workflow;
|
||||
|
||||
import com.arsdigita.kernel.KernelConfig;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.libreccm.configuration.ConfigurationManager;
|
||||
import org.libreccm.core.CcmObject;
|
||||
import org.libreccm.core.CoreConstants;
|
||||
import org.libreccm.l10n.LocalizedString;
|
||||
import org.libreccm.security.AuthorizationRequired;
|
||||
import org.libreccm.security.RequiresPrivilege;
|
||||
import org.libreccm.security.Role;
|
||||
import org.libreccm.security.RoleRepository;
|
||||
import org.libreccm.security.Shiro;
|
||||
import org.libreccm.security.User;
|
||||
|
||||
import java.beans.BeanInfo;
|
||||
import java.beans.IntrospectionException;
|
||||
|
|
@ -33,12 +36,14 @@ import java.beans.Introspector;
|
|||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.inject.Inject;
|
||||
import javax.persistence.EntityManager;
|
||||
|
|
@ -52,6 +57,9 @@ import javax.transaction.Transactional;
|
|||
@RequestScoped
|
||||
public class WorkflowManager {
|
||||
|
||||
private final static Logger LOGGER = LogManager.getLogger(
|
||||
WorkflowManager.class);
|
||||
|
||||
@Inject
|
||||
private EntityManager entityManager;
|
||||
|
||||
|
|
@ -62,15 +70,28 @@ public class WorkflowManager {
|
|||
private TaskRepository taskRepo;
|
||||
|
||||
@Inject
|
||||
private RoleRepository roleRepo;
|
||||
private TaskManager taskManager;
|
||||
|
||||
@Inject
|
||||
private Shiro shiro;
|
||||
|
||||
@Inject
|
||||
private ConfigurationManager confManager;
|
||||
|
||||
private Locale defaultLocale;
|
||||
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
final KernelConfig kernelConfig = confManager.findConfiguration(
|
||||
KernelConfig.class);
|
||||
defaultLocale = kernelConfig.getDefaultLocale();
|
||||
}
|
||||
|
||||
@AuthorizationRequired
|
||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public Workflow createWorkflow(final WorkflowTemplate template) {
|
||||
public Workflow createWorkflow(final WorkflowTemplate template,
|
||||
final CcmObject object) {
|
||||
final Workflow workflow = new Workflow();
|
||||
|
||||
final LocalizedString name = new LocalizedString();
|
||||
|
|
@ -90,6 +111,9 @@ public class WorkflowManager {
|
|||
template.getTasks().forEach(taskTemplate -> fixTaskDependencies(
|
||||
taskTemplate, tasks.get(taskTemplate.getTaskId()), tasks));
|
||||
|
||||
workflow.setObject(object);
|
||||
workflow.setState(WorkflowState.INIT);
|
||||
|
||||
tasks.values().forEach(task -> taskRepo.save(task));
|
||||
workflowRepo.save(workflow);
|
||||
|
||||
|
|
@ -172,139 +196,161 @@ public class WorkflowManager {
|
|||
@AuthorizationRequired
|
||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public void addTask(final Workflow workflow, final Task task) {
|
||||
workflow.addTask(task);
|
||||
task.setWorkflow(workflow);
|
||||
|
||||
workflowRepo.save(workflow);
|
||||
taskRepo.save(task);
|
||||
}
|
||||
|
||||
@AuthorizationRequired
|
||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public void removeTask(final Workflow workflow, final Task task) {
|
||||
workflow.removeTask(task);
|
||||
task.setWorkflow(null);
|
||||
|
||||
workflowRepo.save(workflow);
|
||||
taskRepo.save(task);
|
||||
}
|
||||
|
||||
@AuthorizationRequired
|
||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public void assignTask(final UserTask task, final Role role) {
|
||||
final TaskAssignment assignment = new TaskAssignment();
|
||||
assignment.setTask(task);
|
||||
assignment.setRole(role);
|
||||
|
||||
task.addAssignment(assignment);
|
||||
role.addAssignedTask(assignment);
|
||||
|
||||
entityManager.persist(assignment);
|
||||
taskRepo.save(task);
|
||||
roleRepo.save(role);
|
||||
}
|
||||
|
||||
@AuthorizationRequired
|
||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public void retractTask(final UserTask task, final Role role) {
|
||||
final List<TaskAssignment> result = task.getAssignments().stream()
|
||||
.filter(assigned -> role.equals(assigned.getRole()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (!result.isEmpty()) {
|
||||
final TaskAssignment assignment = result.get(0);
|
||||
task.removeAssignment(assignment);
|
||||
role.removeAssignedTask(assignment);
|
||||
entityManager.remove(assignment);
|
||||
public List<Task> findEnabledTasks(final Workflow workflow) {
|
||||
if (workflow.getState() == WorkflowState.DELETED
|
||||
|| workflow.getState() == WorkflowState.STOPPED) {
|
||||
LOGGER.debug(String.format("Workflow state is \"%s\". Workflow "
|
||||
+ "has no enabled tasks.",
|
||||
workflow.getState().toString()));
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final TypedQuery<Task> query = entityManager.createNamedQuery(
|
||||
"Task.findEnabledTasks", Task.class);
|
||||
query.setParameter("workflow", workflow);
|
||||
|
||||
return Collections.unmodifiableList(query.getResultList());
|
||||
}
|
||||
|
||||
@AuthorizationRequired
|
||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public void addDependentTask(final Task parent, final Task task) {
|
||||
parent.addDependentTask(task);
|
||||
task.addDependsOn(parent);
|
||||
public List<Task> findFinishedTasks(final Workflow workflow) {
|
||||
final TypedQuery<Task> query = entityManager.createNamedQuery(
|
||||
"Task.findFinishedTasks", Task.class);
|
||||
query.setParameter("workflow", workflow);
|
||||
|
||||
taskRepo.save(task);
|
||||
taskRepo.save(parent);
|
||||
return Collections.unmodifiableList(query.getResultList());
|
||||
}
|
||||
|
||||
@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 List<AssignableTask> findOverdueTasks(final Workflow workflow) {
|
||||
final TypedQuery<AssignableTask> query = entityManager.createNamedQuery(
|
||||
"AssignableTask.findOverdueTasks", AssignableTask.class);
|
||||
query.setParameter("workflow", workflow);
|
||||
query.setParameter("now", new Date());
|
||||
|
||||
taskRepo.save(task);
|
||||
taskRepo.save(parent);
|
||||
return Collections.unmodifiableList(query.getResultList());
|
||||
}
|
||||
|
||||
@AuthorizationRequired
|
||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public void lockTask(final UserTask task) {
|
||||
task.setLocked(true);
|
||||
task.setLockingUser(shiro.getUser());
|
||||
|
||||
taskRepo.save(task);
|
||||
}
|
||||
|
||||
@AuthorizationRequired
|
||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public void unlockTask(final UserTask task) {
|
||||
task.setLocked(false);
|
||||
task.setLockingUser(null);
|
||||
|
||||
taskRepo.save(task);
|
||||
}
|
||||
|
||||
@AuthorizationRequired
|
||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public List<UserTask> lockedBy(final User user) {
|
||||
final TypedQuery<UserTask> query = entityManager.createNamedQuery(
|
||||
"UserTask.findLockedBy", UserTask.class);
|
||||
query.setParameter("user", user);
|
||||
|
||||
return query.getResultList();
|
||||
}
|
||||
|
||||
public void start(final Workflow workflow) {
|
||||
if (workflow.getTasks() != null && !workflow.getTasks().isEmpty()) {
|
||||
final Task first = workflow.getTasks().get(0);
|
||||
final WorkflowState oldState = workflow.getState();
|
||||
|
||||
if (first instanceof UserTask) {
|
||||
final User user = shiro.getUser();
|
||||
lockTask((UserTask) first);
|
||||
workflow.setState(WorkflowState.STARTED);
|
||||
if (oldState == WorkflowState.INIT) {
|
||||
workflow.setActive(true);
|
||||
updateState(workflow);
|
||||
|
||||
for (final Task current : workflow.getTasks()) {
|
||||
current.setActive(true);
|
||||
taskManager.updateState(current);
|
||||
}
|
||||
}
|
||||
|
||||
workflowRepo.save(workflow);
|
||||
}
|
||||
|
||||
@AuthorizationRequired
|
||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
private void updateState(final Workflow workflow) {
|
||||
if (workflow.getTasksState() == TaskState.ENABLED) {
|
||||
final TypedQuery<Long> query = entityManager.createNamedQuery(
|
||||
"Task.countUnfinishedAndActiveTasksForWorkflow", Long.class);
|
||||
query.setParameter("workflow", workflow);
|
||||
|
||||
final Long result = query.getSingleResult();
|
||||
|
||||
if (result > 0) {
|
||||
return;
|
||||
} else {
|
||||
finish(workflow);
|
||||
}
|
||||
}
|
||||
|
||||
if (workflow.getTasksState() == TaskState.FINISHED) {
|
||||
final TypedQuery<Long> query = entityManager.createNamedQuery(
|
||||
"Task.countUnfinishedTasksForWorkflow", Long.class);
|
||||
query.setParameter("workflow", workflow);
|
||||
|
||||
final Long result = query.getSingleResult();
|
||||
|
||||
if (result > 0) {
|
||||
enable(workflow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the state of a workflow.
|
||||
*
|
||||
* @param workflow
|
||||
* @return
|
||||
*/
|
||||
public int getState(final Workflow workflow) {
|
||||
@AuthorizationRequired
|
||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public void stop(final Workflow workflow) {
|
||||
workflow.setState(WorkflowState.STOPPED);
|
||||
workflowRepo.save(workflow);
|
||||
}
|
||||
|
||||
final Optional<Task> activeTask = workflow.getTasks()
|
||||
.stream()
|
||||
.filter(task -> task.isActive())
|
||||
.findAny();
|
||||
@AuthorizationRequired
|
||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public void finish(final Workflow workflow) {
|
||||
if (workflow.getTasksState() != TaskState.ENABLED) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"Workflow \"%s\" is not enabled.",
|
||||
workflow.getName().getValue(defaultLocale)));
|
||||
}
|
||||
|
||||
if (activeTask.isPresent()) {
|
||||
return WorkflowConstants.STARTED;
|
||||
} else {
|
||||
return -1;
|
||||
workflow.setTasksState(TaskState.FINISHED);
|
||||
workflowRepo.save(workflow);
|
||||
|
||||
}
|
||||
|
||||
@AuthorizationRequired
|
||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public void enable(final Workflow workflow) {
|
||||
if (workflow.getTasksState() == TaskState.ENABLED) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (workflow.getTasksState()) {
|
||||
case DISABLED:
|
||||
LOGGER.debug("Workflow \"{}\" is disabled; enabling it.",
|
||||
workflow.getName().getValue(defaultLocale));
|
||||
workflow.setTasksState(TaskState.ENABLED);
|
||||
workflowRepo.save(workflow);
|
||||
break;
|
||||
case FINISHED:
|
||||
LOGGER.debug("Workflow \"{}\" is finished; reenabling it.");
|
||||
workflow.setTasksState(TaskState.ENABLED);
|
||||
workflowRepo.save(workflow);
|
||||
break;
|
||||
default:
|
||||
LOGGER.debug("Workflow \"{}\" has tasksState \"{}\", "
|
||||
+ "#enable(Workflow) does nothing.",
|
||||
workflow.getName().getValue(defaultLocale),
|
||||
workflow.getTasksState());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@AuthorizationRequired
|
||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public void disable(final Workflow workflow) {
|
||||
if (workflow.getTasksState() == TaskState.DISABLED) {
|
||||
return;
|
||||
}
|
||||
|
||||
workflow.setTasksState(TaskState.DISABLED);
|
||||
workflowRepo.save(workflow);
|
||||
|
||||
workflow.getTasks().forEach(task -> taskManager.disable(task));
|
||||
workflow.setState(WorkflowState.INIT);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,13 @@
|
|||
package org.libreccm.workflow;
|
||||
|
||||
import org.libreccm.core.AbstractEntityRepository;
|
||||
import org.libreccm.core.CcmObject;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.persistence.NoResultException;
|
||||
import javax.persistence.TypedQuery;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -39,4 +44,21 @@ public class WorkflowRepository extends AbstractEntityRepository<Long, Workflow>
|
|||
return workflow.getWorkflowId() == 0;
|
||||
}
|
||||
|
||||
public Optional<Workflow> findWorkflowForObject(final CcmObject object) {
|
||||
if (object == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Can't find a workflow for object null.");
|
||||
}
|
||||
|
||||
final TypedQuery<Workflow> query = getEntityManager().createNamedQuery(
|
||||
"Workflow.findForObject", Workflow.class);
|
||||
query.setParameter("object", object);
|
||||
|
||||
try {
|
||||
return Optional.of(query.getSingleResult());
|
||||
} catch(NoResultException ex) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ package org.libreccm.workflow;
|
|||
|
||||
import static org.libreccm.core.CoreConstants.*;
|
||||
|
||||
import org.libreccm.core.CcmObject;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
|
|
@ -35,6 +37,12 @@ public class WorkflowTemplate extends Workflow implements Serializable {
|
|||
|
||||
private static final long serialVersionUID = 5770519379144947171L;
|
||||
|
||||
@Override
|
||||
protected void setObject(final CcmObject object) {
|
||||
throw new UnsupportedOperationException(
|
||||
"A WorkflowTemplate has no object.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.hashCode();
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import org.junit.runners.Parameterized;
|
|||
import org.libreccm.core.CcmObject;
|
||||
import org.libreccm.tests.categories.UnitTest;
|
||||
import org.libreccm.testutils.EqualsVerifier;
|
||||
import org.libreccm.workflow.UserTask;
|
||||
import org.libreccm.workflow.AssignableTask;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
|
@ -88,10 +88,10 @@ public class EqualsAndHashCodeTest extends EqualsVerifier {
|
|||
ccmObject1.setObjectId(-200);
|
||||
ccmObject1.setDisplayName("Object 2");
|
||||
|
||||
final UserTask task1 = new UserTask();
|
||||
final AssignableTask task1 = new AssignableTask();
|
||||
task1.setTaskId(-10);
|
||||
|
||||
final UserTask task2 = new UserTask();
|
||||
final AssignableTask task2 = new AssignableTask();
|
||||
task2.setTaskId(-20);
|
||||
|
||||
verifier
|
||||
|
|
@ -100,7 +100,7 @@ public class EqualsAndHashCodeTest extends EqualsVerifier {
|
|||
.withPrefabValues(Role.class, role1, role2)
|
||||
.withPrefabValues(Party.class, party1, party2)
|
||||
.withPrefabValues(CcmObject.class, ccmObject1, ccmObject2)
|
||||
.withPrefabValues(UserTask.class, task1, task2);
|
||||
.withPrefabValues(AssignableTask.class, task1, task2);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ package org.libreccm.workflow;
|
|||
import org.junit.experimental.categories.Category;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.libreccm.core.CcmObject;
|
||||
import org.libreccm.security.Group;
|
||||
import org.libreccm.security.Role;
|
||||
import org.libreccm.security.User;
|
||||
|
|
@ -43,8 +44,9 @@ public class EqualsAndHashCodeTest extends EqualsVerifier {
|
|||
public static Collection<Class<?>> data() {
|
||||
return Arrays.asList(new Class<?>[]{
|
||||
Task.class,
|
||||
TaskComment.class,
|
||||
TaskAssignment.class,
|
||||
UserTask.class,
|
||||
AssignableTask.class,
|
||||
Workflow.class,
|
||||
WorkflowTemplate.class
|
||||
});
|
||||
|
|
@ -53,59 +55,73 @@ public class EqualsAndHashCodeTest extends EqualsVerifier {
|
|||
public EqualsAndHashCodeTest(final Class<?> entityClass) {
|
||||
super(entityClass);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void addPrefabValues(
|
||||
final nl.jqno.equalsverifier.EqualsVerifier<?> verifier) {
|
||||
|
||||
|
||||
super.addPrefabValues(verifier);
|
||||
|
||||
final UserTask userTask1 = new UserTask();
|
||||
|
||||
final AssignableTask userTask1 = new AssignableTask();
|
||||
userTask1.setTaskId(-10);
|
||||
|
||||
final UserTask userTask2 = new UserTask();
|
||||
|
||||
final AssignableTask userTask2 = new AssignableTask();
|
||||
userTask2.setTaskId(-20);
|
||||
|
||||
|
||||
final Role role1 = new Role();
|
||||
role1.setName("role1");
|
||||
|
||||
|
||||
final Role role2 = new Role();
|
||||
role2.setName("role2");
|
||||
|
||||
|
||||
final Task task1 = new Task();
|
||||
task1.setTaskId(-10);
|
||||
|
||||
final Task task2 = new Task();
|
||||
|
||||
final Task task2 = new Task();
|
||||
task2.setTaskId(-20);
|
||||
|
||||
|
||||
final Group group1 = new Group();
|
||||
group1.setName("group1");
|
||||
|
||||
|
||||
final Group group2 = new Group();
|
||||
group2.setName("group2");
|
||||
|
||||
|
||||
final User user1 = new TestUser();
|
||||
user1.setName("user1");
|
||||
|
||||
|
||||
final User user2 = new TestUser();
|
||||
user2.setName("user2");
|
||||
|
||||
|
||||
final Workflow workflow1 = new Workflow();
|
||||
workflow1.getName().addValue(Locale.ENGLISH, "Workflow 1");
|
||||
|
||||
final Workflow workflow2 = new Workflow();
|
||||
workflow2.getName().addValue(Locale.ENGLISH, "Workflow 2");
|
||||
|
||||
final WorkflowTemplate template1 = new WorkflowTemplate();
|
||||
template1.getName().addValue(Locale.ENGLISH, "Template 1");
|
||||
|
||||
|
||||
final WorkflowTemplate template2 = new WorkflowTemplate();
|
||||
template1.getName().addValue(Locale.ENGLISH, "Template 2");
|
||||
|
||||
final CcmObject object1 = new CcmObject();
|
||||
object1.setDisplayName("Object 1");
|
||||
|
||||
final CcmObject object2 = new CcmObject();
|
||||
object2.setDisplayName("Object 2");
|
||||
|
||||
verifier
|
||||
.withPrefabValues(UserTask.class, userTask1, userTask2)
|
||||
.withPrefabValues(AssignableTask.class, userTask1, userTask2)
|
||||
.withPrefabValues(Role.class, role1, role2)
|
||||
.withPrefabValues(Task.class, task1, task2)
|
||||
.withPrefabValues(Group.class, group1, group2)
|
||||
.withPrefabValues(User.class, user1, user2)
|
||||
.withPrefabValues(WorkflowTemplate.class, template1, template2);
|
||||
.withPrefabValues(Workflow.class, workflow1, workflow2)
|
||||
.withPrefabValues(WorkflowTemplate.class, template1, template2)
|
||||
.withPrefabValues(CcmObject.class, object1, object2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* {@link User} has a protected constructor, so have have do this to create
|
||||
* users for the test...
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ public class ToStringTest extends ToStringVerifier {
|
|||
return Arrays.asList(new Class<?>[]{
|
||||
Task.class,
|
||||
TaskAssignment.class,
|
||||
UserTask.class,
|
||||
AssignableTask.class,
|
||||
Workflow.class
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,3 @@
|
|||
DROP SCHEMA IF EXISTS ccm_core;
|
||||
|
||||
DROP SEQUENCE IF EXISTS hibernate_sequence;
|
||||
|
||||
CREATE SCHEMA ccm_core;
|
||||
|
||||
|
||||
create table CCM_CORE.APPLICATIONS (
|
||||
APPLICATION_TYPE varchar(1024) not null,
|
||||
|
|
@ -500,8 +494,8 @@ CREATE SCHEMA ccm_core;
|
|||
NAME varchar(512) not null,
|
||||
SETTING_VALUE_DOUBLE double,
|
||||
SETTING_VALUE_BOOLEAN boolean,
|
||||
SETTING_VALUE_BIG_DECIMAL decimal(19,2),
|
||||
SETTING_VALUE_LONG bigint,
|
||||
SETTING_VALUE_BIG_DECIMAL decimal(19,2),
|
||||
SETTING_VALUE_STRING varchar(1024),
|
||||
primary key (SETTING_ID)
|
||||
);
|
||||
|
|
@ -556,6 +550,17 @@ CREATE SCHEMA ccm_core;
|
|||
primary key (PARTY_ID)
|
||||
);
|
||||
|
||||
create table CCM_CORE.WORKFLOW_ASSIGNABLE_TASKS (
|
||||
DUE_DATE timestamp,
|
||||
DURATION_MINUTES bigint,
|
||||
LOCKED boolean,
|
||||
START_DATE timestamp,
|
||||
TASK_ID bigint not null,
|
||||
LOCKING_USER_ID bigint,
|
||||
NOTIFICATION_SENDER bigint,
|
||||
primary key (TASK_ID)
|
||||
);
|
||||
|
||||
create table CCM_CORE.WORKFLOW_DESCRIPTIONS (
|
||||
WORKFLOW_ID bigint not null,
|
||||
LOCALIZED_VALUE longvarchar,
|
||||
|
|
@ -571,8 +576,11 @@ CREATE SCHEMA ccm_core;
|
|||
);
|
||||
|
||||
create table CCM_CORE.WORKFLOW_TASK_COMMENTS (
|
||||
TASK_ID bigint not null,
|
||||
COMMENT clob
|
||||
COMMENT_ID bigint not null,
|
||||
COMMENT longvarchar,
|
||||
AUTHOR_ID bigint,
|
||||
TASK_ID bigint,
|
||||
primary key (COMMENT_ID)
|
||||
);
|
||||
|
||||
create table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES (
|
||||
|
|
@ -607,19 +615,11 @@ CREATE SCHEMA ccm_core;
|
|||
primary key (WORKFLOW_ID)
|
||||
);
|
||||
|
||||
create table CCM_CORE.WORKFLOW_USER_TASKS (
|
||||
DUE_DATE timestamp,
|
||||
DURATION_MINUTES bigint,
|
||||
LOCKED boolean,
|
||||
START_DATE timestamp,
|
||||
TASK_ID bigint not null,
|
||||
LOCKING_USER_ID bigint,
|
||||
NOTIFICATION_SENDER bigint,
|
||||
primary key (TASK_ID)
|
||||
);
|
||||
|
||||
create table CCM_CORE.WORKFLOWS (
|
||||
WORKFLOW_ID bigint not null,
|
||||
ACTIVE boolean,
|
||||
WORKFLOW_STATE varchar(255),
|
||||
OBJECT_ID bigint,
|
||||
TEMPLATE_ID bigint,
|
||||
primary key (WORKFLOW_ID)
|
||||
);
|
||||
|
|
@ -1054,9 +1054,9 @@ create sequence hibernate_sequence start with 1 increment by 1;
|
|||
references CCM_CORE.CCM_ROLES;
|
||||
|
||||
alter table CCM_CORE.TASK_ASSIGNMENTS
|
||||
add constraint FKc1vovbjg9mp5yegx2fdoutx7u
|
||||
add constraint FKk6gl2yvqr7gnqq25s1bm2gy4i
|
||||
foreign key (TASK_ID)
|
||||
references CCM_CORE.WORKFLOW_USER_TASKS;
|
||||
references CCM_CORE.WORKFLOW_ASSIGNABLE_TASKS;
|
||||
|
||||
alter table CCM_CORE.THREADS
|
||||
add constraint FKsx08mpwvwnw97uwdgjs76q39g
|
||||
|
|
@ -1078,6 +1078,21 @@ create sequence hibernate_sequence start with 1 increment by 1;
|
|||
foreign key (PARTY_ID)
|
||||
references CCM_CORE.PARTIES;
|
||||
|
||||
alter table CCM_CORE.WORKFLOW_ASSIGNABLE_TASKS
|
||||
add constraint FK1pnsq9ur3ylq0ghuj23p4cogs
|
||||
foreign key (LOCKING_USER_ID)
|
||||
references CCM_CORE.USERS;
|
||||
|
||||
alter table CCM_CORE.WORKFLOW_ASSIGNABLE_TASKS
|
||||
add constraint FK9ngp088m8xa82swy7yg3qx6vh
|
||||
foreign key (NOTIFICATION_SENDER)
|
||||
references CCM_CORE.USERS;
|
||||
|
||||
alter table CCM_CORE.WORKFLOW_ASSIGNABLE_TASKS
|
||||
add constraint FKt9ha3no3bj8a50pnw8cnqh2cq
|
||||
foreign key (TASK_ID)
|
||||
references CCM_CORE.WORKFLOW_TASKS;
|
||||
|
||||
alter table CCM_CORE.WORKFLOW_DESCRIPTIONS
|
||||
add constraint FKgx7upkqky82dpxvbs95imfl9l
|
||||
foreign key (WORKFLOW_ID)
|
||||
|
|
@ -1088,6 +1103,11 @@ create sequence hibernate_sequence start with 1 increment by 1;
|
|||
foreign key (WORKFLOW_ID)
|
||||
references CCM_CORE.WORKFLOWS;
|
||||
|
||||
alter table CCM_CORE.WORKFLOW_TASK_COMMENTS
|
||||
add constraint FKd2ymdg8nay9pmh2nn2whba0j8
|
||||
foreign key (AUTHOR_ID)
|
||||
references CCM_CORE.USERS;
|
||||
|
||||
alter table CCM_CORE.WORKFLOW_TASK_COMMENTS
|
||||
add constraint FKkfqrf9jdvm7livu5if06w0r5t
|
||||
foreign key (TASK_ID)
|
||||
|
|
@ -1123,20 +1143,10 @@ create sequence hibernate_sequence start with 1 increment by 1;
|
|||
foreign key (WORKFLOW_ID)
|
||||
references CCM_CORE.WORKFLOWS;
|
||||
|
||||
alter table CCM_CORE.WORKFLOW_USER_TASKS
|
||||
add constraint FKf09depwj5rgso2dair07vnu33
|
||||
foreign key (LOCKING_USER_ID)
|
||||
references CCM_CORE.USERS;
|
||||
|
||||
alter table CCM_CORE.WORKFLOW_USER_TASKS
|
||||
add constraint FK6evo9y34awhdfcyl8gv78qb7f
|
||||
foreign key (NOTIFICATION_SENDER)
|
||||
references CCM_CORE.USERS;
|
||||
|
||||
alter table CCM_CORE.WORKFLOW_USER_TASKS
|
||||
add constraint FKefpdf9ojplu7loo31hfm0wl2h
|
||||
foreign key (TASK_ID)
|
||||
references CCM_CORE.WORKFLOW_TASKS;
|
||||
alter table CCM_CORE.WORKFLOWS
|
||||
add constraint FKrm2yfrs6veoxoy304upq2wc64
|
||||
foreign key (OBJECT_ID)
|
||||
references CCM_CORE.CCM_OBJECTS;
|
||||
|
||||
alter table CCM_CORE.WORKFLOWS
|
||||
add constraint FKeixdxau4jebw682gd49tdbsjy
|
||||
|
|
|
|||
|
|
@ -1,8 +1,3 @@
|
|||
DROP SCHEMA IF EXISTS ccm_core CASCADE;
|
||||
|
||||
DROP SEQUENCE IF EXISTS hibernate_sequence;
|
||||
|
||||
CREATE SCHEMA ccm_core;
|
||||
|
||||
create table CCM_CORE.APPLICATIONS (
|
||||
APPLICATION_TYPE varchar(1024) not null,
|
||||
|
|
@ -499,8 +494,8 @@ CREATE SCHEMA ccm_core;
|
|||
NAME varchar(512) not null,
|
||||
SETTING_VALUE_DOUBLE float8,
|
||||
SETTING_VALUE_BOOLEAN boolean,
|
||||
SETTING_VALUE_BIG_DECIMAL numeric(19, 2),
|
||||
SETTING_VALUE_LONG int8,
|
||||
SETTING_VALUE_BIG_DECIMAL numeric(19, 2),
|
||||
SETTING_VALUE_STRING varchar(1024),
|
||||
primary key (SETTING_ID)
|
||||
);
|
||||
|
|
@ -555,6 +550,17 @@ CREATE SCHEMA ccm_core;
|
|||
primary key (PARTY_ID)
|
||||
);
|
||||
|
||||
create table CCM_CORE.WORKFLOW_ASSIGNABLE_TASKS (
|
||||
DUE_DATE timestamp,
|
||||
DURATION_MINUTES int8,
|
||||
LOCKED boolean,
|
||||
START_DATE timestamp,
|
||||
TASK_ID int8 not null,
|
||||
LOCKING_USER_ID int8,
|
||||
NOTIFICATION_SENDER int8,
|
||||
primary key (TASK_ID)
|
||||
);
|
||||
|
||||
create table CCM_CORE.WORKFLOW_DESCRIPTIONS (
|
||||
WORKFLOW_ID int8 not null,
|
||||
LOCALIZED_VALUE text,
|
||||
|
|
@ -570,8 +576,11 @@ CREATE SCHEMA ccm_core;
|
|||
);
|
||||
|
||||
create table CCM_CORE.WORKFLOW_TASK_COMMENTS (
|
||||
TASK_ID int8 not null,
|
||||
COMMENT text
|
||||
COMMENT_ID int8 not null,
|
||||
COMMENT text,
|
||||
AUTHOR_ID int8,
|
||||
TASK_ID int8,
|
||||
primary key (COMMENT_ID)
|
||||
);
|
||||
|
||||
create table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES (
|
||||
|
|
@ -606,19 +615,11 @@ CREATE SCHEMA ccm_core;
|
|||
primary key (WORKFLOW_ID)
|
||||
);
|
||||
|
||||
create table CCM_CORE.WORKFLOW_USER_TASKS (
|
||||
DUE_DATE timestamp,
|
||||
DURATION_MINUTES int8,
|
||||
LOCKED boolean,
|
||||
START_DATE timestamp,
|
||||
TASK_ID int8 not null,
|
||||
LOCKING_USER_ID int8,
|
||||
NOTIFICATION_SENDER int8,
|
||||
primary key (TASK_ID)
|
||||
);
|
||||
|
||||
create table CCM_CORE.WORKFLOWS (
|
||||
WORKFLOW_ID int8 not null,
|
||||
ACTIVE boolean,
|
||||
WORKFLOW_STATE varchar(255),
|
||||
OBJECT_ID int8,
|
||||
TEMPLATE_ID int8,
|
||||
primary key (WORKFLOW_ID)
|
||||
);
|
||||
|
|
@ -1053,9 +1054,9 @@ create sequence hibernate_sequence start 1 increment 1;
|
|||
references CCM_CORE.CCM_ROLES;
|
||||
|
||||
alter table CCM_CORE.TASK_ASSIGNMENTS
|
||||
add constraint FKc1vovbjg9mp5yegx2fdoutx7u
|
||||
add constraint FKk6gl2yvqr7gnqq25s1bm2gy4i
|
||||
foreign key (TASK_ID)
|
||||
references CCM_CORE.WORKFLOW_USER_TASKS;
|
||||
references CCM_CORE.WORKFLOW_ASSIGNABLE_TASKS;
|
||||
|
||||
alter table CCM_CORE.THREADS
|
||||
add constraint FKsx08mpwvwnw97uwdgjs76q39g
|
||||
|
|
@ -1077,6 +1078,21 @@ create sequence hibernate_sequence start 1 increment 1;
|
|||
foreign key (PARTY_ID)
|
||||
references CCM_CORE.PARTIES;
|
||||
|
||||
alter table CCM_CORE.WORKFLOW_ASSIGNABLE_TASKS
|
||||
add constraint FK1pnsq9ur3ylq0ghuj23p4cogs
|
||||
foreign key (LOCKING_USER_ID)
|
||||
references CCM_CORE.USERS;
|
||||
|
||||
alter table CCM_CORE.WORKFLOW_ASSIGNABLE_TASKS
|
||||
add constraint FK9ngp088m8xa82swy7yg3qx6vh
|
||||
foreign key (NOTIFICATION_SENDER)
|
||||
references CCM_CORE.USERS;
|
||||
|
||||
alter table CCM_CORE.WORKFLOW_ASSIGNABLE_TASKS
|
||||
add constraint FKt9ha3no3bj8a50pnw8cnqh2cq
|
||||
foreign key (TASK_ID)
|
||||
references CCM_CORE.WORKFLOW_TASKS;
|
||||
|
||||
alter table CCM_CORE.WORKFLOW_DESCRIPTIONS
|
||||
add constraint FKgx7upkqky82dpxvbs95imfl9l
|
||||
foreign key (WORKFLOW_ID)
|
||||
|
|
@ -1087,6 +1103,11 @@ create sequence hibernate_sequence start 1 increment 1;
|
|||
foreign key (WORKFLOW_ID)
|
||||
references CCM_CORE.WORKFLOWS;
|
||||
|
||||
alter table CCM_CORE.WORKFLOW_TASK_COMMENTS
|
||||
add constraint FKd2ymdg8nay9pmh2nn2whba0j8
|
||||
foreign key (AUTHOR_ID)
|
||||
references CCM_CORE.USERS;
|
||||
|
||||
alter table CCM_CORE.WORKFLOW_TASK_COMMENTS
|
||||
add constraint FKkfqrf9jdvm7livu5if06w0r5t
|
||||
foreign key (TASK_ID)
|
||||
|
|
@ -1122,20 +1143,10 @@ create sequence hibernate_sequence start 1 increment 1;
|
|||
foreign key (WORKFLOW_ID)
|
||||
references CCM_CORE.WORKFLOWS;
|
||||
|
||||
alter table CCM_CORE.WORKFLOW_USER_TASKS
|
||||
add constraint FKf09depwj5rgso2dair07vnu33
|
||||
foreign key (LOCKING_USER_ID)
|
||||
references CCM_CORE.USERS;
|
||||
|
||||
alter table CCM_CORE.WORKFLOW_USER_TASKS
|
||||
add constraint FK6evo9y34awhdfcyl8gv78qb7f
|
||||
foreign key (NOTIFICATION_SENDER)
|
||||
references CCM_CORE.USERS;
|
||||
|
||||
alter table CCM_CORE.WORKFLOW_USER_TASKS
|
||||
add constraint FKefpdf9ojplu7loo31hfm0wl2h
|
||||
foreign key (TASK_ID)
|
||||
references CCM_CORE.WORKFLOW_TASKS;
|
||||
alter table CCM_CORE.WORKFLOWS
|
||||
add constraint FKrm2yfrs6veoxoy304upq2wc64
|
||||
foreign key (OBJECT_ID)
|
||||
references CCM_CORE.CCM_OBJECTS;
|
||||
|
||||
alter table CCM_CORE.WORKFLOWS
|
||||
add constraint FKeixdxau4jebw682gd49tdbsjy
|
||||
|
|
|
|||
Loading…
Reference in New Issue