AuthoringSteps are now ordinary MVC controllers
parent
a31e242c48
commit
6c9b3748d0
|
|
@ -43,7 +43,6 @@ import org.librecms.ui.contenttypes.MvcArticleCreateStep;
|
||||||
import org.librecms.ui.contenttypes.MvcArticlePropertiesStep;
|
import org.librecms.ui.contenttypes.MvcArticlePropertiesStep;
|
||||||
import org.librecms.ui.contenttypes.MvcArticleTextBodyStep;
|
import org.librecms.ui.contenttypes.MvcArticleTextBodyStep;
|
||||||
import org.librecms.ui.contentsections.documents.MvcAuthoringKit;
|
import org.librecms.ui.contentsections.documents.MvcAuthoringKit;
|
||||||
import org.librecms.ui.contentsections.documents.MvcAuthoringKitStep;
|
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
|
|
@ -79,14 +78,8 @@ import javax.xml.bind.annotation.XmlRootElement;
|
||||||
@MvcAuthoringKit(
|
@MvcAuthoringKit(
|
||||||
createStep = MvcArticleCreateStep.class,
|
createStep = MvcArticleCreateStep.class,
|
||||||
authoringSteps = {
|
authoringSteps = {
|
||||||
@MvcAuthoringKitStep(
|
MvcArticlePropertiesStep.class,
|
||||||
path = "basic-properties",
|
MvcArticleTextBodyStep.class
|
||||||
authoringStep = MvcArticlePropertiesStep.class
|
|
||||||
),
|
|
||||||
@MvcAuthoringKitStep(
|
|
||||||
path = "basic-properties",
|
|
||||||
authoringStep = MvcArticleTextBodyStep.class
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@XmlRootElement(name = "article", namespace = CMS_XML_NS)
|
@XmlRootElement(name = "article", namespace = CMS_XML_NS)
|
||||||
|
|
|
||||||
|
|
@ -1,133 +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;
|
|
||||||
|
|
||||||
import org.libreccm.l10n.GlobalizationHelper;
|
|
||||||
import org.librecms.contentsection.ContentItem;
|
|
||||||
import org.librecms.contentsection.ContentItemManager;
|
|
||||||
import org.librecms.contentsection.ContentSection;
|
|
||||||
import org.librecms.ui.contentsections.documents.MvcAuthoringStep;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.mvc.Models;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
|
||||||
*/
|
|
||||||
public abstract class AbstractMvcAuthoringStep implements MvcAuthoringStep {
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private ContentItemManager itemManager;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private GlobalizationHelper globalizationHelper;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private Models models;
|
|
||||||
|
|
||||||
private ContentSection section;
|
|
||||||
|
|
||||||
private ContentItem document;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ContentSection getContentSection() {
|
|
||||||
return section;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setContentSection(final ContentSection section) {
|
|
||||||
this.section = section;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getContentSectionLabel() {
|
|
||||||
return section.getLabel();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getContentSectionTitle() {
|
|
||||||
return globalizationHelper
|
|
||||||
.getValueFromLocalizedString(section.getTitle());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ContentItem getContentItem() {
|
|
||||||
return document;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setContentItem(final ContentItem document) {
|
|
||||||
this.document = document;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getContentItemPath() {
|
|
||||||
return itemManager.getItemPath(document);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getContentItemTitle() {
|
|
||||||
return globalizationHelper
|
|
||||||
.getValueFromLocalizedString(document.getTitle());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean hasParameter(
|
|
||||||
final Map<String, String[]> parameters,
|
|
||||||
final String parameterName
|
|
||||||
) {
|
|
||||||
Objects.requireNonNull(
|
|
||||||
parameters,
|
|
||||||
"parameters can't be null."
|
|
||||||
);
|
|
||||||
Objects.requireNonNull(
|
|
||||||
parameterName,
|
|
||||||
"parameterName can't be null."
|
|
||||||
);
|
|
||||||
return parameters.containsKey(parameterName)
|
|
||||||
&& parameters.get(parameterName) != null
|
|
||||||
&& parameters.get(parameterName).length != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method to add a form parameter value to {@link #models}.
|
|
||||||
*
|
|
||||||
* @param parameters The form parameters.
|
|
||||||
* @param parameterName The parameter name
|
|
||||||
*/
|
|
||||||
protected void addParameterValueToModels(
|
|
||||||
final Map<String, String[]> parameters,
|
|
||||||
final String parameterName
|
|
||||||
) {
|
|
||||||
models.put(
|
|
||||||
Objects.requireNonNull(
|
|
||||||
parameterName,
|
|
||||||
"parameterName can't be null"
|
|
||||||
),
|
|
||||||
Objects.requireNonNull(
|
|
||||||
parameters,
|
|
||||||
"parameters can't be null."
|
|
||||||
).getOrDefault(parameterName, new String[]{""})[0]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -21,14 +21,23 @@ package org.librecms.ui.contentsections;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.libreccm.ui.IsAuthenticatedFilter;
|
import org.libreccm.ui.IsAuthenticatedFilter;
|
||||||
|
import org.librecms.ui.contentsections.documents.AuthoringStepsValidator;
|
||||||
import org.librecms.ui.contentsections.documents.DocumentController;
|
import org.librecms.ui.contentsections.documents.DocumentController;
|
||||||
import org.librecms.ui.contentsections.documents.DocumentLifecyclesController;
|
import org.librecms.ui.contentsections.documents.DocumentLifecyclesController;
|
||||||
import org.librecms.ui.contentsections.documents.DocumentWorkflowController;
|
import org.librecms.ui.contentsections.documents.DocumentWorkflowController;
|
||||||
|
import org.librecms.ui.contentsections.documents.MvcAuthoringSteps;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import javax.enterprise.inject.Any;
|
||||||
|
import javax.enterprise.inject.Instance;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.mvc.Controller;
|
||||||
import javax.ws.rs.ApplicationPath;
|
import javax.ws.rs.ApplicationPath;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.core.Application;
|
import javax.ws.rs.core.Application;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -43,6 +52,13 @@ public class ContentSectionApplication extends Application {
|
||||||
ContentSectionApplication.class
|
ContentSectionApplication.class
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private AuthoringStepsValidator stepsValidator;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@Any
|
||||||
|
private Instance<MvcAuthoringSteps> authoringSteps;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Class<?>> getClasses() {
|
public Set<Class<?>> getClasses() {
|
||||||
final Set<Class<?>> classes = new HashSet<>();
|
final Set<Class<?>> classes = new HashSet<>();
|
||||||
|
|
@ -57,6 +73,9 @@ public class ContentSectionApplication extends Application {
|
||||||
classes.add(ContentSectionController.class);
|
classes.add(ContentSectionController.class);
|
||||||
classes.add(DocumentFolderController.class);
|
classes.add(DocumentFolderController.class);
|
||||||
classes.add(DocumentController.class);
|
classes.add(DocumentController.class);
|
||||||
|
|
||||||
|
classes.addAll(getAuthoringSteps());
|
||||||
|
|
||||||
classes.add(DocumentLifecyclesController.class);
|
classes.add(DocumentLifecyclesController.class);
|
||||||
classes.add(DocumentWorkflowController.class);
|
classes.add(DocumentWorkflowController.class);
|
||||||
classes.add(IsAuthenticatedFilter.class);
|
classes.add(IsAuthenticatedFilter.class);
|
||||||
|
|
@ -64,6 +83,13 @@ public class ContentSectionApplication extends Application {
|
||||||
return classes;
|
return classes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Set<Class<?>> getAuthoringSteps() {
|
||||||
|
return authoringSteps
|
||||||
|
.stream()
|
||||||
|
.map(MvcAuthoringSteps::getClasses)
|
||||||
|
.flatMap(Set::stream)
|
||||||
|
.filter(stepsValidator::validateAuthoringStep)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ public class AuthoringStepListEntry {
|
||||||
/**
|
/**
|
||||||
* The path fragment of the authoring step.
|
* The path fragment of the authoring step.
|
||||||
*/
|
*/
|
||||||
private String pathFragment;
|
private String path;
|
||||||
|
|
||||||
public String getLabel() {
|
public String getLabel() {
|
||||||
return label;
|
return label;
|
||||||
|
|
@ -59,12 +59,12 @@ public class AuthoringStepListEntry {
|
||||||
this.description = description;
|
this.description = description;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPathFragment() {
|
public String getPath() {
|
||||||
return pathFragment;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPathFragment(final String pathFragment) {
|
public void setPath(final String path) {
|
||||||
this.pathFragment = pathFragment;
|
this.path = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
* 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.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.librecms.contentsection.ContentItem;
|
||||||
|
|
||||||
|
import javax.enterprise.context.Dependent;
|
||||||
|
import javax.mvc.Controller;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@Dependent
|
||||||
|
public class AuthoringStepsValidator {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger(
|
||||||
|
AuthoringStepsValidator.class
|
||||||
|
);
|
||||||
|
|
||||||
|
public boolean validateAuthoringStep(final Class<?> stepClass) {
|
||||||
|
if (stepClass.getAnnotation(Controller.class) == null) {
|
||||||
|
LOGGER.warn(
|
||||||
|
"Class {} is part of a set of authoringsteps, but is not"
|
||||||
|
+ " annotated with {}. The class will be ignored.",
|
||||||
|
stepClass.getName(),
|
||||||
|
Controller.class.getName());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Path pathAnnotation = stepClass.getAnnotation(Path.class);
|
||||||
|
if (pathAnnotation == null) {
|
||||||
|
LOGGER.warn(
|
||||||
|
"Class {} is part of a set of authoring steps, but is not "
|
||||||
|
+ "annotated with {}. the class will be ignored.",
|
||||||
|
stepClass.getName(),
|
||||||
|
Path.class.getName()
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String path = pathAnnotation.value();
|
||||||
|
if (path == null
|
||||||
|
|| !path.startsWith(MvcAuthoringSteps.PATH_PREFIX)) {
|
||||||
|
LOGGER.warn(
|
||||||
|
"Class {} is part of a set of authoring steps, but the value"
|
||||||
|
+ "of the {} annotation of the class does not start "
|
||||||
|
+ "with {}. The class will be ignored.",
|
||||||
|
stepClass.getName(),
|
||||||
|
Path.class.getName(),
|
||||||
|
MvcAuthoringSteps.PATH_PREFIX
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stepClass.getAnnotation(MvcAuthoringStep.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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsItem(
|
||||||
|
final Class<?> stepClass, final ContentItem item
|
||||||
|
) {
|
||||||
|
final MvcAuthoringStep stepAnnotation = stepClass.getAnnotation(
|
||||||
|
MvcAuthoringStep.class
|
||||||
|
);
|
||||||
|
|
||||||
|
if (stepAnnotation == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return item.getClass().isAssignableFrom(
|
||||||
|
stepAnnotation.supportedDocumentType()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -29,8 +29,6 @@ import org.libreccm.core.UnexpectedErrorException;
|
||||||
import org.libreccm.l10n.GlobalizationHelper;
|
import org.libreccm.l10n.GlobalizationHelper;
|
||||||
import org.libreccm.security.PermissionChecker;
|
import org.libreccm.security.PermissionChecker;
|
||||||
import org.librecms.contentsection.ContentItem;
|
import org.librecms.contentsection.ContentItem;
|
||||||
import org.librecms.contentsection.ContentItemManager;
|
|
||||||
import org.librecms.contentsection.ContentSection;
|
|
||||||
import org.librecms.contentsection.privileges.ItemPrivileges;
|
import org.librecms.contentsection.privileges.ItemPrivileges;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
@ -42,10 +40,11 @@ import java.util.stream.Collectors;
|
||||||
import javax.enterprise.context.RequestScoped;
|
import javax.enterprise.context.RequestScoped;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
import javax.mvc.Controller;
|
||||||
import javax.mvc.Models;
|
import javax.mvc.Models;
|
||||||
import javax.transaction.Transactional;
|
import javax.transaction.Transactional;
|
||||||
import javax.ws.rs.FormParam;
|
import javax.ws.rs.FormParam;
|
||||||
import javax.ws.rs.POST;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
|
|
||||||
|
|
@ -56,12 +55,16 @@ import javax.ws.rs.PathParam;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@RequestScoped
|
@RequestScoped
|
||||||
@Path("/")
|
@Path(MvcAuthoringSteps.PATH_PREFIX + "categorization")
|
||||||
@AuthoringStepPathFragment(CategorizationStep.PATH_FRAGMENT)
|
@Controller
|
||||||
@Named("CmsCategorizationStep")
|
@Named("CmsCategorizationStep")
|
||||||
public class CategorizationStep implements MvcAuthoringStep {
|
@MvcAuthoringStep(
|
||||||
|
bundle = DefaultAuthoringStepConstants.BUNDLE,
|
||||||
static final String PATH_FRAGMENT = "categorization";
|
descriptionKey = "authoringsteps.categorization.description",
|
||||||
|
labelKey = "authoringsteps.categorization.label",
|
||||||
|
supportedDocumentType = ContentItem.class
|
||||||
|
)
|
||||||
|
public class CategorizationStep {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private CategoryManager categoryManager;
|
private CategoryManager categoryManager;
|
||||||
|
|
@ -72,9 +75,6 @@ public class CategorizationStep implements MvcAuthoringStep {
|
||||||
@Inject
|
@Inject
|
||||||
private IdentifierParser identifierParser;
|
private IdentifierParser identifierParser;
|
||||||
|
|
||||||
@Inject
|
|
||||||
private ContentItemManager itemManager;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private GlobalizationHelper globalizationHelper;
|
private GlobalizationHelper globalizationHelper;
|
||||||
|
|
||||||
|
|
@ -84,130 +84,35 @@ public class CategorizationStep implements MvcAuthoringStep {
|
||||||
@Inject
|
@Inject
|
||||||
private PermissionChecker permissionChecker;
|
private PermissionChecker permissionChecker;
|
||||||
|
|
||||||
/**
|
@Inject
|
||||||
* The current content section.
|
private MvcAuthoringStepService stepService;
|
||||||
*/
|
|
||||||
private ContentSection section;
|
|
||||||
|
|
||||||
/**
|
@GET
|
||||||
* The current document.
|
@Path("/")
|
||||||
*/
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
private ContentItem document;
|
public String showStep(
|
||||||
|
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
|
||||||
|
final String sectionIdentifier,
|
||||||
|
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM)
|
||||||
|
final String documentPath
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
stepService.setSectionAndDocument(sectionIdentifier, documentPath);
|
||||||
|
} catch (ContentSectionNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
} catch (DocumentNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
if (permissionChecker.isPermitted(
|
||||||
* {@inheritDoc}
|
ItemPrivileges.CATEGORIZE, stepService.getDocument()
|
||||||
*/
|
)) {
|
||||||
@Override
|
|
||||||
public Class<? extends ContentItem> supportedDocumentType() {
|
|
||||||
return ContentItem.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String getLabel() {
|
|
||||||
return globalizationHelper
|
|
||||||
.getLocalizedTextsUtil(getBundle())
|
|
||||||
.getText("authoringsteps.categorization.label");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String getDescription() {
|
|
||||||
return globalizationHelper
|
|
||||||
.getLocalizedTextsUtil(getBundle())
|
|
||||||
.getText("authoringsteps.categorization.description");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String getBundle() {
|
|
||||||
return DefaultAuthoringStepConstants.BUNDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public ContentSection getContentSection() {
|
|
||||||
return section;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void setContentSection(final ContentSection section) {
|
|
||||||
this.section = section;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String getContentSectionLabel() {
|
|
||||||
return section.getLabel();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String getContentSectionTitle() {
|
|
||||||
return globalizationHelper
|
|
||||||
.getValueFromLocalizedString(section.getTitle());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public ContentItem getContentItem() {
|
|
||||||
return document;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void setContentItem(final ContentItem document) {
|
|
||||||
this.document = document;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String getContentItemPath() {
|
|
||||||
return itemManager.getItemPath(document);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String getContentItemTitle() {
|
|
||||||
return globalizationHelper
|
|
||||||
.getValueFromLocalizedString(document.getTitle());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String showStep() {
|
|
||||||
if (permissionChecker.isPermitted(ItemPrivileges.CATEGORIZE, document)) {
|
|
||||||
return "org/librecms/ui/documents/categorization.xhtml";
|
return "org/librecms/ui/documents/categorization.xhtml";
|
||||||
} else {
|
} else {
|
||||||
return documentUi.showAccessDenied(
|
return documentUi.showAccessDenied(
|
||||||
section,
|
stepService.getContentSection(),
|
||||||
document,
|
stepService.getDocument(),
|
||||||
getLabel()
|
stepService.getLabel(getClass())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -223,7 +128,8 @@ public class CategorizationStep implements MvcAuthoringStep {
|
||||||
*/
|
*/
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public List<CategorizationTree> getCategorizationTrees() {
|
public List<CategorizationTree> getCategorizationTrees() {
|
||||||
return section
|
return stepService
|
||||||
|
.getContentSection()
|
||||||
.getDomains()
|
.getDomains()
|
||||||
.stream()
|
.stream()
|
||||||
.map(DomainOwnership::getDomain)
|
.map(DomainOwnership::getDomain)
|
||||||
|
|
@ -234,27 +140,33 @@ public class CategorizationStep implements MvcAuthoringStep {
|
||||||
/**
|
/**
|
||||||
* Update the categorization of the current item.
|
* Update the categorization of the current item.
|
||||||
*
|
*
|
||||||
* @param domainIdentifierParam The identifier for category system to use.
|
* @param parameterPath The identifier for category system to use.
|
||||||
* @param assignedCategoriesParam The UUIDs of the categories assigned to
|
* @param parameters The parameters of the request. The map must contain
|
||||||
* the current content item.
|
* a value with the key {@code assignedCategories}.
|
||||||
|
*
|
||||||
*
|
*
|
||||||
* @return A redirect to the categorization step.
|
* @return A redirect to the categorization step.
|
||||||
*/
|
*/
|
||||||
@POST
|
@MvcAuthoringAction(
|
||||||
@Path("/{domainIdentifier}")
|
method = MvcAuthoringActionMethod.POST,
|
||||||
|
path = "/domains/"
|
||||||
|
)
|
||||||
|
@Path("/domains/{domain}")
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String updateCategorization(
|
public String updateCategorization(
|
||||||
@PathParam("domainIdentifierParam") final String domainIdentifierParam,
|
@PathParam("domain")
|
||||||
@FormParam("assignedCategories")
|
final String domainParam,
|
||||||
|
@FormParam("assignedCategories")
|
||||||
final Set<String> assignedCategoriesParam
|
final Set<String> assignedCategoriesParam
|
||||||
) {
|
) {
|
||||||
final Identifier domainIdentifier = identifierParser.parseIdentifier(
|
final Identifier domainIdentifier = identifierParser.parseIdentifier(
|
||||||
domainIdentifierParam
|
domainParam
|
||||||
);
|
);
|
||||||
final Optional<Domain> domainResult;
|
final Optional<Domain> domainResult;
|
||||||
switch (domainIdentifier.getType()) {
|
switch (domainIdentifier.getType()) {
|
||||||
case ID:
|
case ID:
|
||||||
domainResult = section
|
domainResult = stepService
|
||||||
|
.getContentSection()
|
||||||
.getDomains()
|
.getDomains()
|
||||||
.stream()
|
.stream()
|
||||||
.map(DomainOwnership::getDomain)
|
.map(DomainOwnership::getDomain)
|
||||||
|
|
@ -264,7 +176,8 @@ public class CategorizationStep implements MvcAuthoringStep {
|
||||||
).findAny();
|
).findAny();
|
||||||
break;
|
break;
|
||||||
case UUID:
|
case UUID:
|
||||||
domainResult = section
|
domainResult = stepService
|
||||||
|
.getContentSection()
|
||||||
.getDomains()
|
.getDomains()
|
||||||
.stream()
|
.stream()
|
||||||
.map(DomainOwnership::getDomain)
|
.map(DomainOwnership::getDomain)
|
||||||
|
|
@ -275,7 +188,8 @@ public class CategorizationStep implements MvcAuthoringStep {
|
||||||
).findAny();
|
).findAny();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
domainResult = section
|
domainResult = stepService
|
||||||
|
.getContentSection()
|
||||||
.getDomains()
|
.getDomains()
|
||||||
.stream()
|
.stream()
|
||||||
.map(DomainOwnership::getDomain)
|
.map(DomainOwnership::getDomain)
|
||||||
|
|
@ -287,20 +201,16 @@ public class CategorizationStep implements MvcAuthoringStep {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!domainResult.isPresent()) {
|
if (!domainResult.isPresent()) {
|
||||||
models.put("section", section.getLabel());
|
models.put("section", stepService.getContentSection().getLabel());
|
||||||
models.put("domainIdentifier", domainIdentifierParam);
|
models.put("domainIdentifier", domainIdentifier);
|
||||||
return "org/librecms/ui/documents/categorization-domain-not-found.xhtml";
|
return "org/librecms/ui/documents/categorization-domain-not-found.xhtml";
|
||||||
}
|
}
|
||||||
|
|
||||||
final Domain domain = domainResult.get();
|
updateAssignedCategories(
|
||||||
updateAssignedCategories(domain.getRoot(), assignedCategoriesParam);
|
domainResult.get().getRoot(), assignedCategoriesParam
|
||||||
|
|
||||||
return String.format(
|
|
||||||
"redirect:/%s/@documents/%s/@authoringsteps/%s",
|
|
||||||
section.getLabel(),
|
|
||||||
getContentItemPath(),
|
|
||||||
PATH_FRAGMENT
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return stepService.buildRedirectPathForStep(getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -320,6 +230,7 @@ public class CategorizationStep implements MvcAuthoringStep {
|
||||||
final Category category,
|
final Category category,
|
||||||
final Set<String> assignedCategoriesParam
|
final Set<String> assignedCategoriesParam
|
||||||
) {
|
) {
|
||||||
|
final ContentItem document = stepService.getDocument();
|
||||||
if (assignedCategoriesParam.contains(category.getUuid())
|
if (assignedCategoriesParam.contains(category.getUuid())
|
||||||
&& !categoryManager.isAssignedToCategory(category, document)) {
|
&& !categoryManager.isAssignedToCategory(category, document)) {
|
||||||
categoryManager.addObjectToCategory(document, category);
|
categoryManager.addObjectToCategory(document, category);
|
||||||
|
|
@ -416,6 +327,7 @@ public class CategorizationStep implements MvcAuthoringStep {
|
||||||
final Category category
|
final Category category
|
||||||
) {
|
) {
|
||||||
final CategorizationTreeNode node = new CategorizationTreeNode();
|
final CategorizationTreeNode node = new CategorizationTreeNode();
|
||||||
|
final ContentItem document = stepService.getDocument();
|
||||||
node.setAssigned(categoryManager.isAssignedToCategory(
|
node.setAssigned(categoryManager.isAssignedToCategory(
|
||||||
category, document)
|
category, document)
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -18,30 +18,26 @@
|
||||||
*/
|
*/
|
||||||
package org.librecms.ui.contentsections.documents;
|
package org.librecms.ui.contentsections.documents;
|
||||||
|
|
||||||
import java.lang.annotation.Retention;
|
import java.util.HashSet;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.enterprise.context.ApplicationScoped;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Metadata about an authoring step.
|
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@ApplicationScoped
|
||||||
public @interface MvcAuthoringKitStep {
|
public class CmsMvcAuthoringSteps implements MvcAuthoringSteps {
|
||||||
|
|
||||||
/**
|
|
||||||
* The path of authoring step. This value is added the the path for
|
|
||||||
* authoring steps.
|
|
||||||
*
|
|
||||||
* @return The path fragment for th authoring step.
|
|
||||||
*/
|
|
||||||
String path();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The class implementing the authoring step.
|
|
||||||
*
|
|
||||||
* @return The class implementing the authoring step.
|
|
||||||
*/
|
|
||||||
Class<? extends MvcAuthoringStep> authoringStep();
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<Class<?>> getClasses() {
|
||||||
|
final Set<Class<?>> classes = new HashSet<>();
|
||||||
|
classes.add(ExampleAuthoringStep.class);
|
||||||
|
|
||||||
|
return classes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used by the {@link MvcAuthoringStepService} to indicate that the requested
|
||||||
|
* content section could not be found. The {@link MvcAuthoringStepService} has
|
||||||
|
* already populated {@link Models} with all necessary information. To show the
|
||||||
|
* error message the controller can simply return the string returned by
|
||||||
|
* {@link #showErrorMessage()}.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class ContentSectionNotFoundException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private final String errorMessageTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of <code>ContentSectionNotFound</code> without
|
||||||
|
* detail message.
|
||||||
|
*
|
||||||
|
* @param errorMessageTemplate Template for the error message.
|
||||||
|
*/
|
||||||
|
ContentSectionNotFoundException(final String errorMessageTemplate) {
|
||||||
|
super();
|
||||||
|
this.errorMessageTemplate = errorMessageTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an instance of <code>ContentSectionNotFound</code> with the
|
||||||
|
* specified detail message.
|
||||||
|
*
|
||||||
|
* @param msg The detail message.
|
||||||
|
* @param errorMessageTemplate Template for the error message.
|
||||||
|
*/
|
||||||
|
ContentSectionNotFoundException(
|
||||||
|
final String errorMessageTemplate, final String msg
|
||||||
|
) {
|
||||||
|
super(msg);
|
||||||
|
this.errorMessageTemplate = errorMessageTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String showErrorMessage() {
|
||||||
|
return errorMessageTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -75,6 +75,9 @@ import javax.ws.rs.core.MediaType;
|
||||||
@Controller
|
@Controller
|
||||||
public class DocumentController {
|
public class DocumentController {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private AuthoringStepsValidator stepsValidator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Item manager instance for performing operations on {@link ContentItem}s.
|
* Item manager instance for performing operations on {@link ContentItem}s.
|
||||||
*/
|
*/
|
||||||
|
|
@ -326,7 +329,7 @@ public class DocumentController {
|
||||||
) {
|
) {
|
||||||
final CreateStepResult result = findCreateStep(
|
final CreateStepResult result = findCreateStep(
|
||||||
sectionIdentifier,
|
sectionIdentifier,
|
||||||
folderPath,
|
folderPath,
|
||||||
documentType
|
documentType
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -337,141 +340,140 @@ public class DocumentController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* Redirects to the first authoring step for the document identified by the
|
// * Redirects to the first authoring step for the document identified by the
|
||||||
* provided path.
|
// * provided path.
|
||||||
*
|
// *
|
||||||
* @param sectionIdentifier The identifier of the current content section.
|
// * @param sectionIdentifier The identifier of the current content section.
|
||||||
* @param documentPath The path of the document.
|
// * @param documentPath The path of the document.
|
||||||
*
|
// *
|
||||||
* @return A redirect to the first authoring step of the document, or the
|
// * @return A redirect to the first authoring step of the document, or the
|
||||||
* {@link DocumentNotFound} pseudo authoring step.
|
// * {@link DocumentNotFound} pseudo authoring step.
|
||||||
*/
|
// */
|
||||||
@GET
|
// @GET
|
||||||
@Path("/{documentPath:(.+)?}")
|
// @Path("/{documentPath:(.+)?}")
|
||||||
@AuthorizationRequired
|
// @AuthorizationRequired
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
// @Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String showEditDocument(
|
// public String showEditDocument(
|
||||||
@PathParam("sectionIdentifier") final String sectionIdentifier,
|
// @PathParam("sectionIdentifier") final String sectionIdentifier,
|
||||||
@PathParam("documentPath") final String documentPath
|
// @PathParam("documentPath") final String documentPath
|
||||||
) {
|
// ) {
|
||||||
final Optional<ContentSection> sectionResult = sectionsUi
|
// final Optional<ContentSection> sectionResult = sectionsUi
|
||||||
.findContentSection(sectionIdentifier);
|
// .findContentSection(sectionIdentifier);
|
||||||
if (!sectionResult.isPresent()) {
|
// if (!sectionResult.isPresent()) {
|
||||||
sectionsUi.showContentSectionNotFound(sectionIdentifier);
|
// sectionsUi.showContentSectionNotFound(sectionIdentifier);
|
||||||
}
|
// }
|
||||||
final ContentSection section = sectionResult.get();
|
// final ContentSection section = sectionResult.get();
|
||||||
|
//
|
||||||
final Optional<ContentItem> itemResult = itemRepo
|
// final Optional<ContentItem> itemResult = itemRepo
|
||||||
.findByPath(section, documentPath);
|
// .findByPath(section, documentPath);
|
||||||
if (!itemResult.isPresent()) {
|
// if (!itemResult.isPresent()) {
|
||||||
models.put("section", section.getLabel());
|
// models.put("section", section.getLabel());
|
||||||
models.put("documentPath", documentPath);
|
// models.put("documentPath", documentPath);
|
||||||
documentUi.showDocumentNotFound(section, documentPath);
|
// documentUi.showDocumentNotFound(section, documentPath);
|
||||||
}
|
// }
|
||||||
final ContentItem item = itemResult.get();
|
// final ContentItem item = itemResult.get();
|
||||||
if (!itemPermissionChecker.canEditItem(item)) {
|
// if (!itemPermissionChecker.canEditItem(item)) {
|
||||||
return documentUi.showAccessDenied(
|
// return documentUi.showAccessDenied(
|
||||||
section,
|
// section,
|
||||||
item,
|
// item,
|
||||||
defaultStepsMessageBundle.getMessage("edit_denied")
|
// defaultStepsMessageBundle.getMessage("edit_denied")
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
return String.format(
|
// return String.format(
|
||||||
"redirect:/%s/documents/%s/@authoringsteps/%s",
|
// "redirect:/%s/documents/%s/@authoringsteps/%s",
|
||||||
sectionIdentifier,
|
// sectionIdentifier,
|
||||||
documentPath,
|
// documentPath,
|
||||||
findFirstAuthoringStep(item)
|
// findFirstAuthoringStep(item)
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/**
|
// /**
|
||||||
* Redirect requests for an authoring step to the subresource of the
|
// * Redirect requests for an authoring step to the subresource of the
|
||||||
* authoring step.
|
// * authoring step.
|
||||||
*
|
// *
|
||||||
* @param sectionIdentifier The identifier of the current content
|
// * @param sectionIdentifier The identifier of the current content
|
||||||
* section.
|
// * section.
|
||||||
* @param documentPath The path of the document to edit.
|
// * @param documentPath The path of the document to edit.
|
||||||
* @param authoringStepIdentifier The identifier/path fragment of the
|
// * @param authoringStepIdentifier The identifier/path fragment of the
|
||||||
* authoring step.
|
// * authoring step.
|
||||||
* @param request
|
// * @param request
|
||||||
*
|
// *
|
||||||
* @return The authoring step subresource.
|
// * @return The authoring step subresource.
|
||||||
*/
|
// */
|
||||||
@GET
|
// @GET
|
||||||
@Path("/{documentPath:(.+)?}/@authoringsteps/{authoringStep}")
|
// @Path("/{documentPath:(.+)?}/@authoringsteps/{authoringStep}")
|
||||||
@AuthorizationRequired
|
// @AuthorizationRequired
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
// @Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String showEditDocument(
|
// public String showEditDocument(
|
||||||
@PathParam("sectionIdentifier") final String sectionIdentifier,
|
// @PathParam("sectionIdentifier") final String sectionIdentifier,
|
||||||
@PathParam("documentPath") final String documentPath,
|
// @PathParam("documentPath") final String documentPath,
|
||||||
@PathParam("authoringStep") final String authoringStepIdentifier,
|
// @PathParam("authoringStep") final String authoringStepIdentifier,
|
||||||
@Context final HttpServletRequest request
|
// @Context final HttpServletRequest request
|
||||||
) {
|
// ) {
|
||||||
final Optional<ContentSection> sectionResult = sectionsUi
|
// final Optional<ContentSection> sectionResult = sectionsUi
|
||||||
.findContentSection(sectionIdentifier);
|
// .findContentSection(sectionIdentifier);
|
||||||
if (!sectionResult.isPresent()) {
|
// if (!sectionResult.isPresent()) {
|
||||||
models.put("sectionIdentifier", sectionIdentifier);
|
// models.put("sectionIdentifier", sectionIdentifier);
|
||||||
return sectionsUi.showContentSectionNotFound(sectionIdentifier);
|
// return sectionsUi.showContentSectionNotFound(sectionIdentifier);
|
||||||
}
|
// }
|
||||||
final ContentSection section = sectionResult.get();
|
// final ContentSection section = sectionResult.get();
|
||||||
|
//
|
||||||
final Optional<ContentItem> itemResult = itemRepo
|
// final Optional<ContentItem> itemResult = itemRepo
|
||||||
.findByPath(section, documentPath);
|
// .findByPath(section, documentPath);
|
||||||
if (!itemResult.isPresent()) {
|
// if (!itemResult.isPresent()) {
|
||||||
models.put("section", section.getLabel());
|
// models.put("section", section.getLabel());
|
||||||
models.put("documentPath", documentPath);
|
// models.put("documentPath", documentPath);
|
||||||
return documentUi.showDocumentNotFound(section, documentPath);
|
// return documentUi.showDocumentNotFound(section, documentPath);
|
||||||
}
|
// }
|
||||||
final ContentItem item = itemResult.get();
|
// final ContentItem item = itemResult.get();
|
||||||
if (!itemPermissionChecker.canEditItem(item)) {
|
// if (!itemPermissionChecker.canEditItem(item)) {
|
||||||
models.put("section", section.getLabel());
|
// models.put("section", section.getLabel());
|
||||||
models.put("documentPath", itemManager.getItemFolder(item));
|
// models.put("documentPath", itemManager.getItemFolder(item));
|
||||||
models.put(
|
// models.put(
|
||||||
"step", defaultStepsMessageBundle.getMessage("edit_step")
|
// "step", defaultStepsMessageBundle.getMessage("edit_step")
|
||||||
);
|
// );
|
||||||
return documentUi.showAccessDenied(
|
// return documentUi.showAccessDenied(
|
||||||
section, documentPath, documentPath
|
// section, documentPath, documentPath
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
final Instance<MvcAuthoringStep> instance = authoringSteps
|
// final Instance<MvcAuthoringStep> instance = authoringSteps
|
||||||
.select(
|
// .select(
|
||||||
new AuthoringStepPathFragmentLiteral(
|
// new AuthoringStepPathFragmentLiteral(
|
||||||
authoringStepIdentifier
|
// authoringStepIdentifier
|
||||||
)
|
// )
|
||||||
);
|
// );
|
||||||
if (instance.isUnsatisfied() || instance.isAmbiguous()) {
|
// if (instance.isUnsatisfied() || instance.isAmbiguous()) {
|
||||||
models.put("section", section.getLabel());
|
// models.put("section", section.getLabel());
|
||||||
models.put("documentPath", documentPath);
|
// models.put("documentPath", documentPath);
|
||||||
models.put("authoringStep", authoringStepIdentifier);
|
// models.put("authoringStep", authoringStepIdentifier);
|
||||||
return showAuthoringStepNotAvailable(authoringStepIdentifier);
|
// return showAuthoringStepNotAvailable(authoringStepIdentifier);
|
||||||
}
|
// }
|
||||||
final MvcAuthoringStep authoringStep = instance.get();
|
// final MvcAuthoringStep authoringStep = instance.get();
|
||||||
|
//
|
||||||
if (!authoringStep.supportedDocumentType().isAssignableFrom(item
|
// if (!authoringStep.supportedDocumentType().isAssignableFrom(item
|
||||||
.getClass())) {
|
// .getClass())) {
|
||||||
models.put("section", section.getLabel());
|
// models.put("section", section.getLabel());
|
||||||
models.put("documentPath", documentPath);
|
// models.put("documentPath", documentPath);
|
||||||
models.put("documentType", item.getClass().getName());
|
// models.put("documentType", item.getClass().getName());
|
||||||
models.put("authoringStep", authoringStepIdentifier);
|
// models.put("authoringStep", authoringStepIdentifier);
|
||||||
return showUnsupportedDocumentType(
|
// return showUnsupportedDocumentType(
|
||||||
authoringStepIdentifier,
|
// authoringStepIdentifier,
|
||||||
item.getClass().getName()
|
// item.getClass().getName()
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
models.put("authoringStep", authoringStepIdentifier);
|
// models.put("authoringStep", authoringStepIdentifier);
|
||||||
|
//
|
||||||
selectedDocumentModel.setContentItem(item);
|
// selectedDocumentModel.setContentItem(item);
|
||||||
|
//
|
||||||
authoringStep.setContentSection(section);
|
// authoringStep.setContentSection(section);
|
||||||
authoringStep.setContentItem(item);
|
// authoringStep.setContentItem(item);
|
||||||
|
//
|
||||||
return authoringStep.showStep();
|
// return authoringStep.showStep();
|
||||||
}
|
// }
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Path("/{documentPath:(.+)?}/@authoringsteps/{authoringStep}")
|
@Path("/{documentPath:(.+)?}/@authoringsteps/{authoringStep}")
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
|
|
@ -780,21 +782,17 @@ public class DocumentController {
|
||||||
*
|
*
|
||||||
* @return A list of authoring steps for the provided item.
|
* @return A list of authoring steps for the provided item.
|
||||||
*/
|
*/
|
||||||
private List<MvcAuthoringStep> readAuthoringSteps(
|
private List<Class<?>> readAuthoringSteps(
|
||||||
final ContentItem item
|
final ContentItem item
|
||||||
) {
|
) {
|
||||||
final MvcAuthoringKit authoringKit = item
|
final MvcAuthoringKit authoringKit = item
|
||||||
.getClass()
|
.getClass()
|
||||||
.getAnnotation(MvcAuthoringKit.class);
|
.getAnnotation(MvcAuthoringKit.class);
|
||||||
|
|
||||||
final Class<? extends MvcAuthoringStep>[] stepClasses = authoringKit
|
|
||||||
.authoringSteps();
|
|
||||||
|
|
||||||
return Arrays
|
return Arrays
|
||||||
.stream(stepClasses)
|
.stream(authoringKit.authoringSteps())
|
||||||
.map(authoringSteps::select)
|
.filter(stepsValidator::validateAuthoringStep)
|
||||||
.filter(instance -> instance.isResolvable())
|
.filter(stepClass -> stepsValidator.supportsItem(stepClass, item))
|
||||||
.map(Instance::get)
|
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -804,14 +802,30 @@ public class DocumentController {
|
||||||
*
|
*
|
||||||
* @param item The content item.
|
* @param item The content item.
|
||||||
*
|
*
|
||||||
* @return The path fragment of the first authoring step of the item.
|
* @return The path of the first authoring step of the item.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private String findFirstAuthoringStep(final ContentItem item) {
|
private String findFirstAuthoringStep(final ContentItem item) {
|
||||||
final List<MvcAuthoringStep> steps = readAuthoringSteps(item);
|
final List<Class<?>> steps = readAuthoringSteps(item);
|
||||||
|
|
||||||
final MvcAuthoringStep firstStep = steps.get(0);
|
final Class<?> firstStep = steps.get(0);
|
||||||
return firstStep.getClass().getName();
|
final Path pathAnnotation = firstStep.getAnnotation(Path.class);
|
||||||
|
return pathAnnotation
|
||||||
|
.value()
|
||||||
|
.replace(
|
||||||
|
String.format(
|
||||||
|
"{%s}",
|
||||||
|
MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM
|
||||||
|
),
|
||||||
|
item.getContentType().getContentSection().getLabel()
|
||||||
|
)
|
||||||
|
.replace(
|
||||||
|
String.format(
|
||||||
|
"{%s}",
|
||||||
|
MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM
|
||||||
|
),
|
||||||
|
itemManager.getItemPath(item)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used by the {@link MvcAuthoringStepService} to indicate that the requested
|
||||||
|
* document/content item could not be found. The {@link MvcAuthoringStepService}
|
||||||
|
* has already populated {@link Models} with all necessary information. To show
|
||||||
|
* the error message the controller can simply return the string returned by
|
||||||
|
* {@link #showErrorMessage()}.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class DocumentNotFoundException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private final String errorMessageTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of <code>DocumentNotFoundException</code> without
|
||||||
|
* detail message.
|
||||||
|
*
|
||||||
|
* @param errorMessageTemplate Template for the error message.
|
||||||
|
*/
|
||||||
|
public DocumentNotFoundException(final String errorMessageTemplate) {
|
||||||
|
super();
|
||||||
|
this.errorMessageTemplate = errorMessageTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an instance of <code>DocumentNotFoundException</code> with the
|
||||||
|
* specified detail message.
|
||||||
|
*
|
||||||
|
* @param errorMessageTemplate
|
||||||
|
* @param msg The detail message. Template for the error
|
||||||
|
* message.
|
||||||
|
*/
|
||||||
|
public DocumentNotFoundException(
|
||||||
|
final String errorMessageTemplate, final String msg
|
||||||
|
) {
|
||||||
|
super(msg);
|
||||||
|
this.errorMessageTemplate = errorMessageTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String showErrorMessage() {
|
||||||
|
return errorMessageTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* 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.ContentSection;
|
||||||
|
import org.librecms.ui.contentsections.ContentSectionModel;
|
||||||
|
import org.librecms.ui.contentsections.ContentSectionsUi;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.mvc.Controller;
|
||||||
|
import javax.mvc.Models;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@RequestScoped
|
||||||
|
@Path(MvcAuthoringSteps.PATH_PREFIX + "example")
|
||||||
|
@Controller
|
||||||
|
public class ExampleAuthoringStep {
|
||||||
|
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Models models;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ContentSectionModel sectionModel;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ContentSectionsUi sectionsUi;
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/")
|
||||||
|
public String showStep(
|
||||||
|
@PathParam("sectionIdentifier") final String sectionIdentifier,
|
||||||
|
@PathParam("documentPath") final String documentPath
|
||||||
|
) {
|
||||||
|
models.put("sectionIdentifier", sectionIdentifier);
|
||||||
|
models.put("documentPath", documentPath);
|
||||||
|
|
||||||
|
final Optional<ContentSection> sectionResult = sectionsUi
|
||||||
|
.findContentSection(sectionIdentifier);
|
||||||
|
if (!sectionResult.isPresent()) {
|
||||||
|
return sectionsUi.showContentSectionNotFound(sectionIdentifier);
|
||||||
|
}
|
||||||
|
final ContentSection section = sectionResult.get();
|
||||||
|
sectionModel.setSection(section);
|
||||||
|
|
||||||
|
return "org/librecms/ui/contenttypes/example-authoring.xhtml";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -56,7 +56,8 @@ public @interface MvcAuthoringAction {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The path fragment for invoking the action. The value of this parameter is
|
* The path fragment for invoking the action. The value of this parameter is
|
||||||
* added to the path of the authoring step.
|
* added to the path of the authoring step. Any path fragments after the
|
||||||
|
* value are provided to the method in the {@code parameterPath} parameter.
|
||||||
*
|
*
|
||||||
* @return The path fragment for invoking the action.
|
* @return The path fragment for invoking the action.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ public @interface MvcAuthoringKit {
|
||||||
*
|
*
|
||||||
* @return The authoring steps for the annotated document type.
|
* @return The authoring steps for the annotated document type.
|
||||||
*/
|
*/
|
||||||
MvcAuthoringKitStep[] authoringSteps();
|
Class<?>[] authoringSteps();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If set to {@code true} some authoring steps like categorization or
|
* If set to {@code true} some authoring steps like categorization or
|
||||||
|
|
|
||||||
|
|
@ -20,13 +20,17 @@ package org.librecms.ui.contentsections.documents;
|
||||||
|
|
||||||
import org.libreccm.l10n.GlobalizationHelper;
|
import org.libreccm.l10n.GlobalizationHelper;
|
||||||
import org.librecms.contentsection.ContentItem;
|
import org.librecms.contentsection.ContentItem;
|
||||||
import org.librecms.contentsection.ContentSection;
|
|
||||||
|
|
||||||
import java.util.Map;
|
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.inject.Named;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Metadata of an authoring step for documents (content items).
|
||||||
|
*
|
||||||
* An authoring step for a document (content item). Implementing classes are
|
* 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)
|
* 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},
|
* }. An implementation must be a named CDI bean (annotated with {@link Named},
|
||||||
|
|
@ -37,7 +41,32 @@ import javax.inject.Named;
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
public interface MvcAuthoringStep {
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface MvcAuthoringStep {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
* Authoring steps only support a specific type, and all subtypes.
|
||||||
|
|
@ -46,109 +75,4 @@ public interface MvcAuthoringStep {
|
||||||
*/
|
*/
|
||||||
Class<? extends ContentItem> supportedDocumentType();
|
Class<? extends ContentItem> supportedDocumentType();
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the localized label of the authoring step. The language variant to
|
|
||||||
* return should be selected using the locale returned by
|
|
||||||
* {@link GlobalizationHelper#getNegotiatedLocale()}.
|
|
||||||
*
|
|
||||||
* @return The localized label of the authoring step.
|
|
||||||
*/
|
|
||||||
String getLabel();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the localized description of the authoring step. The language
|
|
||||||
* variant to return should be selected using the locale returned by
|
|
||||||
* {@link GlobalizationHelper#getNegotiatedLocale()}.
|
|
||||||
*
|
|
||||||
* @return The localized description of the authoring step.
|
|
||||||
*/
|
|
||||||
String getDescription();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the name of the resource bundle providing the localized label and
|
|
||||||
* description.
|
|
||||||
*
|
|
||||||
* @return The resource bundle providing the localized label and
|
|
||||||
* description.
|
|
||||||
*/
|
|
||||||
String getBundle();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The current content section.
|
|
||||||
*
|
|
||||||
* @return The current content section.
|
|
||||||
*/
|
|
||||||
ContentSection getContentSection();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convinient method for getting the label of the current content section.
|
|
||||||
*
|
|
||||||
* @return The label of the current content section.
|
|
||||||
*/
|
|
||||||
String getContentSectionLabel();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convinient method for getting the title of the current content section.
|
|
||||||
*
|
|
||||||
* @return The title of the current content section for the current locale.
|
|
||||||
*/
|
|
||||||
String getContentSectionTitle();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The current content section is provided by the
|
|
||||||
* {@link DocumentController}.
|
|
||||||
*
|
|
||||||
* @param section The current content section.
|
|
||||||
*/
|
|
||||||
void setContentSection(final ContentSection section);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The selected document/content item.
|
|
||||||
*
|
|
||||||
* @return The selected document/content item.
|
|
||||||
*/
|
|
||||||
ContentItem getContentItem();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the path of the selected content item.
|
|
||||||
*
|
|
||||||
* @return The path of the selected content item.
|
|
||||||
*/
|
|
||||||
String getContentItemPath();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the title of the selected content item.
|
|
||||||
*
|
|
||||||
* @return The title of the selected content item.
|
|
||||||
*/
|
|
||||||
String getContentItemTitle();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The current document/content item is provided by the
|
|
||||||
* {@link DocumentController}.
|
|
||||||
*
|
|
||||||
* @param document The document/content item to edit.
|
|
||||||
*/
|
|
||||||
void setContentItem(ContentItem document);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Endpoint displaying the authoring step. This should not show the form,
|
|
||||||
* only an overview. The actual form(s) are provided by endpoints added by
|
|
||||||
* the implementation.
|
|
||||||
*
|
|
||||||
* @return The template of the edit step.
|
|
||||||
*/
|
|
||||||
String showStep();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Apply changes from the from of the script.Authoring steps that have
|
|
||||||
* multiple forms may choose to implement this method as any no-op method
|
|
||||||
* that simply redirects to the template view (same as {@link #showStep()}.
|
|
||||||
*
|
|
||||||
* @param formParameters The form parameters submitted.
|
|
||||||
*
|
|
||||||
* @return The template of the view to show.
|
|
||||||
*/
|
|
||||||
String applyEdits(Map<String, String[]> formParameters);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,248 @@
|
||||||
|
/*
|
||||||
|
* 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.ContentSectionsUi;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import javax.enterprise.context.Dependent;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
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 ContentSectionsUi sectionsUi;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private GlobalizationHelper globalizationHelper;
|
||||||
|
|
||||||
|
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)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
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()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
this.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
|
||||||
|
),
|
||||||
|
documentPath
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.map(
|
||||||
|
path -> String.format(
|
||||||
|
"redirect:%s/%s", path, subPathNormalized)
|
||||||
|
).orElse("");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* 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 java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public interface MvcAuthoringSteps {
|
||||||
|
|
||||||
|
public static final String PATH_PREFIX
|
||||||
|
= "/{sectionIdentifier}/documents/{documentPath:(.+)?}/@";
|
||||||
|
|
||||||
|
public static final String SECTION_IDENTIFIER_PATH_PARAM
|
||||||
|
= "sectionIdentifier";
|
||||||
|
|
||||||
|
public static final String DOCUMENT_PATH_PATH_PARAM = "documentPath";
|
||||||
|
|
||||||
|
Set<Class<?>> getClasses();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -19,14 +19,11 @@
|
||||||
package org.librecms.ui.contentsections.documents;
|
package org.librecms.ui.contentsections.documents;
|
||||||
|
|
||||||
import org.libreccm.l10n.GlobalizationHelper;
|
import org.libreccm.l10n.GlobalizationHelper;
|
||||||
import org.libreccm.security.AuthorizationRequired;
|
|
||||||
import org.librecms.contentsection.ContentItem;
|
import org.librecms.contentsection.ContentItem;
|
||||||
import org.librecms.contentsection.ContentItemManager;
|
import org.librecms.contentsection.ContentItemManager;
|
||||||
import org.librecms.contentsection.ContentSection;
|
|
||||||
import org.librecms.lifecycle.Lifecycle;
|
import org.librecms.lifecycle.Lifecycle;
|
||||||
import org.librecms.lifecycle.LifecycleDefinition;
|
import org.librecms.lifecycle.LifecycleDefinition;
|
||||||
import org.librecms.lifecycle.LifecycleDefinitionRepository;
|
import org.librecms.lifecycle.LifecycleDefinitionRepository;
|
||||||
import org.librecms.ui.contentsections.AbstractMvcAuthoringStep;
|
|
||||||
import org.librecms.ui.contentsections.ItemPermissionChecker;
|
import org.librecms.ui.contentsections.ItemPermissionChecker;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
|
@ -37,17 +34,20 @@ import java.time.ZoneOffset;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.time.format.DateTimeParseException;
|
import java.time.format.DateTimeParseException;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import javax.enterprise.context.RequestScoped;
|
import javax.enterprise.context.RequestScoped;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
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.FormParam;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.POST;
|
import javax.ws.rs.POST;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Authoring step (part of the default steps) for publishing a
|
* Authoring step (part of the default steps) for publishing a
|
||||||
|
|
@ -57,22 +57,19 @@ import javax.ws.rs.Path;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@RequestScoped
|
@RequestScoped
|
||||||
@Path("/")
|
@Path(MvcAuthoringSteps.PATH_PREFIX + "publish")
|
||||||
@AuthoringStepPathFragment(PublishStep.PATH_FRAGMENT)
|
@Controller
|
||||||
@Named("CmsPublishStep")
|
@Named("CmsPublishStep")
|
||||||
public class PublishStep extends AbstractMvcAuthoringStep {
|
@MvcAuthoringStep(
|
||||||
|
bundle = DefaultAuthoringStepConstants.BUNDLE,
|
||||||
|
descriptionKey = "authoringsteps.publish.description",
|
||||||
|
labelKey = "authoringsteps.publish.label",
|
||||||
|
supportedDocumentType = ContentItem.class
|
||||||
|
)
|
||||||
|
public class PublishStep {
|
||||||
|
|
||||||
|
private static final String TEMPLATE
|
||||||
private static final String SELECTED_LIFECYCLE_DEF_UUID
|
= "org/librecms/ui/documenttypes/publish.xhtml";
|
||||||
= "selectedLifecycleDefUuid";
|
|
||||||
|
|
||||||
private static final String START_DATE = "startDate";
|
|
||||||
|
|
||||||
private static final String START_TIME = "startTime";
|
|
||||||
|
|
||||||
private static final String END_DATE = "endDate";
|
|
||||||
|
|
||||||
private static final String END_TIME = "endTime";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The path fragment of the publish step.
|
* The path fragment of the publish step.
|
||||||
|
|
@ -100,84 +97,54 @@ public class PublishStep extends AbstractMvcAuthoringStep {
|
||||||
@Inject
|
@Inject
|
||||||
private Models models;
|
private Models models;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private MvcAuthoringStepService stepService;
|
||||||
|
|
||||||
@Override
|
@GET
|
||||||
public Class<? extends ContentItem> supportedDocumentType() {
|
@Path("/")
|
||||||
return ContentItem.class;
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
}
|
public String showStep(
|
||||||
|
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
|
||||||
|
final String sectionIdentifier,
|
||||||
|
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM)
|
||||||
|
final String documentPath
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
stepService.setSectionAndDocument(sectionIdentifier, documentPath);
|
||||||
|
} catch (ContentSectionNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
} catch (DocumentNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
final ContentItem document = stepService.getDocument();
|
||||||
public String getLabel() {
|
if (itemPermissionChecker.canPublishItems(stepService.getDocument())) {
|
||||||
return globalizationHelper
|
|
||||||
.getLocalizedTextsUtil(getBundle())
|
|
||||||
.getText("authoringsteps.publish.label");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getDescription() {
|
|
||||||
return globalizationHelper
|
|
||||||
.getLocalizedTextsUtil(getBundle())
|
|
||||||
.getText("authoringsteps.publish.description");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getBundle() {
|
|
||||||
return DefaultAuthoringStepConstants.BUNDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String showStep() {
|
|
||||||
if (itemPermissionChecker.canPublishItems(getContentItem())) {
|
|
||||||
final String lifecycleDefUuid;
|
final String lifecycleDefUuid;
|
||||||
if (itemManager.isLive(getContentItem())) {
|
if (itemManager.isLive(document)) {
|
||||||
lifecycleDefUuid = getContentItem()
|
lifecycleDefUuid = document
|
||||||
.getLifecycle()
|
.getLifecycle()
|
||||||
.getDefinition()
|
.getDefinition()
|
||||||
.getUuid();
|
.getUuid();
|
||||||
} else {
|
} else {
|
||||||
lifecycleDefUuid = getContentItem()
|
lifecycleDefUuid = document
|
||||||
.getContentType()
|
.getContentType()
|
||||||
.getDefaultLifecycle()
|
.getDefaultLifecycle()
|
||||||
.getUuid();
|
.getUuid();
|
||||||
}
|
}
|
||||||
models.put("lifecycleDefinitionUuid", lifecycleDefUuid);
|
models.put("lifecycleDefinitionUuid", lifecycleDefUuid);
|
||||||
return "org/librecms/ui/documents/publish.xhtml";
|
return TEMPLATE;
|
||||||
} else {
|
} else {
|
||||||
return documentUi.showAccessDenied(
|
return documentUi.showAccessDenied(
|
||||||
getContentSection(),
|
stepService.getContentSection(),
|
||||||
getContentItem(),
|
stepService.getDocument(),
|
||||||
defaultStepsMessageBundle.getMessage(
|
defaultStepsMessageBundle.getMessage(
|
||||||
"access_to_authoringstep_denied", new String[]{getLabel()}
|
"access_to_authoringstep_denied",
|
||||||
|
new String[]{stepService.getLabel(getClass())}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@AuthorizationRequired
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
|
||||||
@Override
|
|
||||||
public String applyEdits(final Map<String, String[]> formParameters) {
|
|
||||||
if (!formParameters.containsKey(SELECTED_LIFECYCLE_DEF_UUID)
|
|
||||||
|| formParameters.get(SELECTED_LIFECYCLE_DEF_UUID) == null
|
|
||||||
|| formParameters.get(SELECTED_LIFECYCLE_DEF_UUID).length == 0) {
|
|
||||||
if (!formParameters.containsKey(SELECTED_LIFECYCLE_DEF_UUID)
|
|
||||||
|| formParameters.get(SELECTED_LIFECYCLE_DEF_UUID) == null
|
|
||||||
|| formParameters.get(SELECTED_LIFECYCLE_DEF_UUID).length == 0) {
|
|
||||||
models.put("missingLifecycleDefinitionUuid", true);
|
|
||||||
addParameterValueToModels(formParameters, START_DATE);
|
|
||||||
addParameterValueToModels(formParameters, START_TIME);
|
|
||||||
addParameterValueToModels(formParameters, END_DATE);
|
|
||||||
addParameterValueToModels(formParameters, END_TIME);
|
|
||||||
|
|
||||||
return "org/librecms/ui/documenttypes/publish.xhtml";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the label of the lifecycle assigned to the current content item. The
|
* Get the label of the lifecycle assigned to the current content item. The
|
||||||
* value is determined from the label of the definition of the lifecycle
|
* value is determined from the label of the definition of the lifecycle
|
||||||
|
|
@ -190,7 +157,7 @@ public class PublishStep extends AbstractMvcAuthoringStep {
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String getAssignedLifecycleLabel() {
|
public String getAssignedLifecycleLabel() {
|
||||||
return Optional
|
return Optional
|
||||||
.ofNullable(getContentItem().getLifecycle())
|
.ofNullable(stepService.getDocument().getLifecycle())
|
||||||
.map(Lifecycle::getDefinition)
|
.map(Lifecycle::getDefinition)
|
||||||
.map(LifecycleDefinition::getLabel)
|
.map(LifecycleDefinition::getLabel)
|
||||||
.map(globalizationHelper::getValueFromLocalizedString)
|
.map(globalizationHelper::getValueFromLocalizedString)
|
||||||
|
|
@ -210,7 +177,7 @@ public class PublishStep extends AbstractMvcAuthoringStep {
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String getAssignedLifecycleDecription() {
|
public String getAssignedLifecycleDecription() {
|
||||||
return Optional
|
return Optional
|
||||||
.ofNullable(getContentItem().getLifecycle())
|
.ofNullable(stepService.getDocument().getLifecycle())
|
||||||
.map(Lifecycle::getDefinition)
|
.map(Lifecycle::getDefinition)
|
||||||
.map(LifecycleDefinition::getDescription)
|
.map(LifecycleDefinition::getDescription)
|
||||||
.map(globalizationHelper::getValueFromLocalizedString)
|
.map(globalizationHelper::getValueFromLocalizedString)
|
||||||
|
|
@ -222,6 +189,9 @@ public class PublishStep extends AbstractMvcAuthoringStep {
|
||||||
* {@code selectedLifecycleDefUuid} is ignored.The apply a new lifecycle the
|
* {@code selectedLifecycleDefUuid} is ignored.The apply a new lifecycle the
|
||||||
* document the unpublished first.
|
* document the unpublished first.
|
||||||
*
|
*
|
||||||
|
*
|
||||||
|
* @param sectionIdentifier
|
||||||
|
* @param documentPath
|
||||||
* @param selectedLifecycleDefUuid The ID of the lifecycle definition from
|
* @param selectedLifecycleDefUuid The ID of the lifecycle definition from
|
||||||
* which the lifecycle for the item is
|
* which the lifecycle for the item is
|
||||||
* created.
|
* created.
|
||||||
|
|
@ -230,37 +200,55 @@ public class PublishStep extends AbstractMvcAuthoringStep {
|
||||||
* @param endDateParam
|
* @param endDateParam
|
||||||
* @param endTimeParam
|
* @param endTimeParam
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @return A redirect the the publish step.
|
* @return A redirect the the publish step.
|
||||||
*/
|
*/
|
||||||
@MvcAuthoringAction(
|
@POST
|
||||||
method = MvcAuthoringActionMethod.POST,
|
@Path("/")
|
||||||
path = "/@publish"
|
|
||||||
)
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String publish(
|
public String publish(
|
||||||
final String parameterPath,
|
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
|
||||||
final Map<String, String[]> parameters
|
final String sectionIdentifier,
|
||||||
|
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM)
|
||||||
|
final String documentPath,
|
||||||
|
@FormParam("selectedLifecycleDefUuid")
|
||||||
|
final String selectedLifecycleDefUuid,
|
||||||
|
@FormParam("startDate") @DefaultValue("")
|
||||||
|
final String startDateParam,
|
||||||
|
@FormParam("startTime") @DefaultValue("")
|
||||||
|
final String startTimeParam,
|
||||||
|
@FormParam("endDate") @DefaultValue("")
|
||||||
|
final String endDateParam,
|
||||||
|
@FormParam("endTime") @DefaultValue("")
|
||||||
|
final String endTimeParam
|
||||||
) {
|
) {
|
||||||
if (selectedLifecycleDefUuid == null) {
|
try {
|
||||||
models.put("missingLifecycleDefinitionUuid", true);
|
stepService.setSectionAndDocument(sectionIdentifier, documentPath);
|
||||||
models.put("startDateTime", startDateParam);
|
} catch (ContentSectionNotFoundException ex) {
|
||||||
models.put("startDateTime", startTimeParam);
|
return ex.showErrorMessage();
|
||||||
models.put("endDateTime", endDateParam);
|
} catch (DocumentNotFoundException ex) {
|
||||||
models.put("endDateTime", endTimeParam);
|
return ex.showErrorMessage();
|
||||||
return "org/librecms/ui/documenttypes/publish.xhtml";
|
|
||||||
}
|
}
|
||||||
if (startDateParam == null
|
|
||||||
|| startDateParam.isEmpty()
|
final ContentItem document = stepService.getDocument();
|
||||||
|| startTimeParam == null
|
|
||||||
|| startTimeParam.isEmpty()) {
|
if (selectedLifecycleDefUuid.isEmpty()) {
|
||||||
|
models.put("missingLifecycleDefinitionUuid", true);
|
||||||
|
models.put("startDate", startDateParam);
|
||||||
|
models.put("startTime", startTimeParam);
|
||||||
|
models.put("endDate", endDateParam);
|
||||||
|
models.put("endTime", endTimeParam);
|
||||||
|
|
||||||
|
return TEMPLATE;
|
||||||
|
}
|
||||||
|
if (startDateParam.isEmpty() || startTimeParam.isEmpty()) {
|
||||||
models.put("lifecycleDefinitionUuid", selectedLifecycleDefUuid);
|
models.put("lifecycleDefinitionUuid", selectedLifecycleDefUuid);
|
||||||
models.put("missingStartDateTime", true);
|
models.put("missingStartDateTime", true);
|
||||||
models.put("startDateTime", startDateParam);
|
models.put("startDate", startDateParam);
|
||||||
models.put("startDateTime", startTimeParam);
|
models.put("startTime", startTimeParam);
|
||||||
models.put("endDateTime", endDateParam);
|
models.put("endDate", endDateParam);
|
||||||
models.put("endDateTime", endTimeParam);
|
models.put("endTime", endTimeParam);
|
||||||
return "org/librecms/ui/documents/publish.xhtml";
|
|
||||||
|
return TEMPLATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
final DateTimeFormatter isoDateFormatter = DateTimeFormatter.ISO_DATE
|
final DateTimeFormatter isoDateFormatter = DateTimeFormatter.ISO_DATE
|
||||||
|
|
@ -274,11 +262,12 @@ public class PublishStep extends AbstractMvcAuthoringStep {
|
||||||
} catch (DateTimeParseException ex) {
|
} catch (DateTimeParseException ex) {
|
||||||
models.put("invalidStartDate", true);
|
models.put("invalidStartDate", true);
|
||||||
models.put("lifecycleDefinitionUuid", selectedLifecycleDefUuid);
|
models.put("lifecycleDefinitionUuid", selectedLifecycleDefUuid);
|
||||||
models.put("startDateTime", startDateParam);
|
models.put("startDate", startDateParam);
|
||||||
models.put("startDateTime", startTimeParam);
|
models.put("startTime", startTimeParam);
|
||||||
models.put("endDateTime", endDateParam);
|
models.put("endDate", endDateParam);
|
||||||
models.put("endDateTime", endTimeParam);
|
models.put("endTime", endTimeParam);
|
||||||
return "org/librecms/ui/documents/publish.xhtml";
|
|
||||||
|
return TEMPLATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
final LocalTime localStartTime;
|
final LocalTime localStartTime;
|
||||||
|
|
@ -287,11 +276,12 @@ public class PublishStep extends AbstractMvcAuthoringStep {
|
||||||
} catch (DateTimeParseException ex) {
|
} catch (DateTimeParseException ex) {
|
||||||
models.put("invalidStartTime", true);
|
models.put("invalidStartTime", true);
|
||||||
models.put("lifecycleDefinitionUuid", selectedLifecycleDefUuid);
|
models.put("lifecycleDefinitionUuid", selectedLifecycleDefUuid);
|
||||||
models.put("startDateTime", startDateParam);
|
models.put("startDate", startDateParam);
|
||||||
models.put("startDateTime", startTimeParam);
|
models.put("startTime", startTimeParam);
|
||||||
models.put("endDateTime", endDateParam);
|
models.put("endDate", endDateParam);
|
||||||
models.put("endDateTime", endTimeParam);
|
models.put("endTime", endTimeParam);
|
||||||
return "org/librecms/ui/documents/publish.xhtml";
|
|
||||||
|
return TEMPLATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
final LocalDateTime startLocalDateTime = LocalDateTime.of(
|
final LocalDateTime startLocalDateTime = LocalDateTime.of(
|
||||||
|
|
@ -309,11 +299,12 @@ public class PublishStep extends AbstractMvcAuthoringStep {
|
||||||
} catch (DateTimeParseException ex) {
|
} catch (DateTimeParseException ex) {
|
||||||
models.put("invalidEndDate", true);
|
models.put("invalidEndDate", true);
|
||||||
models.put("lifecycleDefinitionUuid", selectedLifecycleDefUuid);
|
models.put("lifecycleDefinitionUuid", selectedLifecycleDefUuid);
|
||||||
models.put("startDateTime", startDateParam);
|
models.put("startDate", startDateParam);
|
||||||
models.put("startDateTime", startTimeParam);
|
models.put("startTime", startTimeParam);
|
||||||
models.put("endDateTime", endDateParam);
|
models.put("endDate", endDateParam);
|
||||||
models.put("endDateTime", endTimeParam);
|
models.put("endTime", endTimeParam);
|
||||||
return "org/librecms/ui/documents/publish.xhtml";
|
|
||||||
|
return TEMPLATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
final LocalTime localEndTime;
|
final LocalTime localEndTime;
|
||||||
|
|
@ -322,11 +313,12 @@ public class PublishStep extends AbstractMvcAuthoringStep {
|
||||||
} catch (DateTimeParseException ex) {
|
} catch (DateTimeParseException ex) {
|
||||||
models.put("invalidEndTime", true);
|
models.put("invalidEndTime", true);
|
||||||
models.put("lifecycleDefinitionUuid", selectedLifecycleDefUuid);
|
models.put("lifecycleDefinitionUuid", selectedLifecycleDefUuid);
|
||||||
models.put("startDateTime", startDateParam);
|
models.put("startDate", startDateParam);
|
||||||
models.put("startDateTime", startTimeParam);
|
models.put("startTime", startTimeParam);
|
||||||
models.put("endDateTime", endDateParam);
|
models.put("endDate", endDateParam);
|
||||||
models.put("endDateTime", endTimeParam);
|
models.put("endTime", endTimeParam);
|
||||||
return "org/librecms/ui/documents/publish.xhtml";
|
|
||||||
|
return TEMPLATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
final LocalDateTime endLocalDateTime = LocalDateTime.of(
|
final LocalDateTime endLocalDateTime = LocalDateTime.of(
|
||||||
|
|
@ -340,7 +332,7 @@ public class PublishStep extends AbstractMvcAuthoringStep {
|
||||||
|
|
||||||
if (!itemPermissionChecker.canPublishItems(document)) {
|
if (!itemPermissionChecker.canPublishItems(document)) {
|
||||||
return documentUi.showAccessDenied(
|
return documentUi.showAccessDenied(
|
||||||
section,
|
stepService.getContentSection(),
|
||||||
document,
|
document,
|
||||||
"item.publish"
|
"item.publish"
|
||||||
);
|
);
|
||||||
|
|
@ -354,13 +346,17 @@ public class PublishStep extends AbstractMvcAuthoringStep {
|
||||||
document, definition, startDateTime, endDateTime
|
document, definition, startDateTime, endDateTime
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
itemManager.publish(document, startDateTime, endDateTime);
|
itemManager
|
||||||
|
.publish(document, startDateTime, endDateTime);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
final Optional<LifecycleDefinition> definitionResult
|
final Optional<LifecycleDefinition> definitionResult
|
||||||
= lifecycleDefRepo.findByUuid(selectedLifecycleDefUuid);
|
= lifecycleDefRepo.findByUuid(selectedLifecycleDefUuid);
|
||||||
if (!definitionResult.isPresent()) {
|
if (!definitionResult.isPresent()) {
|
||||||
models.put("contentSection", section.getLabel());
|
models.put(
|
||||||
|
"contentSection",
|
||||||
|
stepService.getContentSection().getLabel()
|
||||||
|
);
|
||||||
models.put("lifecycleDefinitionUuid", selectedLifecycleDefUuid);
|
models.put("lifecycleDefinitionUuid", selectedLifecycleDefUuid);
|
||||||
return "org/librecms/ui/documents/lifecycle-definition-not-found.xhtml";
|
return "org/librecms/ui/documents/lifecycle-definition-not-found.xhtml";
|
||||||
}
|
}
|
||||||
|
|
@ -370,12 +366,7 @@ public class PublishStep extends AbstractMvcAuthoringStep {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return String.format(
|
return stepService.buildRedirectPathForStep(getClass());
|
||||||
"redirect:/%s/@documents/%s/@authoringsteps/%s",
|
|
||||||
section.getLabel(),
|
|
||||||
getContentItemPath(),
|
|
||||||
PATH_FRAGMENT
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -383,13 +374,16 @@ public class PublishStep extends AbstractMvcAuthoringStep {
|
||||||
*
|
*
|
||||||
* @return A redirect to the publish step.
|
* @return A redirect to the publish step.
|
||||||
*/
|
*/
|
||||||
@POST
|
@MvcAuthoringAction(
|
||||||
@Path("/@unpublish")
|
method = MvcAuthoringActionMethod.POST,
|
||||||
|
path = "/@unpublish"
|
||||||
|
)
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String unpublish() {
|
public String unpublish() {
|
||||||
|
final ContentItem document = stepService.getDocument();
|
||||||
if (!itemPermissionChecker.canPublishItems(document)) {
|
if (!itemPermissionChecker.canPublishItems(document)) {
|
||||||
return documentUi.showAccessDenied(
|
return documentUi.showAccessDenied(
|
||||||
section,
|
stepService.getContentSection(),
|
||||||
document,
|
document,
|
||||||
"item.unpublish"
|
"item.unpublish"
|
||||||
);
|
);
|
||||||
|
|
@ -397,13 +391,7 @@ public class PublishStep extends AbstractMvcAuthoringStep {
|
||||||
|
|
||||||
itemManager.unpublish(document);
|
itemManager.unpublish(document);
|
||||||
|
|
||||||
return String.format(
|
return stepService.buildRedirectPathForStep(getClass());
|
||||||
"redirect:/%s/@documents/%s/@authoringsteps/%s",
|
|
||||||
section.getLabel(),
|
|
||||||
getContentItemPath(),
|
|
||||||
PATH_FRAGMENT
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -19,6 +19,7 @@
|
||||||
package org.librecms.ui.contentsections.documents;
|
package org.librecms.ui.contentsections.documents;
|
||||||
|
|
||||||
import org.libreccm.l10n.GlobalizationHelper;
|
import org.libreccm.l10n.GlobalizationHelper;
|
||||||
|
import org.libreccm.l10n.LocalizedTextsUtil;
|
||||||
import org.libreccm.security.PermissionChecker;
|
import org.libreccm.security.PermissionChecker;
|
||||||
import org.libreccm.security.Shiro;
|
import org.libreccm.security.Shiro;
|
||||||
import org.libreccm.workflow.AssignableTask;
|
import org.libreccm.workflow.AssignableTask;
|
||||||
|
|
@ -39,9 +40,9 @@ import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.enterprise.context.RequestScoped;
|
import javax.enterprise.context.RequestScoped;
|
||||||
import javax.enterprise.inject.Instance;
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Model/named bean providing data about the currently selected document for
|
* Model/named bean providing data about the currently selected document for
|
||||||
|
|
@ -60,10 +61,10 @@ public class SelectedDocumentModel {
|
||||||
private AssignableTaskManager taskManager;
|
private AssignableTaskManager taskManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All available authoring steps.
|
* Checks if authoring step classes have all required annotations.
|
||||||
*/
|
*/
|
||||||
@Inject
|
@Inject
|
||||||
private Instance<MvcAuthoringStep> authoringSteps;
|
private AuthoringStepsValidator stepsValidator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to get information about the item.
|
* Used to get information about the item.
|
||||||
|
|
@ -307,14 +308,14 @@ public class SelectedDocumentModel {
|
||||||
.getClass()
|
.getClass()
|
||||||
.getAnnotation(MvcAuthoringKit.class);
|
.getAnnotation(MvcAuthoringKit.class);
|
||||||
|
|
||||||
final Class<? extends MvcAuthoringStep>[] stepClasses = authoringKit
|
final List<Class<?>> stepClasses = Arrays
|
||||||
.authoringSteps();
|
.stream(authoringKit.authoringSteps())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
return Arrays
|
return stepClasses
|
||||||
.stream(stepClasses)
|
.stream()
|
||||||
.map(authoringSteps::select)
|
.filter(stepsValidator::validateAuthoringStep)
|
||||||
.filter(instance -> instance.isResolvable())
|
.filter(stepClass -> stepsValidator.supportsItem(stepClass, item))
|
||||||
.map(Instance::get)
|
|
||||||
.map(this::buildAuthoringStepListEntry)
|
.map(this::buildAuthoringStepListEntry)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
@ -328,27 +329,38 @@ public class SelectedDocumentModel {
|
||||||
* @return An {@link AuthoringStepListEntry} for the step.
|
* @return An {@link AuthoringStepListEntry} for the step.
|
||||||
*/
|
*/
|
||||||
private AuthoringStepListEntry buildAuthoringStepListEntry(
|
private AuthoringStepListEntry buildAuthoringStepListEntry(
|
||||||
final MvcAuthoringStep step
|
final Class<?> authoringStepClass
|
||||||
) {
|
) {
|
||||||
|
final MvcAuthoringStep stepAnnotation = authoringStepClass
|
||||||
|
.getAnnotation(MvcAuthoringStep.class);
|
||||||
|
final Path pathAnnotation = authoringStepClass.getAnnotation(
|
||||||
|
Path.class
|
||||||
|
);
|
||||||
|
final LocalizedTextsUtil textsUtil = globalizationHelper
|
||||||
|
.getLocalizedTextsUtil(stepAnnotation.bundle());
|
||||||
final AuthoringStepListEntry entry = new AuthoringStepListEntry();
|
final AuthoringStepListEntry entry = new AuthoringStepListEntry();
|
||||||
entry.setDescription(step.getDescription());
|
entry.setDescription(textsUtil.getText(stepAnnotation.descriptionKey()));
|
||||||
entry.setLabel(step.getLabel());
|
entry.setLabel(textsUtil.getText(stepAnnotation.labelKey()));
|
||||||
entry.setPathFragment(readAuthoringStepPathFragment(step));
|
entry.setPath(createStepPath(pathAnnotation.value()));
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private String createStepPath(final String path) {
|
||||||
* Helper method for retrieving the path fragment of an authoring step.
|
return path
|
||||||
*
|
.replace(
|
||||||
* @param step The step.
|
String.format(
|
||||||
*
|
"{%s}",
|
||||||
* @return The path fragment of the step.
|
MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM
|
||||||
*/
|
),
|
||||||
private String readAuthoringStepPathFragment(final MvcAuthoringStep step) {
|
item.getContentType().getContentSection().getLabel()
|
||||||
return step
|
)
|
||||||
.getClass()
|
.replace(
|
||||||
.getAnnotation(AuthoringStepPathFragment.class)
|
String.format(
|
||||||
.value();
|
"{%s}",
|
||||||
|
MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM
|
||||||
|
),
|
||||||
|
itemPath
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -285,7 +285,7 @@ public class MvcArticleCreateStep
|
||||||
itemRepo.save(article);
|
itemRepo.save(article);
|
||||||
|
|
||||||
return String.format(
|
return String.format(
|
||||||
"redirect:/%s/documents/%s/%s/@edit/basicproperties",
|
"redirect:/%s/documents/%s/%s/@articleproperties",
|
||||||
getContentSectionLabel(),
|
getContentSectionLabel(),
|
||||||
getFolderPath(),
|
getFolderPath(),
|
||||||
name
|
name
|
||||||
|
|
|
||||||
|
|
@ -18,25 +18,24 @@
|
||||||
*/
|
*/
|
||||||
package org.librecms.ui.contenttypes;
|
package org.librecms.ui.contenttypes;
|
||||||
|
|
||||||
import org.libreccm.core.UnexpectedErrorException;
|
|
||||||
import org.libreccm.l10n.GlobalizationHelper;
|
import org.libreccm.l10n.GlobalizationHelper;
|
||||||
import org.libreccm.l10n.LocalizedString;
|
import org.libreccm.l10n.LocalizedString;
|
||||||
import org.librecms.contentsection.ContentItem;
|
|
||||||
import org.librecms.contentsection.ContentItemManager;
|
import org.librecms.contentsection.ContentItemManager;
|
||||||
import org.librecms.contentsection.ContentItemRepository;
|
import org.librecms.contentsection.ContentItemRepository;
|
||||||
import org.librecms.contentsection.ContentSection;
|
|
||||||
import org.librecms.contentsection.FolderManager;
|
import org.librecms.contentsection.FolderManager;
|
||||||
import org.librecms.contenttypes.Article;
|
import org.librecms.contenttypes.Article;
|
||||||
import org.librecms.ui.contentsections.ItemPermissionChecker;
|
import org.librecms.ui.contentsections.ItemPermissionChecker;
|
||||||
import org.librecms.ui.contentsections.documents.AuthoringStepPathFragment;
|
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.DocumentUi;
|
||||||
|
import org.librecms.ui.contentsections.documents.MvcAuthoringStep;
|
||||||
|
import org.librecms.ui.contentsections.documents.MvcAuthoringStepService;
|
||||||
|
import org.librecms.ui.contentsections.documents.MvcAuthoringSteps;
|
||||||
|
|
||||||
import javax.enterprise.context.RequestScoped;
|
import javax.enterprise.context.RequestScoped;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
|
|
||||||
import org.librecms.ui.contentsections.documents.MvcAuthoringStep;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
@ -44,30 +43,36 @@ import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
import javax.mvc.Controller;
|
||||||
|
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.FormParam;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.POST;
|
import javax.ws.rs.POST;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Authoring step for editing the basic properties of an a {@link Article}.
|
* Authoring step for editing the basic properties of an a {@link Article}.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@RequestScoped
|
@RequestScoped
|
||||||
@Path("/")
|
@Path(MvcAuthoringSteps.PATH_PREFIX + "/@basicproperties")
|
||||||
@AuthoringStepPathFragment(MvcArticlePropertiesStep.PATH_FRAGMENT)
|
@Controller
|
||||||
@Named("CmsArticlePropertiesStep")
|
@Named("CmsArticlePropertiesStep")
|
||||||
public class MvcArticlePropertiesStep implements MvcAuthoringStep {
|
@MvcAuthoringStep(
|
||||||
|
bundle = ArticleStepsConstants.BUNDLE,
|
||||||
|
descriptionKey = "authoringsteps.basicproperties.description",
|
||||||
|
labelKey = "authoringsteps.basicproperties.label",
|
||||||
|
supportedDocumentType = Article.class
|
||||||
|
)
|
||||||
|
public class MvcArticlePropertiesStep {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ArticleMessageBundle articleMessageBundle;
|
private ArticleMessageBundle articleMessageBundle;
|
||||||
|
|
||||||
/**
|
|
||||||
* The path fragment of the step.
|
|
||||||
*/
|
|
||||||
static final String PATH_FRAGMENT = "basicproperties";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used for retrieving and saving the article.
|
* Used for retrieving and saving the article.
|
||||||
*/
|
*/
|
||||||
|
|
@ -98,97 +103,38 @@ public class MvcArticlePropertiesStep implements MvcAuthoringStep {
|
||||||
@Inject
|
@Inject
|
||||||
private ItemPermissionChecker itemPermissionChecker;
|
private ItemPermissionChecker itemPermissionChecker;
|
||||||
|
|
||||||
/**
|
@Inject
|
||||||
* The current content section.
|
private Models models;
|
||||||
*/
|
|
||||||
private ContentSection section;
|
|
||||||
|
|
||||||
/**
|
@Inject
|
||||||
* The {@link Article} to edit.
|
private MvcAuthoringStepService stepService;
|
||||||
*/
|
|
||||||
private Article document;
|
|
||||||
|
|
||||||
@Override
|
@GET
|
||||||
public Class<? extends ContentItem> supportedDocumentType() {
|
@Path("/")
|
||||||
return Article.class;
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
}
|
public String showStep(
|
||||||
|
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
|
||||||
@Override
|
final String sectionIdentifier,
|
||||||
public String getLabel() {
|
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM)
|
||||||
return globalizationHelper
|
final String documentPath
|
||||||
.getLocalizedTextsUtil(getBundle())
|
) {
|
||||||
.getText("authoringsteps.basicproperties.label");
|
try {
|
||||||
}
|
stepService.setSectionAndDocument(sectionIdentifier, documentPath);
|
||||||
|
} catch (ContentSectionNotFoundException ex) {
|
||||||
@Override
|
return ex.showErrorMessage();
|
||||||
public String getDescription() {
|
} catch (DocumentNotFoundException ex) {
|
||||||
return globalizationHelper
|
return ex.showErrorMessage();
|
||||||
.getLocalizedTextsUtil(getBundle())
|
|
||||||
.getText("authoringsteps.basicproperties.description");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getBundle() {
|
|
||||||
return ArticleStepsConstants.BUNDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ContentSection getContentSection() {
|
|
||||||
return section;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getContentSectionLabel() {
|
|
||||||
return section.getLabel();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getContentSectionTitle() {
|
|
||||||
return globalizationHelper
|
|
||||||
.getValueFromLocalizedString(section.getTitle());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setContentSection(final ContentSection section) {
|
|
||||||
this.section = section;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ContentItem getContentItem() {
|
|
||||||
return document;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getContentItemPath() {
|
|
||||||
return itemManager.getItemPath(document);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getContentItemTitle() {
|
|
||||||
return globalizationHelper
|
|
||||||
.getValueFromLocalizedString(document.getTitle());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setContentItem(final ContentItem document) {
|
|
||||||
if (!(document instanceof Article)) {
|
|
||||||
throw new UnexpectedErrorException("Not an article.");
|
|
||||||
}
|
}
|
||||||
this.document = (Article) document;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
if (itemPermissionChecker.canEditItem(stepService.getDocument())) {
|
||||||
public String showStep() {
|
|
||||||
if (itemPermissionChecker.canEditItem(document)) {
|
|
||||||
return "org/librecms/ui/contenttypes/article/article-basic-properties.xhtml";
|
return "org/librecms/ui/contenttypes/article/article-basic-properties.xhtml";
|
||||||
} else {
|
} else {
|
||||||
return documentUi.showAccessDenied(
|
return documentUi.showAccessDenied(
|
||||||
section,
|
stepService.getContentSection(),
|
||||||
document,
|
stepService.getDocument(),
|
||||||
articleMessageBundle.getMessage("article.edit.denied")
|
articleMessageBundle.getMessage("article.edit.denied")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -197,31 +143,54 @@ public class MvcArticlePropertiesStep implements MvcAuthoringStep {
|
||||||
* @return The display name of the current article.
|
* @return The display name of the current article.
|
||||||
*/
|
*/
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return document.getDisplayName();
|
return stepService.getDocument().getDisplayName();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the name of the current article.
|
* Updates the name of the current article.
|
||||||
*
|
*
|
||||||
* @param name The new name of the article.
|
* @param sectionIdentifier
|
||||||
|
* @param documentPath
|
||||||
|
* @param name
|
||||||
*
|
*
|
||||||
* @return A redirect to this authoring step.
|
* @return A redirect to this authoring step.
|
||||||
*/
|
*/
|
||||||
@POST
|
@POST
|
||||||
@Path("/name")
|
@Path("/name")
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String updateName(@FormParam("name") final String name) {
|
public String updateName(
|
||||||
document.setDisplayName(name);
|
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
|
||||||
itemRepo.save(document);
|
final String sectionIdentifier,
|
||||||
return String.format(
|
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM)
|
||||||
"redirect:/@documents/%s/%s/%s/@edit/%s",
|
final String documentPath,
|
||||||
section.getLabel(),
|
@FormParam("name") @DefaultValue("") final String name
|
||||||
folderManager.getFolderPath(
|
) {
|
||||||
itemManager.getItemFolder(document).get()
|
try {
|
||||||
),
|
stepService.setSectionAndDocument(sectionIdentifier, documentPath);
|
||||||
name,
|
} catch (ContentSectionNotFoundException ex) {
|
||||||
PATH_FRAGMENT
|
return ex.showErrorMessage();
|
||||||
);
|
} catch (DocumentNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemPermissionChecker.canEditItem(stepService.getDocument())) {
|
||||||
|
if (name.isEmpty() || name.matches("\\s*")) {
|
||||||
|
models.put("nameMissing", true);
|
||||||
|
|
||||||
|
return showStep(sectionIdentifier, documentPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
stepService.getDocument().setDisplayName(name);
|
||||||
|
itemRepo.save(stepService.getDocument());
|
||||||
|
|
||||||
|
return stepService.buildRedirectPathForStep(getClass());
|
||||||
|
} else {
|
||||||
|
return documentUi.showAccessDenied(
|
||||||
|
stepService.getContentSection(),
|
||||||
|
stepService.getDocument(),
|
||||||
|
stepService.getLabel(getClass())
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -230,7 +199,8 @@ public class MvcArticlePropertiesStep implements MvcAuthoringStep {
|
||||||
* @return The values of the localized title of the article.
|
* @return The values of the localized title of the article.
|
||||||
*/
|
*/
|
||||||
public Map<String, String> getTitleValues() {
|
public Map<String, String> getTitleValues() {
|
||||||
return document
|
return stepService
|
||||||
|
.getDocument()
|
||||||
.getTitle()
|
.getTitle()
|
||||||
.getValues()
|
.getValues()
|
||||||
.entrySet()
|
.entrySet()
|
||||||
|
|
@ -249,7 +219,8 @@ public class MvcArticlePropertiesStep implements MvcAuthoringStep {
|
||||||
* @return The locales for which no localized title has been defined yet.
|
* @return The locales for which no localized title has been defined yet.
|
||||||
*/
|
*/
|
||||||
public List<String> getUnusedTitleLocales() {
|
public List<String> getUnusedTitleLocales() {
|
||||||
final Set<Locale> titleLocales = document
|
final Set<Locale> titleLocales = stepService
|
||||||
|
.getDocument()
|
||||||
.getTitle()
|
.getTitle()
|
||||||
.getAvailableLocales();
|
.getAvailableLocales();
|
||||||
return globalizationHelper
|
return globalizationHelper
|
||||||
|
|
@ -261,37 +232,56 @@ public class MvcArticlePropertiesStep implements MvcAuthoringStep {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a localized title to the article.
|
* Updates a localized title of the article.
|
||||||
*
|
*
|
||||||
* @param localeParam The locale of the title.
|
* @param sectionIdentifier
|
||||||
* @param value The title value.
|
* @param documentPath
|
||||||
|
* @param localeParam The locale to update.
|
||||||
|
* @param value The updated title value.
|
||||||
*
|
*
|
||||||
* @return A redirect to this authoring step.
|
* @return A redirect to this authoring step.
|
||||||
*/
|
*/
|
||||||
@POST
|
@POST
|
||||||
@Path("/title/@add")
|
@Path("/title/@edit/{locale}")
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String addTitle(
|
public String addTitle(
|
||||||
@FormParam("locale") final String localeParam,
|
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
|
||||||
|
final String sectionIdentifier,
|
||||||
|
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM)
|
||||||
|
final String documentPath,
|
||||||
|
@PathParam("locale") final String localeParam,
|
||||||
@FormParam("value") final String value
|
@FormParam("value") final String value
|
||||||
) {
|
) {
|
||||||
final Locale locale = new Locale(localeParam);
|
try {
|
||||||
document.getTitle().addValue(locale, value);
|
stepService.setSectionAndDocument(sectionIdentifier, documentPath);
|
||||||
itemRepo.save(document);
|
} catch (ContentSectionNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
} catch (DocumentNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
}
|
||||||
|
|
||||||
return String.format(
|
if (itemPermissionChecker.canEditItem(stepService.getDocument())) {
|
||||||
"redirect:%s/@documents/%s/@edit/%s",
|
final Locale locale = new Locale(localeParam);
|
||||||
section.getLabel(),
|
stepService.getDocument().getTitle().addValue(locale, value);
|
||||||
getContentItemPath(),
|
itemRepo.save(stepService.getDocument());
|
||||||
PATH_FRAGMENT
|
|
||||||
);
|
return stepService.buildRedirectPathForStep(getClass());
|
||||||
|
} else {
|
||||||
|
return documentUi.showAccessDenied(
|
||||||
|
stepService.getContentSection(),
|
||||||
|
stepService.getDocument(),
|
||||||
|
stepService.getLabel(getClass())
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates a localized title of the article.
|
* Updates a localized title of the article.
|
||||||
*
|
*
|
||||||
* @param localeParam The locale to update.
|
* @param sectionIdentifier
|
||||||
* @param value The updated title value.
|
* @param documentPath
|
||||||
|
* @param localeParam The locale to update.
|
||||||
|
* @param value The updated title value.
|
||||||
*
|
*
|
||||||
* @return A redirect to this authoring step.
|
* @return A redirect to this authoring step.
|
||||||
*/
|
*/
|
||||||
|
|
@ -299,25 +289,41 @@ public class MvcArticlePropertiesStep implements MvcAuthoringStep {
|
||||||
@Path("/title/@edit/{locale}")
|
@Path("/title/@edit/{locale}")
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String editTitle(
|
public String editTitle(
|
||||||
|
final String sectionIdentifier,
|
||||||
|
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM)
|
||||||
|
final String documentPath,
|
||||||
@PathParam("locale") final String localeParam,
|
@PathParam("locale") final String localeParam,
|
||||||
@FormParam("value") final String value
|
@FormParam("value") final String value
|
||||||
) {
|
) {
|
||||||
final Locale locale = new Locale(localeParam);
|
try {
|
||||||
document.getTitle().addValue(locale, value);
|
stepService.setSectionAndDocument(sectionIdentifier, documentPath);
|
||||||
itemRepo.save(document);
|
} catch (ContentSectionNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
} catch (DocumentNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
}
|
||||||
|
|
||||||
return String.format(
|
if (itemPermissionChecker.canEditItem(stepService.getDocument())) {
|
||||||
"redirect:%s/@documents/%s/@edit/%s",
|
final Locale locale = new Locale(localeParam);
|
||||||
section.getLabel(),
|
stepService.getDocument().getTitle().removeValue(locale);
|
||||||
getContentItemPath(),
|
itemRepo.save(stepService.getDocument());
|
||||||
PATH_FRAGMENT
|
|
||||||
);
|
return stepService.buildRedirectPathForStep(getClass());
|
||||||
|
} else {
|
||||||
|
return documentUi.showAccessDenied(
|
||||||
|
stepService.getContentSection(),
|
||||||
|
stepService.getDocument(),
|
||||||
|
stepService.getLabel(getClass())
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a localized title of the article.
|
* Removes a localized title of the article.
|
||||||
*
|
*
|
||||||
* @param localeParam The locale to remove.
|
* @param sectionIdentifier
|
||||||
|
* @param documentPath
|
||||||
|
* @param localeParam The locale to remove.
|
||||||
*
|
*
|
||||||
* @return A redirect to this authoring step.
|
* @return A redirect to this authoring step.
|
||||||
*/
|
*/
|
||||||
|
|
@ -325,18 +331,33 @@ public class MvcArticlePropertiesStep implements MvcAuthoringStep {
|
||||||
@Path("/title/@remove/{locale}")
|
@Path("/title/@remove/{locale}")
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String removeTitle(
|
public String removeTitle(
|
||||||
|
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
|
||||||
|
final String sectionIdentifier,
|
||||||
|
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM)
|
||||||
|
final String documentPath,
|
||||||
@PathParam("locale") final String localeParam
|
@PathParam("locale") final String localeParam
|
||||||
) {
|
) {
|
||||||
final Locale locale = new Locale(localeParam);
|
try {
|
||||||
document.getTitle().removeValue(locale);
|
stepService.setSectionAndDocument(sectionIdentifier, documentPath);
|
||||||
itemRepo.save(document);
|
} catch (ContentSectionNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
} catch (DocumentNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
}
|
||||||
|
|
||||||
return String.format(
|
if (itemPermissionChecker.canEditItem(stepService.getDocument())) {
|
||||||
"redirect:%s/@documents/%s/@edit/%s",
|
final Locale locale = new Locale(localeParam);
|
||||||
section.getLabel(),
|
stepService.getDocument().getTitle().removeValue(locale);
|
||||||
getContentItemPath(),
|
itemRepo.save(stepService.getDocument());
|
||||||
PATH_FRAGMENT
|
|
||||||
);
|
return stepService.buildRedirectPathForStep(getClass());
|
||||||
|
} else {
|
||||||
|
return documentUi.showAccessDenied(
|
||||||
|
stepService.getContentSection(),
|
||||||
|
stepService.getDocument(),
|
||||||
|
stepService.getLabel(getClass())
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -346,7 +367,8 @@ public class MvcArticlePropertiesStep implements MvcAuthoringStep {
|
||||||
* yet.
|
* yet.
|
||||||
*/
|
*/
|
||||||
public List<String> getUnusedDescriptionLocales() {
|
public List<String> getUnusedDescriptionLocales() {
|
||||||
final Set<Locale> descriptionLocales = document
|
final Set<Locale> descriptionLocales = stepService
|
||||||
|
.getDocument()
|
||||||
.getDescription()
|
.getDescription()
|
||||||
.getAvailableLocales();
|
.getAvailableLocales();
|
||||||
return globalizationHelper
|
return globalizationHelper
|
||||||
|
|
@ -363,7 +385,8 @@ public class MvcArticlePropertiesStep implements MvcAuthoringStep {
|
||||||
* @return The values of the localized description of the article.
|
* @return The values of the localized description of the article.
|
||||||
*/
|
*/
|
||||||
public Map<String, String> getDescriptionValues() {
|
public Map<String, String> getDescriptionValues() {
|
||||||
return document
|
return stepService
|
||||||
|
.getDocument()
|
||||||
.getDescription()
|
.getDescription()
|
||||||
.getValues()
|
.getValues()
|
||||||
.entrySet()
|
.entrySet()
|
||||||
|
|
@ -379,8 +402,10 @@ public class MvcArticlePropertiesStep implements MvcAuthoringStep {
|
||||||
/**
|
/**
|
||||||
* Adds a localized description to the article.
|
* Adds a localized description to the article.
|
||||||
*
|
*
|
||||||
* @param localeParam The locale of the description.
|
* @param sectionIdentifier
|
||||||
* @param value The description value.
|
* @param documentPath
|
||||||
|
* @param localeParam The locale of the description.
|
||||||
|
* @param value The description value.
|
||||||
*
|
*
|
||||||
* @return A redirect to this authoring step.
|
* @return A redirect to this authoring step.
|
||||||
*/
|
*/
|
||||||
|
|
@ -388,26 +413,43 @@ public class MvcArticlePropertiesStep implements MvcAuthoringStep {
|
||||||
@Path("/title/@add")
|
@Path("/title/@add")
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String addDescription(
|
public String addDescription(
|
||||||
|
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
|
||||||
|
final String sectionIdentifier,
|
||||||
|
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM)
|
||||||
|
final String documentPath,
|
||||||
@FormParam("locale") final String localeParam,
|
@FormParam("locale") final String localeParam,
|
||||||
@FormParam("value") final String value
|
@FormParam("value") final String value
|
||||||
) {
|
) {
|
||||||
final Locale locale = new Locale(localeParam);
|
try {
|
||||||
document.getDescription().addValue(locale, value);
|
stepService.setSectionAndDocument(sectionIdentifier, documentPath);
|
||||||
itemRepo.save(document);
|
} catch (ContentSectionNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
} catch (DocumentNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
}
|
||||||
|
|
||||||
return String.format(
|
if (itemPermissionChecker.canEditItem(stepService.getDocument())) {
|
||||||
"redirect:%s/@documents/%s/@edit/%s",
|
final Locale locale = new Locale(localeParam);
|
||||||
section.getLabel(),
|
stepService.getDocument().getDescription().addValue(locale, value);
|
||||||
getContentItemPath(),
|
itemRepo.save(stepService.getDocument());
|
||||||
PATH_FRAGMENT
|
|
||||||
);
|
return stepService.buildRedirectPathForStep(getClass());
|
||||||
|
} else {
|
||||||
|
return documentUi.showAccessDenied(
|
||||||
|
stepService.getContentSection(),
|
||||||
|
stepService.getDocument(),
|
||||||
|
stepService.getLabel(getClass())
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates a localized description of the article.
|
* Updates a localized description of the article.
|
||||||
*
|
*
|
||||||
* @param localeParam The locale to update.
|
* @param sectionIdentifier
|
||||||
* @param value The updated description value.
|
* @param documentPath
|
||||||
|
* @param localeParam The locale to update.
|
||||||
|
* @param value The updated description value.
|
||||||
*
|
*
|
||||||
* @return A redirect to this authoring step.
|
* @return A redirect to this authoring step.
|
||||||
*/
|
*/
|
||||||
|
|
@ -415,24 +457,41 @@ public class MvcArticlePropertiesStep implements MvcAuthoringStep {
|
||||||
@Path("/title/@edit/{locale}")
|
@Path("/title/@edit/{locale}")
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String editDescription(
|
public String editDescription(
|
||||||
|
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
|
||||||
|
final String sectionIdentifier,
|
||||||
|
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM)
|
||||||
|
final String documentPath,
|
||||||
@PathParam("locale") final String localeParam,
|
@PathParam("locale") final String localeParam,
|
||||||
@FormParam("value") final String value
|
@FormParam("value") final String value
|
||||||
) {
|
) {
|
||||||
final Locale locale = new Locale(localeParam);
|
try {
|
||||||
document.getDescription().addValue(locale, value);
|
stepService.setSectionAndDocument(sectionIdentifier, documentPath);
|
||||||
itemRepo.save(document);
|
} catch (ContentSectionNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
} catch (DocumentNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
}
|
||||||
|
|
||||||
return String.format(
|
if (itemPermissionChecker.canEditItem(stepService.getDocument())) {
|
||||||
"redirect:%s/@documents/%s/@edit/%s",
|
final Locale locale = new Locale(localeParam);
|
||||||
section.getLabel(),
|
stepService.getDocument().getDescription().addValue(locale, value);
|
||||||
getContentItemPath(),
|
itemRepo.save(stepService.getDocument());
|
||||||
PATH_FRAGMENT
|
|
||||||
);
|
return stepService.buildRedirectPathForStep(getClass());
|
||||||
|
} else {
|
||||||
|
return documentUi.showAccessDenied(
|
||||||
|
stepService.getContentSection(),
|
||||||
|
stepService.getDocument(),
|
||||||
|
stepService.getLabel(getClass())
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a localized description of the article.
|
* Removes a localized description of the article.
|
||||||
*
|
*
|
||||||
|
* @param sectionIdentifier
|
||||||
|
* @param documentPath
|
||||||
* @param localeParam The locale to remove.
|
* @param localeParam The locale to remove.
|
||||||
*
|
*
|
||||||
* @return A redirect to this authoring step.
|
* @return A redirect to this authoring step.
|
||||||
|
|
@ -441,18 +500,33 @@ public class MvcArticlePropertiesStep implements MvcAuthoringStep {
|
||||||
@Path("/title/@remove/{locale}")
|
@Path("/title/@remove/{locale}")
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String removeDescription(
|
public String removeDescription(
|
||||||
|
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
|
||||||
|
final String sectionIdentifier,
|
||||||
|
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM)
|
||||||
|
final String documentPath,
|
||||||
@PathParam("locale") final String localeParam
|
@PathParam("locale") final String localeParam
|
||||||
) {
|
) {
|
||||||
final Locale locale = new Locale(localeParam);
|
try {
|
||||||
document.getDescription().removeValue(locale);
|
stepService.setSectionAndDocument(sectionIdentifier, documentPath);
|
||||||
itemRepo.save(document);
|
} catch (ContentSectionNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
} catch (DocumentNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
}
|
||||||
|
|
||||||
return String.format(
|
if (itemPermissionChecker.canEditItem(stepService.getDocument())) {
|
||||||
"redirect:%s/@documents/%s/@edit/%s",
|
final Locale locale = new Locale(localeParam);
|
||||||
section.getLabel(),
|
stepService.getDocument().getDescription().removeValue(locale);
|
||||||
getContentItemPath(),
|
itemRepo.save(stepService.getDocument());
|
||||||
PATH_FRAGMENT
|
|
||||||
);
|
return stepService.buildRedirectPathForStep(getClass());
|
||||||
|
} else {
|
||||||
|
return documentUi.showAccessDenied(
|
||||||
|
stepService.getContentSection(),
|
||||||
|
stepService.getDocument(),
|
||||||
|
stepService.getLabel(getClass())
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,22 +18,21 @@
|
||||||
*/
|
*/
|
||||||
package org.librecms.ui.contenttypes;
|
package org.librecms.ui.contenttypes;
|
||||||
|
|
||||||
import org.libreccm.core.UnexpectedErrorException;
|
|
||||||
import org.libreccm.l10n.GlobalizationHelper;
|
import org.libreccm.l10n.GlobalizationHelper;
|
||||||
import org.libreccm.l10n.LocalizedString;
|
import org.libreccm.l10n.LocalizedString;
|
||||||
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.contenttypes.Article;
|
import org.librecms.contenttypes.Article;
|
||||||
import org.librecms.ui.contentsections.ItemPermissionChecker;
|
import org.librecms.ui.contentsections.ItemPermissionChecker;
|
||||||
import org.librecms.ui.contentsections.documents.AuthoringStepPathFragment;
|
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.DocumentUi;
|
||||||
|
|
||||||
import javax.mvc.Controller;
|
import javax.mvc.Controller;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
|
|
||||||
import org.librecms.ui.contentsections.documents.MvcAuthoringStep;
|
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;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
@ -44,7 +43,9 @@ import java.util.stream.Collectors;
|
||||||
import javax.enterprise.context.RequestScoped;
|
import javax.enterprise.context.RequestScoped;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
import javax.transaction.Transactional;
|
||||||
import javax.ws.rs.FormParam;
|
import javax.ws.rs.FormParam;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.POST;
|
import javax.ws.rs.POST;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
|
|
||||||
|
|
@ -54,31 +55,26 @@ import javax.ws.rs.PathParam;
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
@RequestScoped
|
@RequestScoped
|
||||||
@Path("/")
|
@Path(MvcAuthoringSteps.PATH_PREFIX + "/@text")
|
||||||
@AuthoringStepPathFragment(MvcArticleTextBodyStep.PATH_FRAGMENT)
|
@Controller
|
||||||
@Named("CmsArticleTextBodyStep")
|
@Named("CmsArticleTextBodyStep")
|
||||||
public class MvcArticleTextBodyStep implements MvcAuthoringStep {
|
@MvcAuthoringStep(
|
||||||
|
bundle = ArticleStepsConstants.BUNDLE,
|
||||||
|
descriptionKey = "authoringsteps.text.description",
|
||||||
|
labelKey = "authoringsteps.text.label",
|
||||||
|
supportedDocumentType = Article.class
|
||||||
|
)
|
||||||
|
public class MvcArticleTextBodyStep {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ArticleMessageBundle articleMessageBundle;
|
private ArticleMessageBundle articleMessageBundle;
|
||||||
|
|
||||||
/**
|
|
||||||
* The path fragment of the step.
|
|
||||||
*/
|
|
||||||
static final String PATH_FRAGMENT = "text";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used for retrieving and saving the article.
|
* Used for retrieving and saving the article.
|
||||||
*/
|
*/
|
||||||
@Inject
|
@Inject
|
||||||
private ContentItemRepository itemRepo;
|
private ContentItemRepository itemRepo;
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides functions for working with content items.
|
|
||||||
*/
|
|
||||||
@Inject
|
|
||||||
private ContentItemManager itemManager;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private DocumentUi documentUi;
|
private DocumentUi documentUi;
|
||||||
|
|
||||||
|
|
@ -91,93 +87,32 @@ public class MvcArticleTextBodyStep implements MvcAuthoringStep {
|
||||||
@Inject
|
@Inject
|
||||||
private ItemPermissionChecker itemPermissionChecker;
|
private ItemPermissionChecker itemPermissionChecker;
|
||||||
|
|
||||||
/**
|
@Inject
|
||||||
* The current content section.
|
private MvcAuthoringStepService stepService;
|
||||||
*/
|
|
||||||
private ContentSection section;
|
|
||||||
|
|
||||||
/**
|
@GET
|
||||||
* The {@link Article} to edit.
|
@Path("/")
|
||||||
*/
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
private Article document;
|
public String showStep(
|
||||||
|
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
|
||||||
@Override
|
final String sectionIdentifier,
|
||||||
public Class<? extends ContentItem> supportedDocumentType() {
|
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM)
|
||||||
return Article.class;
|
final String documentPath
|
||||||
}
|
) {
|
||||||
|
try {
|
||||||
@Override
|
stepService.setSectionAndDocument(sectionIdentifier, documentPath);
|
||||||
public String getLabel() {
|
} catch (ContentSectionNotFoundException ex) {
|
||||||
return globalizationHelper
|
return ex.showErrorMessage();
|
||||||
.getLocalizedTextsUtil(getBundle())
|
} catch (DocumentNotFoundException ex) {
|
||||||
.getText("authoringsteps.text.label");
|
return ex.showErrorMessage();
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getDescription() {
|
|
||||||
return globalizationHelper
|
|
||||||
.getLocalizedTextsUtil(getBundle())
|
|
||||||
.getText("authoringsteps.text.description");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getBundle() {
|
|
||||||
return ArticleStepsConstants.BUNDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ContentSection getContentSection() {
|
|
||||||
return section;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getContentSectionLabel() {
|
|
||||||
return section.getLabel();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getContentSectionTitle() {
|
|
||||||
return globalizationHelper
|
|
||||||
.getValueFromLocalizedString(section.getTitle());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setContentSection(final ContentSection section) {
|
|
||||||
this.section = section;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ContentItem getContentItem() {
|
|
||||||
return document;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getContentItemPath() {
|
|
||||||
return itemManager.getItemPath(document);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getContentItemTitle() {
|
|
||||||
return globalizationHelper
|
|
||||||
.getValueFromLocalizedString(document.getTitle());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setContentItem(final ContentItem document) {
|
|
||||||
if (!(document instanceof Article)) {
|
|
||||||
throw new UnexpectedErrorException("Not an article.");
|
|
||||||
}
|
}
|
||||||
this.document = (Article) document;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
if (itemPermissionChecker.canEditItem(stepService.getDocument())) {
|
||||||
public String showStep() {
|
|
||||||
if (itemPermissionChecker.canEditItem(document)) {
|
|
||||||
return "org/librecms/ui/contenttypes/article/article-text.xhtml";
|
return "org/librecms/ui/contenttypes/article/article-text.xhtml";
|
||||||
} else {
|
} else {
|
||||||
return documentUi.showAccessDenied(
|
return documentUi.showAccessDenied(
|
||||||
section,
|
stepService.getContentSection(),
|
||||||
document,
|
stepService.getDocument(),
|
||||||
articleMessageBundle.getMessage("article.edit.denied")
|
articleMessageBundle.getMessage("article.edit.denied")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -189,7 +124,7 @@ public class MvcArticleTextBodyStep implements MvcAuthoringStep {
|
||||||
* @return The localized values of the main text.
|
* @return The localized values of the main text.
|
||||||
*/
|
*/
|
||||||
public Map<String, String> getTextValues() {
|
public Map<String, String> getTextValues() {
|
||||||
return document
|
return getDocument()
|
||||||
.getText()
|
.getText()
|
||||||
.getValues()
|
.getValues()
|
||||||
.entrySet()
|
.entrySet()
|
||||||
|
|
@ -208,7 +143,7 @@ public class MvcArticleTextBodyStep implements MvcAuthoringStep {
|
||||||
* @return The locales for which the main text has not been defined yet.
|
* @return The locales for which the main text has not been defined yet.
|
||||||
*/
|
*/
|
||||||
public List<String> getUnusedLocales() {
|
public List<String> getUnusedLocales() {
|
||||||
final Set<Locale> locales = document
|
final Set<Locale> locales = getDocument()
|
||||||
.getText()
|
.getText()
|
||||||
.getAvailableLocales();
|
.getAvailableLocales();
|
||||||
return globalizationHelper
|
return globalizationHelper
|
||||||
|
|
@ -222,77 +157,135 @@ public class MvcArticleTextBodyStep implements MvcAuthoringStep {
|
||||||
/**
|
/**
|
||||||
* Adds a localized main text.
|
* Adds a localized main text.
|
||||||
*
|
*
|
||||||
* @param localeParam The locale of the text.
|
* @param sectionIdentifier
|
||||||
* @param value The text.
|
* @param documentPath
|
||||||
|
* @param localeParam The locale of the text.
|
||||||
|
* @param value The text.
|
||||||
*
|
*
|
||||||
* @return A redirect to this authoring step.
|
* @return A redirect to this authoring step.
|
||||||
*/
|
*/
|
||||||
@POST
|
@POST
|
||||||
@Path("/@add")
|
@Path("/@add")
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String addTextValue(
|
public String addTextValue(
|
||||||
|
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
|
||||||
|
final String sectionIdentifier,
|
||||||
|
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM)
|
||||||
|
final String documentPath,
|
||||||
@FormParam("locale") final String localeParam,
|
@FormParam("locale") final String localeParam,
|
||||||
@FormParam("value") final String value
|
@FormParam("value") final String value
|
||||||
) {
|
) {
|
||||||
final Locale locale = new Locale(localeParam);
|
try {
|
||||||
document.getText().addValue(locale, value);
|
stepService.setSectionAndDocument(sectionIdentifier, documentPath);
|
||||||
itemRepo.save(document);
|
} catch (ContentSectionNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
} catch (DocumentNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
}
|
||||||
|
|
||||||
return String.format(
|
if (itemPermissionChecker.canEditItem(stepService.getDocument())) {
|
||||||
"redirect:/@documents/%s/%s/@edit/%s",
|
final Locale locale = new Locale(localeParam);
|
||||||
section.getLabel(),
|
getDocument().getText().addValue(locale, value);
|
||||||
getContentItemPath(),
|
itemRepo.save(stepService.getDocument());
|
||||||
PATH_FRAGMENT
|
|
||||||
);
|
return stepService.buildRedirectPathForStep(getClass());
|
||||||
|
} else {
|
||||||
|
return documentUi.showAccessDenied(
|
||||||
|
stepService.getContentSection(),
|
||||||
|
stepService.getDocument(),
|
||||||
|
stepService.getLabel(getClass())
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates a localized main text.
|
* Updates a localized main text.
|
||||||
*
|
*
|
||||||
* @param localeParam The locale of the text.
|
* @param sectionIdentifier
|
||||||
* @param value The text.
|
* @param documentPath
|
||||||
|
* @param localeParam The locale of the text.
|
||||||
|
* @param value The text.
|
||||||
*
|
*
|
||||||
* @return A redirect to this authoring step.
|
* @return A redirect to this authoring step.
|
||||||
*/
|
*/
|
||||||
@POST
|
@POST
|
||||||
@Path("/@edit/{locale}")
|
@Path("/@edit/{locale}")
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String editTextValue(
|
public String editTextValue(
|
||||||
|
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
|
||||||
|
final String sectionIdentifier,
|
||||||
|
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM)
|
||||||
|
final String documentPath,
|
||||||
@PathParam("locale") final String localeParam,
|
@PathParam("locale") final String localeParam,
|
||||||
@FormParam("value") final String value
|
@FormParam("value") final String value
|
||||||
) {
|
) {
|
||||||
final Locale locale = new Locale(localeParam);
|
try {
|
||||||
document.getText().addValue(locale, value);
|
stepService.setSectionAndDocument(sectionIdentifier, documentPath);
|
||||||
itemRepo.save(document);
|
} catch (ContentSectionNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
} catch (DocumentNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
}
|
||||||
|
|
||||||
return String.format(
|
if (itemPermissionChecker.canEditItem(stepService.getDocument())) {
|
||||||
"redirect:/@documents/%s/%s/@edit/%s",
|
final Locale locale = new Locale(localeParam);
|
||||||
section.getLabel(),
|
getDocument().getText().addValue(locale, value);
|
||||||
getContentItemPath(),
|
itemRepo.save(stepService.getDocument());
|
||||||
PATH_FRAGMENT
|
|
||||||
);
|
return stepService.buildRedirectPathForStep(getClass());
|
||||||
|
} else {
|
||||||
|
return documentUi.showAccessDenied(
|
||||||
|
stepService.getContentSection(),
|
||||||
|
stepService.getDocument(),
|
||||||
|
stepService.getLabel(getClass())
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a localized main text.
|
* Removes a localized main text.
|
||||||
*
|
*
|
||||||
* @param localeParam The locale of the text.
|
* @param sectionIdentifier
|
||||||
|
* @param documentPath
|
||||||
|
* @param localeParam The locale of the text.
|
||||||
*
|
*
|
||||||
* @return A redirect to this authoring step.
|
* @return A redirect to this authoring step.
|
||||||
*/
|
*/
|
||||||
@POST
|
@POST
|
||||||
@Path("/@remove/{locale}")
|
@Path("/@remove/{locale}")
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public String remvoeTextValue(
|
public String remvoeTextValue(
|
||||||
|
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
|
||||||
|
final String sectionIdentifier,
|
||||||
|
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM)
|
||||||
|
final String documentPath,
|
||||||
@PathParam("locale") final String localeParam
|
@PathParam("locale") final String localeParam
|
||||||
) {
|
) {
|
||||||
final Locale locale = new Locale(localeParam);
|
try {
|
||||||
document.getText().removeValue(locale);
|
stepService.setSectionAndDocument(sectionIdentifier, documentPath);
|
||||||
itemRepo.save(document);
|
} catch (ContentSectionNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
} catch (DocumentNotFoundException ex) {
|
||||||
|
return ex.showErrorMessage();
|
||||||
|
}
|
||||||
|
|
||||||
return String.format(
|
if (itemPermissionChecker.canEditItem(stepService.getDocument())) {
|
||||||
"redirect:/@documents/%s/%s/@edit/%s",
|
final Locale locale = new Locale(localeParam);
|
||||||
section.getLabel(),
|
getDocument().getText().removeValue(locale);
|
||||||
getContentItemPath(),
|
itemRepo.save(stepService.getDocument());
|
||||||
PATH_FRAGMENT
|
|
||||||
);
|
return stepService.buildRedirectPathForStep(getClass());
|
||||||
|
} else {
|
||||||
|
return documentUi.showAccessDenied(
|
||||||
|
stepService.getContentSection(),
|
||||||
|
stepService.getDocument(),
|
||||||
|
stepService.getLabel(getClass())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Article getDocument() {
|
||||||
|
return (Article) stepService.getDocument();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -100,10 +100,10 @@
|
||||||
<ul class="list-group">
|
<ul class="list-group">
|
||||||
<c:forEach items="#{CmsSelectedDocumentModel.authoringStepsList}"
|
<c:forEach items="#{CmsSelectedDocumentModel.authoringStepsList}"
|
||||||
var="step">
|
var="step">
|
||||||
<li aria-current="#{step.pathFragment == authoringStep ? 'true' : ''}
|
<li aria-current="#{step.path == authoringStep ? 'true' : ''}
|
||||||
class="list-group-item #{step.pathFragment == authoringStep ? 'active' : ''}">
|
class="list-group-item #{step.path == authoringStep ? 'active' : ''}">
|
||||||
<a class="list-group-item-action"
|
<a class="list-group-item-action"
|
||||||
href="#{mvc.basePath}/documents/#{CmsSelectedDocumentModel.itemPath}/@authoringsteps/#{step.pathFragment}">
|
href="#{mvc.basePath}/documents/#{CmsSelectedDocumentModel.itemPath}/@authoringsteps/#{step.path}">
|
||||||
#{step.label}
|
#{step.label}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
<!DOCTYPE html [<!ENTITY times '×'>]>
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:bootstrap="http://xmlns.jcp.org/jsf/composite/components/bootstrap"
|
||||||
|
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
|
||||||
|
xmlns:libreccm="http://xmlns.jcp.org/jsf/composite/components/libreccm"
|
||||||
|
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
|
||||||
|
<ui:composition template="/WEB-INF/views/org/librecms/ui/contentsection/contentsection.xhtml">
|
||||||
|
|
||||||
|
<ui:define name="main">
|
||||||
|
<div class="container">
|
||||||
|
<h1>Example Authoring Step</h1>
|
||||||
|
|
||||||
|
#{sectionIdentifier}
|
||||||
|
#{documentPath}
|
||||||
|
</div>
|
||||||
|
</ui:define>
|
||||||
|
|
||||||
|
</ui:composition>
|
||||||
|
</html>
|
||||||
Loading…
Reference in New Issue