Base class for all authoring steps

pull/10/head
Jens Pelzetter 2021-05-01 11:38:25 +02:00
parent 0baaefa543
commit b140923d86
14 changed files with 869 additions and 680 deletions

View File

@ -0,0 +1,312 @@
/*
* Copyright (C) 2021 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.ui.contentsections.documents;
import org.hibernate.LazyInitializationException;
import org.libreccm.l10n.GlobalizationHelper;
import org.librecms.contentsection.ContentItem;
import org.librecms.contentsection.ContentItemManager;
import org.librecms.contentsection.ContentItemRepository;
import org.librecms.contentsection.ContentSection;
import org.librecms.ui.contentsections.ContentSectionModel;
import org.librecms.ui.contentsections.ContentSectionsUi;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.mvc.Models;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.UriBuilder;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public abstract class AbstractMvcAuthoringStep implements MvcAuthoringStep {
@Inject
private DocumentUi documentUi;
@Inject
private ContentItemManager itemManager;
@Inject
private ContentItemRepository itemRepo;
@Inject
private ContentSectionModel sectionModel;
@Inject
private ContentSectionsUi sectionsUi;
@Inject
private GlobalizationHelper globalizationHelper;
@Inject
private HttpServletRequest request;
@Inject
private Models models;
@Inject
private SelectedDocumentModel documentModel;
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
private String sectionIdentifier;
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
private String documentPathParam;
private ContentSection contentSection;
private ContentItem document;
private String documentPath;
/**
* Inits the step. This method MUST be called by all resource methods (all
* methods annotated with {@link Path} in an authoring step. This is
* neccessary to keep all JPA operations inside a transaction to avoid
* {@link LazyInitializationException}s.
*
*
* @throws ContentSectionNotFoundException
* @throws DocumentNotFoundException
*/
protected void init()
throws ContentSectionNotFoundException, DocumentNotFoundException {
contentSection = sectionsUi
.findContentSection(sectionIdentifier)
.orElseThrow(
() -> new ContentSectionNotFoundException(
sectionsUi.showContentSectionNotFound(sectionIdentifier),
String.format(
"ContentSection %s not found.",
sectionIdentifier)
)
);
sectionModel.setSection(contentSection);
document = itemRepo
.findByPath(contentSection, documentPathParam)
.orElseThrow(
() -> new DocumentNotFoundException(
documentUi.showDocumentNotFound(
contentSection, documentPathParam),
String.format(
"Not document for path %s in section %s.",
documentPathParam,
contentSection.getLabel()
)
)
);
documentModel.setContentItem(document);
this.documentPath = itemManager.getItemPath(document);
models.put("activeDocumentTab", "editTab");
}
@Override
public ContentSection getContentSection() {
return Optional
.ofNullable(contentSection)
.orElseThrow(
() -> new WebApplicationException(
String.format(
"Authoring Step %s was not initalized properly. "
+ "Did you forget to call %s#init()?",
getStepClass().getName(),
AbstractMvcAuthoringStep.class.getName()
)
)
);
}
@Override
public ContentItem getDocument() {
return Optional
.ofNullable(document)
.orElseThrow(
() -> new WebApplicationException(
String.format(
"Authoring Step %s was not initalized properly. "
+ "Did you forget to call %s#init()?",
getStepClass().getName(),
AbstractMvcAuthoringStep.class.getName()
)
)
);
}
@Override
public String getDocumentPath() {
return Optional
.ofNullable(documentPath)
.orElseThrow(
() -> new WebApplicationException(
String.format(
"Authoring Step %s was not initalized properly. "
+ "Did you forget to call %s#init()?",
getStepClass().getName(),
AbstractMvcAuthoringStep.class.getName()
)
)
);
}
@Override
public String getLabel() {
return Optional
.ofNullable(
getStepClass().getAnnotation(MvcAuthoringStepDef.class)
)
.map(
annotation -> globalizationHelper.getLocalizedTextsUtil(
annotation.bundle()
).getText(annotation.labelKey())
)
.orElse("???");
}
@Override
public String getDescription() {
return Optional
.ofNullable(
getStepClass().getAnnotation(MvcAuthoringStepDef.class)
)
.map(
annotation -> globalizationHelper.getLocalizedTextsUtil(
annotation.bundle()
).getText(annotation.descriptionKey())
)
.orElse("");
}
@Override
public void updateDocumentPath() {
documentPath = itemManager.getItemPath(document).substring(1); // Without leading slash
}
@Override
public String buildRedirectPathForStep() {
final ContentSection section = Optional
.ofNullable(contentSection)
.orElseThrow(
() -> new WebApplicationException(
String.format(
"Authoring Step %s was not initalized properly. "
+ "Did you forget to call %s#init()?",
getStepClass().getName(),
AbstractMvcAuthoringStep.class.getName()
)
)
);
final String docPath = Optional
.ofNullable(documentPath)
.orElseThrow(
() -> new WebApplicationException(
String.format(
"Authoring Step %s was not initalized properly. "
+ "Did you forget to call %s#init()?",
getStepClass().getName(),
AbstractMvcAuthoringStep.class.getName()
)
)
);
final Map<String, String> values = new HashMap<>();
values.put(
MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM,
section.getLabel()
);
values.put(
MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME,
docPath
);
return Optional
.ofNullable(getStepClass().getAnnotation(Path.class))
.map(Path::value)
.map(
path -> UriBuilder
.fromPath(path)
.buildFromMap(values)
)
.map(path -> String.format("redirect:%s", path))
.orElse("");
}
@Override
public String buildRedirectPathForStep(final String subPath) {
final ContentSection section = Optional
.ofNullable(contentSection)
.orElseThrow(
() -> new WebApplicationException(
String.format(
"Authoring Step %s was not initalized properly. "
+ "Did you forget to call %s#init()?",
getStepClass().getName(),
AbstractMvcAuthoringStep.class.getName()
)
)
);
final String docPath = Optional
.ofNullable(documentPath)
.orElseThrow(
() -> new WebApplicationException(
String.format(
"Authoring Step %s was not initalized properly. "
+ "Did you forget to call %s#init()?",
getStepClass().getName(),
AbstractMvcAuthoringStep.class.getName()
)
)
);
final Map<String, String> values = new HashMap<>();
values.put(
MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM,
section.getLabel()
);
values.put(
MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME,
docPath
);
return Optional
.ofNullable(getStepClass().getAnnotation(Path.class))
.map(Path::value)
.map(
path -> UriBuilder
.fromPath(path)
.path(subPath)
.buildFromMap(values)
)
.map(path -> String.format("redirect:%s", path))
.orElse("");
}
}

View File

@ -71,12 +71,12 @@ public class AuthoringStepsValidator {
);
}
if (stepClass.getAnnotation(MvcAuthoringStep.class) == null) {
if (stepClass.getAnnotation(MvcAuthoringStepDef.class) == null) {
LOGGER.warn(
"Class {} is part of a set of authoring steps, but is not "
+ "annotated with {}. The class will be ignored.",
stepClass.getName(),
MvcAuthoringStep.class
MvcAuthoringStepDef.class
);
}
@ -86,8 +86,7 @@ public class AuthoringStepsValidator {
public boolean supportsItem(
final Class<?> stepClass, final ContentItem item
) {
final MvcAuthoringStep stepAnnotation = stepClass.getAnnotation(
MvcAuthoringStep.class
final MvcAuthoringStepDef stepAnnotation = stepClass.getAnnotation(MvcAuthoringStepDef.class
);
if (stepAnnotation == null) {

View File

@ -58,13 +58,13 @@ import javax.ws.rs.PathParam;
@Path(MvcAuthoringSteps.PATH_PREFIX + "categorization")
@Controller
@Named("CmsCategorizationStep")
@MvcAuthoringStep(
@MvcAuthoringStepDef(
bundle = DefaultAuthoringStepConstants.BUNDLE,
descriptionKey = "authoringsteps.categorization.description",
labelKey = "authoringsteps.categorization.label",
supportedDocumentType = ContentItem.class
)
public class CategorizationStep {
public class CategorizationStep extends AbstractMvcAuthoringStep {
@Inject
private CategoryManager categoryManager;
@ -84,9 +84,10 @@ public class CategorizationStep {
@Inject
private PermissionChecker permissionChecker;
@Inject
private MvcAuthoringStepService stepService;
public Class<CategorizationStep> getStepClass() {
return CategorizationStep.class;
}
@GET
@Path("/")
@Transactional(Transactional.TxType.REQUIRED)
@ -97,7 +98,7 @@ public class CategorizationStep {
final String documentPath
) {
try {
stepService.setSectionAndDocument(sectionIdentifier, documentPath);
init();
} catch (ContentSectionNotFoundException ex) {
return ex.showErrorMessage();
} catch (DocumentNotFoundException ex) {
@ -105,14 +106,14 @@ public class CategorizationStep {
}
if (permissionChecker.isPermitted(
ItemPrivileges.CATEGORIZE, stepService.getDocument()
ItemPrivileges.CATEGORIZE, getDocument()
)) {
return "org/librecms/ui/documents/categorization.xhtml";
} else {
return documentUi.showAccessDenied(
stepService.getContentSection(),
stepService.getDocument(),
stepService.getLabel(getClass())
getContentSection(),
getDocument(),
getLabel()
);
}
}
@ -128,8 +129,7 @@ public class CategorizationStep {
*/
@Transactional(Transactional.TxType.REQUIRED)
public List<CategorizationTree> getCategorizationTrees() {
return stepService
.getContentSection()
return getContentSection()
.getDomains()
.stream()
.map(DomainOwnership::getDomain)
@ -139,12 +139,11 @@ public class CategorizationStep {
/**
* Update the categorization of the current item.
*
* @param parameterPath The identifier for category system to use.
* @param parameters The parameters of the request. The map must contain
* a value with the key {@code assignedCategories}.
*
*
* @param domainParam
* @param assignedCategoriesParam
* @return A redirect to the categorization step.
*/
@MvcAuthoringAction(
@ -159,14 +158,21 @@ public class CategorizationStep {
@FormParam("assignedCategories")
final Set<String> assignedCategoriesParam
) {
try {
init();
} catch (ContentSectionNotFoundException ex) {
return ex.showErrorMessage();
} catch (DocumentNotFoundException ex) {
return ex.showErrorMessage();
}
final Identifier domainIdentifier = identifierParser.parseIdentifier(
domainParam
);
final Optional<Domain> domainResult;
switch (domainIdentifier.getType()) {
case ID:
domainResult = stepService
.getContentSection()
domainResult = getContentSection()
.getDomains()
.stream()
.map(DomainOwnership::getDomain)
@ -176,8 +182,7 @@ public class CategorizationStep {
).findAny();
break;
case UUID:
domainResult = stepService
.getContentSection()
domainResult = getContentSection()
.getDomains()
.stream()
.map(DomainOwnership::getDomain)
@ -188,8 +193,7 @@ public class CategorizationStep {
).findAny();
break;
default:
domainResult = stepService
.getContentSection()
domainResult = getContentSection()
.getDomains()
.stream()
.map(DomainOwnership::getDomain)
@ -201,7 +205,7 @@ public class CategorizationStep {
}
if (!domainResult.isPresent()) {
models.put("section", stepService.getContentSection().getLabel());
models.put("section", getContentSection().getLabel());
models.put("domainIdentifier", domainIdentifier);
return "org/librecms/ui/documents/categorization-domain-not-found.xhtml";
}
@ -210,7 +214,7 @@ public class CategorizationStep {
domainResult.get().getRoot(), assignedCategoriesParam
);
return stepService.buildRedirectPathForStep(getClass());
return buildRedirectPathForStep();
}
/**
@ -230,7 +234,7 @@ public class CategorizationStep {
final Category category,
final Set<String> assignedCategoriesParam
) {
final ContentItem document = stepService.getDocument();
final ContentItem document = getDocument();
if (assignedCategoriesParam.contains(category.getUuid())
&& !categoryManager.isAssignedToCategory(category, document)) {
categoryManager.addObjectToCategory(document, category);
@ -327,7 +331,7 @@ public class CategorizationStep {
final Category category
) {
final CategorizationTreeNode node = new CategorizationTreeNode();
final ContentItem document = stepService.getDocument();
final ContentItem document = getDocument();
node.setAssigned(categoryManager.isAssignedToCategory(
category, document)
);

View File

@ -114,11 +114,11 @@ public class DocumentController {
private ContentItemRepository itemRepo;
/**
* All available {@link MvcAuthoringStep}s.
* All available {@link MvcAuthoringStepDef}s.
*/
@Inject
@Any
private Instance<MvcAuthoringStep> authoringSteps;
private Instance<MvcAuthoringStepDef> authoringSteps;
/**
* All available {@link MvcDocumentCreateStep}s.
@ -451,7 +451,7 @@ public class DocumentController {
// models.put("authoringStep", authoringStepIdentifier);
// return showAuthoringStepNotAvailable(authoringStepIdentifier);
// }
// final MvcAuthoringStep authoringStep = instance.get();
// final MvcAuthoringStepDef authoringStep = instance.get();
//
// if (!authoringStep.supportedDocumentType().isAssignableFrom(item
// .getClass())) {

View File

@ -18,61 +18,92 @@
*/
package org.librecms.ui.contentsections.documents;
import org.libreccm.l10n.GlobalizationHelper;
import org.librecms.contentsection.ContentItem;
import org.librecms.contentsection.ContentSection;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.inject.Named;
import javax.ws.rs.Path;
/**
* Metadata of an authoring step for documents (content items).
*
* An authoring step for a document (content item). Implementing classes are
* used as subresources by {@link DocumentController#editDocument(java.lang.String, java.lang.String, java.lang.String)
* }. An implementation must be a named CDI bean (annotated with {@link Named},
* annotated with the {@link AuthoringStepPathFragment} qualifier annotation.
*
* An implementation may contain multiple subresource paths for for displaying
* forms and apply changes from these forms.
* Base interface for authoring steps. For buidling authoring steps it is
* recommanned to use the {@link AbstractMvcAuthoringStep} as base that
* implements most of the methods defined by this interface.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MvcAuthoringStep {
public interface MvcAuthoringStep {
Class<? extends MvcAuthoringStep> getStepClass();
ContentSection getContentSection() throws ContentSectionNotFoundException;
ContentItem getDocument() throws ContentSectionNotFoundException,
DocumentNotFoundException;
String getDocumentPath() throws ContentSectionNotFoundException,
DocumentNotFoundException;
/**
* The name of the resource bundle providing the localized values for
* {@link #labelKey} and {@link descriptionKey}.
* Gets the label for an authoring step.
*
* @return The resource bundle providing the localized labelKey and
* descriptionKey.
* @return The label for the authoring step. If the implementing class is
* not annotated with {@link MvcAuthoringStepDef} the string
* {@code ???} is returned.
*/
String bundle();
String getLabel();
/**
* The key for the localized description of the step.
* Gets the description for an authoring step.
*
* @return The key for the localized description of the step.
* @return The label for the authoring step. If the implementing class is
* not annotated with {@link MvcAuthoringStepDef} an empty stringis
* returned.
*/
String descriptionKey();
String getDescription();
/**
* The key for the localized label of the authoring step..
* If an authoring step alters the name of the content item and therefore
* the path of the item, the step MUST call this method to update the
* document path used by the step.
*
* @return The key for the localized label of the authoring step...
* @throws
* org.librecms.ui.contentsections.documents.ContentSectionNotFoundException
* @throws
* org.librecms.ui.contentsections.documents.DocumentNotFoundException
*/
String labelKey();
void updateDocumentPath() throws ContentSectionNotFoundException,
DocumentNotFoundException;
/**
* Authoring steps only support a specific type, and all subtypes.
* Builds the redirect path of the authoring step.This path is most often
* used to implement the redirect after post pattern.
*
* @return The document type supported by the authoring step.
* @return The redirect path. If the the implementing class is not annotated
* with {@link Path} an empty string is returned.
*
* @throws
* org.librecms.ui.contentsections.documents.ContentSectionNotFoundException
* @throws
* org.librecms.ui.contentsections.documents.DocumentNotFoundException
*/
Class<? extends ContentItem> supportedDocumentType();
String buildRedirectPathForStep() throws ContentSectionNotFoundException,
DocumentNotFoundException;
/**
* Builds the redirect path of the authoring step.This path is most often
* used to implement the redirect after post pattern.
*
* @param subPath additional path elements that are appended to the path of
* the authoring step.
*
* @return The redirect path. If the the implemeting class is not annotated
* with {@link Path} an empty string is returned.
*
* @throws
* org.librecms.ui.contentsections.documents.ContentSectionNotFoundException
* @throws
* org.librecms.ui.contentsections.documents.DocumentNotFoundException
*/
String buildRedirectPathForStep(final String subPath) throws
ContentSectionNotFoundException, DocumentNotFoundException;
}

View File

@ -0,0 +1,77 @@
/*
* Copyright (C) 2021 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.ui.contentsections.documents;
import org.librecms.contentsection.ContentItem;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.inject.Named;
/**
* Metadata of an authoring step for documents (content items).
*
* An authoring step for a document (content item). Implementing classes are
* used as subresources by {@link DocumentController#editDocument(java.lang.String, java.lang.String, java.lang.String)
* }. An implementation must be a named CDI bean (annotated with {@link Named},
* annotated with the {@link AuthoringStepPathFragment} qualifier annotation.
*
* An implementation may contain multiple subresource paths for for displaying
* forms and apply changes from these forms.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MvcAuthoringStepDef {
/**
* The name of the resource bundle providing the localized values for
* {@link #labelKey} and {@link descriptionKey}.
*
* @return The resource bundle providing the localized labelKey and
* descriptionKey.
*/
String bundle();
/**
* The key for the localized description of the step.
*
* @return The key for the localized description of the step.
*/
String descriptionKey();
/**
* The key for the localized label of the authoring step..
*
* @return The key for the localized label of the authoring step...
*/
String labelKey();
/**
* Authoring steps only support a specific type, and all subtypes.
*
* @return The document type supported by the authoring step.
*/
Class<? extends ContentItem> supportedDocumentType();
}

View File

@ -1,266 +0,0 @@
/*
* Copyright (C) 2021 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.ui.contentsections.documents;
import org.libreccm.l10n.GlobalizationHelper;
import org.librecms.contentsection.ContentItem;
import org.librecms.contentsection.ContentItemManager;
import org.librecms.contentsection.ContentItemRepository;
import org.librecms.contentsection.ContentSection;
import org.librecms.ui.contentsections.ContentSectionModel;
import org.librecms.ui.contentsections.ContentSectionsUi;
import java.util.Objects;
import java.util.Optional;
import javax.enterprise.context.Dependent;
import javax.inject.Inject;
import javax.mvc.Models;
import javax.ws.rs.Path;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Dependent
public class MvcAuthoringStepService {
@Inject
private DocumentUi documentUi;
@Inject
private ContentItemManager itemManager;
@Inject
private ContentItemRepository itemRepo;
@Inject
private ContentSectionModel sectionModel;
@Inject
private ContentSectionsUi sectionsUi;
@Inject
private GlobalizationHelper globalizationHelper;
@Inject
private Models models;
@Inject
private SelectedDocumentModel documentModel;
private ContentSection section;
private ContentItem document;
private String documentPath;
public ContentSection getContentSection() {
return section;
}
public ContentItem getDocument() {
return document;
}
public String getDocumentPath() {
return documentPath;
}
/**
* Gets the label for an authoring step.
*
* @param step The authoring step class.
*
* @return The label for the authoring step. If the provided class is not
* annotated with {@link MvcAuthoringStep} the string {@code ???} is
* returned.
*/
public String getLabel(final Class<?> step) {
return Optional
.ofNullable(step.getAnnotation(MvcAuthoringStep.class))
.map(
annotation -> globalizationHelper.getLocalizedTextsUtil(
annotation.bundle()
).getText(annotation.labelKey())
)
.orElse("???");
}
/**
* Gets the description for an authoring step.
*
* @param step The authoring step class.
*
* @return The label for the authoring step. If the provided class is not
* annotated with {@link MvcAuthoringStep} an empty stringis
* returned.
*/
public String getDescription(final Class<?> step) {
return Optional
.ofNullable(step.getAnnotation(MvcAuthoringStep.class))
.map(
annotation -> globalizationHelper.getLocalizedTextsUtil(
annotation.bundle()
).getText(annotation.descriptionKey())
)
.orElse("");
}
/**
* Sets the properties {@link #section}, {@link #document} and
* {@link #documentPath} to content section and the document/content item
* identified by the provided parameters.
*
* @param sectionIdentifier The identifier of the content section.
* @param documentPath The identifier of the document/content item.
*
* @throws ContentSectionNotFoundException If there is no content section
* identified by
* {@code sectionIdentifier}.
* @throws DocumentNotFoundException If there is not document/content
* item with the path
* {@code documentPath} in the
* content section.
*/
public void setSectionAndDocument(
final String sectionIdentifier, final String documentPath
) throws ContentSectionNotFoundException, DocumentNotFoundException {
section = sectionsUi
.findContentSection(sectionIdentifier)
.orElseThrow(
() -> new ContentSectionNotFoundException(
sectionsUi.showContentSectionNotFound(sectionIdentifier),
String.format(
"ContentSection %s not found.",
sectionIdentifier)
)
);
sectionModel.setSection(section);
document = itemRepo
.findByPath(section, documentPath)
.orElseThrow(
() -> new DocumentNotFoundException(
documentUi.showDocumentNotFound(
section, documentPath),
String.format(
"Not document for path %s in section %s.",
documentPath,
section.getLabel()
)
)
);
documentModel.setContentItem(document);
this.documentPath = itemManager.getItemPath(document);
models.put("activeDocumentTab", "editTab");
}
public void updateDocumentPath() {
documentPath = itemManager.getItemPath(document);
}
/**
* Builds the redirect path of the authoring step provided by the class
* {@code step}. This path is most often used to implement the redirect
* after post pattern.
*
* @param step The authoring step class.
*
* @return The redirect path. If the the provided class is not annotated
* with {@link Path} an empty string is returned.
*/
public String buildRedirectPathForStep(final Class<?> step) {
Objects.requireNonNull(step);
return Optional
.ofNullable(step.getAnnotation(Path.class))
.map(Path::value)
.map(
path -> path
.replace(
String.format(
"{%s}",
MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM
),
section.getLabel()
)
.replace(
String.format(
"{%s}",
MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM
),
documentPath
)
)
.map(path -> String.format("redirect:%s", path))
.orElse("");
}
/**
* Builds the redirect path of the authoring step provided by the class
* {@code step}.This path is most often used to implement the redirect after
* post pattern.
*
* @param step The authoring step class.
* @param subPath additional path fragment(s) that are appended to the path
* of the authoring step.
*
* @return The redirect path. If the the provided class is not annotated
* with {@link Path} an empty string is returned.
*/
public String buildRedirectPathForStep(
final Class<?> step, final String subPath
) {
Objects.requireNonNull(step);
Objects.requireNonNull(subPath);
final String subPathNormalized;
if (subPath.startsWith("/")) {
subPathNormalized = subPath.substring(1);
} else {
subPathNormalized = subPath;
}
return Optional
.ofNullable(step.getAnnotation(Path.class))
.map(Path::value)
.map(
path -> path
.replace(
String.format(
"{%s}",
MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM
),
section.getLabel()
)
.replace(
String.format("{%s}",
MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME
),
documentPath
)
)
.map(
path -> String.format(
"redirect:%s/%s", path, subPathNormalized)
).orElse("");
}
}

View File

@ -60,13 +60,13 @@ import javax.ws.rs.PathParam;
@Path(MvcAuthoringSteps.PATH_PREFIX + "publish")
@Controller
@Named("CmsPublishStep")
@MvcAuthoringStep(
@MvcAuthoringStepDef(
bundle = DefaultAuthoringStepConstants.BUNDLE,
descriptionKey = "authoringsteps.publish.description",
labelKey = "authoringsteps.publish.label",
supportedDocumentType = ContentItem.class
)
public class PublishStep {
public class PublishStep extends AbstractMvcAuthoringStep {
private static final String TEMPLATE
= "org/librecms/ui/documenttypes/publish.xhtml";
@ -96,9 +96,11 @@ public class PublishStep {
@Inject
private Models models;
@Inject
private MvcAuthoringStepService stepService;
@Override
public Class<PublishStep> getStepClass() {
return PublishStep.class;
}
@GET
@Path("/")
@ -110,15 +112,15 @@ public class PublishStep {
final String documentPath
) {
try {
stepService.setSectionAndDocument(sectionIdentifier, documentPath);
init();
} catch (ContentSectionNotFoundException ex) {
return ex.showErrorMessage();
} catch (DocumentNotFoundException ex) {
return ex.showErrorMessage();
}
final ContentItem document = stepService.getDocument();
if (itemPermissionChecker.canPublishItems(stepService.getDocument())) {
final ContentItem document = getDocument();
if (itemPermissionChecker.canPublishItems(getDocument())) {
final String lifecycleDefUuid;
if (itemManager.isLive(document)) {
lifecycleDefUuid = document
@ -135,11 +137,11 @@ public class PublishStep {
return TEMPLATE;
} else {
return documentUi.showAccessDenied(
stepService.getContentSection(),
stepService.getDocument(),
getContentSection(),
getDocument(),
defaultStepsMessageBundle.getMessage(
"access_to_authoringstep_denied",
new String[]{stepService.getLabel(getClass())}
new String[]{getLabel()}
)
);
}
@ -157,7 +159,7 @@ public class PublishStep {
@Transactional(Transactional.TxType.REQUIRED)
public String getAssignedLifecycleLabel() {
return Optional
.ofNullable(stepService.getDocument().getLifecycle())
.ofNullable(getDocument().getLifecycle())
.map(Lifecycle::getDefinition)
.map(LifecycleDefinition::getLabel)
.map(globalizationHelper::getValueFromLocalizedString)
@ -177,7 +179,7 @@ public class PublishStep {
@Transactional(Transactional.TxType.REQUIRED)
public String getAssignedLifecycleDecription() {
return Optional
.ofNullable(stepService.getDocument().getLifecycle())
.ofNullable(getDocument().getLifecycle())
.map(Lifecycle::getDefinition)
.map(LifecycleDefinition::getDescription)
.map(globalizationHelper::getValueFromLocalizedString)
@ -222,14 +224,14 @@ public class PublishStep {
final String endTimeParam
) {
try {
stepService.setSectionAndDocument(sectionIdentifier, documentPath);
init();
} catch (ContentSectionNotFoundException ex) {
return ex.showErrorMessage();
} catch (DocumentNotFoundException ex) {
return ex.showErrorMessage();
}
final ContentItem document = stepService.getDocument();
final ContentItem document = getDocument();
if (selectedLifecycleDefUuid.isEmpty()) {
models.put("missingLifecycleDefinitionUuid", true);
@ -332,7 +334,7 @@ public class PublishStep {
if (!itemPermissionChecker.canPublishItems(document)) {
return documentUi.showAccessDenied(
stepService.getContentSection(),
getContentSection(),
document,
"item.publish"
);
@ -355,7 +357,7 @@ public class PublishStep {
if (!definitionResult.isPresent()) {
models.put(
"contentSection",
stepService.getContentSection().getLabel()
getContentSection().getLabel()
);
models.put("lifecycleDefinitionUuid", selectedLifecycleDefUuid);
return "org/librecms/ui/documents/lifecycle-definition-not-found.xhtml";
@ -366,7 +368,7 @@ public class PublishStep {
);
}
return stepService.buildRedirectPathForStep(getClass());
return buildRedirectPathForStep();
}
/**
@ -380,10 +382,10 @@ public class PublishStep {
)
@Transactional(Transactional.TxType.REQUIRED)
public String unpublish() {
final ContentItem document = stepService.getDocument();
final ContentItem document = getDocument();
if (!itemPermissionChecker.canPublishItems(document)) {
return documentUi.showAccessDenied(
stepService.getContentSection(),
getContentSection(),
document,
"item.unpublish"
);
@ -391,7 +393,7 @@ public class PublishStep {
itemManager.unpublish(document);
return stepService.buildRedirectPathForStep(getClass());
return buildRedirectPathForStep();
}
}

View File

@ -35,14 +35,20 @@ import org.librecms.ui.contentsections.FolderBreadcrumbsModel;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Path;
import javax.ws.rs.core.UriBuilder;
import static javax.transaction.Transactional.TxType.values;
/**
* Model/named bean providing data about the currently selected document for
@ -84,6 +90,9 @@ public class SelectedDocumentModel {
@Inject
private GlobalizationHelper globalizationHelper;
@Inject
private HttpServletRequest request;
/**
* Used to check permissions
*/
@ -209,7 +218,7 @@ public class SelectedDocumentModel {
itemTitle = globalizationHelper.getValueFromLocalizedString(
item.getTitle()
);
itemPath = itemManager.getItemPath(item);
itemPath = itemManager.getItemPath(item).substring(1); //Without leading slash
parentFolderBreadcrumbs = itemManager
.getItemFolders(item)
.stream()
@ -322,7 +331,7 @@ public class SelectedDocumentModel {
/**
* Helper method for building a {@link AuthoringStepListEntry} from the
* {@link MvcAuthoringStep}.
* {@link MvcAuthoringStepDef}.
*
* @param step Th step.
*
@ -331,8 +340,8 @@ public class SelectedDocumentModel {
private AuthoringStepListEntry buildAuthoringStepListEntry(
final Class<?> authoringStepClass
) {
final MvcAuthoringStep stepAnnotation = authoringStepClass
.getAnnotation(MvcAuthoringStep.class);
final MvcAuthoringStepDef stepAnnotation = authoringStepClass
.getAnnotation(MvcAuthoringStepDef.class);
final Path pathAnnotation = authoringStepClass.getAnnotation(
Path.class
);
@ -341,7 +350,7 @@ public class SelectedDocumentModel {
final AuthoringStepListEntry entry = new AuthoringStepListEntry();
entry.setDescription(textsUtil.getText(stepAnnotation.descriptionKey()));
entry.setLabel(textsUtil.getText(stepAnnotation.labelKey()));
entry.setPath(createStepPath(pathAnnotation.value()));
entry.setPath(createStepPath(authoringStepClass));
return entry;
}
@ -363,4 +372,30 @@ public class SelectedDocumentModel {
);
}
private String createStepPath(final Class<?> stepClass) {
final Map<String, String> values = new HashMap<>();
values.put(
MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM,
item.getContentType().getContentSection().getLabel()
);
values.put(
MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME,
itemPath
);
final UriBuilder uriBuilder;
if (request.getContextPath() == null) {
uriBuilder = UriBuilder.fromPath("/@contentsections");
} else {
uriBuilder = UriBuilder
.fromPath(request.getContextPath())
.path("/@contentsections");
}
return uriBuilder
.path(stepClass)
.buildFromMap(values, false)
.toString();
}
}

View File

@ -25,11 +25,11 @@ import org.librecms.contentsection.ContentItemRepository;
import org.librecms.contentsection.FolderManager;
import org.librecms.contenttypes.Article;
import org.librecms.ui.contentsections.ItemPermissionChecker;
import org.librecms.ui.contentsections.documents.AbstractMvcAuthoringStep;
import org.librecms.ui.contentsections.documents.ContentSectionNotFoundException;
import org.librecms.ui.contentsections.documents.DocumentNotFoundException;
import org.librecms.ui.contentsections.documents.DocumentUi;
import org.librecms.ui.contentsections.documents.MvcAuthoringStep;
import org.librecms.ui.contentsections.documents.MvcAuthoringStepService;
import org.librecms.ui.contentsections.documents.MvcAuthoringStepDef;
import org.librecms.ui.contentsections.documents.MvcAuthoringSteps;
import java.util.Collections;
@ -63,13 +63,13 @@ import javax.ws.rs.PathParam;
@Path(MvcAuthoringSteps.PATH_PREFIX + "article-basicproperties")
@Controller
@Named("CmsArticlePropertiesStep")
@MvcAuthoringStep(
@MvcAuthoringStepDef(
bundle = ArticleStepsConstants.BUNDLE,
descriptionKey = "authoringsteps.basicproperties.description",
labelKey = "authoringsteps.basicproperties.label",
supportedDocumentType = Article.class
)
public class MvcArticlePropertiesStep {
public class MvcArticlePropertiesStep extends AbstractMvcAuthoringStep {
@Inject
private ArticleMessageBundle articleMessageBundle;
@ -107,9 +107,6 @@ public class MvcArticlePropertiesStep {
@Inject
private Models models;
@Inject
private MvcAuthoringStepService stepService;
private Map<String, String> titleValues;
private List<String> unusedTitleLocales;
@ -118,6 +115,11 @@ public class MvcArticlePropertiesStep {
private List<String> unusedDescriptionLocales;
@Override
public Class<MvcArticlePropertiesStep> getStepClass() {
return MvcArticlePropertiesStep.class;
}
@GET
@Path("/")
@Transactional(Transactional.TxType.REQUIRED)
@ -128,16 +130,15 @@ public class MvcArticlePropertiesStep {
final String documentPath
) {
try {
stepService.setSectionAndDocument(sectionIdentifier, documentPath);
init();
} catch (ContentSectionNotFoundException ex) {
return ex.showErrorMessage();
} catch (DocumentNotFoundException ex) {
return ex.showErrorMessage();
}
if (itemPermissionChecker.canEditItem(stepService.getDocument())) {
titleValues = stepService
.getDocument()
if (itemPermissionChecker.canEditItem(getDocument())) {
titleValues = getDocument()
.getTitle()
.getValues()
.entrySet()
@ -149,8 +150,7 @@ public class MvcArticlePropertiesStep {
)
);
final Set<Locale> titleLocales = stepService
.getDocument()
final Set<Locale> titleLocales = getDocument()
.getTitle()
.getAvailableLocales();
@ -161,8 +161,7 @@ public class MvcArticlePropertiesStep {
.map(Locale::toString)
.collect(Collectors.toList());
descriptionValues = stepService
.getDocument()
descriptionValues = getDocument()
.getDescription()
.getValues()
.entrySet()
@ -174,8 +173,7 @@ public class MvcArticlePropertiesStep {
)
);
final Set<Locale> descriptionLocales = stepService
.getDocument()
final Set<Locale> descriptionLocales = getDocument()
.getDescription()
.getAvailableLocales();
@ -189,8 +187,8 @@ public class MvcArticlePropertiesStep {
return "org/librecms/ui/contenttypes/article/article-basic-properties.xhtml";
} else {
return documentUi.showAccessDenied(
stepService.getContentSection(),
stepService.getDocument(),
getContentSection(),
getDocument(),
articleMessageBundle.getMessage("article.edit.denied")
);
}
@ -203,7 +201,7 @@ public class MvcArticlePropertiesStep {
* @return The display name of the current article.
*/
public String getName() {
return stepService.getDocument().getDisplayName();
return getDocument().getDisplayName();
}
/**
@ -226,33 +224,31 @@ public class MvcArticlePropertiesStep {
@FormParam("name") @DefaultValue("") final String name
) {
try {
stepService.setSectionAndDocument(sectionIdentifier, documentPath);
init();
} catch (ContentSectionNotFoundException ex) {
return ex.showErrorMessage();
} catch (DocumentNotFoundException ex) {
return ex.showErrorMessage();
}
if (itemPermissionChecker.canEditItem(stepService.getDocument())) {
if (itemPermissionChecker.canEditItem(getDocument())) {
if (name.isEmpty() || name.matches("\\s*")) {
models.put("nameMissing", true);
return showStep(sectionIdentifier, documentPath);
}
stepService.getDocument().setDisplayName(name);
itemRepo.save(stepService.getDocument());
stepService.updateDocumentPath();
getDocument().setDisplayName(name);
itemRepo.save(getDocument());
return stepService.buildRedirectPathForStep(
MvcArticlePropertiesStep.class
);
updateDocumentPath();
return buildRedirectPathForStep();
} else {
return documentUi.showAccessDenied(
stepService.getContentSection(),
stepService.getDocument(),
stepService.getLabel(MvcArticlePropertiesStep.class)
getContentSection(),
getDocument(),
getLabel()
);
}
}
@ -297,24 +293,24 @@ public class MvcArticlePropertiesStep {
@FormParam("value") final String value
) {
try {
stepService.setSectionAndDocument(sectionIdentifier, documentPath);
init();
} catch (ContentSectionNotFoundException ex) {
return ex.showErrorMessage();
} catch (DocumentNotFoundException ex) {
return ex.showErrorMessage();
}
if (itemPermissionChecker.canEditItem(stepService.getDocument())) {
if (itemPermissionChecker.canEditItem(getDocument())) {
final Locale locale = new Locale(localeParam);
stepService.getDocument().getTitle().addValue(locale, value);
itemRepo.save(stepService.getDocument());
getDocument().getTitle().addValue(locale, value);
itemRepo.save(getDocument());
return stepService.buildRedirectPathForStep(MvcArticlePropertiesStep.class);
return buildRedirectPathForStep();
} else {
return documentUi.showAccessDenied(
stepService.getContentSection(),
stepService.getDocument(),
stepService.getLabel(MvcArticlePropertiesStep.class)
getContentSection(),
getDocument(),
getLabel()
);
}
}
@ -333,7 +329,7 @@ public class MvcArticlePropertiesStep {
@Path("/title/@edit/{locale}")
@Transactional(Transactional.TxType.REQUIRED)
public String editTitle(
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
final String sectionIdentifier,
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
final String documentPath,
@ -341,24 +337,24 @@ public class MvcArticlePropertiesStep {
@FormParam("value") final String value
) {
try {
stepService.setSectionAndDocument(sectionIdentifier, documentPath);
init();
} catch (ContentSectionNotFoundException ex) {
return ex.showErrorMessage();
} catch (DocumentNotFoundException ex) {
return ex.showErrorMessage();
}
if (itemPermissionChecker.canEditItem(stepService.getDocument())) {
if (itemPermissionChecker.canEditItem(getDocument())) {
final Locale locale = new Locale(localeParam);
stepService.getDocument().getTitle().addValue(locale, value);
itemRepo.save(stepService.getDocument());
getDocument().getTitle().addValue(locale, value);
itemRepo.save(getDocument());
return stepService.buildRedirectPathForStep(MvcArticlePropertiesStep.class);
return buildRedirectPathForStep();
} else {
return documentUi.showAccessDenied(
stepService.getContentSection(),
stepService.getDocument(),
stepService.getLabel(MvcArticlePropertiesStep.class)
getContentSection(),
getDocument(),
getLabel()
);
}
}
@ -383,24 +379,24 @@ public class MvcArticlePropertiesStep {
@PathParam("locale") final String localeParam
) {
try {
stepService.setSectionAndDocument(sectionIdentifier, documentPath);
init();
} catch (ContentSectionNotFoundException ex) {
return ex.showErrorMessage();
} catch (DocumentNotFoundException ex) {
return ex.showErrorMessage();
}
if (itemPermissionChecker.canEditItem(stepService.getDocument())) {
if (itemPermissionChecker.canEditItem(getDocument())) {
final Locale locale = new Locale(localeParam);
stepService.getDocument().getTitle().removeValue(locale);
itemRepo.save(stepService.getDocument());
getDocument().getTitle().removeValue(locale);
itemRepo.save(getDocument());
return stepService.buildRedirectPathForStep(MvcArticlePropertiesStep.class);
return buildRedirectPathForStep();
} else {
return documentUi.showAccessDenied(
stepService.getContentSection(),
stepService.getDocument(),
stepService.getLabel(MvcArticlePropertiesStep.class)
getContentSection(),
getDocument(),
getLabel()
);
}
}
@ -446,24 +442,24 @@ public class MvcArticlePropertiesStep {
@FormParam("value") final String value
) {
try {
stepService.setSectionAndDocument(sectionIdentifier, documentPath);
init();
} catch (ContentSectionNotFoundException ex) {
return ex.showErrorMessage();
} catch (DocumentNotFoundException ex) {
return ex.showErrorMessage();
}
if (itemPermissionChecker.canEditItem(stepService.getDocument())) {
if (itemPermissionChecker.canEditItem(getDocument())) {
final Locale locale = new Locale(localeParam);
stepService.getDocument().getDescription().addValue(locale, value);
itemRepo.save(stepService.getDocument());
getDocument().getDescription().addValue(locale, value);
itemRepo.save(getDocument());
return stepService.buildRedirectPathForStep(MvcArticlePropertiesStep.class);
return buildRedirectPathForStep();
} else {
return documentUi.showAccessDenied(
stepService.getContentSection(),
stepService.getDocument(),
stepService.getLabel(MvcArticlePropertiesStep.class)
getContentSection(),
getDocument(),
getLabel()
);
}
}
@ -490,24 +486,24 @@ public class MvcArticlePropertiesStep {
@FormParam("value") final String value
) {
try {
stepService.setSectionAndDocument(sectionIdentifier, documentPath);
init();
} catch (ContentSectionNotFoundException ex) {
return ex.showErrorMessage();
} catch (DocumentNotFoundException ex) {
return ex.showErrorMessage();
}
if (itemPermissionChecker.canEditItem(stepService.getDocument())) {
if (itemPermissionChecker.canEditItem(getDocument())) {
final Locale locale = new Locale(localeParam);
stepService.getDocument().getDescription().addValue(locale, value);
itemRepo.save(stepService.getDocument());
getDocument().getDescription().addValue(locale, value);
itemRepo.save(getDocument());
return stepService.buildRedirectPathForStep(MvcArticlePropertiesStep.class);
return buildRedirectPathForStep();
} else {
return documentUi.showAccessDenied(
stepService.getContentSection(),
stepService.getDocument(),
stepService.getLabel(MvcArticlePropertiesStep.class)
getContentSection(),
getDocument(),
getLabel()
);
}
}
@ -532,24 +528,24 @@ public class MvcArticlePropertiesStep {
@PathParam("locale") final String localeParam
) {
try {
stepService.setSectionAndDocument(sectionIdentifier, documentPath);
init();
} catch (ContentSectionNotFoundException ex) {
return ex.showErrorMessage();
} catch (DocumentNotFoundException ex) {
return ex.showErrorMessage();
}
if (itemPermissionChecker.canEditItem(stepService.getDocument())) {
if (itemPermissionChecker.canEditItem(getDocument())) {
final Locale locale = new Locale(localeParam);
stepService.getDocument().getDescription().removeValue(locale);
itemRepo.save(stepService.getDocument());
getDocument().getDescription().removeValue(locale);
itemRepo.save(getDocument());
return stepService.buildRedirectPathForStep(MvcArticlePropertiesStep.class);
return buildRedirectPathForStep();
} else {
return documentUi.showAccessDenied(
stepService.getContentSection(),
stepService.getDocument(),
stepService.getLabel(MvcArticlePropertiesStep.class)
getContentSection(),
getDocument(),
getLabel()
);
}
}

View File

@ -23,6 +23,7 @@ import org.libreccm.l10n.LocalizedString;
import org.librecms.contentsection.ContentItemRepository;
import org.librecms.contenttypes.Article;
import org.librecms.ui.contentsections.ItemPermissionChecker;
import org.librecms.ui.contentsections.documents.AbstractMvcAuthoringStep;
import org.librecms.ui.contentsections.documents.ContentSectionNotFoundException;
import org.librecms.ui.contentsections.documents.DocumentNotFoundException;
import org.librecms.ui.contentsections.documents.DocumentUi;
@ -30,8 +31,6 @@ import org.librecms.ui.contentsections.documents.DocumentUi;
import javax.mvc.Controller;
import javax.ws.rs.Path;
import org.librecms.ui.contentsections.documents.MvcAuthoringStep;
import org.librecms.ui.contentsections.documents.MvcAuthoringStepService;
import org.librecms.ui.contentsections.documents.MvcAuthoringSteps;
import java.util.List;
@ -49,6 +48,8 @@ import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PathParam;
import org.librecms.ui.contentsections.documents.MvcAuthoringStepDef;
/**
* Authoring step for editing the main text of an {@link Article}.
*
@ -58,13 +59,13 @@ import javax.ws.rs.PathParam;
@Path(MvcAuthoringSteps.PATH_PREFIX + "text")
@Controller
@Named("CmsArticleTextBodyStep")
@MvcAuthoringStep(
@MvcAuthoringStepDef(
bundle = ArticleStepsConstants.BUNDLE,
descriptionKey = "authoringsteps.text.description",
labelKey = "authoringsteps.text.label",
supportedDocumentType = Article.class
)
public class MvcArticleTextBodyStep {
public class MvcArticleTextBodyStep extends AbstractMvcAuthoringStep {
@Inject
private ArticleMessageBundle articleMessageBundle;
@ -87,9 +88,11 @@ public class MvcArticleTextBodyStep {
@Inject
private ItemPermissionChecker itemPermissionChecker;
@Inject
private MvcAuthoringStepService stepService;
@Override
public Class<MvcArticleTextBodyStep> getStepClass() {
return MvcArticleTextBodyStep.class;
}
@GET
@Path("/")
@Transactional(Transactional.TxType.REQUIRED)
@ -100,19 +103,19 @@ public class MvcArticleTextBodyStep {
final String documentPath
) {
try {
stepService.setSectionAndDocument(sectionIdentifier, documentPath);
init();
} catch (ContentSectionNotFoundException ex) {
return ex.showErrorMessage();
} catch (DocumentNotFoundException ex) {
return ex.showErrorMessage();
}
if (itemPermissionChecker.canEditItem(stepService.getDocument())) {
if (itemPermissionChecker.canEditItem(getArticle())) {
return "org/librecms/ui/contenttypes/article/article-text.xhtml";
} else {
return documentUi.showAccessDenied(
stepService.getContentSection(),
stepService.getDocument(),
getContentSection(),
getArticle(),
articleMessageBundle.getMessage("article.edit.denied")
);
}
@ -124,7 +127,7 @@ public class MvcArticleTextBodyStep {
* @return The localized values of the main text.
*/
public Map<String, String> getTextValues() {
return getDocument()
return getArticle()
.getText()
.getValues()
.entrySet()
@ -143,7 +146,7 @@ public class MvcArticleTextBodyStep {
* @return The locales for which the main text has not been defined yet.
*/
public List<String> getUnusedLocales() {
final Set<Locale> locales = getDocument()
final Set<Locale> locales = getArticle()
.getText()
.getAvailableLocales();
return globalizationHelper
@ -176,24 +179,24 @@ public class MvcArticleTextBodyStep {
@FormParam("value") final String value
) {
try {
stepService.setSectionAndDocument(sectionIdentifier, documentPath);
init();
} catch (ContentSectionNotFoundException ex) {
return ex.showErrorMessage();
} catch (DocumentNotFoundException ex) {
return ex.showErrorMessage();
}
if (itemPermissionChecker.canEditItem(stepService.getDocument())) {
if (itemPermissionChecker.canEditItem(getArticle())) {
final Locale locale = new Locale(localeParam);
getDocument().getText().addValue(locale, value);
itemRepo.save(stepService.getDocument());
getArticle().getText().addValue(locale, value);
itemRepo.save(getArticle());
return stepService.buildRedirectPathForStep(getClass());
return buildRedirectPathForStep();
} else {
return documentUi.showAccessDenied(
stepService.getContentSection(),
stepService.getDocument(),
stepService.getLabel(getClass())
getContentSection(),
getArticle(),
getLabel()
);
}
}
@ -220,24 +223,24 @@ public class MvcArticleTextBodyStep {
@FormParam("value") final String value
) {
try {
stepService.setSectionAndDocument(sectionIdentifier, documentPath);
init();
} catch (ContentSectionNotFoundException ex) {
return ex.showErrorMessage();
} catch (DocumentNotFoundException ex) {
return ex.showErrorMessage();
}
if (itemPermissionChecker.canEditItem(stepService.getDocument())) {
if (itemPermissionChecker.canEditItem(getArticle())) {
final Locale locale = new Locale(localeParam);
getDocument().getText().addValue(locale, value);
itemRepo.save(stepService.getDocument());
getArticle().getText().addValue(locale, value);
itemRepo.save(getArticle());
return stepService.buildRedirectPathForStep(getClass());
return buildRedirectPathForStep();
} else {
return documentUi.showAccessDenied(
stepService.getContentSection(),
stepService.getDocument(),
stepService.getLabel(getClass())
getContentSection(),
getArticle(),
getLabel()
);
}
}
@ -262,30 +265,30 @@ public class MvcArticleTextBodyStep {
@PathParam("locale") final String localeParam
) {
try {
stepService.setSectionAndDocument(sectionIdentifier, documentPath);
init();
} catch (ContentSectionNotFoundException ex) {
return ex.showErrorMessage();
} catch (DocumentNotFoundException ex) {
return ex.showErrorMessage();
}
if (itemPermissionChecker.canEditItem(stepService.getDocument())) {
if (itemPermissionChecker.canEditItem(getArticle())) {
final Locale locale = new Locale(localeParam);
getDocument().getText().removeValue(locale);
itemRepo.save(stepService.getDocument());
getArticle().getText().removeValue(locale);
itemRepo.save(getArticle());
return stepService.buildRedirectPathForStep(getClass());
return buildRedirectPathForStep();
} else {
return documentUi.showAccessDenied(
stepService.getContentSection(),
stepService.getDocument(),
stepService.getLabel(getClass())
getContentSection(),
getArticle(),
getLabel()
);
}
}
private Article getDocument() {
return (Article) stepService.getDocument();
private Article getArticle() {
return (Article) getDocument();
}
}

View File

@ -103,7 +103,7 @@
<li aria-current="#{step.path == authoringStep ? 'true' : ''}"
class="list-group-item #{step.path == authoringStep ? 'active' : ''}">
<a class="list-group-item-action"
href="#{mvc.basePath}/documents/#{CmsSelectedDocumentModel.itemPath}/@authoringsteps/#{step.path}">
href="#{step.path}">
#{step.label}
</a>
</li>

View File

@ -28,7 +28,7 @@
id="name-edit-dialog"
tabindex="-1">
<div class="modal-dialog">
<form action="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents#{CmsSelectedDocumentModel.itemPath}/@article-basicproperties/name"
<form action="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@article-basicproperties/name"
class="modal-content"
method="post">
<div class="modal-header">
@ -78,14 +78,14 @@
addDialogTitle="#{CmsArticleMessageBundle['basicproperties.title.add.header']}"
addDialogValueHelp="#{CmsArticleMessageBundle['basicproperties.title.add.value.help']}"
addDialogValueLabel="#{CmsArticleMessageBundle['basicproperties.title.add.value.label']}"
addMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents#{CmsSelectedDocumentModel.itemPath}/@article-basicproperties/title/@add"
addMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@article-basicproperties/title/@add"
editButtonLabel="#{CmsArticleMessageBundle['basicproperties.title.edit']}"
editDialogCancelLabel="#{CmsArticleMessageBundle['basicproperties.title.edit.cancel']}"
editDialogSubmitLabel="#{CmsArticleMessageBundle['basicproperties.title.edit.submit']}"
editDialogTitle="#{CmsArticleMessageBundle['basicproperties.title.edit.header']}"
editDialogValueHelp="#{CmsArticleMessageBundle['basicproperties.title.edit.value.help']}"
editDialogValueLabel="#{CmsArticleMessageBundle['basicproperties.title.edit.value.label']}"
editMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents#{CmsSelectedDocumentModel.itemPath}/@article-basicproperties/title/@edit"
editMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@article-basicproperties/title/@edit"
editorId="title-editor"
hasUnusedLocales="#{!CmsArticlePropertiesStep.unusedTitleLocales.isEmpty()}"
headingLevel="3"
@ -95,7 +95,7 @@
removeDialogSubmitLabel="#{CmsArticleMessageBundle['basicproperties.title.remove.submit']}"
removeDialogText="#{CmsArticleMessageBundle['basicproperties.title.remove.text']}"
removeDialogTitle="#{CmsArticleMessageBundle['basicproperties.title.remove.header']}"
removeMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents#{CmsSelectedDocumentModel.itemPath}/@article-basicproperties/title/@remove"
removeMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@article-basicproperties/title/@remove"
title="#{CmsArticleMessageBundle['basicproperties.title.header']}"
unusedLocales="#{CmsArticlePropertiesStep.unusedTitleLocales}"
values="#{CmsArticlePropertiesStep.titleValues}"
@ -111,14 +111,14 @@
addDialogTitle="#{CmsArticleMessageBundle['basicproperties.description.add.header']}"
addDialogValueHelp="#{CmsArticleMessageBundle['basicproperties.description.add.value.help']}"
addDialogValueLabel="#{CmsArticleMessageBundle['basicproperties.description.add.value.label']}"
addMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents#{CmsSelectedDocumentModel.itemPath}/@article-basicproperties/description/@add"
addMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@article-basicproperties/description/@add"
editButtonLabel="#{CmsArticleMessageBundle['basicproperties.description.edit']}"
editDialogCancelLabel="#{CmsArticleMessageBundle['basicproperties.description.edit.cancel']}"
editDialogSubmitLabel="#{CmsArticleMessageBundle['basicproperties.description.edit.submit']}"
editDialogTitle="#{CmsArticleMessageBundle['basicproperties.description.edit.header']}"
editDialogValueHelp="#{CmsArticleMessageBundle['basicproperties.description.edit.value.help']}"
editDialogValueLabel="#{CmsArticleMessageBundle['basicproperties.description.edit.value.label']}"
editMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents#{CmsSelectedDocumentModel.itemPath}/@article-basicproperties/description/@edit"
editMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@article-basicproperties/description/@edit"
editorId="description-editor"
hasUnusedLocales="#{!CmsArticlePropertiesStep.unusedDescriptionLocales.isEmpty()}"
headingLevel="3"
@ -128,7 +128,7 @@
removeDialogSubmitLabel="#{CmsArticleMessageBundle['basicproperties.description.remove.submit']}"
removeDialogText="#{CmsArticleMessageBundle['basicproperties.description.remove.text']}"
removeDialogTitle="#{CmsArticleMessageBundle['basicproperties.description.remove.header']}"
removeMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents#{CmsSelectedDocumentModel.itemPath}/@article-basicproperties/description/@remove"
removeMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@article-basicproperties/description/@remove"
title="#{CmsArticleMessageBundle['basicproperties.description.header']}"
unusedLocales="#{CmsArticlePropertiesStep.unusedDescriptionLocales}"
values="#{CmsArticlePropertiesStep.descriptionValues}"