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 itemId the id of the ContentItem object to display
|
||||||
* @param tab The index of the tab 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 =
|
final ContentItem item =
|
||||||
(ContentItem) DomainObjectFactory.newInstance(new OID(
|
(ContentItem) DomainObjectFactory.newInstance(new OID(
|
||||||
ContentItem.BASE_DATA_OBJECT_TYPE, itemId));
|
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.Assert;
|
||||||
import com.arsdigita.util.SequentialMap;
|
import com.arsdigita.util.SequentialMap;
|
||||||
import com.arsdigita.util.UncheckedWrapperException;
|
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.Constructor;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
|
@ -66,6 +66,9 @@ import java.util.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
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
|
* 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
|
* This constructor will be called when the component is automatically
|
||||||
* instantiated by the <code>AuthoringKitWizard</code>.</p>
|
* 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 {
|
public class AuthoringKitWizard extends LayoutPanel implements Resettable {
|
||||||
|
|
||||||
/** Private Logger instance for this class */
|
/** Private Logger instance for this class */
|
||||||
private static final Logger s_log = Logger.getLogger(
|
private static final Logger LOGGER = LogManager.getLogger(
|
||||||
AuthoringKitWizard.class);
|
AuthoringKitWizard.class);
|
||||||
private static Class[] s_args = new Class[]{
|
private static Class[] s_args = new Class[]{
|
||||||
ItemSelectionModel.class,
|
ItemSelectionModel.class,
|
||||||
|
|
@ -103,8 +105,8 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
|
||||||
private static final java.util.List<AssetStepEntry> s_assets = new
|
private static final java.util.List<AssetStepEntry> s_assets = new
|
||||||
ArrayList<AssetStepEntry>();
|
ArrayList<AssetStepEntry>();
|
||||||
private final Object[] m_vals;
|
private final Object[] m_vals;
|
||||||
private final ContentType m_type;
|
private final ContentTypeInfo m_type;
|
||||||
private final AuthoringKit m_kit;
|
private final AuthoringKitInfo m_kit;
|
||||||
private final ItemSelectionModel m_sel;
|
private final ItemSelectionModel m_sel;
|
||||||
private final WorkflowRequestLocal m_workflow;
|
private final WorkflowRequestLocal m_workflow;
|
||||||
private final AssignedTaskTable m_tasks;
|
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
|
* @param type The content type of the items that this wizard will
|
||||||
* handle
|
* handle
|
||||||
*
|
* @param model
|
||||||
* @param itemModel The item selection model which will supply
|
|
||||||
* this wizard with the content item object
|
|
||||||
*/
|
*/
|
||||||
public AuthoringKitWizard(final ContentType type,
|
public AuthoringKitWizard(final ContentTypeInfo type,
|
||||||
final ItemSelectionModel model) {
|
final ItemSelectionModel model) {
|
||||||
if (s_log.isDebugEnabled()) {
|
if (LOGGER.isDebugEnabled()) {
|
||||||
s_log.debug("Authoring kit wizard for type " + type + " "
|
LOGGER.debug("Authoring kit wizard for type " + type + " "
|
||||||
+ "undergoing creation");
|
+ "undergoing creation");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -262,9 +262,9 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
|
||||||
Collection skipSteps = ContentSection.getConfig().getAssetStepsToSkip(
|
Collection skipSteps = ContentSection.getConfig().getAssetStepsToSkip(
|
||||||
type);
|
type);
|
||||||
Iterator it = skipSteps.iterator();
|
Iterator it = skipSteps.iterator();
|
||||||
if (s_log.isDebugEnabled()) {
|
if (LOGGER.isDebugEnabled()) {
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
s_log.debug("skip step " + it.next());
|
LOGGER.debug("skip step " + it.next());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Iterator assets = s_assets.iterator();
|
//Iterator assets = s_assets.iterator();
|
||||||
|
|
@ -276,7 +276,7 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
|
||||||
final String baseObjectType = data.getBaseDataObjectType();
|
final String baseObjectType = data.getBaseDataObjectType();
|
||||||
//Class step = (Class) data[1];
|
//Class step = (Class) data[1];
|
||||||
Class step = data.getStep();
|
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())) {
|
if (!skipSteps.contains(step.getName())) {
|
||||||
//GlobalizedMessage label = (GlobalizedMessage) data[2];
|
//GlobalizedMessage label = (GlobalizedMessage) data[2];
|
||||||
GlobalizedMessage label = data.getLabel();
|
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
|
// 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
|
// 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
|
// runs after original ccm-ldn-image-step initializer and override the registered step here
|
||||||
s_log.debug(
|
LOGGER.debug(
|
||||||
"registering asset step - label: "
|
"registering asset step - label: "
|
||||||
+ label.localize()
|
+ label.localize()
|
||||||
+ " step class: "
|
+ " step class: "
|
||||||
|
|
@ -451,7 +451,7 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
|
||||||
*/
|
*/
|
||||||
if ((thisObjectType.equals(baseObjectType))
|
if ((thisObjectType.equals(baseObjectType))
|
||||||
&& (thisLabel.localize().equals(label.localize()))) {
|
&& (thisLabel.localize().equals(label.localize()))) {
|
||||||
s_log.debug(
|
LOGGER.debug(
|
||||||
"registering authoring step with same label as previously registered step");
|
"registering authoring step with same label as previously registered step");
|
||||||
s_assets.remove(data);
|
s_assets.remove(data);
|
||||||
break;
|
break;
|
||||||
|
|
@ -570,8 +570,8 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
|
||||||
* @param className The Java class name of the step
|
* @param className The Java class name of the step
|
||||||
*/
|
*/
|
||||||
protected Component instantiateStep(String name) {
|
protected Component instantiateStep(String name) {
|
||||||
if (s_log.isDebugEnabled()) {
|
if (LOGGER.isDebugEnabled()) {
|
||||||
s_log.debug("Instantiating kit wizard '" + name + "' with "
|
LOGGER.debug("Instantiating kit wizard '" + name + "' with "
|
||||||
+ "arguments " + s_args);
|
+ "arguments " + s_args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@
|
||||||
*/
|
*/
|
||||||
package com.arsdigita.cms.ui.authoring;
|
package com.arsdigita.cms.ui.authoring;
|
||||||
|
|
||||||
|
|
||||||
import com.arsdigita.bebop.Component;
|
import com.arsdigita.bebop.Component;
|
||||||
import com.arsdigita.bebop.PageState;
|
import com.arsdigita.bebop.PageState;
|
||||||
import com.arsdigita.bebop.Resettable;
|
import com.arsdigita.bebop.Resettable;
|
||||||
|
|
@ -33,6 +32,7 @@ import org.librecms.contentsection.ContentType;
|
||||||
|
|
||||||
import com.arsdigita.cms.ItemSelectionModel;
|
import com.arsdigita.cms.ItemSelectionModel;
|
||||||
import com.arsdigita.toolbox.ui.LayoutPanel;
|
import com.arsdigita.toolbox.ui.LayoutPanel;
|
||||||
|
import com.arsdigita.util.UncheckedWrapperException;
|
||||||
import com.arsdigita.xml.Element;
|
import com.arsdigita.xml.Element;
|
||||||
|
|
||||||
import oracle.jrockit.jfr.events.ContentTypeImpl;
|
import oracle.jrockit.jfr.events.ContentTypeImpl;
|
||||||
|
|
@ -42,15 +42,14 @@ import org.librecms.contenttypes.ContentTypeInfo;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An invisible component which contains all the possible authoring kits.
|
* An invisible component which contains all the possible authoring kits. The
|
||||||
* The kits are loaded from the database at construction time. The selector
|
* kits are loaded from the database at construction time. The selector chooses
|
||||||
* chooses which kit to display at page rendering time based on the value
|
* which kit to display at page rendering time based on the value of the
|
||||||
* of the content_type state parameter.
|
* content_type state parameter.
|
||||||
*
|
*
|
||||||
* Essentially, this component is a hack which is used to get around
|
* Essentially, this component is a hack which is used to get around the fact
|
||||||
* the fact that we cannot instantiate stateful components dynamically.
|
* that we cannot instantiate stateful components dynamically.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
* @author unknown
|
* @author unknown
|
||||||
|
|
@ -61,14 +60,14 @@ public class WizardSelector extends AuthoringKitSelector
|
||||||
private ItemSelectionModel itemSelectionModel;
|
private ItemSelectionModel itemSelectionModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new WizardSelector. Load all the possible authoring kits
|
* Construct a new WizardSelector. Load all the possible authoring kits from
|
||||||
* from the database and construct wizards for them.
|
* the database and construct wizards for them.
|
||||||
*
|
*
|
||||||
* @param model the {@link ItemSelectionModel} which will
|
* @param model the {@link ItemSelectionModel} which will supply the wizard
|
||||||
* supply the wizard with its item
|
* with its item
|
||||||
*
|
*
|
||||||
* @param typeModel the {@link ACSObjectSelectionModel} which will
|
* @param typeModel the {@link ACSObjectSelectionModel} which will supply
|
||||||
* supply the default content type
|
* the default content type
|
||||||
*
|
*
|
||||||
* @pre itemModel != null
|
* @pre itemModel != null
|
||||||
*/
|
*/
|
||||||
|
|
@ -81,16 +80,17 @@ public class WizardSelector extends AuthoringKitSelector
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the wizard for the given kit.
|
* Get the wizard for the given kit.
|
||||||
|
*
|
||||||
* @param kit
|
* @param kit
|
||||||
* @param type
|
* @param type
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public Component instantiateKitComponent(final AuthoringKitInfo kit,
|
public Component instantiateKitComponent(final AuthoringKitInfo kit,
|
||||||
final ContentTypeInfo type) {
|
final ContentTypeInfo type) {
|
||||||
|
|
||||||
final ItemSelectionModel itemModel = new
|
final ItemSelectionModel itemModel = new ItemSelectionModel(
|
||||||
ItemSelectionModel(type,
|
type, (LongParameter) itemSelectionModel.getStateParameter());
|
||||||
(LongParameter)itemSelectionModel.getStateParameter());
|
|
||||||
|
|
||||||
final AuthoringKitWizard wizard = new AuthoringKitWizard(type, itemModel);
|
final AuthoringKitWizard wizard = new AuthoringKitWizard(type, itemModel);
|
||||||
return wizard;
|
return wizard;
|
||||||
|
|
@ -107,54 +107,51 @@ public class WizardSelector extends AuthoringKitSelector
|
||||||
private Component getCurrentWizard(PageState state) {
|
private Component getCurrentWizard(PageState state) {
|
||||||
|
|
||||||
// Get the current item and extract its content type
|
// Get the current item and extract its content type
|
||||||
if(!itemSelectionModel.isSelected(state))
|
if (!itemSelectionModel.isSelected(state)) {
|
||||||
throw new RuntimeException( (String) GlobalizationUtil.globalize(
|
throw new UncheckedWrapperException("No item selected.");
|
||||||
"cms.ui.authoring.missing_item_id")
|
}
|
||||||
.localize());
|
|
||||||
|
|
||||||
ContentItem item =
|
final ContentItem item = (ContentItem) itemSelectionModel
|
||||||
(ContentItem)itemSelectionModel.getSelectedObject(state);
|
.getSelectedObject(state);
|
||||||
|
|
||||||
ContentType type = item.getContentType();
|
final ContentType type = item.getContentType();
|
||||||
BigDecimal typeId;
|
final String typeClass;
|
||||||
|
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
// Try to get the default content type
|
// Try to get the default content type
|
||||||
typeId = (BigDecimal)getComponentSelectionModel().getSelectedKey(state);
|
typeClass = getComponentSelectionModel().getSelectedKey(state);
|
||||||
if(typeId == null) {
|
if (typeClass == null || typeClass.isEmpty()) {
|
||||||
throw new RuntimeException((String) GlobalizationUtil.globalize(
|
throw new UncheckedWrapperException("Content type is missing");
|
||||||
"cms.ui.authoring.missing_content_type")
|
|
||||||
.localize());
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
typeId = type.getID();
|
typeClass = type.getContentItemClass();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the selected wizard
|
// Return the selected wizard
|
||||||
return (Component)getComponent(typeId);
|
return (Component) getComponent(typeClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Choose the right wizard and run it
|
// 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) {
|
if (component == null) {
|
||||||
throw new RuntimeException( (String) GlobalizationUtil.globalize(
|
throw new UncheckedWrapperException("No Wizard.");
|
||||||
"cms.ui.authoring.no_current_wizard")
|
|
||||||
.localize());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c.generateXML(state, parent);
|
component.generateXML(state, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset the state of the current wizard
|
* Reset the state of the current wizard
|
||||||
*/
|
*/
|
||||||
public void reset(PageState state) {
|
public void reset(final PageState state) {
|
||||||
Resettable r = (Resettable)getCurrentWizard(state);
|
final Resettable resettable = (Resettable) getCurrentWizard(state);
|
||||||
if(r != null) r.reset(state);
|
if (resettable != null) {
|
||||||
|
resettable.reset(state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,8 @@ import com.arsdigita.kernel.KernelConfig;
|
||||||
import org.libreccm.configuration.ConfigurationManager;
|
import org.libreccm.configuration.ConfigurationManager;
|
||||||
import org.libreccm.security.Shiro;
|
import org.libreccm.security.Shiro;
|
||||||
import org.libreccm.security.User;
|
import org.libreccm.security.User;
|
||||||
import org.libreccm.workflow.UserTask;
|
import org.libreccm.workflow.AssignableTask;
|
||||||
import org.libreccm.workflow.UserTaskRepository;
|
import org.libreccm.workflow.AssignableTaskRepository;
|
||||||
import org.libreccm.workflow.Workflow;
|
import org.libreccm.workflow.Workflow;
|
||||||
import org.libreccm.workflow.WorkflowManager;
|
import org.libreccm.workflow.WorkflowManager;
|
||||||
|
|
||||||
|
|
@ -50,7 +50,7 @@ public class AssignedTaskController {
|
||||||
private WorkflowManager workflowManager;
|
private WorkflowManager workflowManager;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private UserTaskRepository userTaskRepo;
|
private AssignableTaskRepository userTaskRepo;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private Shiro shiro;
|
private Shiro shiro;
|
||||||
|
|
@ -71,7 +71,7 @@ public class AssignedTaskController {
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public List<RowData<Long>> getAssignedTasks(final Workflow workflow) {
|
public List<RowData<Long>> getAssignedTasks(final Workflow workflow) {
|
||||||
final User user = shiro.getUser();
|
final User user = shiro.getUser();
|
||||||
final List<UserTask> tasks = userTaskRepo.getAssignedTasks(user,
|
final List<AssignableTask> tasks = userTaskRepo.getAssignedTasks(user,
|
||||||
workflow);
|
workflow);
|
||||||
|
|
||||||
return tasks
|
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);
|
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.cdi.utils.CdiUtil;
|
||||||
import org.libreccm.security.Shiro;
|
import org.libreccm.security.Shiro;
|
||||||
import org.libreccm.workflow.Task;
|
import org.libreccm.workflow.Task;
|
||||||
import org.libreccm.workflow.UserTask;
|
import org.libreccm.workflow.AssignableTask;
|
||||||
import org.libreccm.workflow.UserTaskRepository;
|
import org.libreccm.workflow.AssignableTaskRepository;
|
||||||
import org.libreccm.workflow.WorkflowConstants;
|
import org.libreccm.workflow.WorkflowConstants;
|
||||||
import org.libreccm.workflow.WorkflowManager;
|
import org.libreccm.workflow.WorkflowManager;
|
||||||
import org.libreccm.workflow.WorkflowRepository;
|
import org.libreccm.workflow.WorkflowRepository;
|
||||||
import org.librecms.CmsConstants;
|
import org.librecms.CmsConstants;
|
||||||
import org.librecms.workflow.CmsTask;
|
import org.librecms.workflow.CmsTask;
|
||||||
import org.librecms.workflow.CmsTaskType;
|
import org.librecms.workflow.CmsTaskTypeOld;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
@ -177,16 +177,15 @@ public final class AssignedTaskSection extends Section {
|
||||||
protected final Object initialValue(final PageState state) {
|
protected final Object initialValue(final PageState state) {
|
||||||
final Workflow workflow = m_flow.getWorkflow(state);
|
final Workflow workflow = m_flow.getWorkflow(state);
|
||||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||||
final UserTaskRepository userTaskRepo = cdiUtil.findBean(
|
final AssignableTaskRepository userTaskRepo = cdiUtil.findBean(AssignableTaskRepository.class);
|
||||||
UserTaskRepository.class);
|
|
||||||
final Shiro shiro = cdiUtil.findBean(Shiro.class);
|
final Shiro shiro = cdiUtil.findBean(Shiro.class);
|
||||||
return userTaskRepo.findEnabledTasksForWorkflow(shiro.getUser(),
|
return userTaskRepo.findEnabledTasksForWorkflow(shiro.getUser(),
|
||||||
workflow);
|
workflow);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
final List<UserTask> getTasks(final PageState state) {
|
final List<AssignableTask> getTasks(final PageState state) {
|
||||||
return (ArrayList<UserTask>) get(state);
|
return (ArrayList<AssignableTask>) get(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -208,7 +207,7 @@ public final class AssignedTaskSection extends Section {
|
||||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||||
final WorkflowManager workflowManager = cdiUtil.findBean(WorkflowManager.class);
|
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()) {
|
if (relevant(task) && !task.isLocked()) {
|
||||||
workflowManager.lockTask(task);
|
workflowManager.lockTask(task);
|
||||||
}
|
}
|
||||||
|
|
@ -219,7 +218,7 @@ public final class AssignedTaskSection extends Section {
|
||||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||||
final WorkflowManager workflowManager = cdiUtil.findBean(WorkflowManager.class);
|
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()) {
|
if (relevant(task) && task.isLocked()) {
|
||||||
workflowManager.unlockTask(task);
|
workflowManager.unlockTask(task);
|
||||||
}
|
}
|
||||||
|
|
@ -227,7 +226,7 @@ public final class AssignedTaskSection extends Section {
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean tasksLocked(final PageState state) {
|
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()) {
|
if (relevant(task) && !task.isLocked()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -248,7 +247,7 @@ public final class AssignedTaskSection extends Section {
|
||||||
return !m_tasks.getTasks(state).isEmpty();
|
return !m_tasks.getTasks(state).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean relevant(final UserTask task) {
|
private boolean relevant(final AssignableTask task) {
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// ToDo
|
// ToDo
|
||||||
|
|
@ -40,8 +40,8 @@ import org.apache.log4j.Logger;
|
||||||
import org.libreccm.cdi.utils.CdiUtil;
|
import org.libreccm.cdi.utils.CdiUtil;
|
||||||
import org.libreccm.security.Shiro;
|
import org.libreccm.security.Shiro;
|
||||||
import org.libreccm.security.User;
|
import org.libreccm.security.User;
|
||||||
import org.libreccm.workflow.UserTask;
|
import org.libreccm.workflow.AssignableTask;
|
||||||
import org.libreccm.workflow.UserTaskRepository;
|
import org.libreccm.workflow.AssignableTaskRepository;
|
||||||
import org.libreccm.workflow.WorkflowManager;
|
import org.libreccm.workflow.WorkflowManager;
|
||||||
import org.librecms.CmsConstants;
|
import org.librecms.CmsConstants;
|
||||||
import org.librecms.workflow.CmsTaskTypeRepository;
|
import org.librecms.workflow.CmsTaskTypeRepository;
|
||||||
|
|
@ -70,13 +70,12 @@ public final class AssignedTaskTable extends Table {
|
||||||
final int column = event.getColumn();
|
final int column = event.getColumn();
|
||||||
|
|
||||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||||
final UserTaskRepository userTaskRepo = cdiUtil.findBean(
|
final AssignableTaskRepository userTaskRepo = cdiUtil.findBean(AssignableTaskRepository.class);
|
||||||
UserTaskRepository.class);
|
|
||||||
final WorkflowManager workflowManager = cdiUtil.findBean(WorkflowManager.class);
|
final WorkflowManager workflowManager = cdiUtil.findBean(WorkflowManager.class);
|
||||||
final Shiro shiro = cdiUtil.findBean(Shiro.class);
|
final Shiro shiro = cdiUtil.findBean(Shiro.class);
|
||||||
|
|
||||||
if (column == 1) {
|
if (column == 1) {
|
||||||
final UserTask task = userTaskRepo.findById((Long) event
|
final AssignableTask task = userTaskRepo.findById((Long) event
|
||||||
.getRowKey());
|
.getRowKey());
|
||||||
final User currentUser = shiro.getUser();
|
final User currentUser = shiro.getUser();
|
||||||
final User lockingUser = task.getLockingUser();
|
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.BaseForm;
|
||||||
import com.arsdigita.cms.ui.ListOptionPrintListener;
|
import com.arsdigita.cms.ui.ListOptionPrintListener;
|
||||||
|
|
||||||
import org.librecms.workflow.CmsTaskType;
|
import org.librecms.workflow.CmsTaskTypeOld;
|
||||||
|
|
||||||
import com.arsdigita.globalization.GlobalizedMessage;
|
import com.arsdigita.globalization.GlobalizedMessage;
|
||||||
import com.arsdigita.kernel.KernelConfig;
|
import com.arsdigita.kernel.KernelConfig;
|
||||||
|
|
@ -142,27 +142,27 @@ class BaseTaskForm extends BaseForm {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
// Fix this one too
|
// Fix this one too
|
||||||
private class TaskTypePrintListener extends ListOptionPrintListener<CmsTaskType> {
|
private class TaskTypePrintListener extends ListOptionPrintListener<CmsTaskTypeOld> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<CmsTaskType> getDataQuery(final PageState state) {
|
protected List<CmsTaskTypeOld> getDataQuery(final PageState state) {
|
||||||
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
|
||||||
final CmsTaskTypeRepository taskTypeRepo = cdiUtil.findBean(
|
final CmsTaskTypeRepository taskTypeRepo = cdiUtil.findBean(
|
||||||
CmsTaskTypeRepository.class);
|
CmsTaskTypeRepository.class);
|
||||||
|
|
||||||
final List<CmsTaskType> taskTypes = taskTypeRepo.findAll();
|
final List<CmsTaskTypeOld> taskTypes = taskTypeRepo.findAll();
|
||||||
|
|
||||||
return taskTypes;
|
return taskTypes;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getKey(final CmsTaskType taskType) {
|
public String getKey(final CmsTaskTypeOld taskType) {
|
||||||
return Long.toString(taskType.getTaskTypeId());
|
return Long.toString(taskType.getTaskTypeId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getValue(final CmsTaskType taskType) {
|
public String getValue(final CmsTaskTypeOld taskType) {
|
||||||
final KernelConfig kernelConfig = KernelConfig.getConfig();
|
final KernelConfig kernelConfig = KernelConfig.getConfig();
|
||||||
final Locale defaultLocale = kernelConfig.getDefaultLocale();
|
final Locale defaultLocale = kernelConfig.getDefaultLocale();
|
||||||
return taskType.getName().getValue(defaultLocale);
|
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 com.arsdigita.kernel.KernelConfig;
|
||||||
|
|
||||||
import org.librecms.workflow.CmsTask;
|
import org.librecms.workflow.CmsTask;
|
||||||
import org.librecms.workflow.CmsTaskType;
|
import org.librecms.workflow.CmsTaskTypeOld;
|
||||||
|
|
||||||
import com.arsdigita.util.UncheckedWrapperException;
|
import com.arsdigita.util.UncheckedWrapperException;
|
||||||
|
|
||||||
|
|
@ -120,7 +120,7 @@ class TaskAddForm extends BaseTaskForm {
|
||||||
defaultLocale,
|
defaultLocale,
|
||||||
((String) m_description.getValue(state)));
|
((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.setTaskType(taskType);
|
||||||
task.setActive(true);
|
task.setActive(true);
|
||||||
|
|
||||||
|
|
@ -30,7 +30,7 @@ import com.arsdigita.cms.ui.UserSearchForm;
|
||||||
import com.arsdigita.globalization.GlobalizedMessage;
|
import com.arsdigita.globalization.GlobalizedMessage;
|
||||||
|
|
||||||
import org.libreccm.security.User;
|
import org.libreccm.security.User;
|
||||||
import org.libreccm.workflow.UserTask;
|
import org.libreccm.workflow.AssignableTask;
|
||||||
|
|
||||||
import com.arsdigita.xml.Element;
|
import com.arsdigita.xml.Element;
|
||||||
|
|
||||||
|
|
@ -146,7 +146,7 @@ class TaskAddUser extends SimpleContainer {
|
||||||
WorkflowManager.class);
|
WorkflowManager.class);
|
||||||
final UserRepository userRepo = cdiUtil.findBean(UserRepository.class);
|
final UserRepository userRepo = cdiUtil.findBean(UserRepository.class);
|
||||||
|
|
||||||
final UserTask task = m_task.getTask(state);
|
final AssignableTask task = m_task.getTask(state);
|
||||||
User user;
|
User user;
|
||||||
|
|
||||||
for (int i = 0; i < users.length; i++) {
|
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.configuration.ConfigurationManager;
|
||||||
import org.libreccm.workflow.Task;
|
import org.libreccm.workflow.Task;
|
||||||
import org.libreccm.workflow.TaskRepository;
|
import org.libreccm.workflow.TaskRepository;
|
||||||
import org.librecms.workflow.CmsTaskType;
|
import org.librecms.workflow.CmsTaskTypeOld;
|
||||||
import org.librecms.workflow.CmsTaskTypeRepository;
|
import org.librecms.workflow.CmsTaskTypeRepository;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
@ -144,7 +144,7 @@ class TaskEditForm extends BaseTaskForm {
|
||||||
defaultLocale,
|
defaultLocale,
|
||||||
(String) m_description.getValue(state));
|
(String) m_description.getValue(state));
|
||||||
|
|
||||||
final CmsTaskType taskType = taskTypeRepo.findById((Long) m_type
|
final CmsTaskTypeOld taskType = taskTypeRepo.findById((Long) m_type
|
||||||
.getValue(state));
|
.getValue(state));
|
||||||
task.setTaskType(taskType);
|
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.RoleRepository;
|
||||||
import org.libreccm.security.Shiro;
|
import org.libreccm.security.Shiro;
|
||||||
import org.libreccm.workflow.Task;
|
import org.libreccm.workflow.Task;
|
||||||
import org.libreccm.workflow.UserTask;
|
import org.libreccm.workflow.AssignableTask;
|
||||||
import org.libreccm.workflow.WorkflowManager;
|
import org.libreccm.workflow.WorkflowManager;
|
||||||
import org.librecms.CmsConstants;
|
import org.librecms.CmsConstants;
|
||||||
import org.librecms.contentsection.privileges.AdminPrivileges;
|
import org.librecms.contentsection.privileges.AdminPrivileges;
|
||||||
|
|
@ -173,7 +173,7 @@ final class TaskItemPane extends BaseItemPane {
|
||||||
|
|
||||||
final User user = shiro.getUser();
|
final User user = shiro.getUser();
|
||||||
|
|
||||||
final List<UserTask> tasks = workflowManager.lockedBy(user);
|
final List<AssignableTask> tasks = workflowManager.lockedBy(user);
|
||||||
|
|
||||||
return tasks.contains(task);
|
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);
|
||||||
|
}
|
||||||
|
|
@ -73,21 +73,24 @@ import static org.librecms.CmsConstants.*;
|
||||||
query = "SELECT i FROM ContentItem i "
|
query = "SELECT i FROM ContentItem i "
|
||||||
+ "JOIN i.categories c "
|
+ "JOIN i.categories c "
|
||||||
+ "WHERE c.category = :folder "
|
+ "WHERE c.category = :folder "
|
||||||
+ "AND c.type = '" + CATEGORIZATION_TYPE_FOLDER + "'")
|
+ "AND c.type = '" + CATEGORIZATION_TYPE_FOLDER
|
||||||
|
+ "'")
|
||||||
,
|
,
|
||||||
@NamedQuery(
|
@NamedQuery(
|
||||||
name = "ContentItem.countItemsInFolder",
|
name = "ContentItem.countItemsInFolder",
|
||||||
query = "SELECT count(i) FROM ContentItem i "
|
query = "SELECT count(i) FROM ContentItem i "
|
||||||
+ "JOIN i.categories c "
|
+ "JOIN i.categories c "
|
||||||
+ "WHERE c.category = :folder "
|
+ "WHERE c.category = :folder "
|
||||||
+ "AND c.type = '" + CATEGORIZATION_TYPE_FOLDER + "'")
|
+ "AND c.type = '" + CATEGORIZATION_TYPE_FOLDER
|
||||||
|
+ "'")
|
||||||
,
|
,
|
||||||
@NamedQuery(
|
@NamedQuery(
|
||||||
name = "ContentItem.countByNameInFolder",
|
name = "ContentItem.countByNameInFolder",
|
||||||
query = "SELECT COUNT(i) FROM ContentItem i "
|
query = "SELECT COUNT(i) FROM ContentItem i "
|
||||||
+ "JOIN i.categories c "
|
+ "JOIN i.categories c "
|
||||||
+ "WHERE c.category = :folder "
|
+ "WHERE c.category = :folder "
|
||||||
+ "AND c.type = '" + CATEGORIZATION_TYPE_FOLDER + "' "
|
+ "AND c.type = '" + CATEGORIZATION_TYPE_FOLDER
|
||||||
|
+ "' "
|
||||||
+ "AND i.displayName = :name")
|
+ "AND i.displayName = :name")
|
||||||
,
|
,
|
||||||
@NamedQuery(
|
@NamedQuery(
|
||||||
|
|
@ -95,7 +98,8 @@ import static org.librecms.CmsConstants.*;
|
||||||
query = "SELECT i FROM ContentItem i "
|
query = "SELECT i FROM ContentItem i "
|
||||||
+ "JOIN i.categories c "
|
+ "JOIN i.categories c "
|
||||||
+ "WHERE c.category = :folder "
|
+ "WHERE c.category = :folder "
|
||||||
+ "AND c.type = '" + CATEGORIZATION_TYPE_FOLDER + "' "
|
+ "AND c.type = '" + CATEGORIZATION_TYPE_FOLDER
|
||||||
|
+ "' "
|
||||||
+ "AND LOWER(i.displayName) LIKE CONCAT(LOWER(:name), '%')")
|
+ "AND LOWER(i.displayName) LIKE CONCAT(LOWER(:name), '%')")
|
||||||
,
|
,
|
||||||
@NamedQuery(
|
@NamedQuery(
|
||||||
|
|
@ -103,7 +107,8 @@ import static org.librecms.CmsConstants.*;
|
||||||
query = "SELECT COUNT(i) FROM ContentItem i "
|
query = "SELECT COUNT(i) FROM ContentItem i "
|
||||||
+ "JOIN i.categories c "
|
+ "JOIN i.categories c "
|
||||||
+ "WHERE c.category = :folder "
|
+ "WHERE c.category = :folder "
|
||||||
+ "AND c.type = '" + CATEGORIZATION_TYPE_FOLDER + "' "
|
+ "AND c.type = '" + CATEGORIZATION_TYPE_FOLDER
|
||||||
|
+ "' "
|
||||||
+ "AND LOWER(i.displayName) LIKE CONCAT(LOWER(:name), '%')"
|
+ "AND LOWER(i.displayName) LIKE CONCAT(LOWER(:name), '%')"
|
||||||
)
|
)
|
||||||
,
|
,
|
||||||
|
|
@ -125,7 +130,12 @@ import static org.librecms.CmsConstants.*;
|
||||||
query = "SELECT i FROM ContentItem i "
|
query = "SELECT i FROM ContentItem i "
|
||||||
+ "WHERE i.itemUuid = :uuid "
|
+ "WHERE i.itemUuid = :uuid "
|
||||||
+ "AND i.version = org.librecms.contentsection.ContentItemVersion.LIVE")
|
+ "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,
|
public class ContentItem extends CcmObject implements Serializable,
|
||||||
InheritsPermissions {
|
InheritsPermissions {
|
||||||
|
|
|
||||||
|
|
@ -169,7 +169,8 @@ public class ContentItemManager {
|
||||||
*
|
*
|
||||||
* @param <T> The type of the content item.
|
* @param <T> The type of the content item.
|
||||||
* @param name The name (URL stub) of the new content item.
|
* @param name The name (URL stub) of the new content item.
|
||||||
* @param section The content section in which the item is generated.
|
* @param section The content section in which the item is
|
||||||
|
* generated.
|
||||||
* @param folder The folder in which in the item is stored.
|
* @param folder The folder in which in the item is stored.
|
||||||
* @param workflowTemplate The template for the workflow to apply to the new
|
* @param workflowTemplate The template for the workflow to apply to the new
|
||||||
* item.
|
* item.
|
||||||
|
|
@ -225,7 +226,7 @@ public class ContentItemManager {
|
||||||
|
|
||||||
if (workflowTemplate != null) {
|
if (workflowTemplate != null) {
|
||||||
final Workflow workflow = workflowManager.createWorkflow(
|
final Workflow workflow = workflowManager.createWorkflow(
|
||||||
workflowTemplate);
|
workflowTemplate, item);
|
||||||
item.setWorkflow(workflow);
|
item.setWorkflow(workflow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -319,8 +320,9 @@ public class ContentItemManager {
|
||||||
*
|
*
|
||||||
* @param item The item to copy.
|
* @param item The item to copy.
|
||||||
* @param targetFolder The folder in which the copy is created. If the
|
* @param targetFolder The folder in which the copy is created. If the
|
||||||
* target folder is the same folder as the folder of the original item an
|
* target folder is the same folder as the folder of the
|
||||||
* index is appended to the name of the item.
|
* original item an index is appended to the name of the
|
||||||
|
* item.
|
||||||
*
|
*
|
||||||
* @return The copy of the item
|
* @return The copy of the item
|
||||||
*/
|
*/
|
||||||
|
|
@ -383,7 +385,7 @@ public class ContentItemManager {
|
||||||
final WorkflowTemplate template = draftItem.getWorkflow()
|
final WorkflowTemplate template = draftItem.getWorkflow()
|
||||||
.getTemplate();
|
.getTemplate();
|
||||||
final Workflow copyWorkflow = workflowManager.createWorkflow(
|
final Workflow copyWorkflow = workflowManager.createWorkflow(
|
||||||
template);
|
template, item);
|
||||||
copy.setWorkflow(copyWorkflow);
|
copy.setWorkflow(copyWorkflow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -562,7 +564,8 @@ public class ContentItemManager {
|
||||||
private void copyAttachmentList(final AttachmentList sourceList,
|
private void copyAttachmentList(final AttachmentList sourceList,
|
||||||
final ContentItem target) {
|
final ContentItem target) {
|
||||||
final AttachmentList targetList = new AttachmentList();
|
final AttachmentList targetList = new AttachmentList();
|
||||||
copyLocalizedString(sourceList.getDescription(), targetList.getDescription());
|
copyLocalizedString(sourceList.getDescription(), targetList
|
||||||
|
.getDescription());
|
||||||
targetList.setItem(target);
|
targetList.setItem(target);
|
||||||
targetList.setName(sourceList.getName());
|
targetList.setName(sourceList.getName());
|
||||||
targetList.setOrder(sourceList.getOrder());
|
targetList.setOrder(sourceList.getOrder());
|
||||||
|
|
@ -844,8 +847,8 @@ public class ContentItemManager {
|
||||||
targetAsset = sourceAttachment.getAsset();
|
targetAsset = sourceAttachment.getAsset();
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
targetAsset = sourceAttachment.getAsset().getClass().
|
targetAsset = sourceAttachment.getAsset().getClass()
|
||||||
newInstance();
|
.newInstance();
|
||||||
} catch (InstantiationException | IllegalAccessException ex) {
|
} catch (InstantiationException | IllegalAccessException ex) {
|
||||||
throw new UncheckedWrapperException(ex);
|
throw new UncheckedWrapperException(ex);
|
||||||
}
|
}
|
||||||
|
|
@ -1143,9 +1146,9 @@ public class ContentItemManager {
|
||||||
* @param type Type of the content item.
|
* @param type Type of the content item.
|
||||||
*
|
*
|
||||||
* @return The live version of an item. If the item provided is already the
|
* @return The live version of an item. If the item provided is already the
|
||||||
* live version the provided item is returned, otherwise the live version is
|
* live version the provided item is returned, otherwise the live
|
||||||
* returned. If there is no live version an empty {@link Optional} is
|
* version is returned. If there is no live version an empty
|
||||||
* returned.
|
* {@link Optional} is returned.
|
||||||
*/
|
*/
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
|
@ -1203,10 +1206,10 @@ public class ContentItemManager {
|
||||||
* @param type Type of the item.
|
* @param type Type of the item.
|
||||||
*
|
*
|
||||||
* @return The draft version of the provided content item. If the provided
|
* @return The draft version of the provided content item. If the provided
|
||||||
* item is the draft version the provided item is simply returned. Otherwise
|
* item is the draft version the provided item is simply returned.
|
||||||
* the draft version is retrieved from the database and is returned. Each
|
* Otherwise the draft version is retrieved from the database and is
|
||||||
* content item has a draft version (otherwise something is seriously wrong
|
* returned. Each content item has a draft version (otherwise
|
||||||
* with the database) this method will
|
* something is seriously wrong with the database) this method will
|
||||||
* <b>never</b> return {@code null}.
|
* <b>never</b> return {@code null}.
|
||||||
*/
|
*/
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,9 @@ import java.util.UUID;
|
||||||
|
|
||||||
import javax.enterprise.context.RequestScoped;
|
import javax.enterprise.context.RequestScoped;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import javax.persistence.NoResultException;
|
||||||
import javax.persistence.TypedQuery;
|
import javax.persistence.TypedQuery;
|
||||||
|
import org.libreccm.workflow.Workflow;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Repository for content items.
|
* Repository for content items.
|
||||||
|
|
@ -251,4 +253,17 @@ public class ContentItemRepository
|
||||||
return query.getSingleResult();
|
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;
|
package org.librecms.workflow;
|
||||||
|
|
||||||
import org.libreccm.workflow.UserTask;
|
import org.libreccm.workflow.AssignableTask;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.JoinColumn;
|
import javax.persistence.EnumType;
|
||||||
import javax.persistence.OneToOne;
|
import javax.persistence.Enumerated;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
import static org.librecms.CmsConstants.*;
|
import static org.librecms.CmsConstants.*;
|
||||||
|
|
@ -36,12 +37,12 @@ import static org.librecms.CmsConstants.*;
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "WORKFLOW_TASKS", schema = DB_SCHEMA)
|
@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;
|
private static final long serialVersionUID = -3988352366529930659L;
|
||||||
|
|
||||||
@OneToOne
|
@Column(name = "TASK_TYPE")
|
||||||
@JoinColumn(name = "TASK_TYPE_ID")
|
@Enumerated(EnumType.STRING)
|
||||||
private CmsTaskType taskType;
|
private CmsTaskType taskType;
|
||||||
|
|
||||||
public CmsTaskType getTaskType() {
|
public CmsTaskType getTaskType() {
|
||||||
|
|
@ -79,7 +80,7 @@ public class CmsTask extends UserTask implements Serializable {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Objects.equals(taskType, other.taskType);
|
return Objects.equals(taskType, other.getTaskType());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
|
@ -18,188 +18,38 @@
|
||||||
*/
|
*/
|
||||||
package org.librecms.workflow;
|
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 org.librecms.contentsection.privileges.ItemPrivileges;
|
||||||
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.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
public enum CmsTaskType {
|
||||||
@Table(name = "WORKFLOW_TASK_TYPES", schema = DB_SCHEMA)
|
|
||||||
public class CmsTaskType implements Serializable {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = -4326031746212785970L;
|
AUTHOR(AuthoringTaskURLGenerator.class, ItemPrivileges.EDIT),
|
||||||
|
EDIT(EditingTaskURLGenerator.class, ItemPrivileges.APPROVE),
|
||||||
|
DEPLOY(DeployTaskURLGenerator.class, ItemPrivileges.PUBLISH);
|
||||||
|
|
||||||
@Id
|
private final Class<? extends TaskURLGenerator> urlGenerator;
|
||||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
private final String privilege;
|
||||||
@Column(name = "TASK_TYPE_ID")
|
|
||||||
private long taskTypeId;
|
|
||||||
|
|
||||||
@Embedded
|
private CmsTaskType(final Class<? extends TaskURLGenerator> urlGenerator,
|
||||||
@AssociationOverride(
|
final String privilege) {
|
||||||
name = "values",
|
this.urlGenerator = urlGenerator;
|
||||||
joinTable = @JoinTable(name = "ARTICLE_LEADS",
|
this.privilege = privilege;
|
||||||
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() {
|
public Class<? extends TaskURLGenerator> getUrlGenerator() {
|
||||||
return taskTypeId;
|
return urlGenerator;
|
||||||
}
|
|
||||||
|
|
||||||
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() {
|
public String getPrivilege() {
|
||||||
return privilege;
|
return privilege;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPrivilege(final String privilege) {
|
|
||||||
this.privilege = privilege;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<TaskEventUrlGenerator> getGenerators() {
|
|
||||||
if (generators == null) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
return Collections.unmodifiableSet(generators);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setGenerators(final Set<TaskEventUrlGenerator> generators) {
|
|
||||||
this.generators = generators;
|
|
||||||
}
|
|
||||||
|
|
||||||
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>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "WORKFLOW_USER_TASKS", schema = DB_SCHEMA)
|
@Table(name = "WORKFLOW_ASSIGNABLE_TASKS", schema = DB_SCHEMA)
|
||||||
@NamedQueries({
|
@NamedQueries({
|
||||||
@NamedQuery(
|
@NamedQuery(
|
||||||
name = "UserTask.findLockedBy",
|
name = "AssignableTask.findLockedBy",
|
||||||
query = "SELECT t FROM UserTask t WHERE t.lockingUser = :user")
|
query = "SELECT t FROM AssignableTask t WHERE t.lockingUser = :user")
|
||||||
,
|
,
|
||||||
@NamedQuery(
|
@NamedQuery(
|
||||||
name = "UserTask.findEnabledTasksForWorkflow",
|
name = "AssignableTask.findEnabledTasksForWorkflow",
|
||||||
query = "SELECT t FROM UserTask t "
|
query = "SELECT t FROM AssignableTask t "
|
||||||
+ "WHERE t.lockingUser = :user "
|
+ "WHERE t.lockingUser = :user "
|
||||||
+ "AND t.workflow = :workflow"
|
+ "AND t.workflow = :workflow"
|
||||||
)
|
)
|
||||||
,
|
,
|
||||||
@NamedQuery(
|
@NamedQuery(
|
||||||
name = "UserTask.findAssignedTasks",
|
name = "AssignableTask.findAssignedTasks",
|
||||||
query = "SELECT t FROM UserTask t "
|
query = "SELECT t FROM AssignableTask t "
|
||||||
+ "WHERE t.assignments.role IN :roles "
|
+ "WHERE t.assignments.role IN :roles "
|
||||||
+ "AND t.assignments.workflow = :workflow "
|
+ "AND t.assignments.workflow = :workflow "
|
||||||
+ "AND t.active = true")
|
+ "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
|
//Can't reduce complexity yet
|
||||||
@SuppressWarnings({"PMD.CyclomaticComplexity",
|
@SuppressWarnings({"PMD.CyclomaticComplexity",
|
||||||
"PMD.StdCyclomaticComplexity",
|
"PMD.StdCyclomaticComplexity",
|
||||||
"PMD.ModifiedCyclomaticComplexity"})
|
"PMD.ModifiedCyclomaticComplexity"})
|
||||||
public class UserTask extends Task implements Serializable {
|
public class AssignableTask extends Task implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 4188064584389893019L;
|
private static final long serialVersionUID = 4188064584389893019L;
|
||||||
|
|
||||||
|
|
@ -99,7 +105,7 @@ public class UserTask extends Task implements Serializable {
|
||||||
@OneToMany(mappedBy = "task")
|
@OneToMany(mappedBy = "task")
|
||||||
private List<TaskAssignment> assignments;
|
private List<TaskAssignment> assignments;
|
||||||
|
|
||||||
public UserTask() {
|
public AssignableTask() {
|
||||||
super();
|
super();
|
||||||
assignments = new ArrayList<>();
|
assignments = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
@ -217,10 +223,10 @@ public class UserTask extends Task implements Serializable {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(obj instanceof UserTask)) {
|
if (!(obj instanceof AssignableTask)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final UserTask other = (UserTask) obj;
|
final AssignableTask other = (AssignableTask) obj;
|
||||||
if (!other.canEqual(this)) {
|
if (!other.canEqual(this)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -245,7 +251,7 @@ public class UserTask extends Task implements Serializable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canEqual(final Object obj) {
|
public boolean canEqual(final Object obj) {
|
||||||
return obj instanceof UserTask;
|
return obj instanceof AssignableTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -33,32 +33,35 @@ import javax.persistence.TypedQuery;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@RequestScoped
|
@RequestScoped
|
||||||
public class UserTaskRepository extends AbstractEntityRepository<Long, UserTask> {
|
public class AssignableTaskRepository
|
||||||
|
extends AbstractEntityRepository<Long, AssignableTask> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<UserTask> getEntityClass() {
|
public Class<AssignableTask> getEntityClass() {
|
||||||
return UserTask.class;
|
return AssignableTask.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isNew(final UserTask task) {
|
public boolean isNew(final AssignableTask task) {
|
||||||
return task.getTaskId() == 0;
|
return task.getTaskId() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<UserTask> findEnabledTasksForWorkflow(final User user,
|
public List<AssignableTask> findEnabledTasksForWorkflow(
|
||||||
final Workflow workflow) {
|
final User user, final Workflow workflow) {
|
||||||
final TypedQuery<UserTask> query = getEntityManager().createNamedQuery(
|
final TypedQuery<AssignableTask> query = getEntityManager()
|
||||||
"UserTask.findEnabledTasksForWorkflow", UserTask.class);
|
.createNamedQuery(
|
||||||
|
"UserTask.findEnabledTasksForWorkflow", AssignableTask.class);
|
||||||
query.setParameter("user", user);
|
query.setParameter("user", user);
|
||||||
query.setParameter("workflow", workflow);
|
query.setParameter("workflow", workflow);
|
||||||
|
|
||||||
return query.getResultList();
|
return query.getResultList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<UserTask> getAssignedTasks(final User user,
|
public List<AssignableTask> getAssignedTasks(final User user,
|
||||||
final Workflow workflow) {
|
final Workflow workflow) {
|
||||||
final TypedQuery<UserTask> query = getEntityManager().createNamedQuery(
|
final TypedQuery<AssignableTask> query = getEntityManager()
|
||||||
"UserTask.findAssignedTasks", UserTask.class);
|
.createNamedQuery(
|
||||||
|
"UserTask.findAssignedTasks", AssignableTask.class);
|
||||||
final List<Role> roles = user.getRoleMemberships()
|
final List<Role> roles = user.getRoleMemberships()
|
||||||
.stream()
|
.stream()
|
||||||
.map(membership -> membership.getRole())
|
.map(membership -> membership.getRole())
|
||||||
|
|
@ -30,9 +30,10 @@ import java.util.Objects;
|
||||||
|
|
||||||
import javax.persistence.AssociationOverride;
|
import javax.persistence.AssociationOverride;
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.ElementCollection;
|
|
||||||
import javax.persistence.Embedded;
|
import javax.persistence.Embedded;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.EnumType;
|
||||||
|
import javax.persistence.Enumerated;
|
||||||
import javax.persistence.GeneratedValue;
|
import javax.persistence.GeneratedValue;
|
||||||
import javax.persistence.GenerationType;
|
import javax.persistence.GenerationType;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
|
|
@ -40,9 +41,11 @@ import javax.persistence.Inheritance;
|
||||||
import javax.persistence.InheritanceType;
|
import javax.persistence.InheritanceType;
|
||||||
import javax.persistence.JoinColumn;
|
import javax.persistence.JoinColumn;
|
||||||
import javax.persistence.JoinTable;
|
import javax.persistence.JoinTable;
|
||||||
import javax.persistence.Lob;
|
|
||||||
import javax.persistence.ManyToMany;
|
import javax.persistence.ManyToMany;
|
||||||
import javax.persistence.ManyToOne;
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.NamedQueries;
|
||||||
|
import javax.persistence.NamedQuery;
|
||||||
|
import javax.persistence.OneToMany;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -59,6 +62,35 @@ import javax.persistence.Table;
|
||||||
"PMD.ShortClassName",
|
"PMD.ShortClassName",
|
||||||
"PMD.TooManyMethods",
|
"PMD.TooManyMethods",
|
||||||
"PMD.AvoidDuplicateLiterals"})
|
"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 {
|
public class Task implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 8161343036908150426L;
|
private static final long serialVersionUID = 8161343036908150426L;
|
||||||
|
|
@ -90,7 +122,8 @@ public class Task implements Serializable {
|
||||||
private boolean active;
|
private boolean active;
|
||||||
|
|
||||||
@Column(name = "TASK_STATE", length = 512)
|
@Column(name = "TASK_STATE", length = 512)
|
||||||
private String taskState;
|
@Enumerated(EnumType.STRING)
|
||||||
|
private TaskState taskState;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "WORKFLOW_ID")
|
@JoinColumn(name = "WORKFLOW_ID")
|
||||||
|
|
@ -108,14 +141,9 @@ public class Task implements Serializable {
|
||||||
@JoinColumn(name = "DEPENDENT_TASK_ID")})
|
@JoinColumn(name = "DEPENDENT_TASK_ID")})
|
||||||
private List<Task> dependsOn;
|
private List<Task> dependsOn;
|
||||||
|
|
||||||
@ElementCollection
|
@OneToMany
|
||||||
@JoinTable(name = "WORKFLOW_TASK_COMMENTS",
|
@JoinColumn(name = "TASK_ID")
|
||||||
schema = DB_SCHEMA,
|
private List<TaskComment> comments;
|
||||||
joinColumns = {
|
|
||||||
@JoinColumn(name = "TASK_ID")})
|
|
||||||
@Column(name = "COMMENT")
|
|
||||||
@Lob
|
|
||||||
private List<String> comments;
|
|
||||||
|
|
||||||
public Task() {
|
public Task() {
|
||||||
super();
|
super();
|
||||||
|
|
@ -159,11 +187,11 @@ public class Task implements Serializable {
|
||||||
this.active = active;
|
this.active = active;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTaskState() {
|
public TaskState getTaskState() {
|
||||||
return taskState;
|
return taskState;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTaskState(final String taskState) {
|
protected void setTaskState(final TaskState taskState) {
|
||||||
this.taskState = taskState;
|
this.taskState = taskState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -215,7 +243,7 @@ public class Task implements Serializable {
|
||||||
dependsOn.remove(task);
|
dependsOn.remove(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getComments() {
|
public List<TaskComment> getComments() {
|
||||||
if (comments == null) {
|
if (comments == null) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} 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;
|
this.comments = comments;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addComment(final String comment) {
|
public void addComment(final TaskComment comment) {
|
||||||
comments.add(comment);
|
comments.add(comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeComment(final String comment) {
|
public void removeComment(final TaskComment comment) {
|
||||||
comments.remove(comment);
|
comments.remove(comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ public class TaskAssignment implements Serializable {
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "TASK_ID")
|
@JoinColumn(name = "TASK_ID")
|
||||||
private UserTask task;
|
private AssignableTask task;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "ROLE_ID")
|
@JoinColumn(name = "ROLE_ID")
|
||||||
|
|
@ -65,11 +65,11 @@ public class TaskAssignment implements Serializable {
|
||||||
this.taskAssignmentId = taskAssignmentId;
|
this.taskAssignmentId = taskAssignmentId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserTask getTask() {
|
public AssignableTask getTask() {
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setTask(final UserTask task) {
|
protected void setTask(final AssignableTask task) {
|
||||||
this.task = task;
|
this.task = task;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ package org.libreccm.workflow;
|
||||||
|
|
||||||
import static org.libreccm.core.CoreConstants.*;
|
import static org.libreccm.core.CoreConstants.*;
|
||||||
|
|
||||||
|
import org.libreccm.core.CcmObject;
|
||||||
import org.libreccm.l10n.LocalizedString;
|
import org.libreccm.l10n.LocalizedString;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
@ -32,6 +33,8 @@ import javax.persistence.AssociationOverride;
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Embedded;
|
import javax.persistence.Embedded;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.EnumType;
|
||||||
|
import javax.persistence.Enumerated;
|
||||||
import javax.persistence.GeneratedValue;
|
import javax.persistence.GeneratedValue;
|
||||||
import javax.persistence.GenerationType;
|
import javax.persistence.GenerationType;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
|
|
@ -40,7 +43,10 @@ import javax.persistence.InheritanceType;
|
||||||
import javax.persistence.JoinColumn;
|
import javax.persistence.JoinColumn;
|
||||||
import javax.persistence.JoinTable;
|
import javax.persistence.JoinTable;
|
||||||
import javax.persistence.ManyToOne;
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.NamedQueries;
|
||||||
|
import javax.persistence.NamedQuery;
|
||||||
import javax.persistence.OneToMany;
|
import javax.persistence.OneToMany;
|
||||||
|
import javax.persistence.OneToOne;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -50,6 +56,12 @@ import javax.persistence.Table;
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "WORKFLOWS", schema = DB_SCHEMA)
|
@Table(name = "WORKFLOWS", schema = DB_SCHEMA)
|
||||||
@Inheritance(strategy = InheritanceType.JOINED)
|
@Inheritance(strategy = InheritanceType.JOINED)
|
||||||
|
@NamedQueries({
|
||||||
|
@NamedQuery(
|
||||||
|
name = "Workflow.findForObject",
|
||||||
|
query = "SELECT w FROM Workflow w "
|
||||||
|
+ "WHERE W.object = :object")
|
||||||
|
})
|
||||||
public class Workflow implements Serializable {
|
public class Workflow implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 4322500264543325829L;
|
private static final long serialVersionUID = 4322500264543325829L;
|
||||||
|
|
@ -82,6 +94,21 @@ public class Workflow implements Serializable {
|
||||||
}))
|
}))
|
||||||
private LocalizedString description;
|
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")
|
@OneToMany(mappedBy = "workflow")
|
||||||
private List<Task> tasks;
|
private List<Task> tasks;
|
||||||
|
|
||||||
|
|
@ -125,6 +152,38 @@ public class Workflow implements Serializable {
|
||||||
this.description = description;
|
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() {
|
public List<Task> getTasks() {
|
||||||
if (tasks == null) {
|
if (tasks == null) {
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -150,6 +209,11 @@ public class Workflow implements Serializable {
|
||||||
int hash = 5;
|
int hash = 5;
|
||||||
hash = 79 * hash + (int) (this.workflowId ^ (this.workflowId >>> 32));
|
hash = 79 * hash + (int) (this.workflowId ^ (this.workflowId >>> 32));
|
||||||
hash = 79 * hash + Objects.hashCode(this.name);
|
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;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -166,10 +230,31 @@ public class Workflow implements Serializable {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.workflowId != other.getWorkflowId()) {
|
if (workflowId != other.getWorkflowId()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return Objects.equals(this.name, other.getName());
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Objects.equals(tasksState, other.getTasksState())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Objects.equals(object, other.getObject());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -185,11 +270,19 @@ public class Workflow implements Serializable {
|
||||||
public String toString(final String data) {
|
public String toString(final String data) {
|
||||||
return String.format("%s{ "
|
return String.format("%s{ "
|
||||||
+ "workflowId = %d, "
|
+ "workflowId = %d, "
|
||||||
+ "name = \"%s\"%s"
|
+ "name = \"%s\", "
|
||||||
|
+ "description = \"%s\", "
|
||||||
|
+ "state = \"%s\", "
|
||||||
|
+ "active = %b"
|
||||||
|
+ "object = \"%s\"%s"
|
||||||
+ " }",
|
+ " }",
|
||||||
super.toString(),
|
super.toString(),
|
||||||
workflowId,
|
workflowId,
|
||||||
name,
|
Objects.toString(name),
|
||||||
|
Objects.toString(description),
|
||||||
|
Objects.toString(state),
|
||||||
|
active,
|
||||||
|
Objects.toString(object),
|
||||||
data);
|
data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,14 +18,17 @@
|
||||||
*/
|
*/
|
||||||
package org.libreccm.workflow;
|
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.core.CoreConstants;
|
||||||
import org.libreccm.l10n.LocalizedString;
|
import org.libreccm.l10n.LocalizedString;
|
||||||
import org.libreccm.security.AuthorizationRequired;
|
import org.libreccm.security.AuthorizationRequired;
|
||||||
import org.libreccm.security.RequiresPrivilege;
|
import org.libreccm.security.RequiresPrivilege;
|
||||||
import org.libreccm.security.Role;
|
|
||||||
import org.libreccm.security.RoleRepository;
|
|
||||||
import org.libreccm.security.Shiro;
|
import org.libreccm.security.Shiro;
|
||||||
import org.libreccm.security.User;
|
|
||||||
|
|
||||||
import java.beans.BeanInfo;
|
import java.beans.BeanInfo;
|
||||||
import java.beans.IntrospectionException;
|
import java.beans.IntrospectionException;
|
||||||
|
|
@ -33,12 +36,14 @@ import java.beans.Introspector;
|
||||||
import java.beans.PropertyDescriptor;
|
import java.beans.PropertyDescriptor;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
import javax.enterprise.context.RequestScoped;
|
import javax.enterprise.context.RequestScoped;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
|
|
@ -52,6 +57,9 @@ import javax.transaction.Transactional;
|
||||||
@RequestScoped
|
@RequestScoped
|
||||||
public class WorkflowManager {
|
public class WorkflowManager {
|
||||||
|
|
||||||
|
private final static Logger LOGGER = LogManager.getLogger(
|
||||||
|
WorkflowManager.class);
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private EntityManager entityManager;
|
private EntityManager entityManager;
|
||||||
|
|
||||||
|
|
@ -62,15 +70,28 @@ public class WorkflowManager {
|
||||||
private TaskRepository taskRepo;
|
private TaskRepository taskRepo;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private RoleRepository roleRepo;
|
private TaskManager taskManager;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private Shiro shiro;
|
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
|
@AuthorizationRequired
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@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 Workflow workflow = new Workflow();
|
||||||
|
|
||||||
final LocalizedString name = new LocalizedString();
|
final LocalizedString name = new LocalizedString();
|
||||||
|
|
@ -90,6 +111,9 @@ public class WorkflowManager {
|
||||||
template.getTasks().forEach(taskTemplate -> fixTaskDependencies(
|
template.getTasks().forEach(taskTemplate -> fixTaskDependencies(
|
||||||
taskTemplate, tasks.get(taskTemplate.getTaskId()), tasks));
|
taskTemplate, tasks.get(taskTemplate.getTaskId()), tasks));
|
||||||
|
|
||||||
|
workflow.setObject(object);
|
||||||
|
workflow.setState(WorkflowState.INIT);
|
||||||
|
|
||||||
tasks.values().forEach(task -> taskRepo.save(task));
|
tasks.values().forEach(task -> taskRepo.save(task));
|
||||||
workflowRepo.save(workflow);
|
workflowRepo.save(workflow);
|
||||||
|
|
||||||
|
|
@ -172,139 +196,161 @@ public class WorkflowManager {
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public void addTask(final Workflow workflow, final Task task) {
|
public List<Task> findEnabledTasks(final Workflow workflow) {
|
||||||
workflow.addTask(task);
|
if (workflow.getState() == WorkflowState.DELETED
|
||||||
task.setWorkflow(workflow);
|
|| workflow.getState() == WorkflowState.STOPPED) {
|
||||||
|
LOGGER.debug(String.format("Workflow state is \"%s\". Workflow "
|
||||||
|
+ "has no enabled tasks.",
|
||||||
|
workflow.getState().toString()));
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
workflowRepo.save(workflow);
|
final TypedQuery<Task> query = entityManager.createNamedQuery(
|
||||||
taskRepo.save(task);
|
"Task.findEnabledTasks", Task.class);
|
||||||
|
query.setParameter("workflow", workflow);
|
||||||
|
|
||||||
|
return Collections.unmodifiableList(query.getResultList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public void removeTask(final Workflow workflow, final Task task) {
|
public List<Task> findFinishedTasks(final Workflow workflow) {
|
||||||
workflow.removeTask(task);
|
final TypedQuery<Task> query = entityManager.createNamedQuery(
|
||||||
task.setWorkflow(null);
|
"Task.findFinishedTasks", Task.class);
|
||||||
|
query.setParameter("workflow", workflow);
|
||||||
|
|
||||||
workflowRepo.save(workflow);
|
return Collections.unmodifiableList(query.getResultList());
|
||||||
taskRepo.save(task);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public void assignTask(final UserTask task, final Role role) {
|
public List<AssignableTask> findOverdueTasks(final Workflow workflow) {
|
||||||
final TaskAssignment assignment = new TaskAssignment();
|
final TypedQuery<AssignableTask> query = entityManager.createNamedQuery(
|
||||||
assignment.setTask(task);
|
"AssignableTask.findOverdueTasks", AssignableTask.class);
|
||||||
assignment.setRole(role);
|
query.setParameter("workflow", workflow);
|
||||||
|
query.setParameter("now", new Date());
|
||||||
|
|
||||||
task.addAssignment(assignment);
|
return Collections.unmodifiableList(query.getResultList());
|
||||||
role.addAssignedTask(assignment);
|
|
||||||
|
|
||||||
entityManager.persist(assignment);
|
|
||||||
taskRepo.save(task);
|
|
||||||
roleRepo.save(role);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@AuthorizationRequired
|
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
|
||||||
public void addDependentTask(final Task parent, final Task task) {
|
|
||||||
parent.addDependentTask(task);
|
|
||||||
task.addDependsOn(parent);
|
|
||||||
|
|
||||||
taskRepo.save(task);
|
|
||||||
taskRepo.save(parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@AuthorizationRequired
|
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
|
||||||
public void removeDependentTask(final Task parent, final Task task) {
|
|
||||||
parent.removeDependentTask(task);
|
|
||||||
task.removeDependsOn(parent);
|
|
||||||
|
|
||||||
taskRepo.save(task);
|
|
||||||
taskRepo.save(parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@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) {
|
public void start(final Workflow workflow) {
|
||||||
if (workflow.getTasks() != null && !workflow.getTasks().isEmpty()) {
|
final WorkflowState oldState = workflow.getState();
|
||||||
final Task first = workflow.getTasks().get(0);
|
|
||||||
|
|
||||||
if (first instanceof UserTask) {
|
workflow.setState(WorkflowState.STARTED);
|
||||||
final User user = shiro.getUser();
|
if (oldState == WorkflowState.INIT) {
|
||||||
lockTask((UserTask) first);
|
workflow.setActive(true);
|
||||||
|
updateState(workflow);
|
||||||
|
|
||||||
|
for (final Task current : workflow.getTasks()) {
|
||||||
|
current.setActive(true);
|
||||||
|
taskManager.updateState(current);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
workflowRepo.save(workflow);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@AuthorizationRequired
|
||||||
* Gets the state of a workflow.
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
*
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
* @param workflow
|
private void updateState(final Workflow workflow) {
|
||||||
* @return
|
if (workflow.getTasksState() == TaskState.ENABLED) {
|
||||||
*/
|
final TypedQuery<Long> query = entityManager.createNamedQuery(
|
||||||
public int getState(final Workflow workflow) {
|
"Task.countUnfinishedAndActiveTasksForWorkflow", Long.class);
|
||||||
|
query.setParameter("workflow", workflow);
|
||||||
|
|
||||||
final Optional<Task> activeTask = workflow.getTasks()
|
final Long result = query.getSingleResult();
|
||||||
.stream()
|
|
||||||
.filter(task -> task.isActive())
|
|
||||||
.findAny();
|
|
||||||
|
|
||||||
if (activeTask.isPresent()) {
|
if (result > 0) {
|
||||||
return WorkflowConstants.STARTED;
|
return;
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@AuthorizationRequired
|
||||||
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public void stop(final Workflow workflow) {
|
||||||
|
workflow.setState(WorkflowState.STOPPED);
|
||||||
|
workflowRepo.save(workflow);
|
||||||
|
}
|
||||||
|
|
||||||
|
@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)));
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
package org.libreccm.workflow;
|
||||||
|
|
||||||
import org.libreccm.core.AbstractEntityRepository;
|
import org.libreccm.core.AbstractEntityRepository;
|
||||||
|
import org.libreccm.core.CcmObject;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import javax.enterprise.context.RequestScoped;
|
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;
|
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 static org.libreccm.core.CoreConstants.*;
|
||||||
|
|
||||||
|
import org.libreccm.core.CcmObject;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
|
|
@ -35,6 +37,12 @@ public class WorkflowTemplate extends Workflow implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 5770519379144947171L;
|
private static final long serialVersionUID = 5770519379144947171L;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setObject(final CcmObject object) {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"A WorkflowTemplate has no object.");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return super.hashCode();
|
return super.hashCode();
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ import org.junit.runners.Parameterized;
|
||||||
import org.libreccm.core.CcmObject;
|
import org.libreccm.core.CcmObject;
|
||||||
import org.libreccm.tests.categories.UnitTest;
|
import org.libreccm.tests.categories.UnitTest;
|
||||||
import org.libreccm.testutils.EqualsVerifier;
|
import org.libreccm.testutils.EqualsVerifier;
|
||||||
import org.libreccm.workflow.UserTask;
|
import org.libreccm.workflow.AssignableTask;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
@ -88,10 +88,10 @@ public class EqualsAndHashCodeTest extends EqualsVerifier {
|
||||||
ccmObject1.setObjectId(-200);
|
ccmObject1.setObjectId(-200);
|
||||||
ccmObject1.setDisplayName("Object 2");
|
ccmObject1.setDisplayName("Object 2");
|
||||||
|
|
||||||
final UserTask task1 = new UserTask();
|
final AssignableTask task1 = new AssignableTask();
|
||||||
task1.setTaskId(-10);
|
task1.setTaskId(-10);
|
||||||
|
|
||||||
final UserTask task2 = new UserTask();
|
final AssignableTask task2 = new AssignableTask();
|
||||||
task2.setTaskId(-20);
|
task2.setTaskId(-20);
|
||||||
|
|
||||||
verifier
|
verifier
|
||||||
|
|
@ -100,7 +100,7 @@ public class EqualsAndHashCodeTest extends EqualsVerifier {
|
||||||
.withPrefabValues(Role.class, role1, role2)
|
.withPrefabValues(Role.class, role1, role2)
|
||||||
.withPrefabValues(Party.class, party1, party2)
|
.withPrefabValues(Party.class, party1, party2)
|
||||||
.withPrefabValues(CcmObject.class, ccmObject1, ccmObject2)
|
.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.experimental.categories.Category;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
|
import org.libreccm.core.CcmObject;
|
||||||
import org.libreccm.security.Group;
|
import org.libreccm.security.Group;
|
||||||
import org.libreccm.security.Role;
|
import org.libreccm.security.Role;
|
||||||
import org.libreccm.security.User;
|
import org.libreccm.security.User;
|
||||||
|
|
@ -43,8 +44,9 @@ public class EqualsAndHashCodeTest extends EqualsVerifier {
|
||||||
public static Collection<Class<?>> data() {
|
public static Collection<Class<?>> data() {
|
||||||
return Arrays.asList(new Class<?>[]{
|
return Arrays.asList(new Class<?>[]{
|
||||||
Task.class,
|
Task.class,
|
||||||
|
TaskComment.class,
|
||||||
TaskAssignment.class,
|
TaskAssignment.class,
|
||||||
UserTask.class,
|
AssignableTask.class,
|
||||||
Workflow.class,
|
Workflow.class,
|
||||||
WorkflowTemplate.class
|
WorkflowTemplate.class
|
||||||
});
|
});
|
||||||
|
|
@ -60,10 +62,10 @@ public class EqualsAndHashCodeTest extends EqualsVerifier {
|
||||||
|
|
||||||
super.addPrefabValues(verifier);
|
super.addPrefabValues(verifier);
|
||||||
|
|
||||||
final UserTask userTask1 = new UserTask();
|
final AssignableTask userTask1 = new AssignableTask();
|
||||||
userTask1.setTaskId(-10);
|
userTask1.setTaskId(-10);
|
||||||
|
|
||||||
final UserTask userTask2 = new UserTask();
|
final AssignableTask userTask2 = new AssignableTask();
|
||||||
userTask2.setTaskId(-20);
|
userTask2.setTaskId(-20);
|
||||||
|
|
||||||
final Role role1 = new Role();
|
final Role role1 = new Role();
|
||||||
|
|
@ -90,19 +92,33 @@ public class EqualsAndHashCodeTest extends EqualsVerifier {
|
||||||
final User user2 = new TestUser();
|
final User user2 = new TestUser();
|
||||||
user2.setName("user2");
|
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();
|
final WorkflowTemplate template1 = new WorkflowTemplate();
|
||||||
template1.getName().addValue(Locale.ENGLISH, "Template 1");
|
template1.getName().addValue(Locale.ENGLISH, "Template 1");
|
||||||
|
|
||||||
final WorkflowTemplate template2 = new WorkflowTemplate();
|
final WorkflowTemplate template2 = new WorkflowTemplate();
|
||||||
template1.getName().addValue(Locale.ENGLISH, "Template 2");
|
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
|
verifier
|
||||||
.withPrefabValues(UserTask.class, userTask1, userTask2)
|
.withPrefabValues(AssignableTask.class, userTask1, userTask2)
|
||||||
.withPrefabValues(Role.class, role1, role2)
|
.withPrefabValues(Role.class, role1, role2)
|
||||||
.withPrefabValues(Task.class, task1, task2)
|
.withPrefabValues(Task.class, task1, task2)
|
||||||
.withPrefabValues(Group.class, group1, group2)
|
.withPrefabValues(Group.class, group1, group2)
|
||||||
.withPrefabValues(User.class, user1, user2)
|
.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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ public class ToStringTest extends ToStringVerifier {
|
||||||
return Arrays.asList(new Class<?>[]{
|
return Arrays.asList(new Class<?>[]{
|
||||||
Task.class,
|
Task.class,
|
||||||
TaskAssignment.class,
|
TaskAssignment.class,
|
||||||
UserTask.class,
|
AssignableTask.class,
|
||||||
Workflow.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 (
|
create table CCM_CORE.APPLICATIONS (
|
||||||
APPLICATION_TYPE varchar(1024) not null,
|
APPLICATION_TYPE varchar(1024) not null,
|
||||||
|
|
@ -500,8 +494,8 @@ CREATE SCHEMA ccm_core;
|
||||||
NAME varchar(512) not null,
|
NAME varchar(512) not null,
|
||||||
SETTING_VALUE_DOUBLE double,
|
SETTING_VALUE_DOUBLE double,
|
||||||
SETTING_VALUE_BOOLEAN boolean,
|
SETTING_VALUE_BOOLEAN boolean,
|
||||||
SETTING_VALUE_BIG_DECIMAL decimal(19,2),
|
|
||||||
SETTING_VALUE_LONG bigint,
|
SETTING_VALUE_LONG bigint,
|
||||||
|
SETTING_VALUE_BIG_DECIMAL decimal(19,2),
|
||||||
SETTING_VALUE_STRING varchar(1024),
|
SETTING_VALUE_STRING varchar(1024),
|
||||||
primary key (SETTING_ID)
|
primary key (SETTING_ID)
|
||||||
);
|
);
|
||||||
|
|
@ -556,6 +550,17 @@ CREATE SCHEMA ccm_core;
|
||||||
primary key (PARTY_ID)
|
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 (
|
create table CCM_CORE.WORKFLOW_DESCRIPTIONS (
|
||||||
WORKFLOW_ID bigint not null,
|
WORKFLOW_ID bigint not null,
|
||||||
LOCALIZED_VALUE longvarchar,
|
LOCALIZED_VALUE longvarchar,
|
||||||
|
|
@ -571,8 +576,11 @@ CREATE SCHEMA ccm_core;
|
||||||
);
|
);
|
||||||
|
|
||||||
create table CCM_CORE.WORKFLOW_TASK_COMMENTS (
|
create table CCM_CORE.WORKFLOW_TASK_COMMENTS (
|
||||||
TASK_ID bigint not null,
|
COMMENT_ID bigint not null,
|
||||||
COMMENT clob
|
COMMENT longvarchar,
|
||||||
|
AUTHOR_ID bigint,
|
||||||
|
TASK_ID bigint,
|
||||||
|
primary key (COMMENT_ID)
|
||||||
);
|
);
|
||||||
|
|
||||||
create table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES (
|
create table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES (
|
||||||
|
|
@ -607,19 +615,11 @@ CREATE SCHEMA ccm_core;
|
||||||
primary key (WORKFLOW_ID)
|
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 (
|
create table CCM_CORE.WORKFLOWS (
|
||||||
WORKFLOW_ID bigint not null,
|
WORKFLOW_ID bigint not null,
|
||||||
|
ACTIVE boolean,
|
||||||
|
WORKFLOW_STATE varchar(255),
|
||||||
|
OBJECT_ID bigint,
|
||||||
TEMPLATE_ID bigint,
|
TEMPLATE_ID bigint,
|
||||||
primary key (WORKFLOW_ID)
|
primary key (WORKFLOW_ID)
|
||||||
);
|
);
|
||||||
|
|
@ -1054,9 +1054,9 @@ create sequence hibernate_sequence start with 1 increment by 1;
|
||||||
references CCM_CORE.CCM_ROLES;
|
references CCM_CORE.CCM_ROLES;
|
||||||
|
|
||||||
alter table CCM_CORE.TASK_ASSIGNMENTS
|
alter table CCM_CORE.TASK_ASSIGNMENTS
|
||||||
add constraint FKc1vovbjg9mp5yegx2fdoutx7u
|
add constraint FKk6gl2yvqr7gnqq25s1bm2gy4i
|
||||||
foreign key (TASK_ID)
|
foreign key (TASK_ID)
|
||||||
references CCM_CORE.WORKFLOW_USER_TASKS;
|
references CCM_CORE.WORKFLOW_ASSIGNABLE_TASKS;
|
||||||
|
|
||||||
alter table CCM_CORE.THREADS
|
alter table CCM_CORE.THREADS
|
||||||
add constraint FKsx08mpwvwnw97uwdgjs76q39g
|
add constraint FKsx08mpwvwnw97uwdgjs76q39g
|
||||||
|
|
@ -1078,6 +1078,21 @@ create sequence hibernate_sequence start with 1 increment by 1;
|
||||||
foreign key (PARTY_ID)
|
foreign key (PARTY_ID)
|
||||||
references CCM_CORE.PARTIES;
|
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
|
alter table CCM_CORE.WORKFLOW_DESCRIPTIONS
|
||||||
add constraint FKgx7upkqky82dpxvbs95imfl9l
|
add constraint FKgx7upkqky82dpxvbs95imfl9l
|
||||||
foreign key (WORKFLOW_ID)
|
foreign key (WORKFLOW_ID)
|
||||||
|
|
@ -1088,6 +1103,11 @@ create sequence hibernate_sequence start with 1 increment by 1;
|
||||||
foreign key (WORKFLOW_ID)
|
foreign key (WORKFLOW_ID)
|
||||||
references CCM_CORE.WORKFLOWS;
|
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
|
alter table CCM_CORE.WORKFLOW_TASK_COMMENTS
|
||||||
add constraint FKkfqrf9jdvm7livu5if06w0r5t
|
add constraint FKkfqrf9jdvm7livu5if06w0r5t
|
||||||
foreign key (TASK_ID)
|
foreign key (TASK_ID)
|
||||||
|
|
@ -1123,20 +1143,10 @@ create sequence hibernate_sequence start with 1 increment by 1;
|
||||||
foreign key (WORKFLOW_ID)
|
foreign key (WORKFLOW_ID)
|
||||||
references CCM_CORE.WORKFLOWS;
|
references CCM_CORE.WORKFLOWS;
|
||||||
|
|
||||||
alter table CCM_CORE.WORKFLOW_USER_TASKS
|
alter table CCM_CORE.WORKFLOWS
|
||||||
add constraint FKf09depwj5rgso2dair07vnu33
|
add constraint FKrm2yfrs6veoxoy304upq2wc64
|
||||||
foreign key (LOCKING_USER_ID)
|
foreign key (OBJECT_ID)
|
||||||
references CCM_CORE.USERS;
|
references CCM_CORE.CCM_OBJECTS;
|
||||||
|
|
||||||
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
|
alter table CCM_CORE.WORKFLOWS
|
||||||
add constraint FKeixdxau4jebw682gd49tdbsjy
|
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 (
|
create table CCM_CORE.APPLICATIONS (
|
||||||
APPLICATION_TYPE varchar(1024) not null,
|
APPLICATION_TYPE varchar(1024) not null,
|
||||||
|
|
@ -499,8 +494,8 @@ CREATE SCHEMA ccm_core;
|
||||||
NAME varchar(512) not null,
|
NAME varchar(512) not null,
|
||||||
SETTING_VALUE_DOUBLE float8,
|
SETTING_VALUE_DOUBLE float8,
|
||||||
SETTING_VALUE_BOOLEAN boolean,
|
SETTING_VALUE_BOOLEAN boolean,
|
||||||
SETTING_VALUE_BIG_DECIMAL numeric(19, 2),
|
|
||||||
SETTING_VALUE_LONG int8,
|
SETTING_VALUE_LONG int8,
|
||||||
|
SETTING_VALUE_BIG_DECIMAL numeric(19, 2),
|
||||||
SETTING_VALUE_STRING varchar(1024),
|
SETTING_VALUE_STRING varchar(1024),
|
||||||
primary key (SETTING_ID)
|
primary key (SETTING_ID)
|
||||||
);
|
);
|
||||||
|
|
@ -555,6 +550,17 @@ CREATE SCHEMA ccm_core;
|
||||||
primary key (PARTY_ID)
|
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 (
|
create table CCM_CORE.WORKFLOW_DESCRIPTIONS (
|
||||||
WORKFLOW_ID int8 not null,
|
WORKFLOW_ID int8 not null,
|
||||||
LOCALIZED_VALUE text,
|
LOCALIZED_VALUE text,
|
||||||
|
|
@ -570,8 +576,11 @@ CREATE SCHEMA ccm_core;
|
||||||
);
|
);
|
||||||
|
|
||||||
create table CCM_CORE.WORKFLOW_TASK_COMMENTS (
|
create table CCM_CORE.WORKFLOW_TASK_COMMENTS (
|
||||||
TASK_ID int8 not null,
|
COMMENT_ID int8 not null,
|
||||||
COMMENT text
|
COMMENT text,
|
||||||
|
AUTHOR_ID int8,
|
||||||
|
TASK_ID int8,
|
||||||
|
primary key (COMMENT_ID)
|
||||||
);
|
);
|
||||||
|
|
||||||
create table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES (
|
create table CCM_CORE.WORKFLOW_TASK_DEPENDENCIES (
|
||||||
|
|
@ -606,19 +615,11 @@ CREATE SCHEMA ccm_core;
|
||||||
primary key (WORKFLOW_ID)
|
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 (
|
create table CCM_CORE.WORKFLOWS (
|
||||||
WORKFLOW_ID int8 not null,
|
WORKFLOW_ID int8 not null,
|
||||||
|
ACTIVE boolean,
|
||||||
|
WORKFLOW_STATE varchar(255),
|
||||||
|
OBJECT_ID int8,
|
||||||
TEMPLATE_ID int8,
|
TEMPLATE_ID int8,
|
||||||
primary key (WORKFLOW_ID)
|
primary key (WORKFLOW_ID)
|
||||||
);
|
);
|
||||||
|
|
@ -1053,9 +1054,9 @@ create sequence hibernate_sequence start 1 increment 1;
|
||||||
references CCM_CORE.CCM_ROLES;
|
references CCM_CORE.CCM_ROLES;
|
||||||
|
|
||||||
alter table CCM_CORE.TASK_ASSIGNMENTS
|
alter table CCM_CORE.TASK_ASSIGNMENTS
|
||||||
add constraint FKc1vovbjg9mp5yegx2fdoutx7u
|
add constraint FKk6gl2yvqr7gnqq25s1bm2gy4i
|
||||||
foreign key (TASK_ID)
|
foreign key (TASK_ID)
|
||||||
references CCM_CORE.WORKFLOW_USER_TASKS;
|
references CCM_CORE.WORKFLOW_ASSIGNABLE_TASKS;
|
||||||
|
|
||||||
alter table CCM_CORE.THREADS
|
alter table CCM_CORE.THREADS
|
||||||
add constraint FKsx08mpwvwnw97uwdgjs76q39g
|
add constraint FKsx08mpwvwnw97uwdgjs76q39g
|
||||||
|
|
@ -1077,6 +1078,21 @@ create sequence hibernate_sequence start 1 increment 1;
|
||||||
foreign key (PARTY_ID)
|
foreign key (PARTY_ID)
|
||||||
references CCM_CORE.PARTIES;
|
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
|
alter table CCM_CORE.WORKFLOW_DESCRIPTIONS
|
||||||
add constraint FKgx7upkqky82dpxvbs95imfl9l
|
add constraint FKgx7upkqky82dpxvbs95imfl9l
|
||||||
foreign key (WORKFLOW_ID)
|
foreign key (WORKFLOW_ID)
|
||||||
|
|
@ -1087,6 +1103,11 @@ create sequence hibernate_sequence start 1 increment 1;
|
||||||
foreign key (WORKFLOW_ID)
|
foreign key (WORKFLOW_ID)
|
||||||
references CCM_CORE.WORKFLOWS;
|
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
|
alter table CCM_CORE.WORKFLOW_TASK_COMMENTS
|
||||||
add constraint FKkfqrf9jdvm7livu5if06w0r5t
|
add constraint FKkfqrf9jdvm7livu5if06w0r5t
|
||||||
foreign key (TASK_ID)
|
foreign key (TASK_ID)
|
||||||
|
|
@ -1122,20 +1143,10 @@ create sequence hibernate_sequence start 1 increment 1;
|
||||||
foreign key (WORKFLOW_ID)
|
foreign key (WORKFLOW_ID)
|
||||||
references CCM_CORE.WORKFLOWS;
|
references CCM_CORE.WORKFLOWS;
|
||||||
|
|
||||||
alter table CCM_CORE.WORKFLOW_USER_TASKS
|
alter table CCM_CORE.WORKFLOWS
|
||||||
add constraint FKf09depwj5rgso2dair07vnu33
|
add constraint FKrm2yfrs6veoxoy304upq2wc64
|
||||||
foreign key (LOCKING_USER_ID)
|
foreign key (OBJECT_ID)
|
||||||
references CCM_CORE.USERS;
|
references CCM_CORE.CCM_OBJECTS;
|
||||||
|
|
||||||
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
|
alter table CCM_CORE.WORKFLOWS
|
||||||
add constraint FKeixdxau4jebw682gd49tdbsjy
|
add constraint FKeixdxau4jebw682gd49tdbsjy
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue