Controller methods for workflow and lifecycle management of content items/documents

pull/10/head
Jens Pelzetter 2021-03-15 21:09:42 +01:00
parent b5178788c2
commit c7a8756c9c
6 changed files with 922 additions and 0 deletions

View File

@ -5,24 +5,47 @@
*/ */
package org.librecms.ui.contentsections.documents; package org.librecms.ui.contentsections.documents;
import org.libreccm.api.Identifier;
import org.libreccm.api.IdentifierParser;
import org.libreccm.l10n.GlobalizationHelper;
import org.libreccm.security.AuthorizationRequired;
import org.libreccm.security.PermissionChecker;
import org.libreccm.workflow.AssignableTask;
import org.libreccm.workflow.AssignableTaskManager;
import org.libreccm.workflow.TaskManager;
import org.libreccm.workflow.Workflow;
import org.libreccm.workflow.WorkflowManager;
import org.libreccm.workflow.WorkflowRepository;
import org.librecms.contentsection.ContentItem; import org.librecms.contentsection.ContentItem;
import org.librecms.contentsection.ContentItemManager;
import org.librecms.contentsection.ContentItemRepository; import org.librecms.contentsection.ContentItemRepository;
import org.librecms.contentsection.ContentSection; import org.librecms.contentsection.ContentSection;
import org.librecms.contentsection.Folder; import org.librecms.contentsection.Folder;
import org.librecms.contentsection.FolderRepository; import org.librecms.contentsection.FolderRepository;
import org.librecms.contentsection.FolderType; import org.librecms.contentsection.FolderType;
import org.librecms.contentsection.privileges.ItemPrivileges;
import org.librecms.lifecycle.LifecycleDefinition;
import org.librecms.lifecycle.LifecycleManager;
import org.librecms.lifecycle.Phase;
import org.librecms.ui.contentsections.ContentSectionsUi; import org.librecms.ui.contentsections.ContentSectionsUi;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors;
import javax.enterprise.context.RequestScoped; import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Instance; import javax.enterprise.inject.Instance;
import javax.enterprise.util.AnnotationLiteral; import javax.enterprise.util.AnnotationLiteral;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named;
import javax.mvc.Controller; import javax.mvc.Controller;
import javax.mvc.Models; import javax.mvc.Models;
import javax.transaction.Transactional; import javax.transaction.Transactional;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET; import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path; import javax.ws.rs.Path;
import javax.ws.rs.PathParam; import javax.ws.rs.PathParam;
@ -33,8 +56,12 @@ import javax.ws.rs.PathParam;
@RequestScoped @RequestScoped
@Path("/{sectionIdentifier}/documents") @Path("/{sectionIdentifier}/documents")
@Controller @Controller
@Named("CmsDocumentController")
public class DocumentController { public class DocumentController {
@Inject
private ContentItemManager itemManager;
@Inject @Inject
private ContentSectionsUi sectionsUi; private ContentSectionsUi sectionsUi;
@ -50,11 +77,42 @@ public class DocumentController {
@Inject @Inject
private Instance<MvcDocumentCreateStep<?>> createSteps; private Instance<MvcDocumentCreateStep<?>> createSteps;
@Inject
private GlobalizationHelper globalizationHelper;
@Inject
private IdentifierParser identifierParser;
@Inject
private LifecycleManager lifecycleManager;
@Inject @Inject
private Models models; private Models models;
@Inject
private PermissionChecker permissionChecker;
@Inject
private PublishStepModel publishStepModel;
@Inject
private SelectedDocumentModel selectedDocumentModel;
@Inject
private WorkflowManager workflowManager;
@Inject
private AssignableTaskManager assignableTaskManager;
@Inject
private TaskManager taskManager;
@Inject
private WorkflowRepository workflowRepository;
@GET @GET
@Path("/") @Path("/")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public String redirectToDocumentFolders( public String redirectToDocumentFolders(
@PathParam("sectionIdentifider") final String sectionIdentifier @PathParam("sectionIdentifider") final String sectionIdentifier
@ -66,6 +124,7 @@ public class DocumentController {
} }
@Path("/@create/{documentType}") @Path("/@create/{documentType}")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public MvcDocumentCreateStep<? extends ContentItem> createDocument( public MvcDocumentCreateStep<? extends ContentItem> createDocument(
@PathParam("sectionIdentifider") final String sectionIdentifier, @PathParam("sectionIdentifider") final String sectionIdentifier,
@ -75,6 +134,7 @@ public class DocumentController {
} }
@Path("/{folderPath:(.+)?}/@create/{documentType}") @Path("/{folderPath:(.+)?}/@create/{documentType}")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public MvcDocumentCreateStep<? extends ContentItem> createDocument( public MvcDocumentCreateStep<? extends ContentItem> createDocument(
@ -146,6 +206,7 @@ public class DocumentController {
} }
@Path("/{documentPath:(.+)?}/@authoringsteps/{authoringStep}") @Path("/{documentPath:(.+)?}/@authoringsteps/{authoringStep}")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public MvcAuthoringStep editDocument( public MvcAuthoringStep editDocument(
@PathParam("sectionIdentifider") final String sectionIdentifier, @PathParam("sectionIdentifider") final String sectionIdentifier,
@ -192,12 +253,518 @@ public class DocumentController {
return new UnsupportedDocumentType(); return new UnsupportedDocumentType();
} }
selectedDocumentModel.setContentItem(item);
authoringStep.setContentSection(section); authoringStep.setContentSection(section);
authoringStep.setContentItem(item); authoringStep.setContentItem(item);
return authoringStep; return authoringStep;
} }
@POST
@Path("/{documentPath:(.+)?}/@history")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String showHistory(
@PathParam("sectionIdentifider") final String sectionIdentifier,
@PathParam("documentPath") final String documentPath
) {
final Optional<ContentSection> sectionResult = sectionsUi
.findContentSection(sectionIdentifier);
if (!sectionResult.isPresent()) {
return sectionsUi.showContentSectionNotFound(sectionIdentifier);
}
final ContentSection section = sectionResult.get();
final Optional<ContentItem> itemResult = itemRepo
.findByPath(section, documentPath);
if (!itemResult.isPresent()) {
return showDocumentNotFound(section, documentPath);
}
final ContentItem item = itemResult.get();
if (!permissionChecker.isPermitted(ItemPrivileges.EDIT, item)) {
return sectionsUi.showAccessDenied(
"sectionIdentifier", sectionIdentifier,
"documentPath", documentPath
);
}
selectedDocumentModel.setContentItem(item);
models.put(
"revisions",
itemRepo.retrieveRevisions(item, item.getObjectId())
);
return "org/librecms/ui/contentsection/documents/history.xhtml";
}
@GET
@Path("/{documentPath:(.+)?}/@publish")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String showPublishStep(
@PathParam("sectionIdentifider") final String sectionIdentifier,
@PathParam("documentPath") final String documentPath
) {
final Optional<ContentSection> sectionResult = sectionsUi
.findContentSection(sectionIdentifier);
if (!sectionResult.isPresent()) {
return sectionsUi.showContentSectionNotFound(sectionIdentifier);
}
final ContentSection section = sectionResult.get();
final Optional<ContentItem> itemResult = itemRepo
.findByPath(section, documentPath);
if (!itemResult.isPresent()) {
return showDocumentNotFound(section, documentPath);
}
final ContentItem item = itemResult.get();
if (!permissionChecker.isPermitted(ItemPrivileges.PUBLISH, item)) {
return sectionsUi.showAccessDenied(
"sectionIdentifier", sectionIdentifier,
"documentPath", documentPath
);
}
publishStepModel.setAvailableLifecycles(
section
.getLifecycleDefinitions()
.stream()
.map(this::buildLifecycleListEntry)
.collect(Collectors.toList())
);
if (item.getLifecycle() != null) {
publishStepModel.setPhases(
item
.getLifecycle()
.getPhases()
.stream()
.map(this::buildPhaseListEntry)
.collect(Collectors.toList())
);
}
return "org/librecms/ui/contentsection/documents/publish.xhtml";
}
@POST
@Path("/{documentPath:(.+)?}/@lifecycle/phases/{phaseId}")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String updatePhaseDates(
@PathParam("sectionIdentifider") final String sectionIdentifier,
@PathParam("documentPath") final String documentPath,
@PathParam("phaseId") final long phaseId,
@FormParam("startDate") final String startDateParam,
@FormParam("endDate") final String endDateParam
) {
throw new UnsupportedOperationException("ToDo");
}
@POST
@Path("/{documentPath:(.+)?}/@publish")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String publish(
@PathParam("sectionIdentifider") final String sectionIdentifier,
@PathParam("documentPath") final String documentPath,
@FormParam("selectedLifecycleUuid") @DefaultValue("")
final String selectedLifecycleUuid
) {
final Optional<ContentSection> sectionResult = sectionsUi
.findContentSection(sectionIdentifier);
if (!sectionResult.isPresent()) {
return sectionsUi.showContentSectionNotFound(sectionIdentifier);
}
final ContentSection section = sectionResult.get();
final Optional<ContentItem> itemResult = itemRepo
.findByPath(section, documentPath);
if (!itemResult.isPresent()) {
return showDocumentNotFound(section, documentPath);
}
final ContentItem item = itemResult.get();
if (!permissionChecker.isPermitted(ItemPrivileges.PUBLISH, item)) {
return sectionsUi.showAccessDenied(
"sectionIdentifier", sectionIdentifier,
"documentPath", documentPath
);
}
if (selectedLifecycleUuid.isEmpty()) {
itemManager.publish(item);
} else {
final Optional<LifecycleDefinition> result = section
.getLifecycleDefinitions()
.stream()
.filter(
definition -> definition.getUuid().equals(
selectedLifecycleUuid
)
).findAny();
if (!result.isPresent()) {
models.put("section", section.getLabel());
models.put("lifecycleDefUuid", selectedLifecycleUuid);
return "org/librecms/ui/contentsection/lifecycle-def-not-found.xhtml";
}
}
return String.format(
"redirect:/%s/documents/%s/@publish",
sectionIdentifier,
documentPath
);
}
@POST
@Path("/{documentPath:(.+)?}/@republish")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String republish(
@PathParam("sectionIdentifider") final String sectionIdentifier,
@PathParam("documentPath") final String documentPath
) {
final Optional<ContentSection> sectionResult = sectionsUi
.findContentSection(sectionIdentifier);
if (!sectionResult.isPresent()) {
return sectionsUi.showContentSectionNotFound(sectionIdentifier);
}
final ContentSection section = sectionResult.get();
final Optional<ContentItem> itemResult = itemRepo
.findByPath(section, documentPath);
if (!itemResult.isPresent()) {
return showDocumentNotFound(section, documentPath);
}
final ContentItem item = itemResult.get();
if (!permissionChecker.isPermitted(ItemPrivileges.PUBLISH, item)) {
return sectionsUi.showAccessDenied(
"sectionIdentifier", sectionIdentifier,
"documentPath", documentPath
);
}
itemManager.publish(item);
return String.format(
"redirect:/%s/documents/%s/@publish",
sectionIdentifier,
documentPath
);
}
public String unpublish() {
throw new UnsupportedOperationException("ToDo");
}
@POST
@Path("/{documentPath:(.+)?}/@workflow/tasks/${taskIdentifier}/@lock")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String lockTask(
@PathParam("sectionIdentifider") final String sectionIdentifier,
@PathParam("documentPath") final String documentPath,
@PathParam("taskIdentifier") final String taskIdentifier,
@FormParam("returnUrl") final String returnUrl
) {
final Optional<ContentSection> sectionResult = sectionsUi
.findContentSection(sectionIdentifier);
if (!sectionResult.isPresent()) {
return sectionsUi.showContentSectionNotFound(sectionIdentifier);
}
final ContentSection section = sectionResult.get();
final Optional<ContentItem> itemResult = itemRepo
.findByPath(section, documentPath);
if (!itemResult.isPresent()) {
return showDocumentNotFound(section, documentPath);
}
final ContentItem item = itemResult.get();
selectedDocumentModel.setContentItem(item);
final Optional<AssignableTask> taskResult = findTask(
item, taskIdentifier
);
if (!taskResult.isPresent()) {
return showTaskNotFound(section, documentPath, taskIdentifier);
}
final AssignableTask task = taskResult.get();
assignableTaskManager.lockTask(task);
return String.format("redirect:%s", returnUrl);
}
@POST
@Path("/{documentPath:(.+)?}/@workflow/tasks/${taskIdentifier}/@unlock")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String unlockTask(
@PathParam("sectionIdentifider") final String sectionIdentifier,
@PathParam("documentPath") final String documentPath,
@PathParam("taskIdentifier") final String taskIdentifier,
@FormParam("returnUrl") final String returnUrl
) {
final Optional<ContentSection> sectionResult = sectionsUi
.findContentSection(sectionIdentifier);
if (!sectionResult.isPresent()) {
return sectionsUi.showContentSectionNotFound(sectionIdentifier);
}
final ContentSection section = sectionResult.get();
final Optional<ContentItem> itemResult = itemRepo
.findByPath(section, documentPath);
if (!itemResult.isPresent()) {
return showDocumentNotFound(section, documentPath);
}
final ContentItem item = itemResult.get();
selectedDocumentModel.setContentItem(item);
final Optional<AssignableTask> taskResult = findTask(
item, taskIdentifier
);
if (!taskResult.isPresent()) {
return showTaskNotFound(section, documentPath, taskIdentifier);
}
final AssignableTask task = taskResult.get();
assignableTaskManager.unlockTask(task);
return String.format("redirect:%s", returnUrl);
}
@POST
@Path("/{documentPath:(.+)?}/@workflow/tasks/${taskIdentifier}/@finish")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String finishTask(
@PathParam("sectionIdentifider") final String sectionIdentifier,
@PathParam("documentPath") final String documentPath,
@PathParam("taskIdentifier") final String taskIdentifier,
@FormParam("comment") @DefaultValue("") final String comment,
@FormParam("returnUrl") final String returnUrl
) {
final Optional<ContentSection> sectionResult = sectionsUi
.findContentSection(sectionIdentifier);
if (!sectionResult.isPresent()) {
return sectionsUi.showContentSectionNotFound(sectionIdentifier);
}
final ContentSection section = sectionResult.get();
final Optional<ContentItem> itemResult = itemRepo
.findByPath(section, documentPath);
if (!itemResult.isPresent()) {
return showDocumentNotFound(section, documentPath);
}
final ContentItem item = itemResult.get();
selectedDocumentModel.setContentItem(item);
final Optional<AssignableTask> taskResult = findTask(
item, taskIdentifier
);
if (!taskResult.isPresent()) {
return showTaskNotFound(section, documentPath, taskIdentifier);
}
final AssignableTask task = taskResult.get();
if (comment.isEmpty()) {
assignableTaskManager.finish(task);
} else {
assignableTaskManager.finish(task, comment);
}
return String.format("redirect:%s", returnUrl);
}
@POST
@Path(
"/{documentPath:(.+)?}/@workflow/@applyAlternative/{workflowIdentifier}")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String applyAlternateWorkflow(
@PathParam("sectionIdentifider") final String sectionIdentifier,
@PathParam("documentPath") final String documentPath,
@FormParam("newWorkflowUuid") final String newWorkflowUuid,
@FormParam("returnUrl") final String returnUrl
) {
final Optional<ContentSection> sectionResult = sectionsUi
.findContentSection(sectionIdentifier);
if (!sectionResult.isPresent()) {
return sectionsUi.showContentSectionNotFound(sectionIdentifier);
}
final ContentSection section = sectionResult.get();
final Optional<ContentItem> itemResult = itemRepo
.findByPath(section, documentPath);
if (!itemResult.isPresent()) {
return showDocumentNotFound(section, documentPath);
}
final ContentItem item = itemResult.get();
selectedDocumentModel.setContentItem(item);
if (!permissionChecker.isPermitted(
ItemPrivileges.APPLY_ALTERNATE_WORKFLOW, item)) {
return sectionsUi.showAccessDenied(
"sectionIdentifier", sectionIdentifier,
"documentPath", documentPath
);
}
final Optional<Workflow> workflowResult = section
.getWorkflowTemplates()
.stream()
.filter(template -> template.getUuid().equals(newWorkflowUuid))
.findAny();
if (!workflowResult.isPresent()) {
models.put("section", section.getLabel());
models.put("workflowUuid", newWorkflowUuid);
return "org/librecms/ui/contentsection/workflow-not-found.xhtml";
}
workflowManager.createWorkflow(workflowResult.get(), item);
return String.format("redirect:%s", returnUrl);
}
@POST
@Path("/{documentPath:(.+)?}/@workflow/@restart")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String restartWorkflow(
@PathParam("sectionIdentifider") final String sectionIdentifier,
@PathParam("documentPath") final String documentPath,
@FormParam("returnUrl") final String returnUrl
) {
final Optional<ContentSection> sectionResult = sectionsUi
.findContentSection(sectionIdentifier);
if (!sectionResult.isPresent()) {
return sectionsUi.showContentSectionNotFound(sectionIdentifier);
}
final ContentSection section = sectionResult.get();
final Optional<ContentItem> itemResult = itemRepo
.findByPath(section, documentPath);
if (!itemResult.isPresent()) {
return showDocumentNotFound(section, documentPath);
}
final ContentItem item = itemResult.get();
selectedDocumentModel.setContentItem(item);
if (!permissionChecker.isPermitted(
ItemPrivileges.APPLY_ALTERNATE_WORKFLOW, item)) {
return sectionsUi.showAccessDenied(
"sectionIdentifier", sectionIdentifier,
"documentPath", documentPath
);
}
if (item.getWorkflow() != null) {
workflowManager.start(item.getWorkflow());
}
return String.format("redirect:%s", returnUrl);
}
private Optional<AssignableTask> findTask(
final ContentItem item,
final String taskIdentifier
) {
final Workflow workflow = item.getWorkflow();
if (workflow == null) {
return Optional.empty();
}
final Identifier identifier = identifierParser.parseIdentifier(
taskIdentifier
);
switch (identifier.getType()) {
case ID:
return workflow
.getTasks()
.stream()
.filter(task -> task instanceof AssignableTask)
.map(task -> (AssignableTask) task)
.filter(
task -> task.getTaskId() == Long
.parseLong(identifier.getIdentifier())
).findAny();
default:
return workflow
.getTasks()
.stream()
.filter(task -> task instanceof AssignableTask)
.map(task -> (AssignableTask) task)
.filter(
task -> task.getUuid().equals(
identifier.getIdentifier()
)
).findAny();
}
}
private LifecycleListEntry buildLifecycleListEntry(
final LifecycleDefinition definition
) {
final LifecycleListEntry entry = new LifecycleListEntry();
entry.setDescription(
globalizationHelper.getValueFromLocalizedString(
definition.getDescription()
)
);
entry.setLabel(
globalizationHelper.getValueFromLocalizedString(
definition.getLabel()
)
);
entry.setUuid(definition.getUuid());
return entry;
}
private PhaseListEntry buildPhaseListEntry(final Phase phase) {
final DateTimeFormatter dateTimeFormatter
= DateTimeFormatter.ISO_DATE_TIME
.withZone(ZoneId.systemDefault());
final PhaseListEntry entry = new PhaseListEntry();
entry.setDescription(
globalizationHelper.getValueFromLocalizedString(
phase.getDefinition().getDescription()
)
);
entry.setEndDateTime(
dateTimeFormatter.format(phase.getEndDateTime().toInstant())
);
entry.setFinished(phase.isFinished());
entry.setLabel(
globalizationHelper.getValueFromLocalizedString(
phase.getDefinition().getLabel()
)
);
entry.setPhaseId(phase.getPhaseId());
entry.setStartDateTime(
dateTimeFormatter.format(phase.getStartDateTime().toInstant())
);
entry.setStarted(phase.isStarted());
return entry;
}
private String showDocumentNotFound(
final ContentSection section, final String documentPath
) {
models.put("section", section.getLabel());
models.put("documentPath", documentPath);
return "org/librecms/ui/contentsection/document-not-found.xhtml";
}
private String showTaskNotFound(
final ContentSection section,
final String documentPath,
final String taskIdentifier
) {
models.put("section", section.getLabel());
models.put("documentPath", documentPath);
models.put("taskIdentifier", taskIdentifier);
return "org/librecms/ui/contentsection/task-not-found.xhtml";
}
private static class CreateDocumentOfTypeLiteral private static class CreateDocumentOfTypeLiteral
extends AnnotationLiteral<CreatesDocumentOfType> extends AnnotationLiteral<CreatesDocumentOfType>
implements CreatesDocumentOfType { implements CreatesDocumentOfType {

View File

@ -0,0 +1,46 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.librecms.ui.contentsections.documents;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class LifecycleListEntry {
private String uuid;
private String label;
private String description;
public String getLabel() {
return label;
}
public void setLabel(final String label) {
this.label = label;
}
public String getDescription() {
return description;
}
public void setDescription(final String description) {
this.description = description;
}
public String getUuid() {
return uuid;
}
public void setUuid(final String uuid) {
this.uuid = uuid;
}
}

View File

@ -0,0 +1,84 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.librecms.ui.contentsections.documents;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class PhaseListEntry {
private long phaseId;
private String label;
private String description;
private boolean started;
private boolean finished;
private String startDateTime;
private String endDateTime;
public String getLabel() {
return label;
}
public void setLabel(final String label) {
this.label = label;
}
public String getDescription() {
return description;
}
public void setDescription(final String description) {
this.description = description;
}
public boolean isStarted() {
return started;
}
public void setStarted(final boolean started) {
this.started = started;
}
public boolean isFinished() {
return finished;
}
public void setFinished(final boolean finished) {
this.finished = finished;
}
public String getStartDateTime() {
return startDateTime;
}
public void setStartDateTime(final String startDateTime) {
this.startDateTime = startDateTime;
}
public String getEndDateTime() {
return endDateTime;
}
public void setEndDateTime(final String endDateTime) {
this.endDateTime = endDateTime;
}
public long getPhaseId() {
return phaseId;
}
public void setPhaseId(long phaseId) {
this.phaseId = phaseId;
}
}

View File

@ -0,0 +1,50 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.librecms.ui.contentsections.documents;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
@Named("CmsDocumentPublishStepModel")
public class PublishStepModel {
private List<LifecycleListEntry> availableListcycles;
private List<PhaseListEntry> phases;
public PublishStepModel() {
availableListcycles = new ArrayList<>();
phases = new ArrayList<>();
}
public List<LifecycleListEntry> getAvailableListcycles() {
return Collections.unmodifiableList(availableListcycles);
}
public void setAvailableLifecycles(
final List<LifecycleListEntry> availableListcycles
) {
this.availableListcycles = new ArrayList<>(availableListcycles);
}
public List<PhaseListEntry> getPhases() {
return Collections.unmodifiableList(phases);
}
public void setPhases(final List<PhaseListEntry> phases) {
this.phases = new ArrayList<>(phases);
}
}

View File

@ -0,0 +1,109 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.librecms.ui.contentsections.documents;
import org.libreccm.l10n.GlobalizationHelper;
import org.libreccm.security.PermissionChecker;
import org.libreccm.security.Shiro;
import org.libreccm.workflow.AssignableTask;
import org.libreccm.workflow.AssignableTaskManager;
import org.libreccm.workflow.TaskState;
import org.libreccm.workflow.Workflow;
import org.librecms.contentsection.ContentItem;
import org.librecms.contentsection.privileges.ItemPrivileges;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
@Named("CmsSelectedDocumentModel")
public class SelectedDocumentModel {
@Inject
private AssignableTaskManager taskManager;
@Inject
private GlobalizationHelper globalizationHelper;
@Inject
private PermissionChecker permissionChecker;
@Inject
private Shiro shiro;
private ContentItem item;
private Workflow workflow;
private TaskListEntry currentTask;
private List<TaskListEntry> allTasks;
void setContentItem(final ContentItem item) {
this.item = Objects.requireNonNull(item);
workflow = item.getWorkflow();
allTasks = workflow
.getTasks()
.stream()
.filter(task -> task instanceof AssignableTask)
.map(task -> (AssignableTask) task)
.map(this::buildTaskListEntry)
.collect(Collectors.toList());
currentTask = allTasks
.stream()
.filter(task -> task.getTaskState() == TaskState.ENABLED)
.findFirst()
.orElse(null);
if (currentTask != null) {
currentTask.setCurrentTask(true);
}
}
public TaskListEntry getCurrentTask() {
return currentTask;
}
public boolean getCanChangeWorkflow() {
return permissionChecker.isPermitted(
ItemPrivileges.APPLY_ALTERNATE_WORKFLOW, item
);
}
private TaskListEntry buildTaskListEntry(final AssignableTask task) {
final TaskListEntry entry = new TaskListEntry();
entry.setLabel(
globalizationHelper.getValueFromLocalizedString(
task.getLabel()
)
);
entry.setDescription(
globalizationHelper.getValueFromLocalizedString(
task.getDescription()
)
);
entry.setTaskState(task.getTaskState());
entry.setAssignedToCurrentUser(
shiro
.getUser()
.map(user -> taskManager.isAssignedTo(task, user))
.orElse(false)
);
return entry;
}
}

View File

@ -0,0 +1,66 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.librecms.ui.contentsections.documents;
import org.libreccm.workflow.TaskState;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class TaskListEntry {
private String label;
private String description;
private TaskState taskState;
private boolean currentTask;
private boolean assignedToCurrentUser;
public String getLabel() {
return label;
}
public void setLabel(final String label) {
this.label = label;
}
public TaskState getTaskState() {
return taskState;
}
public void setTaskState(TaskState taskState) {
this.taskState = taskState;
}
public boolean isCurrentTask() {
return currentTask;
}
public void setCurrentTask(final boolean currentTask) {
this.currentTask = currentTask;
}
public boolean isAssignedToCurrentUser() {
return assignedToCurrentUser;
}
public void setAssignedToCurrentUser(final boolean assignedToCurrentUser) {
this.assignedToCurrentUser = assignedToCurrentUser;
}
public String getDescription() {
return description;
}
public void setDescription(final String description) {
this.description = description;
}
}