diff --git a/sci-publications/src/main/java/org/scientificcms/publications/ui/contenttypes/ArticleInCollectedVolumeRow.java b/sci-publications/src/main/java/org/scientificcms/publications/ui/contenttypes/ArticleInCollectedVolumeRow.java new file mode 100644 index 0000000..1e5c20a --- /dev/null +++ b/sci-publications/src/main/java/org/scientificcms/publications/ui/contenttypes/ArticleInCollectedVolumeRow.java @@ -0,0 +1,41 @@ +package org.scientificcms.publications.ui.contenttypes; + +import java.util.Comparator; + +/** + * + * @author Jens Pelzetter + */ +public class ArticleInCollectedVolumeRow + implements Comparable { + + private String title; + + private String chapter; + + public String getTitle() { + return title; + } + + public void setTitle(final String title) { + this.title = title; + } + + public String getChapter() { + return chapter; + } + + public void setChapter(final String chapter) { + this.chapter = chapter; + } + + @Override + public int compareTo(final ArticleInCollectedVolumeRow other) { + return Comparator + .nullsFirst( + Comparator.comparing(ArticleInCollectedVolumeRow::getChapter) + ) + .compare(this, other); + } + +} diff --git a/sci-publications/src/main/java/org/scientificcms/publications/ui/contenttypes/CollectedVolumePropertiesStep.java b/sci-publications/src/main/java/org/scientificcms/publications/ui/contenttypes/CollectedVolumePropertiesStep.java new file mode 100644 index 0000000..98fca9c --- /dev/null +++ b/sci-publications/src/main/java/org/scientificcms/publications/ui/contenttypes/CollectedVolumePropertiesStep.java @@ -0,0 +1,310 @@ +package org.scientificcms.publications.ui.contenttypes; + +import org.libreccm.api.Identifier; +import org.libreccm.api.IdentifierParser; +import org.libreccm.l10n.GlobalizationHelper; +import org.libreccm.security.AuthorizationRequired; +import org.librecms.ui.contentsections.ContentSectionNotFoundException; +import org.librecms.ui.contentsections.ItemPermissionChecker; +import org.librecms.ui.contentsections.documents.DocumentNotFoundException; +import org.librecms.ui.contentsections.documents.DocumentUi; +import org.librecms.ui.contentsections.documents.MvcAuthoringStepDef; +import org.librecms.ui.contentsections.documents.MvcAuthoringSteps; +import org.scientificcms.publications.ArticleInCollectedVolume; +import org.scientificcms.publications.CollectedVolume; +import org.scientificcms.publications.CollectedVolumeManager; +import org.scientificcms.publications.PublicationRepository; +import org.scientificcms.publications.contenttypes.CollectedVolumeItem; +import org.scientificcms.publications.contenttypes.MonographItem; +import org.scientificcms.publications.ui.SciPublicationsUiConstants; +import org.scientificcms.publications.ui.SciPublicationsUiMessageBundle; + +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.mvc.Controller; +import javax.mvc.Models; +import javax.transaction.Transactional; +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; + +/** + * + * @author Jens Pelzetter + */ +@RequestScoped +@Path(MvcAuthoringSteps.PATH_PREFIX + + CollectedVolumePropertiesStep.EDIT_STEP_URL_FRAGMENT) +@Controller +@MvcAuthoringStepDef( + bundle = SciPublicationsUiConstants.BUNDLE, + descriptionKey = "authoringsteps.basicproperties.description", + labelKey = "authoringsteps.basicproperties.label", + supportedDocumentType = MonographItem.class +) +public class CollectedVolumePropertiesStep + extends AbstractPublicationWithPublisherPropertiesStep { + + public static final String EDIT_STEP_URL_FRAGMENT + = "collectedvolume-basicproperties"; + + @Inject + private DocumentUi documentUi; + + @Inject + private GlobalizationHelper globalizationHelper; + + @Inject + private IdentifierParser identifierParser; + + @Inject + private ItemPermissionChecker itemPermissionChecker; + + @Inject + private CollectedVolumeManager collectedVolumeManager; + + @Inject + private CollectedVolumePropertiesStepModel propertiesStepModel; + + @Inject + private Models models; + + @Inject + private PublicationRepository publicationRepo; + + @Inject + private SciPublicationsUiMessageBundle messageBundle; + + @Override + public Class getStepClass() { + return CollectedVolumePropertiesStep.class; + } + + @Override + protected String getEditStepUrlFragment() { + return EDIT_STEP_URL_FRAGMENT; + } + + @Override + public Class getPublicationClass() { + return CollectedVolume.class; + } + + @Override + protected String getStepTemplatePath() { + return "org/scientificcms/contenttypes/ui/collectedvolume/edit-collectedvolume.xhtml"; + } + + @Override + @Transactional(Transactional.TxType.REQUIRED) + protected void init() throws ContentSectionNotFoundException, + DocumentNotFoundException { + super.init(); + + propertiesStepModel.setArticles( + getPublication() + .getArticles() + .stream() + .map(this::buildArticleInCollectedVolumeRow) + .collect(Collectors.toList()) + ); + } + + @GET + @Path("/") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + @Override + public String showStep( + @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) + final String documentPath + ) { + return super.showStep(sectionIdentifier, documentPath); + } + + @POST() + @Path("/properties") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + @Override + public String updateProperties( + @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) + final String documentPath, + @FormParam("yearOfPublication") + final String yearOfPublicationParam + ) { + return super.updateProperties( + sectionIdentifier, + documentPath, + yearOfPublicationParam + ); + } + + @POST + @Path("/articles") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + public String addArticle( + @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) + final String documentPath, + @FormParam("articleIdentifier") + final String articleIdentifier + ) { + try { + init(); + } catch (ContentSectionNotFoundException ex) { + return ex.showErrorMessage(); + } catch (DocumentNotFoundException ex) { + return ex.showErrorMessage(); + } + + if (itemPermissionChecker.canEditItem(getDocument())) { + final Identifier identifier = identifierParser.parseIdentifier( + articleIdentifier + ); + final Optional articleResult; + switch (identifier.getType()) { + case ID: + articleResult = publicationRepo.findByIdAndType( + Long.parseLong(identifier.getIdentifier()), + ArticleInCollectedVolume.class + ); + break; + case UUID: + articleResult = publicationRepo.findByUuidAndType( + identifier.getIdentifier(), + ArticleInCollectedVolume.class + ); + break; + default: + articleResult = Optional.empty(); + break; + } + + if (articleResult.isEmpty()) { + return showArticleNotFound( + sectionIdentifier, + documentPath, + articleIdentifier + ); + } + + final ArticleInCollectedVolume article = articleResult.get(); + collectedVolumeManager.addArticleToCollectedVolume( + article, + getPublication() + ); + + return buildRedirectPathForStep(); + } else { + return documentUi.showAccessDenied( + getContentSection(), + getDocument(), + getLabel() + ); + } + } + + @POST + @Path("/articles/{articleUuid}/remove") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + public String removeArticle( + @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) + final String documentPath, + @PathParam("articleUuid") + final String articleUuid + ) { + try { + init(); + } catch (ContentSectionNotFoundException ex) { + return ex.showErrorMessage(); + } catch (DocumentNotFoundException ex) { + return ex.showErrorMessage(); + } + + if (itemPermissionChecker.canEditItem(getDocument())) { + final Optional articleResult + = getPublication() + .getArticles() + .stream() + .filter( + article -> Objects.equals( + article.getUuid(), + articleUuid + ) + ) + .findAny(); + + if (articleResult.isEmpty()) { + return showArticleNotPartOfCollectedVolume( + sectionIdentifier, + documentPath, + articleUuid + ); + } + + final ArticleInCollectedVolume article = articleResult.get(); + collectedVolumeManager.removeArticleFromCollectedVolume( + article, + getPublication() + ); + + return buildRedirectPathForStep(); + } else { + return documentUi.showAccessDenied( + getContentSection(), + getDocument(), + getLabel() + ); + } + } + + private ArticleInCollectedVolumeRow buildArticleInCollectedVolumeRow( + final ArticleInCollectedVolume article + ) { + final ArticleInCollectedVolumeRow row + = new ArticleInCollectedVolumeRow(); + row.setTitle( + globalizationHelper.getValueFromLocalizedString( + article.getTitle() + ) + ); + row.setChapter(article.getChapter()); + + return row; + } + + private String showArticleNotFound( + final String sectionIdentifier, + final String documentPath, + final String articleIdentifier + ) { + models.put("articleNotFound", articleIdentifier); + return showStep(sectionIdentifier, documentPath); + } + + private String showArticleNotPartOfCollectedVolume( + final String sectionIdentifier, + final String documentPath, + final String articleIdentifier + ) { + models.put("articleNotPartOfCollectedVolume", articleIdentifier); + return showStep(sectionIdentifier, documentPath); + } + +} diff --git a/sci-publications/src/main/java/org/scientificcms/publications/ui/contenttypes/CollectedVolumePropertiesStepModel.java b/sci-publications/src/main/java/org/scientificcms/publications/ui/contenttypes/CollectedVolumePropertiesStepModel.java new file mode 100644 index 0000000..41e684d --- /dev/null +++ b/sci-publications/src/main/java/org/scientificcms/publications/ui/contenttypes/CollectedVolumePropertiesStepModel.java @@ -0,0 +1,30 @@ +package org.scientificcms.publications.ui.contenttypes; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Named; + +/** + * + * @author Jens Pelzetter + */ +@RequestScoped +@Named("SciCmsCollectedVolumePropertiesStepModel") +public class CollectedVolumePropertiesStepModel { + + private List articles; + + public List getArticles() { + return Collections.unmodifiableList(articles); + } + + public void setArticles(final List articles) { + this.articles = new ArrayList<>(articles); + } + + + +}