diff --git a/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/ContactRepository.java b/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/ContactRepository.java
new file mode 100644
index 0000000..1ede221
--- /dev/null
+++ b/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/ContactRepository.java
@@ -0,0 +1,42 @@
+package org.scientificcms.contenttypes.sciproject;
+
+import org.libreccm.auditing.AbstractAuditedEntityRepository;
+
+import javax.enterprise.context.RequestScoped;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@RequestScoped
+public class ContactRepository
+ extends AbstractAuditedEntityRepository {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public Long getEntityId(final Contact contact) {
+ return contact.getContactId();
+ }
+
+ @Override
+ public Class getEntityClass() {
+ return Contact.class;
+ }
+
+ @Override
+ public String getIdAttributeName() {
+ return "contactId";
+ }
+
+ @Override
+ public Long getIdOfEntity(final Contact contact) {
+ return contact.getContactId();
+ }
+
+ @Override
+ public boolean isNew(final Contact contact) {
+ return contact.getContactId() == 0;
+ }
+
+}
diff --git a/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/MembershipRepository.java b/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/MembershipRepository.java
new file mode 100644
index 0000000..87e9f70
--- /dev/null
+++ b/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/MembershipRepository.java
@@ -0,0 +1,42 @@
+package org.scientificcms.contenttypes.sciproject;
+
+import org.libreccm.auditing.AbstractAuditedEntityRepository;
+
+import javax.enterprise.context.RequestScoped;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@RequestScoped
+public class MembershipRepository
+ extends AbstractAuditedEntityRepository {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public Long getEntityId(final Membership membership) {
+ return membership.getMembershipId();
+ }
+
+ @Override
+ public Class getEntityClass() {
+ return Membership.class;
+ }
+
+ @Override
+ public String getIdAttributeName() {
+ return "membershipId";
+ }
+
+ @Override
+ public Long getIdOfEntity(final Membership membership) {
+ return membership.getMembershipId();
+ }
+
+ @Override
+ public boolean isNew(final Membership membership) {
+ return membership.getMembershipId() == 0;
+ }
+
+}
diff --git a/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/SciProjectMananger.java b/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/SciProjectMananger.java
index f256a1d..06f1424 100644
--- a/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/SciProjectMananger.java
+++ b/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/SciProjectMananger.java
@@ -9,6 +9,7 @@ import org.librecms.assets.ContactableEntity;
import org.librecms.assets.Organization;
import org.librecms.assets.Person;
import org.librecms.contentsection.ContentItemRepository;
+import org.librecms.ui.contentsections.ContentSectionsUi;
import java.io.Serializable;
import java.util.Objects;
@@ -28,10 +29,16 @@ public class SciProjectMananger implements Serializable {
private static final long serialVersionUID = 1L;
@Inject
- private ContentItemRepository contentItemRepository;
-
+ private ContactRepository contactRepo;
+
@Inject
- private SciProjectRepository sciProjectRepository;
+ private ContentItemRepository itemRepo;
+
+ @Inject
+ private MembershipRepository membershipRepo;
+
+ @Inject
+ private SponsoringRepository sponsoringRepo;
@Transactional(Transactional.TxType.REQUIRED)
public void addContact(final ContactableEntity contactable,
@@ -50,8 +57,9 @@ public class SciProjectMananger implements Serializable {
contact.setOrder(toProject.getContacts().size());
toProject.addContact(contact);
+ contactRepo.save(contact);
- contentItemRepository.save(toProject);
+ itemRepo.save(toProject);
}
@Transactional(Transactional.TxType.REQUIRED)
@@ -74,7 +82,8 @@ public class SciProjectMananger implements Serializable {
if (result.isPresent()) {
final Contact remove = result.get();
fromProject.removeContact(remove);
- contentItemRepository.save(fromProject);
+ itemRepo.save(fromProject);
+ contactRepo.delete(remove);
}
}
@@ -101,7 +110,8 @@ public class SciProjectMananger implements Serializable {
toProject.addMember(membership);
- contentItemRepository.save(toProject);
+ membershipRepo.save(membership);
+ itemRepo.save(toProject);
}
@Transactional(Transactional.TxType.REQUIRED)
@@ -128,7 +138,8 @@ public class SciProjectMananger implements Serializable {
if (result.isPresent()) {
final Membership remove = result.get();
fromProject.removeMembership(remove);
- contentItemRepository.save(fromProject);
+ itemRepo.save(fromProject);
+ membershipRepo.delete(remove);
}
}
@@ -149,7 +160,8 @@ public class SciProjectMananger implements Serializable {
toProject.addSponsor(sponsoring);
- contentItemRepository.save(toProject);
+ sponsoringRepo.save(sponsoring);
+ itemRepo.save(toProject);
}
@Transactional(Transactional.TxType.REQUIRED)
@@ -169,7 +181,8 @@ public class SciProjectMananger implements Serializable {
if (result.isPresent()) {
final Sponsoring sponsoring = result.get();
fromProject.removeSponsor(sponsoring);
- contentItemRepository.save(fromProject);
+ sponsoringRepo.delete(sponsoring);
+ itemRepo.save(fromProject);
}
}
diff --git a/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/SponsoringRepository.java b/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/SponsoringRepository.java
new file mode 100644
index 0000000..eb70f8b
--- /dev/null
+++ b/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/SponsoringRepository.java
@@ -0,0 +1,42 @@
+package org.scientificcms.contenttypes.sciproject;
+
+import org.libreccm.auditing.AbstractAuditedEntityRepository;
+
+import javax.enterprise.context.RequestScoped;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@RequestScoped
+public class SponsoringRepository
+ extends AbstractAuditedEntityRepository {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public Long getEntityId(final Sponsoring sponsoring) {
+ return sponsoring.getSponsoringId();
+ }
+
+ @Override
+ public Class getEntityClass() {
+ return Sponsoring.class;
+ }
+
+ @Override
+ public String getIdAttributeName() {
+ return "sponsoringId";
+ }
+
+ @Override
+ public Long getIdOfEntity(final Sponsoring sponsoring) {
+ return sponsoring.getSponsoringId();
+ }
+
+ @Override
+ public boolean isNew(final Sponsoring sponsoring) {
+ return sponsoring.getSponsoringId() == 0;
+ }
+
+}
diff --git a/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/ui/SciProjectDescriptionContactsModel.java b/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/ui/SciProjectDescriptionContactsModel.java
index 6c8ee42..5577bf1 100644
--- a/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/ui/SciProjectDescriptionContactsModel.java
+++ b/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/ui/SciProjectDescriptionContactsModel.java
@@ -23,6 +23,10 @@ public class SciProjectDescriptionContactsModel {
return canEdit;
}
+ protected void setCanEdit(final boolean canEdit) {
+ this.canEdit = canEdit;
+ }
+
public List getContacts() {
return Collections.unmodifiableList(contacts);
}
@@ -31,8 +35,4 @@ public class SciProjectDescriptionContactsModel {
this.contacts = new ArrayList<>(contacts);
}
- protected void setCanEdit(final boolean canEdit) {
- this.canEdit = canEdit;
- }
-
}
diff --git a/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/ui/SciProjectDescriptionStep.java b/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/ui/SciProjectDescriptionStep.java
index d1f53ae..b5a02c9 100644
--- a/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/ui/SciProjectDescriptionStep.java
+++ b/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/ui/SciProjectDescriptionStep.java
@@ -77,9 +77,6 @@ public class SciProjectDescriptionStep extends AbstractMvcAuthoringStep {
@Inject
private AssetRepository assetRepo;
- @Inject
- private ContactableEntityRepository contactableRepo;
-
@Inject
private ContentItemRepository itemRepo;
@@ -135,7 +132,7 @@ public class SciProjectDescriptionStep extends AbstractMvcAuthoringStep {
return documentUi.showAccessDenied(
getContentSection(),
getProject(),
- sciProjectMessageBundle.getMessage("event.edit.denied")
+ sciProjectMessageBundle.getMessage("sciproject.edit.denied")
);
}
}
@@ -520,10 +517,12 @@ public class SciProjectDescriptionStep extends AbstractMvcAuthoringStep {
.getValues()
.entrySet()
.stream()
- .collect(Collectors.toMap(
- entry -> entry.getKey().toString(),
- Map.Entry::getValue
- ))
+ .collect(
+ Collectors.toMap(
+ entry -> entry.getKey().toString(),
+ Map.Entry::getValue
+ )
+ )
);
descriptionModel.setVariants(
getProject()
@@ -558,10 +557,10 @@ public class SciProjectDescriptionStep extends AbstractMvcAuthoringStep {
membersModel.setCanEdit(canEdit);
membersModel.setMembers(
getProject()
- .getMembers()
- .stream()
- .map(this::buildMembershipModel)
- .collect(Collectors.toList())
+ .getMembers()
+ .stream()
+ .map(this::buildMembershipModel)
+ .collect(Collectors.toList())
);
}
diff --git a/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/ui/SciProjectDescriptionStepService.java b/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/ui/SciProjectDescriptionStepService.java
new file mode 100644
index 0000000..ae66eac
--- /dev/null
+++ b/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/ui/SciProjectDescriptionStepService.java
@@ -0,0 +1,132 @@
+package org.scientificcms.contenttypes.sciproject.ui;
+
+import org.librecms.contentsection.ContentItem;
+import org.librecms.contentsection.ContentItemRepository;
+import org.librecms.contentsection.ContentSection;
+import org.librecms.ui.contentsections.ContentSectionsUi;
+import org.librecms.ui.contentsections.documents.MvcAuthoringSteps;
+import org.scientificcms.contenttypes.sciproject.Contact;
+import org.scientificcms.contenttypes.sciproject.ContactRepository;
+import org.scientificcms.contenttypes.sciproject.MembershipRepository;
+import org.scientificcms.contenttypes.sciproject.SciProject;
+import org.scientificcms.contenttypes.sciproject.SciProjectRepository;
+
+import java.util.List;
+
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Inject;
+import javax.transaction.Transactional;
+import javax.ws.rs.BadRequestException;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.NotFoundException;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@RequestScoped
+@Path(MvcAuthoringSteps.PATH_PREFIX + "sciproject-description-service")
+public class SciProjectDescriptionStepService {
+
+ @Inject
+ private ContactRepository contactRepo;
+
+ @Inject
+ private ContentItemRepository itemRepo;
+
+ @Inject
+ private ContentSectionsUi sectionsUi;
+
+ @POST
+ @Path("/contacts/save-order")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Transactional(Transactional.TxType.REQUIRED)
+ public Response saveContactsOrder(
+ @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
+ final String sectionIdentifier,
+ @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
+ final String documentPath,
+ final List contactsOrder
+ ) {
+ final ContentSection contentSection = sectionsUi
+ .findContentSection(sectionIdentifier)
+ .orElseThrow(
+ () -> new NotFoundException(
+ String.format(
+ "No content identifed by %s found.",
+ sectionIdentifier
+ )
+ )
+ );
+
+ final ContentItem document = itemRepo
+ .findByPath(contentSection, documentPath)
+ .orElseThrow(
+ () -> new NotFoundException(
+ String.format(
+ "No document for path %s in section %s.",
+ documentPath,
+ contentSection.getLabel()
+ )
+ )
+ );
+
+ if ((document instanceof SciProject)) {
+ throw new BadRequestException(
+ String.format(
+ "Document %s is not a %s.",
+ documentPath,
+ SciProject.class.getSimpleName()
+ )
+ );
+ }
+
+ final SciProject project = (SciProject) document;
+
+ final List contacts = project.getContacts();
+
+ if (contactsOrder.size() != contacts.size()) {
+ throw new BadRequestException(
+ String.format(
+ "Number of contacts of the SciProject %s does "
+ + "not match the number of values in the order "
+ + "list. Number of contactas: %d, number of values in "
+ + "the contacts order list: %d",
+ documentPath,
+ contacts.size(),
+ contactsOrder.size()
+ )
+ );
+ }
+
+ for (int i = 0; i < contactsOrder.size(); i++) {
+ final String contactIdParam = contactsOrder.get(i);
+ final long contactId = Long.parseLong(contactIdParam);
+ final Contact contact = contacts
+ .stream()
+ .filter(con -> con.getContactId() == contactId)
+ .findAny()
+ .orElseThrow(
+ () -> new BadRequestException(
+ String.format(
+ "contactsOrder has an entry for contact with "
+ + "ID %d, but there is not contact with that "
+ + "ID.",
+ contactId
+ )
+ )
+ );
+
+ contact.setOrder(i);
+ contactRepo.save(contact);
+ }
+
+ return Response.ok().build();
+ }
+
+}
diff --git a/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/ui/SciProjectFundingSponsoringModel.java b/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/ui/SciProjectFundingSponsoringModel.java
new file mode 100644
index 0000000..af8b0eb
--- /dev/null
+++ b/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/ui/SciProjectFundingSponsoringModel.java
@@ -0,0 +1,41 @@
+package org.scientificcms.contenttypes.sciproject.ui;
+
+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("SciProjectFundingSponsoring")
+public class SciProjectFundingSponsoringModel {
+
+ private boolean canEdit;
+
+ private List sponsoring;
+
+ public boolean getCanEdit() {
+ return canEdit;
+ }
+
+ protected void setCanEdit(final boolean canEdit) {
+ this.canEdit = canEdit;
+ }
+
+ public List getSponsoring() {
+ return Collections.unmodifiableList(sponsoring);
+ }
+
+ protected void setSponsoring(
+ final List sponsoring
+ ) {
+ this.sponsoring = new ArrayList<>(sponsoring);
+ }
+
+}
diff --git a/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/ui/SciProjectFundingStep.java b/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/ui/SciProjectFundingStep.java
new file mode 100644
index 0000000..3ce370f
--- /dev/null
+++ b/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/ui/SciProjectFundingStep.java
@@ -0,0 +1,661 @@
+package org.scientificcms.contenttypes.sciproject.ui;
+
+import org.libreccm.l10n.GlobalizationHelper;
+import org.librecms.assets.Organization;
+import org.librecms.contentsection.AssetRepository;
+import org.librecms.contentsection.ContentItemRepository;
+import org.librecms.ui.contentsections.ContentSectionNotFoundException;
+import org.librecms.ui.contentsections.ItemPermissionChecker;
+import org.librecms.ui.contentsections.documents.AbstractMvcAuthoringStep;
+import org.librecms.ui.contentsections.documents.CmsEditorUtil;
+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.contenttypes.sciproject.SciProject;
+import org.scientificcms.contenttypes.sciproject.SciProjectMananger;
+import org.scientificcms.contenttypes.sciproject.Sponsoring;
+
+import java.util.Locale;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+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 + "sciproject-funding")
+@Controller
+@MvcAuthoringStepDef(
+ bundle = SciProjectStepsConstants.BUNDLE,
+ descriptionKey = "authoringsteps.projectfunding.description",
+ labelKey = "authoringsteps.projectfunding.label",
+ supportedDocumentType = SciProject.class
+)
+public class SciProjectFundingStep extends AbstractMvcAuthoringStep {
+
+ @Inject
+ private SciProjectMessageBundle sciProjectMessageBundle;
+
+ @Inject
+ private AssetRepository assetRepo;
+
+ @Inject
+ private ContentItemRepository itemRepo;
+
+ @Inject
+ private DocumentUi documentUi;
+
+ @Inject
+ private GlobalizationHelper globalizationHelper;
+
+ @Inject
+ private ItemPermissionChecker itemPermissionChecker;
+
+ @Inject
+ private Models models;
+
+ @Inject
+ private SciProjectMananger projectManager;
+
+ @Inject
+ private SciProjectFundingTextModel fundingTextModel;
+
+ @Inject
+ private SciProjectFundingVolumeModel fundingVolumeModel;
+
+ @Inject
+ private SciProjectFundingSponsoringModel sponsoringModel;
+
+ @Override
+ public Class getStepClass() {
+ return SciProjectFundingStep.class;
+ }
+
+ @GET
+ @Path("/")
+ @Transactional(Transactional.TxType.REQUIRED)
+ public String showStep(
+ @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
+ final String sectionIdentifier,
+ @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
+ final String documentPath
+ ) {
+ try {
+ init();
+ } catch (ContentSectionNotFoundException ex) {
+ return ex.showErrorMessage();
+ } catch (DocumentNotFoundException ex) {
+ return ex.showErrorMessage();
+ }
+
+ if (itemPermissionChecker.canEditItem(getProject())) {
+ return "org/scientificcms/contenttypes/sciproject/ui/sciproject-funding.xhtml";
+ } else {
+ return documentUi.showAccessDenied(
+ getContentSection(),
+ getProject(),
+ sciProjectMessageBundle.getMessage("event.edit.denied")
+ );
+ }
+ }
+
+ @GET
+ @Path("/funding-text/view/{locale}")
+ @Transactional(Transactional.TxType.REQUIRED)
+ public String viewFundingText(
+ @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
+ final String sectionIdentifier,
+ @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
+ final String documentPath,
+ @PathParam("locale") final String localeParam
+ ) {
+ try {
+ init();
+ } catch (ContentSectionNotFoundException ex) {
+ return ex.showErrorMessage();
+ } catch (DocumentNotFoundException ex) {
+ return ex.showErrorMessage();
+ }
+
+ if (itemPermissionChecker.canEditItem(getProject())) {
+ fundingTextModel.setSelectedLocale(
+ new Locale(localeParam).toString()
+ );
+
+ return "org/scientificcms/contenttypes/sciproject/ui/sciproject-fundingtext/view.xhtml";
+ } else {
+ return documentUi.showAccessDenied(
+ getContentSection(),
+ getProject(),
+ sciProjectMessageBundle.getMessage("event.edit.denied")
+ );
+ }
+ }
+
+ @POST
+ @Path("/funding-text/add")
+ @Transactional(Transactional.TxType.REQUIRED)
+ public String addFundingTextValue(
+ @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
+ final String sectionIdentifier,
+ @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
+ final String documentPath,
+ @FormParam("locale") final String localeParam
+ ) {
+ try {
+ init();
+ } catch (ContentSectionNotFoundException ex) {
+ return ex.showErrorMessage();
+ } catch (DocumentNotFoundException ex) {
+ return ex.showErrorMessage();
+ }
+
+ if (itemPermissionChecker.canEditItem(getProject())) {
+ final String value;
+ if (getProject().getFunding().getAvailableLocales().isEmpty()) {
+ value = "";
+ } else {
+ value = globalizationHelper.getValueFromLocalizedString(
+ getProject().getFunding()
+ );
+ }
+ final Locale locale = new Locale(localeParam);
+ getProject().getFunding().putValue(locale, value);
+ itemRepo.save(getProject());
+
+ return buildRedirectPathForStep();
+ } else {
+ return documentUi.showAccessDenied(
+ getContentSection(),
+ getProject(),
+ sciProjectMessageBundle.getMessage("event.edit.denied")
+ );
+ }
+ }
+
+ @GET
+ @Path("/funding-text/edit")
+ @Transactional(Transactional.TxType.REQUIRED)
+ public String editFundingTextValue(
+ @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
+ final String sectionIdentifier,
+ @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
+ final String documentPath,
+ @PathParam("locale") final String localeParam
+ ) {
+ try {
+ init();
+ } catch (ContentSectionNotFoundException ex) {
+ return ex.showErrorMessage();
+ } catch (DocumentNotFoundException ex) {
+ return ex.showErrorMessage();
+ }
+
+ if (itemPermissionChecker.canEditItem(getProject())) {
+ fundingTextModel.setSelectedLocale(
+ new Locale(localeParam).toString()
+ );
+
+ return "org/scientificcms/contenttypes/sciproject/ui/sciproject-fundingtext/edit.xhtml";
+ } else {
+ return documentUi.showAccessDenied(
+ getContentSection(),
+ getProject(),
+ sciProjectMessageBundle.getMessage("event.edit.denied")
+ );
+ }
+ }
+
+ @POST
+ @Path("/funding-text/edit/{locale}")
+ @Transactional(Transactional.TxType.REQUIRED)
+ public String editFundingTextValue(
+ @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
+ ) {
+ try {
+ init();
+ } catch (ContentSectionNotFoundException ex) {
+ return ex.showErrorMessage();
+ } catch (DocumentNotFoundException ex) {
+ return ex.showErrorMessage();
+ }
+
+ if (itemPermissionChecker.canEditItem(getProject())) {
+ final Locale locale = new Locale(localeParam);
+ getProject().getFunding().putValue(locale, value);
+ itemRepo.save(getProject());
+
+ return buildRedirectPathForStep();
+ } else {
+ return documentUi.showAccessDenied(
+ getContentSection(),
+ getProject(),
+ sciProjectMessageBundle.getMessage("event.edit.denied")
+ );
+ }
+ }
+
+ @POST
+ @Path("/funding-text/remove/{locale}")
+ @Transactional(Transactional.TxType.REQUIRED)
+ public String removeFundingTextValue(
+ @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
+ final String sectionIdentifier,
+ @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
+ final String documentPath,
+ @PathParam("locale") final String localeParam
+ ) {
+ try {
+ init();
+ } catch (ContentSectionNotFoundException ex) {
+ return ex.showErrorMessage();
+ } catch (DocumentNotFoundException ex) {
+ return ex.showErrorMessage();
+ }
+
+ if (itemPermissionChecker.canEditItem(getProject())) {
+ final Locale locale = new Locale(localeParam);
+ getProject().getFunding().removeValue(locale);
+ itemRepo.save(getProject());
+
+ return buildRedirectPathForStep();
+ } else {
+ return documentUi.showAccessDenied(
+ getContentSection(),
+ getProject(),
+ sciProjectMessageBundle.getMessage("event.edit.denied")
+ );
+ }
+ }
+
+ @GET
+ @Path("/funding-volume/view/{locale}")
+ @Transactional(Transactional.TxType.REQUIRED)
+ public String viewFundingVolume(
+ @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
+ final String sectionIdentifier,
+ @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
+ final String documentPath,
+ @PathParam("locale") final String localeParam
+ ) {
+ try {
+ init();
+ } catch (ContentSectionNotFoundException ex) {
+ return ex.showErrorMessage();
+ } catch (DocumentNotFoundException ex) {
+ return ex.showErrorMessage();
+ }
+
+ if (itemPermissionChecker.canEditItem(getProject())) {
+ fundingVolumeModel.setSelectedLocale(
+ new Locale(localeParam).toString()
+ );
+
+ return "org/scientificcms/contenttypes/sciproject/ui/sciproject-fundingvolume/view.xhtml";
+ } else {
+ return documentUi.showAccessDenied(
+ getContentSection(),
+ getProject(),
+ sciProjectMessageBundle.getMessage("event.edit.denied")
+ );
+ }
+ }
+
+ @POST
+ @Path("/funding-volume/add")
+ @Transactional(Transactional.TxType.REQUIRED)
+ public String addFundingVolumeValue(
+ @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
+ final String sectionIdentifier,
+ @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
+ final String documentPath,
+ @FormParam("locale") final String localeParam
+ ) {
+ try {
+ init();
+ } catch (ContentSectionNotFoundException ex) {
+ return ex.showErrorMessage();
+ } catch (DocumentNotFoundException ex) {
+ return ex.showErrorMessage();
+ }
+
+ if (itemPermissionChecker.canEditItem(getProject())) {
+ final String value;
+ if (getProject().getFundingVolume().getAvailableLocales().isEmpty()) {
+ value = "";
+ } else {
+ value = globalizationHelper.getValueFromLocalizedString(
+ getProject().getFundingVolume()
+ );
+ }
+ final Locale locale = new Locale(localeParam);
+ getProject().getFundingVolume().putValue(locale, value);
+ itemRepo.save(getProject());
+
+ return buildRedirectPathForStep();
+ } else {
+ return documentUi.showAccessDenied(
+ getContentSection(),
+ getProject(),
+ sciProjectMessageBundle.getMessage("event.edit.denied")
+ );
+ }
+ }
+
+ @GET
+ @Path("/funding-volume/edit")
+ @Transactional(Transactional.TxType.REQUIRED)
+ public String editFundingVolumeValue(
+ @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
+ final String sectionIdentifier,
+ @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
+ final String documentPath,
+ @PathParam("locale") final String localeParam
+ ) {
+ try {
+ init();
+ } catch (ContentSectionNotFoundException ex) {
+ return ex.showErrorMessage();
+ } catch (DocumentNotFoundException ex) {
+ return ex.showErrorMessage();
+ }
+
+ if (itemPermissionChecker.canEditItem(getProject())) {
+ fundingVolumeModel.setSelectedLocale(
+ new Locale(localeParam).toString()
+ );
+
+ return "org/scientificcms/contenttypes/sciproject/ui/sciproject-fundingtext/edit.xhtml";
+ } else {
+ return documentUi.showAccessDenied(
+ getContentSection(),
+ getProject(),
+ sciProjectMessageBundle.getMessage("event.edit.denied")
+ );
+ }
+ }
+
+ @POST
+ @Path("/funding-volume/edit/{locale}")
+ @Transactional(Transactional.TxType.REQUIRED)
+ public String editFundingVolumeValue(
+ @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
+ ) {
+ try {
+ init();
+ } catch (ContentSectionNotFoundException ex) {
+ return ex.showErrorMessage();
+ } catch (DocumentNotFoundException ex) {
+ return ex.showErrorMessage();
+ }
+
+ if (itemPermissionChecker.canEditItem(getProject())) {
+ final Locale locale = new Locale(localeParam);
+ getProject().getFundingVolume().putValue(locale, value);
+ itemRepo.save(getProject());
+
+ return buildRedirectPathForStep();
+ } else {
+ return documentUi.showAccessDenied(
+ getContentSection(),
+ getProject(),
+ sciProjectMessageBundle.getMessage("event.edit.denied")
+ );
+ }
+ }
+
+ @POST
+ @Path("/funding-volume/remove/{locale}")
+ @Transactional(Transactional.TxType.REQUIRED)
+ public String removeFundingVolumeValue(
+ @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
+ final String sectionIdentifier,
+ @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
+ final String documentPath,
+ @PathParam("locale") final String localeParam
+ ) {
+ try {
+ init();
+ } catch (ContentSectionNotFoundException ex) {
+ return ex.showErrorMessage();
+ } catch (DocumentNotFoundException ex) {
+ return ex.showErrorMessage();
+ }
+
+ if (itemPermissionChecker.canEditItem(getProject())) {
+ final Locale locale = new Locale(localeParam);
+ getProject().getFundingVolume().removeValue(locale);
+ itemRepo.save(getProject());
+
+ return buildRedirectPathForStep();
+ } else {
+ return documentUi.showAccessDenied(
+ getContentSection(),
+ getProject(),
+ sciProjectMessageBundle.getMessage("event.edit.denied")
+ );
+ }
+ }
+
+ @POST
+ @Path("/sponsoring/add")
+ @Transactional(Transactional.TxType.REQUIRED)
+ public String addSponsoring(
+ @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
+ final String sectionIdentifier,
+ @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
+ final String documentPath,
+ @FormParam("sponsorUuid")
+ final String sponsorUuid,
+ @FormParam("fundingCode")
+ final String fundingCode
+ ) {
+ try {
+ init();
+ } catch (ContentSectionNotFoundException ex) {
+ return ex.showErrorMessage();
+ } catch (DocumentNotFoundException ex) {
+ return ex.showErrorMessage();
+ }
+
+ if (itemPermissionChecker.canEditItem(getProject())) {
+ final Optional result = assetRepo
+ .findByUuidAndType(sponsorUuid, Organization.class);
+
+ if (!result.isPresent()) {
+ models.put("sponsorNotFound", sponsorUuid);
+ return showStep(sectionIdentifier, documentPath);
+ }
+
+ final Organization sponsor = result.get();
+ projectManager.addSponsor(sponsor, getProject(), fundingCode);
+
+ return buildRedirectPathForStep();
+ } else {
+ return documentUi.showAccessDenied(
+ getContentSection(),
+ getProject(),
+ sciProjectMessageBundle.getMessage("event.edit.denied")
+ );
+ }
+ }
+
+ @POST
+ @Path("/sponsoring/remove")
+ @Transactional(Transactional.TxType.REQUIRED)
+ public String removeSponsor(
+ @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
+ final String sectionIdentifier,
+ @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
+ final String documentPath,
+ @FormParam("sponsoringId")
+ final String sponsoringId
+ ) {
+ try {
+ init();
+ } catch (ContentSectionNotFoundException ex) {
+ return ex.showErrorMessage();
+ } catch (DocumentNotFoundException ex) {
+ return ex.showErrorMessage();
+ }
+
+ if (itemPermissionChecker.canEditItem(getProject())) {
+ final Optional result = getProject()
+ .getSponsoring()
+ .stream()
+ .filter(
+ sponsoring -> Long
+ .toString(sponsoring.getSponsoringId())
+ .equals(sponsoringId)
+ )
+ .findFirst();
+
+ if (result.isPresent()) {
+ projectManager.removeSponsor(
+ result.get().getSponsor(),
+ getProject()
+ );
+ }
+
+ return buildRedirectPathForStep();
+ } else {
+ return documentUi.showAccessDenied(
+ getContentSection(),
+ getProject(),
+ sciProjectMessageBundle.getMessage("event.edit.denied")
+ );
+ }
+ }
+
+ @Override
+ public void init() throws ContentSectionNotFoundException,
+ DocumentNotFoundException {
+ super.init();
+
+ final boolean canEdit = itemPermissionChecker.canEditItem(getProject());
+ if (canEdit) {
+ fundingTextModel.setCanEdit(canEdit);
+ fundingTextModel.setFundingTextValues(
+ getProject()
+ .getFunding()
+ .getValues()
+ .entrySet()
+ .stream()
+ .collect(
+ Collectors.toMap(
+ entry -> entry.getKey().toString(),
+ Map.Entry::getValue
+ )
+ )
+ );
+ fundingTextModel.setVariants(
+ getProject()
+ .getFunding()
+ .getValues()
+ .entrySet()
+ .stream()
+ .map(CmsEditorUtil::buildVariantRow)
+ .collect(Collectors.toList())
+ );
+ final Set fundingTextLocales = getProject()
+ .getFunding()
+ .getAvailableLocales();
+ fundingTextModel.setUnusedLocales(
+ globalizationHelper
+ .getAvailableLocales()
+ .stream()
+ .filter(locale -> !fundingTextLocales.contains(locale))
+ .map(Locale::toString)
+ .collect(Collectors.toList())
+ );
+
+ fundingVolumeModel.setCanEdit(canEdit);
+ fundingVolumeModel.setFundingVolumeValues(
+ getProject()
+ .getFundingVolume()
+ .getValues()
+ .entrySet()
+ .stream()
+ .collect(
+ Collectors.toMap(
+ entry -> entry.getKey().toString(),
+ Map.Entry::getValue
+ )
+ )
+ );
+ fundingVolumeModel.setVariants(
+ getProject()
+ .getFundingVolume()
+ .getValues()
+ .entrySet()
+ .stream()
+ .map(CmsEditorUtil::buildVariantRow)
+ .collect(Collectors.toList())
+ );
+ final Set fundingVolumeLocales = getProject()
+ .getProjectDescription()
+ .getAvailableLocales();
+ fundingVolumeModel.setUnusedLocales(
+ globalizationHelper
+ .getAvailableLocales()
+ .stream()
+ .filter(locale -> !fundingVolumeLocales.contains(locale))
+ .map(Locale::toString)
+ .collect(Collectors.toList())
+ );
+
+ sponsoringModel.setCanEdit(canEdit);
+ sponsoringModel.setSponsoring(
+ getProject()
+ .getSponsoring()
+ .stream()
+ .map(this::buildSponsoringModel)
+ .collect(Collectors.toList())
+ );
+ }
+ }
+
+ private SciProject getProject() {
+ return (SciProject) getDocument();
+ }
+
+ private SciProjectSponsoringModel buildSponsoringModel(
+ final Sponsoring sponsoring
+ ) {
+ final SciProjectSponsoringModel model = new SciProjectSponsoringModel();
+ model.setFundingCode(sponsoring.getFundingCode());
+ model.setOrder(sponsoring.getOrder());
+ model.setSponsor(sponsoring.getSponsor().getTitle().getValue(
+ globalizationHelper.getNegotiatedLocale()
+ ));
+ model.setSponsoringId(sponsoring.getSponsoringId());
+
+ return model;
+ }
+
+}
diff --git a/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/ui/SciProjectFundingStepService.java b/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/ui/SciProjectFundingStepService.java
new file mode 100644
index 0000000..0d9b496
--- /dev/null
+++ b/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/ui/SciProjectFundingStepService.java
@@ -0,0 +1,127 @@
+package org.scientificcms.contenttypes.sciproject.ui;
+
+import org.librecms.contentsection.ContentItem;
+import org.librecms.contentsection.ContentItemRepository;
+import org.librecms.contentsection.ContentSection;
+import org.librecms.ui.contentsections.ContentSectionsUi;
+import org.librecms.ui.contentsections.documents.MvcAuthoringSteps;
+import org.scientificcms.contenttypes.sciproject.SciProject;
+import org.scientificcms.contenttypes.sciproject.Sponsoring;
+import org.scientificcms.contenttypes.sciproject.SponsoringRepository;
+
+import java.util.List;
+
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Inject;
+import javax.transaction.Transactional;
+import javax.ws.rs.BadRequestException;
+import javax.ws.rs.NotFoundException;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.core.Response;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@RequestScoped
+@Path(MvcAuthoringSteps.PATH_PREFIX + "sciproject-funding-service")
+public class SciProjectFundingStepService {
+
+ @Inject
+ private SponsoringRepository sponsoringRepo;
+
+ @Inject
+ private ContentItemRepository itemRepo;
+
+ @Inject
+ private ContentSectionsUi sectionsUi;
+
+ @POST
+ @Path("/sponsoring/save-order")
+ @Transactional(Transactional.TxType.REQUIRED)
+ public Response saveSponsoringOrder(
+ @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
+ final String sectionIdentifier,
+ @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
+ final String documentPath,
+ final List sponsoringOrder
+ ) {
+ final ContentSection contentSection = sectionsUi
+ .findContentSection(sectionIdentifier)
+ .orElseThrow(
+ () -> new NotFoundException(
+ String.format(
+ "No content identifed by %s found.",
+ sectionIdentifier
+ )
+ )
+ );
+
+ final ContentItem document = itemRepo
+ .findByPath(contentSection, documentPath)
+ .orElseThrow(
+ () -> new NotFoundException(
+ String.format(
+ "No document for path %s in section %s.",
+ documentPath,
+ contentSection.getLabel()
+ )
+ )
+ );
+
+ if ((document instanceof SciProject)) {
+ throw new BadRequestException(
+ String.format(
+ "Document %s is not a %s.",
+ documentPath,
+ SciProject.class.getSimpleName()
+ )
+ );
+ }
+
+ final SciProject project = (SciProject) document;
+
+ final List sponsorings = project.getSponsoring();
+
+ if (sponsoringOrder.size() != sponsorings.size()) {
+ throw new BadRequestException(
+ String.format(
+ "Number of sponsorings of the SciProject %s does "
+ + "not match the number of values in the order "
+ + "list. Number of sponsoringas: %d, number of values in "
+ + "the sponsorings order list: %d",
+ documentPath,
+ sponsorings.size(),
+ sponsoringOrder.size()
+ )
+ );
+ }
+
+ for (int i = 0; i < sponsoringOrder.size(); i++) {
+ final String sponsoringIdParam = sponsoringOrder.get(i);
+ final long sponsoringId = Long.parseLong(sponsoringIdParam);
+ final Sponsoring sponsoring = sponsorings
+ .stream()
+ .filter(sponsor -> sponsor.getSponsoringId() == sponsoringId)
+ .findAny()
+ .orElseThrow(
+ () -> new BadRequestException(
+ String.format(
+ "sponsoringsOrder has an entry for sponsoring with "
+ + "ID %d, but there is not sponsoring with that "
+ + "ID.",
+ sponsoringId
+ )
+ )
+ );
+
+ sponsoring.setOrder(i);
+ sponsoringRepo.save(sponsoring);
+ }
+
+ return Response.ok().build();
+ }
+
+}
diff --git a/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/ui/SciProjectFundingTextModel.java b/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/ui/SciProjectFundingTextModel.java
index 1d6666c..bef4065 100644
--- a/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/ui/SciProjectFundingTextModel.java
+++ b/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/ui/SciProjectFundingTextModel.java
@@ -37,7 +37,7 @@ public class SciProjectFundingTextModel {
.orElse(Collections.emptyMap());
}
- protected void setFundingValues(
+ protected void setFundingTextValues(
final Map fundingValues
) {
this.fundingValues = Optional
diff --git a/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/ui/SciProjectSponsoringModel.java b/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/ui/SciProjectSponsoringModel.java
new file mode 100644
index 0000000..2a4e208
--- /dev/null
+++ b/sci-types-project/src/main/java/org/scientificcms/contenttypes/sciproject/ui/SciProjectSponsoringModel.java
@@ -0,0 +1,51 @@
+package org.scientificcms.contenttypes.sciproject.ui;
+
+/**
+ * DTO providing the information about a {@link Sponsoring} of a
+ * {@link SciProject} in an form that easy usable from a MVC template.
+ *
+ * @author Jens Pelzetter
+ */
+public class SciProjectSponsoringModel {
+
+ private long sponsoringId;
+
+ private String fundingCode;
+
+ private long order;
+
+ private String sponsor;
+
+ public long getSponsoringId() {
+ return sponsoringId;
+ }
+
+ public void setSponsoringId(final long sponsoringId) {
+ this.sponsoringId = sponsoringId;
+ }
+
+ public String getFundingCode() {
+ return fundingCode;
+ }
+
+ public void setFundingCode(final String fundingCode) {
+ this.fundingCode = fundingCode;
+ }
+
+ public long getOrder() {
+ return order;
+ }
+
+ public void setOrder(final long order) {
+ this.order = order;
+ }
+
+ public String getSponsor() {
+ return sponsor;
+ }
+
+ public void setSponsor(final String sponsor) {
+ this.sponsor = sponsor;
+ }
+
+}