Bugfixes for workflow handling.
parent
eef4210785
commit
7dd51f4c46
|
|
@ -301,19 +301,19 @@ public class DocumentWorkflowController {
|
|||
* @param documentPath The path of the currentd document.
|
||||
* @param newWorkflowUuid The UUID of the the workflow definition form
|
||||
* which the new workflow is created.
|
||||
* @param returnUrl The URL to return to.
|
||||
* @param returnUrlParam The URL to return to.
|
||||
*
|
||||
* @return A redirect to the {@code returnUrl}.
|
||||
*/
|
||||
@POST
|
||||
@Path("@workflow/@applyAlternative/{workflowIdentifier}")
|
||||
@Path("/apply-alternative")
|
||||
@AuthorizationRequired
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public String applyAlternateWorkflow(
|
||||
@PathParam("sectionIdentifier") final String sectionIdentifier,
|
||||
@PathParam("documentPath") final String documentPath,
|
||||
@FormParam("newWorkflowUuid") final String newWorkflowUuid,
|
||||
@FormParam("returnUrl") final String returnUrl
|
||||
@FormParam("returnUrl") final String returnUrlParam
|
||||
) {
|
||||
final Optional<ContentSection> sectionResult = sectionsUi
|
||||
.findContentSection(sectionIdentifier);
|
||||
|
|
@ -347,18 +347,35 @@ public class DocumentWorkflowController {
|
|||
);
|
||||
}
|
||||
|
||||
final Optional<Workflow> workflowResult = section
|
||||
final Optional<Workflow> workflowTemplateResult = section
|
||||
.getWorkflowTemplates()
|
||||
.stream()
|
||||
.filter(template -> template.getUuid().equals(newWorkflowUuid))
|
||||
.findAny();
|
||||
if (!workflowResult.isPresent()) {
|
||||
if (!workflowTemplateResult.isPresent()) {
|
||||
models.put("section", section.getLabel());
|
||||
models.put("workflowUuid", newWorkflowUuid);
|
||||
return "org/librecms/ui/contentsection/documents/workflow-not-found.xhtml";
|
||||
}
|
||||
|
||||
workflowManager.createWorkflow(workflowResult.get(), item);
|
||||
final String returnUrl;
|
||||
if (returnUrlParam.startsWith("/@contentsections")) {
|
||||
returnUrl = returnUrlParam.substring("/@contentsections".length());
|
||||
} else if(returnUrlParam.startsWith("@contentsections")) {
|
||||
returnUrl = returnUrlParam.substring("@contentsections".length());
|
||||
} else {
|
||||
returnUrl = returnUrlParam;
|
||||
}
|
||||
|
||||
final Workflow oldWorkflow = item.getWorkflow();
|
||||
if (oldWorkflow != null) {
|
||||
workflowManager.removeWorkflowFromObject(oldWorkflow, item);
|
||||
}
|
||||
|
||||
final Workflow workflow = workflowManager.createWorkflow(
|
||||
workflowTemplateResult.get(), item
|
||||
);
|
||||
item.setWorkflow(workflow);
|
||||
return String.format("redirect:%s", returnUrl);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import org.librecms.contentsection.Folder;
|
|||
import org.librecms.contentsection.FolderManager;
|
||||
import org.librecms.contentsection.privileges.ItemPrivileges;
|
||||
import org.librecms.ui.contentsections.FolderBreadcrumbsModel;
|
||||
import org.librecms.ui.contentsections.WorkflowTemplateListModel;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
|
@ -45,6 +46,7 @@ import javax.enterprise.context.RequestScoped;
|
|||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.transaction.Transactional;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
|
||||
/**
|
||||
|
|
@ -166,6 +168,11 @@ public class SelectedDocumentModel {
|
|||
*/
|
||||
private List<TaskListEntry> allTasks;
|
||||
|
||||
/**
|
||||
* Available workflows that can be assigned to the item.
|
||||
*/
|
||||
private List<WorkflowTemplateListModel> availableWorkflows;
|
||||
|
||||
public String getItemName() {
|
||||
return itemName;
|
||||
}
|
||||
|
|
@ -216,12 +223,17 @@ public class SelectedDocumentModel {
|
|||
);
|
||||
}
|
||||
|
||||
public List<WorkflowTemplateListModel> getAvailableWorkflows() {
|
||||
return Collections.unmodifiableList(availableWorkflows);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current content item/document and sets the properties of this
|
||||
* model based on the item.
|
||||
*
|
||||
* @param item
|
||||
*/
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
void setContentItem(final ContentItem item) {
|
||||
this.item = Objects.requireNonNull(item);
|
||||
itemName = item.getDisplayName();
|
||||
|
|
@ -261,6 +273,14 @@ public class SelectedDocumentModel {
|
|||
currentTask.setCurrentTask(true);
|
||||
}
|
||||
}
|
||||
|
||||
availableWorkflows = item
|
||||
.getContentType()
|
||||
.getContentSection()
|
||||
.getWorkflowTemplates()
|
||||
.stream()
|
||||
.map(this::buildWorkflowTemplateListModel)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -395,4 +415,30 @@ public class SelectedDocumentModel {
|
|||
.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for building a {@link WorkflowTemplateListModel} for a
|
||||
* {@link Workflow}.
|
||||
*
|
||||
* @param workflow The workflow.
|
||||
*
|
||||
* @return A {@link WorkflowTemplateListModel} for the {@code workflow}.
|
||||
*/
|
||||
private WorkflowTemplateListModel buildWorkflowTemplateListModel(
|
||||
final Workflow workflow
|
||||
) {
|
||||
final WorkflowTemplateListModel model = new WorkflowTemplateListModel();
|
||||
model.setDescription(
|
||||
globalizationHelper.getValueFromLocalizedString(
|
||||
workflow.getDescription()
|
||||
)
|
||||
);
|
||||
model.setHasTasks(!workflow.getTasks().isEmpty());
|
||||
model.setName(
|
||||
globalizationHelper.getValueFromLocalizedString(workflow.getName())
|
||||
);
|
||||
model.setUuid(workflow.getUuid());
|
||||
model.setWorkflowId(workflow.getWorkflowId());
|
||||
return model;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
<!DOCTYPE html [<!ENTITY times '×'>]>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:bootstrap="http://xmlns.jcp.org/jsf/composite/components/bootstrap"
|
||||
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
|
||||
<ui:composition template="/WEB-INF/views/org/librecms/ui/contentsection/contentsection.xhtml">
|
||||
|
|
@ -29,10 +30,72 @@
|
|||
#{CmsAdminMessages['contentsection.document.authoring.workflow.active_workflow_label']}:
|
||||
#{CmsSelectedDocumentModel.workflowName}
|
||||
<button class="btn btn-secondary btn-sm"
|
||||
data-toggle="modal"
|
||||
data-target="#change-workflow-dialog"
|
||||
disabled="#{!CmsSelectedDocumentModel.canChangeWorkflow ? 'disabled': ''}"
|
||||
type="button">
|
||||
#{CmsAdminMessages['contentsection.document.authoring.workflow.change_workflow']}
|
||||
</button>
|
||||
<c:if test="#{CmsSelectedDocumentModel.canChangeWorkflow}">
|
||||
<div aria-labelledby="change-workflow-dialog-title"
|
||||
aria-hidden="true"
|
||||
class="modal fade"
|
||||
id="change-workflow-dialog"
|
||||
tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<form action="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@workflow/apply-alternative"
|
||||
class="modal-content"
|
||||
method="post">
|
||||
<div class="modal-header">
|
||||
<h3 class="modal-title"
|
||||
id="change-workflow-dialog-title">
|
||||
#{CmsAdminMessages['contentsection.document.authoring.workflow.change_workflow.title']}
|
||||
</h3>
|
||||
<button aria-label="#{CmsAdminMessages['contentsection.document.authoring.workflow.change_workflow.close']} "
|
||||
class="close"
|
||||
data-dismiss="modal"
|
||||
type="button">
|
||||
<bootstrap:svgIcon icon="x-circle" />
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<c:forEach items="#{CmsSelectedDocumentModel.availableWorkflows}"
|
||||
var="workflow">
|
||||
|
||||
<div class="form-group form-check">
|
||||
<input
|
||||
aria-describedby="workflow-#{workflow.uuid}-description"
|
||||
id="workflow-#{workflow.uuid}"
|
||||
name="newWorkflowUuid"
|
||||
type="radio"
|
||||
value="#{workflow.uuid}"/>
|
||||
<label for="workflow-#{workflow.uuid}">#{workflow.name}</label>
|
||||
<span class="form-text text-muted"
|
||||
id="workflow-#{workflow.uuid}-description">
|
||||
#{workflow.description}
|
||||
</span>
|
||||
</div>
|
||||
</c:forEach>
|
||||
<input
|
||||
name="returnUrl"
|
||||
type="hidden"
|
||||
value="#{authoringStep}" />
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-warning"
|
||||
data-dismiss="modal"
|
||||
type="button">
|
||||
#{CmsAdminMessages['contentsection.document.authoring.workflow.change_workflow.close']}
|
||||
</button>
|
||||
<button class="btn btn-success"
|
||||
type="submit">
|
||||
#{CmsAdminMessages['contentsection.document.authoring.workflow.change_workflow.submit']}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</c:if>
|
||||
</p>
|
||||
<p>
|
||||
<c:choose>
|
||||
|
|
@ -40,7 +103,7 @@
|
|||
#{CmsAdminMessages['contentsection.document.authoring.workflow.active_task']}
|
||||
#{CmsSelectedDocumentModel.currentTask.label}
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
<c:when test="#{CmsSelectedDocumentModel.workflowName != null}">
|
||||
#{CmsAdminMessages['contentsection.document.authoring.workflow.active_task.none']}
|
||||
<form action="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@workflow/@start"
|
||||
method="post">
|
||||
|
|
@ -53,6 +116,9 @@
|
|||
#{CmsAdminMessages['contentsection.document.authoring.workflow.start']}
|
||||
</button>
|
||||
</form>
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
#{CmsAdminMessages['contentsection.document.authoring.workflow.none']}
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
<c:if test="#{CmsSelectedDocumentModel.currentTask != null}">
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<ui:composition template="/WEB-INF/views/org/librecms/ui/contentsection/documents/authoringstep.xhtml">
|
||||
|
||||
<ui:param name="authoringStep"
|
||||
value="/libreccm/@contentsections/info/documents/test-article/@article-basicproperties" />
|
||||
value="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@article-basicproperties" />
|
||||
|
||||
<ui:define name="authoringStep">
|
||||
<h2>#{CmsArticleMessageBundle.getMessage('basicproperties.header', [CmsArticlePropertiesStep.name])}</h2>
|
||||
|
|
|
|||
|
|
@ -1010,3 +1010,7 @@ pages.page.details.dialog.category.label=Category
|
|||
pages.page.details.dialog.properties.label=Properties
|
||||
pages.page.details.dialog.properties.key=Name
|
||||
pages.page.details.dialog.properties.value=Value
|
||||
contentsection.document.authoring.workflow.none=No workflow assigned
|
||||
contentsection.document.authoring.workflow.change_workflow.title=Assign workflow
|
||||
contentsection.document.authoring.workflow.change_workflow.submit=Assign workflow
|
||||
contentsection.document.authoring.workflow.change_workflow.close=Cancel
|
||||
|
|
|
|||
|
|
@ -1011,3 +1011,7 @@ pages.page.details.dialog.category.label=Kategorie
|
|||
pages.page.details.dialog.properties.label=Eigenschaften
|
||||
pages.page.details.dialog.properties.key=Name
|
||||
pages.page.details.dialog.properties.value=Wert
|
||||
contentsection.document.authoring.workflow.none=Kein Arbeitsablauf zugewiesen
|
||||
contentsection.document.authoring.workflow.change_workflow.title=Arbeitsablauf zuweisen
|
||||
contentsection.document.authoring.workflow.change_workflow.submit=Arbeitsablauf zuweisen
|
||||
contentsection.document.authoring.workflow.change_workflow.close=Abbrechen
|
||||
|
|
|
|||
|
|
@ -71,10 +71,12 @@ import java.util.Optional;
|
|||
*/
|
||||
@RequestScoped
|
||||
public class WorkflowManager implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -6939804120313699606L;
|
||||
|
||||
private final static Logger LOGGER = LogManager.getLogger(
|
||||
WorkflowManager.class);
|
||||
WorkflowManager.class
|
||||
);
|
||||
|
||||
@Inject
|
||||
private EntityManager entityManager;
|
||||
|
|
@ -105,7 +107,8 @@ public class WorkflowManager implements Serializable {
|
|||
@PostConstruct
|
||||
private void init() {
|
||||
final KernelConfig kernelConfig = confManager.findConfiguration(
|
||||
KernelConfig.class);
|
||||
KernelConfig.class
|
||||
);
|
||||
defaultLocale = kernelConfig.getDefaultLocale();
|
||||
}
|
||||
|
||||
|
|
@ -121,23 +124,29 @@ public class WorkflowManager implements Serializable {
|
|||
@AuthorizationRequired
|
||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public Workflow createWorkflow(final Workflow template,
|
||||
final CcmObject object) {
|
||||
Objects.requireNonNull(template,
|
||||
"Can't create a workflow without a template.");
|
||||
public Workflow createWorkflow(
|
||||
final Workflow template, final CcmObject object
|
||||
) {
|
||||
Objects.requireNonNull(
|
||||
template, "Can't create a workflow without a template."
|
||||
);
|
||||
if (!template.isAbstractWorkflow()) {
|
||||
throw new IllegalArgumentException(
|
||||
"The provided template is not an abstract workflow");
|
||||
"The provided template is not an abstract workflow"
|
||||
);
|
||||
}
|
||||
|
||||
Objects.requireNonNull(object,
|
||||
"Can't create a workflow without an object.");
|
||||
Objects.requireNonNull(
|
||||
object, "Can't create a workflow without an object."
|
||||
);
|
||||
|
||||
final Workflow workflow = new Workflow();
|
||||
|
||||
final LocalizedString name = new LocalizedString();
|
||||
template.getName().getValues().forEach(
|
||||
(locale, str) -> name.addValue(locale, str));
|
||||
template
|
||||
.getName()
|
||||
.getValues()
|
||||
.forEach((locale, str) -> name.addValue(locale, str));
|
||||
workflow.setName(name);
|
||||
|
||||
final LocalizedString description = new LocalizedString();
|
||||
|
|
@ -156,13 +165,16 @@ public class WorkflowManager implements Serializable {
|
|||
.forEach(taskTemplate -> createTask(workflow, taskTemplate, tasks));
|
||||
template
|
||||
.getTasks()
|
||||
.forEach(taskTemplate -> {
|
||||
fixTaskDependencies(taskTemplate,
|
||||
tasks.get(taskTemplate.getTaskId()),
|
||||
tasks);
|
||||
.forEach(
|
||||
taskTemplate -> {
|
||||
fixTaskDependencies(
|
||||
taskTemplate,
|
||||
tasks.get(taskTemplate.getTaskId()),
|
||||
tasks
|
||||
);
|
||||
});
|
||||
|
||||
for(final Map.Entry<Long, Task> task : tasks.entrySet()) {
|
||||
for (final Map.Entry<Long, Task> task : tasks.entrySet()) {
|
||||
task.getValue().setTaskState(TaskState.DISABLED);
|
||||
}
|
||||
|
||||
|
|
@ -175,6 +187,20 @@ public class WorkflowManager implements Serializable {
|
|||
return workflow;
|
||||
}
|
||||
|
||||
@AuthorizationRequired
|
||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public void removeWorkflowFromObject(
|
||||
final Workflow workflow, final CcmObject object) {
|
||||
Objects.requireNonNull(workflow, "Can't delete null.");
|
||||
Objects.requireNonNull(object);
|
||||
|
||||
for(final Task task : workflow.getTasks()) {
|
||||
taskRepo.delete(task);
|
||||
}
|
||||
workflowRepo.delete(workflow);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for
|
||||
* {@link #createWorkflow(org.libreccm.workflow.WorkflowTemplate, org.libreccm.core.CcmObject)}
|
||||
|
|
@ -184,15 +210,19 @@ public class WorkflowManager implements Serializable {
|
|||
* @param template The template for the task from the workflow template.
|
||||
* @param tasks A map for storing the new tasks.
|
||||
*/
|
||||
private void createTask(final Workflow workflow,
|
||||
final Task template,
|
||||
final Map<Long, Task> tasks) {
|
||||
|
||||
private void createTask(
|
||||
final Workflow workflow,
|
||||
final Task template,
|
||||
final Map<Long, Task> tasks
|
||||
) {
|
||||
final Class<? extends Task> templateClass = template.getClass();
|
||||
final Task task;
|
||||
try {
|
||||
task = templateClass.getDeclaredConstructor().newInstance();
|
||||
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException ex) {
|
||||
} catch (InstantiationException
|
||||
| IllegalAccessException
|
||||
| NoSuchMethodException
|
||||
| InvocationTargetException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
|
|
@ -227,8 +257,9 @@ public class WorkflowManager implements Serializable {
|
|||
final LocalizedString localized = (LocalizedString) value;
|
||||
final LocalizedString copy = new LocalizedString();
|
||||
|
||||
localized.getValues().forEach(
|
||||
(locale, str) -> copy.addValue(locale, str));
|
||||
localized
|
||||
.getValues()
|
||||
.forEach((locale, str) -> copy.addValue(locale, str));
|
||||
|
||||
writeMethod.invoke(task, copy);
|
||||
} else {
|
||||
|
|
@ -247,16 +278,18 @@ public class WorkflowManager implements Serializable {
|
|||
|
||||
if (template instanceof AssignableTask) {
|
||||
final AssignableTask assignableTemplate
|
||||
= (AssignableTask) template;
|
||||
= (AssignableTask) template;
|
||||
final AssignableTask assignableTask = (AssignableTask) task;
|
||||
|
||||
assignableTemplate
|
||||
.getAssignments()
|
||||
.stream()
|
||||
.map(TaskAssignment::getRole)
|
||||
.forEach(role -> {
|
||||
assignableTaskManager.assignTask(assignableTask, role);
|
||||
});
|
||||
.forEach(
|
||||
role -> assignableTaskManager.assignTask(
|
||||
assignableTask, role
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -270,19 +303,19 @@ public class WorkflowManager implements Serializable {
|
|||
* @param task
|
||||
* @param tasks
|
||||
*/
|
||||
private void fixTaskDependencies(final Task template,
|
||||
final Task task,
|
||||
final Map<Long, Task> tasks) {
|
||||
|
||||
private void fixTaskDependencies(
|
||||
final Task template, final Task task, final Map<Long, Task> tasks
|
||||
) {
|
||||
if (template.getBlockedTasks() != null
|
||||
&& !template.getBlockedTasks().isEmpty()) {
|
||||
|
||||
for (final TaskDependency blocked : template.getBlockedTasks()) {
|
||||
|
||||
final Task blockingTask = tasks
|
||||
.get(blocked.getBlockingTask().getTaskId());
|
||||
final Task blockedTask = tasks
|
||||
.get(blocked.getBlockedTask().getTaskId());
|
||||
final Task blockingTask = tasks.get(
|
||||
blocked.getBlockingTask().getTaskId()
|
||||
);
|
||||
final Task blockedTask = tasks.get(
|
||||
blocked.getBlockedTask().getTaskId()
|
||||
);
|
||||
try {
|
||||
taskManager.addDependentTask(blockingTask, blockedTask);
|
||||
} catch (CircularTaskDependencyException ex) {
|
||||
|
|
@ -297,14 +330,17 @@ public class WorkflowManager implements Serializable {
|
|||
// -> task.addDependentTask(tasks.get(dependent.getTaskId())));
|
||||
// }
|
||||
for (final TaskDependency blocking : template.getBlockingTasks()) {
|
||||
|
||||
final Task blockingTask = tasks
|
||||
.get(blocking.getBlockingTask().getTaskId());
|
||||
final Task blockedTask = tasks
|
||||
.get(blocking.getBlockedTask().getTaskId());
|
||||
final Task blockingTask = tasks.get(
|
||||
blocking.getBlockingTask().getTaskId()
|
||||
);
|
||||
final Task blockedTask = tasks.get(
|
||||
blocking.getBlockedTask().getTaskId()
|
||||
);
|
||||
try {
|
||||
taskManager.addDependentTask(blockingTask, blockedTask);
|
||||
} catch(CircularTaskDependencyException ex) {
|
||||
taskManager.addDependentTask(
|
||||
blockingTask, blockedTask
|
||||
);
|
||||
} catch (CircularTaskDependencyException ex) {
|
||||
throw new UnexpectedErrorException(ex);
|
||||
}
|
||||
|
||||
|
|
@ -331,14 +367,18 @@ public class WorkflowManager implements Serializable {
|
|||
public List<Task> findEnabledTasks(final Workflow workflow) {
|
||||
if (workflow.getState() == WorkflowState.DELETED
|
||||
|| workflow.getState() == WorkflowState.STOPPED) {
|
||||
LOGGER.debug(String.format("Workflow state is \"%s\". Workflow "
|
||||
+ "has no enabled tasks.",
|
||||
workflow.getState().toString()));
|
||||
LOGGER.debug(
|
||||
String.format(
|
||||
"Workflow state is \"%s\". Workflow has no enabled tasks.",
|
||||
workflow.getState().toString()
|
||||
)
|
||||
);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final TypedQuery<Task> query = entityManager.createNamedQuery(
|
||||
"Task.findEnabledTasks", Task.class);
|
||||
"Task.findEnabledTasks", Task.class
|
||||
);
|
||||
query.setParameter("workflow", workflow);
|
||||
|
||||
return Collections.unmodifiableList(query.getResultList());
|
||||
|
|
@ -357,7 +397,8 @@ public class WorkflowManager implements Serializable {
|
|||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public List<Task> findFinishedTasks(final Workflow workflow) {
|
||||
final TypedQuery<Task> query = entityManager.createNamedQuery(
|
||||
"Task.findFinishedTasks", Task.class);
|
||||
"Task.findFinishedTasks", Task.class
|
||||
);
|
||||
query.setParameter("workflow", workflow);
|
||||
|
||||
return Collections.unmodifiableList(query.getResultList());
|
||||
|
|
@ -376,7 +417,8 @@ public class WorkflowManager implements Serializable {
|
|||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public List<AssignableTask> findOverdueTasks(final Workflow workflow) {
|
||||
final TypedQuery<AssignableTask> query = entityManager.createNamedQuery(
|
||||
"AssignableTask.findOverdueTasks", AssignableTask.class);
|
||||
"AssignableTask.findOverdueTasks", AssignableTask.class
|
||||
);
|
||||
query.setParameter("workflow", workflow);
|
||||
query.setParameter("now", new Date());
|
||||
|
||||
|
|
@ -392,7 +434,6 @@ public class WorkflowManager implements Serializable {
|
|||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public void start(final Workflow workflow) {
|
||||
|
||||
final WorkflowState oldState = workflow.getState();
|
||||
|
||||
workflow.setState(WorkflowState.STARTED);
|
||||
|
|
@ -414,10 +455,13 @@ public class WorkflowManager implements Serializable {
|
|||
final Optional<User> currentUser = shiro.getUser();
|
||||
if (currentUser.isPresent()
|
||||
&& assignableTaskManager
|
||||
.isAssignedTo((AssignableTask) firstTask,
|
||||
currentUser.get())) {
|
||||
assignableTaskManager
|
||||
.lockTask((AssignableTask) firstTask);
|
||||
.isAssignedTo(
|
||||
(AssignableTask) firstTask,
|
||||
currentUser.get()
|
||||
)) {
|
||||
assignableTaskManager.lockTask(
|
||||
(AssignableTask) firstTask
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -437,7 +481,8 @@ public class WorkflowManager implements Serializable {
|
|||
private void updateState(final Workflow workflow) {
|
||||
if (workflow.getTasksState() == TaskState.ENABLED) {
|
||||
final TypedQuery<Long> query = entityManager.createNamedQuery(
|
||||
"Task.countUnfinishedAndActiveTasksForWorkflow", Long.class);
|
||||
"Task.countUnfinishedAndActiveTasksForWorkflow", Long.class
|
||||
);
|
||||
query.setParameter("workflow", workflow);
|
||||
|
||||
final Long result = query.getSingleResult();
|
||||
|
|
@ -451,7 +496,8 @@ public class WorkflowManager implements Serializable {
|
|||
|
||||
if (workflow.getTasksState() == TaskState.FINISHED) {
|
||||
final TypedQuery<Long> query = entityManager.createNamedQuery(
|
||||
"Task.countUnfinishedTasksForWorkflow", Long.class);
|
||||
"Task.countUnfinishedTasksForWorkflow", Long.class
|
||||
);
|
||||
query.setParameter("workflow", workflow);
|
||||
|
||||
final Long result = query.getSingleResult();
|
||||
|
|
@ -485,9 +531,12 @@ public class WorkflowManager implements Serializable {
|
|||
@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)));
|
||||
throw new IllegalArgumentException(
|
||||
String.format(
|
||||
"Workflow \"%s\" is not enabled.",
|
||||
workflow.getName().getValue(defaultLocale)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
workflow.setTasksState(TaskState.FINISHED);
|
||||
|
|
@ -510,8 +559,10 @@ public class WorkflowManager implements Serializable {
|
|||
|
||||
switch (workflow.getTasksState()) {
|
||||
case DISABLED:
|
||||
LOGGER.debug("Workflow \"{}\" is disabled; enabling it.",
|
||||
workflow.getName().getValue(defaultLocale));
|
||||
LOGGER.debug(
|
||||
"Workflow \"{}\" is disabled; enabling it.",
|
||||
workflow.getName().getValue(defaultLocale)
|
||||
);
|
||||
workflow.setTasksState(TaskState.ENABLED);
|
||||
workflowRepo.save(workflow);
|
||||
break;
|
||||
|
|
@ -521,10 +572,12 @@ public class WorkflowManager implements Serializable {
|
|||
workflowRepo.save(workflow);
|
||||
break;
|
||||
default:
|
||||
LOGGER.debug("Workflow \"{}\" has tasksState \"{}\", "
|
||||
+ "#enable(Workflow) does nothing.",
|
||||
workflow.getName().getValue(defaultLocale),
|
||||
workflow.getTasksState());
|
||||
LOGGER.debug(
|
||||
"Workflow \"{}\" has tasksState \"{}\", "
|
||||
+ "#enable(Workflow) does nothing.",
|
||||
workflow.getName().getValue(defaultLocale),
|
||||
workflow.getTasksState()
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ public class WorkflowRepository extends AbstractEntityRepository<Long, Workflow>
|
|||
* @return An {@link Optional} containing the {@link Workflow} identified by
|
||||
* the provided UUID.
|
||||
*/
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public Optional<Workflow> findByUuid(final String uuid) {
|
||||
if (uuid == null) {
|
||||
throw new IllegalArgumentException(
|
||||
|
|
@ -102,6 +103,7 @@ public class WorkflowRepository extends AbstractEntityRepository<Long, Workflow>
|
|||
* {@code object} if the object has a workflow. Otherwise an empty
|
||||
* {@link Optional} is returned.
|
||||
*/
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public Optional<Workflow> findWorkflowForObject(final CcmObject object) {
|
||||
if (object == null) {
|
||||
throw new IllegalArgumentException(
|
||||
|
|
|
|||
Loading…
Reference in New Issue