Controller methods for workflow and lifecycle management of content items/documents
parent
b5178788c2
commit
c7a8756c9c
|
|
@ -5,24 +5,47 @@
|
|||
*/
|
||||
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.ContentItemManager;
|
||||
import org.librecms.contentsection.ContentItemRepository;
|
||||
import org.librecms.contentsection.ContentSection;
|
||||
import org.librecms.contentsection.Folder;
|
||||
import org.librecms.contentsection.FolderRepository;
|
||||
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 java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.enterprise.inject.Instance;
|
||||
import javax.enterprise.util.AnnotationLiteral;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.mvc.Controller;
|
||||
import javax.mvc.Models;
|
||||
import javax.transaction.Transactional;
|
||||
import javax.ws.rs.DefaultValue;
|
||||
import javax.ws.rs.FormParam;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
|
||||
|
|
@ -33,8 +56,12 @@ import javax.ws.rs.PathParam;
|
|||
@RequestScoped
|
||||
@Path("/{sectionIdentifier}/documents")
|
||||
@Controller
|
||||
@Named("CmsDocumentController")
|
||||
public class DocumentController {
|
||||
|
||||
@Inject
|
||||
private ContentItemManager itemManager;
|
||||
|
||||
@Inject
|
||||
private ContentSectionsUi sectionsUi;
|
||||
|
||||
|
|
@ -50,11 +77,42 @@ public class DocumentController {
|
|||
@Inject
|
||||
private Instance<MvcDocumentCreateStep<?>> createSteps;
|
||||
|
||||
@Inject
|
||||
private GlobalizationHelper globalizationHelper;
|
||||
|
||||
@Inject
|
||||
private IdentifierParser identifierParser;
|
||||
|
||||
@Inject
|
||||
private LifecycleManager lifecycleManager;
|
||||
|
||||
@Inject
|
||||
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
|
||||
@Path("/")
|
||||
@AuthorizationRequired
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public String redirectToDocumentFolders(
|
||||
@PathParam("sectionIdentifider") final String sectionIdentifier
|
||||
|
|
@ -66,6 +124,7 @@ public class DocumentController {
|
|||
}
|
||||
|
||||
@Path("/@create/{documentType}")
|
||||
@AuthorizationRequired
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public MvcDocumentCreateStep<? extends ContentItem> createDocument(
|
||||
@PathParam("sectionIdentifider") final String sectionIdentifier,
|
||||
|
|
@ -75,6 +134,7 @@ public class DocumentController {
|
|||
}
|
||||
|
||||
@Path("/{folderPath:(.+)?}/@create/{documentType}")
|
||||
@AuthorizationRequired
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
@SuppressWarnings("unchecked")
|
||||
public MvcDocumentCreateStep<? extends ContentItem> createDocument(
|
||||
|
|
@ -146,6 +206,7 @@ public class DocumentController {
|
|||
}
|
||||
|
||||
@Path("/{documentPath:(.+)?}/@authoringsteps/{authoringStep}")
|
||||
@AuthorizationRequired
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public MvcAuthoringStep editDocument(
|
||||
@PathParam("sectionIdentifider") final String sectionIdentifier,
|
||||
|
|
@ -192,12 +253,518 @@ public class DocumentController {
|
|||
return new UnsupportedDocumentType();
|
||||
}
|
||||
|
||||
selectedDocumentModel.setContentItem(item);
|
||||
|
||||
authoringStep.setContentSection(section);
|
||||
authoringStep.setContentItem(item);
|
||||
|
||||
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
|
||||
extends AnnotationLiteral<CreatesDocumentOfType>
|
||||
implements CreatesDocumentOfType {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue