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 index bfaad8b..710c67e 100644 --- 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 @@ -15,7 +15,6 @@ 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; diff --git a/sci-publications/src/main/java/org/scientificcms/publications/ui/contenttypes/InProcedingsRow.java b/sci-publications/src/main/java/org/scientificcms/publications/ui/contenttypes/InProcedingsRow.java new file mode 100644 index 0000000..303c3c4 --- /dev/null +++ b/sci-publications/src/main/java/org/scientificcms/publications/ui/contenttypes/InProcedingsRow.java @@ -0,0 +1,64 @@ +package org.scientificcms.publications.ui.contenttypes; + +import java.util.Comparator; + +/** + * + * @author Jens Pelzetter + */ +public class InProcedingsRow implements Comparable{ + + private String inProceedingsUuid; + + private String title; + + private Integer startPage; + + private Integer endPage; + + public String getInProceedingsUuid() { + return inProceedingsUuid; + } + + public void setInProceedingsUuid(final String inProceedingsUuid) { + this.inProceedingsUuid = inProceedingsUuid; + } + + public String getTitle() { + return title; + } + + public void setTitle(final String title) { + this.title = title; + } + + public Integer getStartPage() { + return startPage; + } + + public void setStartPage(final Integer startPage) { + this.startPage = startPage; + } + + public Integer getEndPage() { + return endPage; + } + + public void setEndPage(final Integer endPage) { + this.endPage = endPage; + } + + @Override + public int compareTo(final InProcedingsRow other) { + return Comparator + .nullsFirst( + Comparator.comparing(InProcedingsRow::getStartPage) + .thenComparing(InProcedingsRow::getEndPage) + .thenComparing(InProcedingsRow::getTitle) + ) + .compare(this, other); + } + + + +} diff --git a/sci-publications/src/main/java/org/scientificcms/publications/ui/contenttypes/ProceedingsPropertiesStep.java b/sci-publications/src/main/java/org/scientificcms/publications/ui/contenttypes/ProceedingsPropertiesStep.java new file mode 100644 index 0000000..73f6f97 --- /dev/null +++ b/sci-publications/src/main/java/org/scientificcms/publications/ui/contenttypes/ProceedingsPropertiesStep.java @@ -0,0 +1,555 @@ +package org.scientificcms.publications.ui.contenttypes; + +import freemarker.template.utility.DateUtil; +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.InProceedings; +import org.scientificcms.publications.Proceedings; +import org.scientificcms.publications.ProceedingsManager; +import org.scientificcms.publications.PublicationRepository; +import org.scientificcms.publications.contenttypes.ProceedingsItem; +import org.scientificcms.publications.ui.SciPublicationsUiConstants; +import org.scientificcms.publications.ui.SciPublicationsUiMessageBundle; + +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +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.DefaultValue; +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; + +/** + * + * @author Jens Pelzetter + */ +@RequestScoped +@Path( + MvcAuthoringSteps.PATH_PREFIX + + ProceedingsPropertiesStep.EDIT_STEP_URL_FRAGMENT +) +@Controller +@MvcAuthoringStepDef( + bundle = SciPublicationsUiConstants.BUNDLE, + descriptionKey = "authoringsteps.basicproperties.description", + labelKey = "authoringsteps.basicproperties.label", + supportedDocumentType = ProceedingsItem.class +) +public class ProceedingsPropertiesStep + extends AbstractPublicationWithPublisherPropertiesStep { + + public static final String EDIT_STEP_URL_FRAGMENT + = "proceedings-basicproperties"; + + @Inject + private DocumentUi documentUi; + + @Inject + private GlobalizationHelper globalizationHelper; + + @Inject + private IdentifierParser identifierParser; + + @Inject + private ItemPermissionChecker itemPermissionChecker; + + @Inject + private ProceedingsManager proceedingsManager; + + @Inject + private ProceedingsPropertiesStepModel propertiesStepModel; + + @Inject + private Models models; + + @Inject + private PublicationRepository publicationRepo; + + @Inject + private SciPublicationsUiMessageBundle messageBundle; + + @Override + public Class getStepClass() { + return ProceedingsPropertiesStep.class; + } + + @Override + protected String getEditStepUrlFragment() { + return EDIT_STEP_URL_FRAGMENT; + } + + @Override + public Class getPublicationClass() { + return Proceedings.class; + } + + @Override + protected String getStepTemplatePath() { + return "org/scientificcms/contenttypes/ui/proceedings/edit-proceedings.xhtml"; + } + + @Override + @Transactional(Transactional.TxType.REQUIRED) + protected void init() throws ContentSectionNotFoundException, + DocumentNotFoundException { + super.init(); + + final DateTimeFormatter isoDateFormatter = DateTimeFormatter.ISO_DATE + .withZone(ZoneId.systemDefault()); + + propertiesStepModel.setEndDate( + Optional + .ofNullable(getPublication().getEndDate()) + .map(endDate -> isoDateFormatter.format(endDate)) + .orElse(null) + ); + propertiesStepModel.setInProceedings( + getPublication() + .getPapers() + .stream() + .map(this::buildInProcedingsRow) + .collect(Collectors.toList()) + ); + propertiesStepModel.setNameOfConference( + getPublication().getNameOfConference() + ); + propertiesStepModel.setOrganizer( + Optional + .ofNullable(getPublication().getOrganizer()) + .map(organizer -> organizer.getName()) + .orElse(null) + ); + propertiesStepModel.setPlaceOfConference( + getPublication().getPlaceOfConference() + ); + propertiesStepModel.setStartDate( + Optional + .ofNullable(getPublication().getStartDate()) + .map(startDate -> isoDateFormatter.format(startDate)) + .orElse(null) + ); + } + + @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("/name") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + @Override + public String updateName( + @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) + final String documentPath, + @FormParam("name") @DefaultValue("") + final String name + ) { + return super.updateName(sectionIdentifier, documentPath, name); + } + + @POST + @Path("/title/@add") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + @Override + public String addTitle( + @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) + final String documentPath, + @FormParam("locale") final String localeParam, + @FormParam("value") final String value + ) { + return super.addTitle( + sectionIdentifier, + documentPath, + localeParam, + value + ); + } + + @POST + @Path("/title/@edit/{locale}") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + @Override + public String editTitle( + @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) + final String documentPath, + @PathParam("locale") final String localeParam, + @FormParam("value") final String value + ) { + return super.editTitle( + sectionIdentifier, + documentPath, + localeParam, + value + ); + } + + @POST + @Path("/title/@remove/{locale}") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + @Override + public String removeTitle( + @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) + final String documentPath, + @PathParam("locale") final String localeParam + ) { + return super.removeTitle(sectionIdentifier, documentPath, localeParam); + } + + @POST + @Path("/shortdescription/@add") + @Transactional(Transactional.TxType.REQUIRED) + @Override + public String addShortDescription( + @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) + final String documentPath, + @FormParam("locale") final String localeParam, + @FormParam("value") final String value + ) { + return super.addShortDescription( + sectionIdentifier, + documentPath, + localeParam, + value + ); + } + + @POST + @Path("/shortdescription/@edit/{locale}") + @Transactional(Transactional.TxType.REQUIRED) + @Override + public String editShortDescription( + @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) + final String documentPath, + @PathParam("locale") final String localeParam, + @FormParam("value") final String value + ) { + return super.editShortDescription( + sectionIdentifier, + documentPath, + localeParam, + value + ); + } + + @POST + @Path("/shortdescription/@remove/{locale}") + @Transactional(Transactional.TxType.REQUIRED) + @Override + public String removeShortDescription( + @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) + final String documentPath, + @PathParam("locale") final String localeParam + ) { + return super.removeShortDescription( + sectionIdentifier, + documentPath, + localeParam + ); + } + + @POST + @Path("/authors") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + @Override + public String addAuthor( + @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) + final String documentPath, + @FormParam("authorIdentifier") + final String authorIdentifier, + @FormParam("editor") + final String editorParam + ) { + return super.addAuthor( + sectionIdentifier, + documentPath, + authorIdentifier, + editorParam + ); + } + + @POST + @Path("/authors/{authorshipUuid}") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + @Override + public String editAuthorship( + @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) + final String documentPath, + @PathParam("authorshipUuid") + final String authorshipUuid, + @FormParam("editor") + final String editorParam + ) { + return super.editAuthorship( + sectionIdentifier, + documentPath, + authorshipUuid, + editorParam + ); + } + + @POST + @Path("/authors/{authorshipUuid}/remove") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + @Override + public String removeAuthorship( + @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) + final String documentPath, + @PathParam("authorshipUuid") + final String authorshipUuid + ) { + return super.removeAuthorship( + sectionIdentifier, + documentPath, + authorshipUuid + ); + } + + @POST + @Path("/publisher") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + @Override + public String setPublisher( + @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) + final String documentPath, + @FormParam("publisherIdentifier") + final String publisherIdentifier + ) { + return super.setPublisher( + sectionIdentifier, + documentPath, + publisherIdentifier + ); + } + + @POST + @Path("/publisher/@remove") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + @Override + public String removePublisher( + @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) + final String documentPath + ) { + return super.removePublisher(sectionIdentifier, documentPath); + } + + @POST() + @Path("/properties") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + 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, + @FormParam("nameOfConference") + final String nameOfConference, + @FormParam("placeOfConference") + final String placeOfConference, + @FormParam("startDate") + final String startDateParam, + @FormParam("endDateParam") + final String endDateParam + ) { + super.updateProperties( + sectionIdentifier, + documentPath, + yearOfPublicationParam + ); + + final DateTimeFormatter isoDateFormatter = DateTimeFormatter.ISO_DATE + .withZone(ZoneId.systemDefault()); + + final LocalDate startDate; + try { + startDate = Optional + .ofNullable(startDateParam) + .filter(param -> !param.isBlank()) + .map(param -> LocalDate.parse(param, isoDateFormatter)) + .orElse(null); + } catch (DateTimeParseException ex) { + return showInvalidStartDate( + sectionIdentifier, + documentPath, + startDateParam + ); + } + + final LocalDate endDate; + try { + endDate = Optional + .ofNullable(endDateParam) + .filter(param -> !param.isBlank()) + .map(param -> LocalDate.parse(param, isoDateFormatter)) + .orElse(null); + } catch (DateTimeParseException ex) { + return showInvalidEndDate( + sectionIdentifier, + documentPath, + endDateParam + ); + } + + getPublication().setEndDate(endDate); + getPublication().setNameOfConference(nameOfConference); + getPublication().setPlaceOfConference(placeOfConference); + getPublication().setStartDate(startDate); + + return buildRedirectPathForStep(); + } + + @POST + @Path("/papers") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + public String addPaper( + @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) + final String documentPath, + @FormParam("paperIdentifier") + final String paperIdentifier + ) { + throw new UnsupportedOperationException(); + } + + @POST + @Path("/papers/{paperUuid}/remove") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + public String removePaper( + @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) + final String documentPath, + @PathParam("paperUuid") + final String paperUuid + ) { + throw new UnsupportedOperationException(); + } + + @POST + @Path("/organizer") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + public String setOrganizer( + @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) + final String documentPath, + @FormParam("organizerIdentifier") + final String organizerIdentifier + ) { + throw new UnsupportedOperationException(); + } + + @POST + @Path("/organizer/@remove") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + public String removeOrganizer( + @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) + final String documentPath + ) { + throw new UnsupportedOperationException(); + } + + private String showInvalidStartDate( + final String sectionIdentifier, + final String documentPath, + final String startDateParam + ) { + models.put("invalidStartDate", startDateParam); + return showStep(sectionIdentifier, documentPath); + } + + private String showInvalidEndDate( + final String sectionIdentifier, + final String documentPath, + final String endDateParam + ) { + models.put("invalidEndDate", endDateParam); + return showStep(sectionIdentifier, documentPath); + } + + private InProcedingsRow buildInProcedingsRow( + final InProceedings inProceedings + ) { + final InProcedingsRow row = new InProcedingsRow(); + row.setEndPage(inProceedings.getEndPage()); + row.setInProceedingsUuid(inProceedings.getUuid()); + row.setStartPage(inProceedings.getStartPage()); + row.setTitle( + globalizationHelper.getValueFromLocalizedString( + inProceedings.getTitle() + ) + ); + + return row; + } + +} diff --git a/sci-publications/src/main/java/org/scientificcms/publications/ui/contenttypes/ProceedingsPropertiesStepModel.java b/sci-publications/src/main/java/org/scientificcms/publications/ui/contenttypes/ProceedingsPropertiesStepModel.java new file mode 100644 index 0000000..114ac42 --- /dev/null +++ b/sci-publications/src/main/java/org/scientificcms/publications/ui/contenttypes/ProceedingsPropertiesStepModel.java @@ -0,0 +1,84 @@ +package org.scientificcms.publications.ui.contenttypes; + +import org.scientificcms.publications.InProceedings; + +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("SciCmsProceedingsStepModel") +public class ProceedingsPropertiesStepModel { + + private String nameOfConference; + + private String placeOfConference; + + private String startDate; + + private String endDate; + + private String organizer; + + private List inProceedings; + + public String getInProceedingsType() { + return InProceedings.class.getName(); + } + + public String getNameOfConference() { + return nameOfConference; + } + + public void setNameOfConference(final String nameOfConference) { + this.nameOfConference = nameOfConference; + } + + public String getPlaceOfConference() { + return placeOfConference; + } + + public void setPlaceOfConference(final String placeOfConference) { + this.placeOfConference = placeOfConference; + } + + public String getStartDate() { + return startDate; + } + + public void setStartDate(final String startDate) { + this.startDate = startDate; + } + + public String getEndDate() { + return endDate; + } + + public void setEndDate(final String endDate) { + this.endDate = endDate; + } + + public String getOrganizer() { + return organizer; + } + + public void setOrganizer(final String organizer) { + this.organizer = organizer; + } + + public List getInProceedings() { + return Collections.unmodifiableList(inProceedings); + } + + public void setInProceedings(final List inProceedings) { + this.inProceedings = new ArrayList<>(inProceedings); + } + +}