diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/PersonFormController.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/PersonFormController.java index 43277e35c..07ac21250 100644 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/PersonFormController.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/PersonFormController.java @@ -161,25 +161,23 @@ public class PersonFormController final String suffix = (String) data.get(SUFFIX); if (asset.getPersonName() == null) { - personManager.addPersonName(asset); + final PersonName personName = new PersonName(); + personName.setGivenName(givenName); + personName.setSuffix(suffix); + personName.setPrefix(prefix); + personName.setSurname(surname); + personManager.addPersonName(asset, personName); } - - asset.getPersonName().setSurname(surname); - asset.getPersonName().setGivenName(givenName); - asset.getPersonName().setPrefix(prefix); - asset.getPersonName().setSuffix(suffix); - } @Transactional(Transactional.TxType.REQUIRED) public void addPersonName(final long personId) { - final Person person = personRepository .findById(personId) .orElseThrow(() -> new IllegalArgumentException(String.format( "No Person with ID %d found.", personId))); - personManager.addPersonName(person); + personManager.addPersonName(person, new PersonName()); } } diff --git a/ccm-cms/src/main/java/org/librecms/assets/ContactEntryKey.java b/ccm-cms/src/main/java/org/librecms/assets/ContactEntryKey.java index bc22d943a..f9113fa6b 100644 --- a/ccm-cms/src/main/java/org/librecms/assets/ContactEntryKey.java +++ b/ccm-cms/src/main/java/org/librecms/assets/ContactEntryKey.java @@ -65,11 +65,12 @@ public class ContactEntryKey @Embedded @AssociationOverride( name = "values", - joinTable = @JoinTable(name = "CONTACT_ENTRY_KEY_LABELS", - schema = DB_SCHEMA, - joinColumns = { - @JoinColumn(name = "KEY_ID") - } + joinTable = @JoinTable( + name = "CONTACT_ENTRY_KEY_LABELS", + schema = DB_SCHEMA, + joinColumns = { + @JoinColumn(name = "KEY_ID") + } ) ) private LocalizedString label; @@ -104,10 +105,10 @@ public class ContactEntryKey this.label = Objects.requireNonNull(label); } - + @Override public int compareTo(final ContactEntryKey other) { - + return entryKey.compareTo(other.getEntryKey()); } diff --git a/ccm-cms/src/main/java/org/librecms/assets/ContactableEntityManager.java b/ccm-cms/src/main/java/org/librecms/assets/ContactableEntityManager.java index b1eecdf63..b5d0f78e3 100644 --- a/ccm-cms/src/main/java/org/librecms/assets/ContactableEntityManager.java +++ b/ccm-cms/src/main/java/org/librecms/assets/ContactableEntityManager.java @@ -65,6 +65,7 @@ public class ContactableEntityManager { contactableEntity.setPostalAddress(postalAddress); assetRepository.save(postalAddress); + assetRepository.save(contactableEntity); } public void removePostalAddressFromContactableEntity( @@ -73,6 +74,7 @@ public class ContactableEntityManager { contactableEntity.setPostalAddress(null); assetRepository.save(postalAddress); + assetRepository.save(contactableEntity); } } diff --git a/ccm-cms/src/main/java/org/librecms/assets/Person.java b/ccm-cms/src/main/java/org/librecms/assets/Person.java index f715f57c3..550c73977 100644 --- a/ccm-cms/src/main/java/org/librecms/assets/Person.java +++ b/ccm-cms/src/main/java/org/librecms/assets/Person.java @@ -21,6 +21,9 @@ package org.librecms.assets; import com.arsdigita.cms.ui.assets.forms.PersonForm; import org.hibernate.envers.Audited; +import org.librecms.ui.contentsections.assets.MvcAssetEditKit; +import org.librecms.ui.contentsections.assets.PersonCreateStep; +import org.librecms.ui.contentsections.assets.PersonEditStep; import java.time.LocalDate; import java.util.ArrayList; @@ -46,11 +49,17 @@ import static org.librecms.assets.AssetConstants.*; @Entity @Table(name = "PERSONS", schema = DB_SCHEMA) @Audited -@AssetType(assetForm = PersonForm.class, +@AssetType( + assetForm = PersonForm.class, labelBundle = ASSETS_BUNDLE, labelKey = "person.label", descriptionBundle = ASSETS_BUNDLE, - descriptionKey = "person.description") + descriptionKey = "person.description" +) +@MvcAssetEditKit( + createStep = PersonCreateStep.class, + editStep = PersonEditStep.class +) public class Person extends ContactableEntity { private static final long serialVersionUID = 1L; diff --git a/ccm-cms/src/main/java/org/librecms/assets/PersonManager.java b/ccm-cms/src/main/java/org/librecms/assets/PersonManager.java index ee9a3d9a8..52151021f 100644 --- a/ccm-cms/src/main/java/org/librecms/assets/PersonManager.java +++ b/ccm-cms/src/main/java/org/librecms/assets/PersonManager.java @@ -18,7 +18,6 @@ */ package org.librecms.assets; -import java.util.Objects; import javax.enterprise.context.RequestScoped; import javax.inject.Inject; @@ -35,17 +34,19 @@ public class PersonManager { private PersonRepository personRepository; @Transactional(Transactional.TxType.REQUIRED) - public void addPersonName(final Person toPerson) { - - final PersonName current = Objects - .requireNonNull(toPerson, "Can't add a name to Person null.") - .getPersonName(); - - if (current == null) { - toPerson.addPersonName(new PersonName()); - } else { - toPerson.addPersonName(current); - } + public void addPersonName( + final Person toPerson, final PersonName personName + ) { +// final PersonName current = Objects +// .requireNonNull(toPerson, "Can't add a name to Person null.") +// .getPersonName(); +// +// if (current == null) { +// toPerson.addPersonName(new PersonName()); +// } else { +// toPerson.addPersonName(current); +// } + toPerson.addPersonName(personName); personRepository.save(toPerson); } diff --git a/ccm-cms/src/main/java/org/librecms/contentsection/AssetRepository.java b/ccm-cms/src/main/java/org/librecms/contentsection/AssetRepository.java index 67eaf2f46..d5522c261 100644 --- a/ccm-cms/src/main/java/org/librecms/contentsection/AssetRepository.java +++ b/ccm-cms/src/main/java/org/librecms/contentsection/AssetRepository.java @@ -262,9 +262,10 @@ public class AssetRepository } /** - * Finds an {@link Asset} by its UUID and type. This method - * does not distinguish between shared and non shared assets. + * Finds an {@link Asset} by its UUID and type.This method + does not distinguish between shared and non shared assets. * + * @param Type of the asset * @param uuid The UUID of the asset to retrieve. * @param type The type of the asset to retrieve. * @@ -274,8 +275,9 @@ public class AssetRepository * {@link Optional} is returned. */ @Transactional(Transactional.TxType.REQUIRED) - public Optional findByUuidAndType( - final String uuid, final Class extends Asset> type) { + @SuppressWarnings("unchecked") + public Optional findByUuidAndType( + final String uuid, final Class type) { final TypedQuery query = entityManager.createNamedQuery( "Asset.findByUuidAndType", Asset.class); @@ -284,7 +286,11 @@ public class AssetRepository setAuthorizationParameters(query); try { - return Optional.of(query.getSingleResult()); + final Asset result = query.getSingleResult(); + if (result.getClass().isAssignableFrom(type)) { + return Optional.of((T) result); + } + return Optional.empty(); } catch (NoResultException ex) { return Optional.empty(); } diff --git a/ccm-cms/src/main/java/org/librecms/contentsection/rs/Assets.java b/ccm-cms/src/main/java/org/librecms/contentsection/rs/Assets.java index 66c01f318..2663d7349 100644 --- a/ccm-cms/src/main/java/org/librecms/contentsection/rs/Assets.java +++ b/ccm-cms/src/main/java/org/librecms/contentsection/rs/Assets.java @@ -53,6 +53,7 @@ import javax.json.JsonObject; import javax.json.JsonObjectBuilder; import javax.json.JsonWriter; import javax.transaction.Transactional; +import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; import javax.ws.rs.NotFoundException; import javax.ws.rs.Path; @@ -115,7 +116,7 @@ public class Assets { @Transactional(Transactional.TxType.REQUIRED) public String findAssets( @PathParam("content-section") final String section, - @QueryParam("query") final String query, + @QueryParam("query") @DefaultValue("") final String query, @QueryParam("type") final String type) { final ContentSection contentSection = sectionRepo diff --git a/ccm-cms/src/main/java/org/librecms/contentsection/rs/Images.java b/ccm-cms/src/main/java/org/librecms/contentsection/rs/Images.java index 220e5bf06..9f0ca3c88 100644 --- a/ccm-cms/src/main/java/org/librecms/contentsection/rs/Images.java +++ b/ccm-cms/src/main/java/org/librecms/contentsection/rs/Images.java @@ -76,21 +76,11 @@ public class Images { @DefaultValue("-1") final String heightParam) { - final Optional asset = assetRepo + final Optional asset = assetRepo .findByUuidAndType(uuid, Image.class); if (asset.isPresent()) { - if (asset.get() instanceof Image) { - return loadImage((Image) asset.get(), widthParam, heightParam); - } else { - return Response - .status(Response.Status.NOT_FOUND) - .entity(String - .format("The asset with the requested UUID \"%s\" " - + "is not an image.", - uuid)) - .build(); - } + return loadImage(asset.get(), widthParam, heightParam); } else { return Response .status(Response.Status.NOT_FOUND) @@ -107,21 +97,12 @@ public class Images { @PathParam("content-section") final String sectionName, @PathParam("uuid") final String uuid) { - final Optional asset = assetRepo.findByUuidAndType(uuid, - Image.class); + final Optional asset = assetRepo.findByUuidAndType( + uuid, Image.class + ); if (asset.isPresent()) { - if (asset.get() instanceof Image) { - return readImageProperties((Image) asset.get()); - } else { - return Response - .status(Response.Status.NOT_FOUND) - .entity(String - .format("The asset with the requested UUID \"%s\" " - + "is not an image.", - uuid)) - .build(); - } + return readImageProperties(asset.get()); } else { return Response .status(Response.Status.NOT_FOUND) @@ -319,7 +300,7 @@ public class Images { height); final ByteArrayOutputStream outputStream - = new ByteArrayOutputStream(); + = new ByteArrayOutputStream(); final BufferedImage bufferedScaledImage = new BufferedImage( scaledImage.getWidth(null), scaledImage.getHeight(null), diff --git a/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/AbstractContactableEntityEditStep.java b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/AbstractContactableEntityEditStep.java new file mode 100644 index 000000000..74b8f5e8a --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/AbstractContactableEntityEditStep.java @@ -0,0 +1,305 @@ +/* + * 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.assets; + +import org.libreccm.api.Identifier; +import org.libreccm.api.IdentifierParser; +import org.libreccm.l10n.GlobalizationHelper; +import org.libreccm.security.AuthorizationRequired; +import org.librecms.assets.ContactEntry; +import org.librecms.assets.ContactEntryKey; +import org.librecms.assets.ContactEntryKeyRepository; +import org.librecms.assets.ContactEntryRepository; +import org.librecms.assets.ContactableEntity; +import org.librecms.assets.ContactableEntityManager; +import org.librecms.assets.PostalAddress; +import org.librecms.contentsection.Asset; +import org.librecms.contentsection.AssetRepository; +import org.librecms.ui.contentsections.ContentSectionNotFoundException; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import javax.inject.Inject; +import javax.mvc.Models; +import javax.transaction.Transactional; +import javax.ws.rs.FormParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; + +/** + * + * @author Jens Pelzetter + */ +public abstract class AbstractContactableEntityEditStep + extends AbstractMvcAssetEditStep { + + @Inject + private AssetRepository assetRepo; + + @Inject + private AssetUi assetUi; + + @Inject + private ContactEntryRepository entryRepo; + + @Inject + private ContactEntryKeyRepository entryKeyRepo; + + @Inject + private ContactableEntityManager contactableManager; + + @Inject + private ContactableEntityEditStepModel editStepModel; + + @Inject + private GlobalizationHelper globalizationHelper; + + @Inject + private IdentifierParser identifierParser; + + @Inject + private Models models; + + @Override + @Transactional(Transactional.TxType.REQUIRED) + protected void init() throws ContentSectionNotFoundException, + AssetNotFoundException { + super.init(); + + if (getAsset() instanceof ContactableEntity) { + editStepModel + .setAvailableContactEntryKeys( + entryKeyRepo + .findAll() + .stream() + .map(this::buildContactEntryKeyListItemModel) + .collect( + Collectors.toMap( + item -> item.getEntryKey(), + item -> item.getLabel() + ) + ) + ); + editStepModel + .setContactEntries( + getContactableEntity() + .getContactEntries() + .stream() + .map(this::buildContactEntryListItemModel) + .collect(Collectors.toList()) + ); + editStepModel.setPostalAddress( + getContactableEntity().getPostalAddress() + ); + } else { + throw new AssetNotFoundException( + assetUi.showAssetNotFound( + getContentSection(), getAssetPath() + ), + String.format( + "No ContactableEntity for path %s found in section %s.", + getAssetPath(), + getContentSection().getLabel() + ) + ); + } + } + + protected ContactableEntity getContactableEntity() { + return (ContactableEntity) getAsset(); + } + + @POST + @Path("/contactentries") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + public String addContactEntry( + @FormParam("entryKey") final String entryKeyParam, + @FormParam("entryValue") final String entryValue + ) { + final Optional entryKeyResult = entryKeyRepo + .findByEntryKey(entryKeyParam); + if (!entryKeyResult.isPresent()) { + return showContactEntryKeyNoFound(entryKeyParam); + } + final ContactEntryKey entryKey = entryKeyResult.get(); + + final ContactableEntity contactable = getContactableEntity(); + final ContactEntry contactEntry = new ContactEntry(); + contactEntry.setKey(entryKey); + contactEntry.setValue(entryValue); + contactableManager.addContactEntryToContactableEntity( + contactEntry, contactable + ); + + return buildRedirectPathForStep(); + } + + @POST + @Path("/contactentries/{index}") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + public String updateContactEntry( + @PathParam("index") final int index, + @FormParam("entryValue") final String entryValue + ) { + final List entries = getContactableEntity() + .getContactEntries(); + if (index >= entries.size()) { + return showContactEntryNotFound(index); + } + + final ContactEntry entry = entries.get(index); + entry.setValue(entryValue); + + entryRepo.save(entry); + + return buildRedirectPathForStep(); + } + + @POST + @Path("/contactentries/{index}/@remove") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + public String removeContactEntry( + @PathParam("index") final int index + ) { + final List entries = getContactableEntity() + .getContactEntries(); + if (index >= entries.size()) { + return showContactEntryNotFound(index); + } + final ContactEntry entry = entries.get(index); + + contactableManager.removeContactEntryFromContactableEntity( + entry, getContactableEntity() + ); + + return buildRedirectPathForStep(); + } + + @POST + @Path("/postaladdress") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + public String setPostalAddress( + final String postalAddressIdentifier + ) { + final Identifier identifier = identifierParser + .parseIdentifier(postalAddressIdentifier); + final Optional postalAddressResult; + switch (identifier.getType()) { + case ID: + postalAddressResult = assetRepo.findById( + Long.parseLong(identifier.getIdentifier()), + PostalAddress.class + ); + break; + case UUID: + postalAddressResult = assetRepo.findByUuidAndType( + identifier.getIdentifier(), + PostalAddress.class + ); + break; + default: + postalAddressResult = assetRepo + .findByPath(identifier.getIdentifier()) + .map(result -> (PostalAddress) result); + break; + } + if (!postalAddressResult.isPresent()) { + return showPostalAddressNotFound(postalAddressIdentifier); + } + final PostalAddress postalAddress = postalAddressResult.get(); + + contactableManager.addPostalAddressToContactableEntity( + postalAddress, getContactableEntity() + ); + + return buildRedirectPathForStep(); + } + + @POST + @Path("/postaladdress/@remove") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + public String removePostalAddress() { + contactableManager.removePostalAddressFromContactableEntity( + getContactableEntity().getPostalAddress(), getContactableEntity() + ); + + return buildRedirectPathForStep(); + } + + private String showContactEntryNotFound( + final int index + ) { + models.put("entryIndex", index); + return "org/librecms/ui/contentsection/assets/contactable/entry-not-found.xhtml"; + } + + private String showContactEntryKeyNoFound(final String entryKeyParam) { + models.put("entryKeyParam", entryKeyParam); + return "org/librecms/ui/contentsection/assets/contactable/entry-key-not-found.xhtml"; + } + + private String showPostalAddressNotFound( + final String postalAddressIdentifier + ) { + models.put("postalAddressIdentifier", postalAddressIdentifier); + return "org/librecms/ui/contentsection/assets/contactable/postal-address-not-found.xhtml"; + } + + private ContactEntryKeyListItemModel buildContactEntryKeyListItemModel( + final ContactEntryKey entryKey + ) { + final ContactEntryKeyListItemModel model + = new ContactEntryKeyListItemModel(); + model.setKeyId(entryKey.getKeyId()); + model.setEntryKey(entryKey.getEntryKey()); + model.setLabel( + globalizationHelper.getValueFromLocalizedString( + entryKey.getLabel()) + ); + + return model; + } + + private ContactEntryListItemModel buildContactEntryListItemModel( + final ContactEntry entry + ) { + final ContactEntryListItemModel model = new ContactEntryListItemModel(); + model.setContactEntryId(entry.getContactEntryId()); + model.setEntryKey(entry.getKey().getEntryKey()); + model.setEntryKeyId(entry.getKey().getKeyId()); + model.setEntryKeyLabel( + globalizationHelper.getValueFromLocalizedString( + entry.getKey().getLabel() + ) + ); + model.setOrder(entry.getOrder()); + model.setValue(entry.getValue()); + + return model; + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/ContactEntryKeyListItemModel.java b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/ContactEntryKeyListItemModel.java new file mode 100644 index 000000000..70f39273d --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/ContactEntryKeyListItemModel.java @@ -0,0 +1,59 @@ +/* + * 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.assets; + +/** + * + * @author Jens Pelzetter + */ +public class ContactEntryKeyListItemModel { + + private long keyId; + + private String entryKey; + + private String label; + + public long getKeyId() { + return keyId; + } + + protected void setKeyId(final long keyId) { + this.keyId = keyId; + } + + public String getEntryKey() { + return entryKey; + } + + protected void setEntryKey(final String entryKey) { + this.entryKey = entryKey; + } + + public String getLabel() { + return label; + } + + protected void setLabel(final String label) { + this.label = label; + } + + + +} diff --git a/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/ContactEntryListItemModel.java b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/ContactEntryListItemModel.java new file mode 100644 index 000000000..39da2eae5 --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/ContactEntryListItemModel.java @@ -0,0 +1,87 @@ +/* + * 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.assets; + +/** + * + * @author Jens Pelzetter + */ +public class ContactEntryListItemModel { + + private long contactEntryId; + + private long order; + + private long entryKeyId; + + private String entryKey; + + private String entryKeyLabel; + + private String value; + + public long getContactEntryId() { + return contactEntryId; + } + + protected void setContactEntryId(final long contactEntryId) { + this.contactEntryId = contactEntryId; + } + + public long getOrder() { + return order; + } + + protected void setOrder(final long order) { + this.order = order; + } + + public long getEntryKeyId() { + return entryKeyId; + } + + protected void setEntryKeyId(final long entryKeyId) { + this.entryKeyId = entryKeyId; + } + + public String getEntryKey() { + return entryKey; + } + + protected void setEntryKey(final String entryKey) { + this.entryKey = entryKey; + } + + public String getEntryKeyLabel() { + return entryKeyLabel; + } + + protected void setEntryKeyLabel(final String entryKeyLabel) { + this.entryKeyLabel = entryKeyLabel; + } + + public String getValue() { + return value; + } + + protected void setValue(final String value) { + this.value = value; + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/ContactableEntityEditStepModel.java b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/ContactableEntityEditStepModel.java new file mode 100644 index 000000000..07e84b0f8 --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/ContactableEntityEditStepModel.java @@ -0,0 +1,76 @@ +/* + * 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.assets; + +import org.librecms.assets.PostalAddress; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Named; + +/** + * + * @author Jens Pelzetter + */ +@RequestScoped +@Named("CmsContactableEditStepModel") +public class ContactableEntityEditStepModel { + + private Map availableContactEntryKeys; + + private List contactEntries; + + private PostalAddress postalAddress; + + public Map getAvailableContactEntryKeys() { + return Collections.unmodifiableMap(availableContactEntryKeys); + } + + public void setAvailableContactEntryKeys( + final Map availableContactEntryKeys + ) { + this.availableContactEntryKeys = new HashMap<>( + availableContactEntryKeys + ); + } + + public List getContactEntries() { + return Collections.unmodifiableList(contactEntries); + } + + protected void setContactEntries( + final List contactEntries + ) { + this.contactEntries = new ArrayList<>(contactEntries); + } + + public PostalAddress getPostalAddress() { + return postalAddress; + } + + protected void setPostalAddress(final PostalAddress postalAddress) { + this.postalAddress = postalAddress; + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/FileAssetEditStep.java b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/FileAssetEditStep.java index 766038b51..c0b8bb39c 100644 --- a/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/FileAssetEditStep.java +++ b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/FileAssetEditStep.java @@ -29,18 +29,14 @@ import org.librecms.contentsection.AssetRepository; import org.librecms.ui.contentsections.AssetPermissionsChecker; import org.librecms.ui.contentsections.ContentSectionNotFoundException; -import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; -import java.net.URLConnection; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Optional; import java.util.Set; -import java.util.logging.Level; import java.util.stream.Collectors; import javax.activation.MimeType; diff --git a/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/PersonCreateStep.java b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/PersonCreateStep.java new file mode 100644 index 000000000..34cc419c8 --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/PersonCreateStep.java @@ -0,0 +1,88 @@ +/* + * 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.assets; + +import org.libreccm.l10n.GlobalizationHelper; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Named; + +import org.librecms.assets.Person; +import org.librecms.contentsection.AssetRepository; + +import java.util.Map; + +import javax.inject.Inject; + +/** + * + * @author Jens Pelzetter + */ +@RequestScoped +@Named("CmsPersonCreateStep") +public class PersonCreateStep extends AbstractMvcAssetCreateStep { + + @Inject + private AssetRepository assetRepo; + + @Inject + private GlobalizationHelper globalizationHelper; + + @Override + public String showCreateStep() { + return "org/librecms/ui/contentsection/assets/person/create-person.xhtml"; + } + + @Override + public String getLabel() { + return globalizationHelper + .getLocalizedTextsUtil(getBundle()) + .getText("person.label"); + } + + @Override + public String getDescription() { + return globalizationHelper + .getLocalizedTextsUtil(getBundle()) + .getText("person.description"); + } + + @Override + public String getBundle() { + return MvcAssetStepsConstants.BUNDLE; + } + + @Override + protected Class getAssetClass() { + return Person.class; + } + + @Override + protected String setAssetProperties( + final Person person, final Map formParams + ) { + return String.format( + "redirect:/%s/assets/%s/%s/@person-edit", + getContentSectionLabel(), + getFolderPath(), + getName() + ); + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/PersonEditStep.java b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/PersonEditStep.java new file mode 100644 index 000000000..5e2b35989 --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/PersonEditStep.java @@ -0,0 +1,265 @@ +/* + * 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.assets; + +import org.libreccm.l10n.GlobalizationHelper; +import org.libreccm.security.AuthorizationRequired; +import org.librecms.assets.Person; +import org.librecms.assets.PersonManager; +import org.librecms.assets.PersonName; +import org.librecms.contentsection.AssetRepository; +import org.librecms.ui.contentsections.AssetPermissionsChecker; +import org.librecms.ui.contentsections.ContentSectionNotFoundException; + +import java.time.format.DateTimeFormatter; +import java.time.format.FormatStyle; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.mvc.Controller; +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(MvcAssetEditSteps.PATH_PREFIX + "person-edit") +@Controller +@MvcAssetEditStepDef( + bundle = MvcAssetStepsConstants.BUNDLE, + descriptionKey = "person.editstep.description", + labelKey = "person.editstep.lable", + supportedAssetType = Person.class +) +public class PersonEditStep extends AbstractContactableEntityEditStep { + + @Inject + private AssetStepsDefaultMessagesBundle messageBundle; + + @Inject + private AssetPermissionsChecker assetPermissionsChecker; + + @Inject + private AssetRepository assetRepo; + + @Inject + private AssetUi assetUi; + + @Inject + private GlobalizationHelper globalizationHelper; + + @Inject + private PersonEditStepModel editStepModel; + + @Inject + private PersonManager personManager; + + @Override + public Class extends MvcAssetEditStep> getStepClass() { + return PersonEditStep.class; + } + + protected Person getPerson() { + return (Person) getAsset(); + } + + @Override + protected void init() throws ContentSectionNotFoundException, + AssetNotFoundException { + super.init(); + + if (getAsset() instanceof Person) { + editStepModel.setBirthdate( + DateTimeFormatter + .ofLocalizedDate(FormatStyle.SHORT) + .withLocale(globalizationHelper.getNegotiatedLocale()) + .format(getPerson().getBirthdate()) + ); + editStepModel.setPersonNames(getPerson().getPersonNames()); + } else { + throw new AssetNotFoundException( + assetUi.showAssetNotFound( + getContentSection(), getAssetPath() + ), + String.format( + "No Person for path %s found in section %s.", + getAssetPath(), + getContentSection().getLabel() + ) + ); + } + } + + @GET + @Path("/") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + @Override + public String showStep( + @PathParam(MvcAssetEditSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME) + final String assetPath + ) { + try { + init(); + } catch (ContentSectionNotFoundException ex) { + return ex.showErrorMessage(); + } catch (AssetNotFoundException ex) { + return ex.showErrorMessage(); + } + + if (assetPermissionsChecker.canEditAsset(getAsset())) { + return "org/librecms/ui/contentsection/assets/person/edit-person.xhtml"; + } else { + return assetUi.showAccessDenied( + getContentSection(), + getAsset(), + messageBundle.get("asset.edit.denied")); + } + } + + @POST + @Path("/personnames/@add") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + public String addPersonName( + @PathParam(MvcAssetEditSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME) + final String assetPath, + @FormParam("surname") final String surname, + @FormParam("givenName") final String givenName, + @FormParam("prefix") final String prefix, + @FormParam("suffix") final String suffix + ) { + try { + init(); + } catch (ContentSectionNotFoundException ex) { + return ex.showErrorMessage(); + } catch (AssetNotFoundException ex) { + return ex.showErrorMessage(); + } + + if (assetPermissionsChecker.canEditAsset(getAsset())) { + final PersonName personName = new PersonName(); + personName.setGivenName(givenName); + personName.setPrefix(prefix); + personName.setSuffix(suffix); + personName.setSurname(surname); + personManager.addPersonName(getPerson(), personName); + + return buildRedirectPathForStep(); + } else { + return assetUi.showAccessDenied( + getContentSection(), + getAsset(), + messageBundle.get("asset.edit.denied")); + } + } + + @POST + @Path("/personnames/{index}/@edit") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + public String updatePersonName( + @PathParam(MvcAssetEditSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME) + final String assetPath, + @PathParam("index") final int index, + @FormParam("surname") final String surname, + @FormParam("givenName") final String givenName, + @FormParam("prefix") final String prefix, + @FormParam("suffix") final String suffix + ) { + try { + init(); + } catch (ContentSectionNotFoundException ex) { + return ex.showErrorMessage(); + } catch (AssetNotFoundException ex) { + return ex.showErrorMessage(); + } + + if (assetPermissionsChecker.canEditAsset(getAsset())) { + if (index < getPerson().getPersonNames().size()) { + final PersonName personName = getPerson() + .getPersonNames() + .get(index); + + personName.setGivenName(givenName); + personName.setPrefix(prefix); + personName.setSuffix(suffix); + personName.setSurname(surname); + + assetRepo.save(getPerson()); + } + + return buildRedirectPathForStep(); + } else { + return assetUi.showAccessDenied( + getContentSection(), + getAsset(), + messageBundle.get("asset.edit.denied")); + } + } + + @POST + @Path("/personnames/{index}/@remove") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + public String removePersonName( + @PathParam(MvcAssetEditSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME) + final String assetPath, + @PathParam("index") final int index + ) { + try { + init(); + } catch (ContentSectionNotFoundException ex) { + return ex.showErrorMessage(); + } catch (AssetNotFoundException ex) { + return ex.showErrorMessage(); + } + + if (assetPermissionsChecker.canEditAsset(getAsset())) { + if (index < getPerson().getPersonNames().size()) { + final PersonName personName = getPerson() + .getPersonNames() + .get(index); + personManager.removePersonName(getPerson(), personName); + } + + return buildRedirectPathForStep(); + } else { + return assetUi.showAccessDenied( + getContentSection(), + getAsset(), + messageBundle.get("asset.edit.denied")); + } + } + +} diff --git a/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/PersonEditStepModel.java b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/PersonEditStepModel.java new file mode 100644 index 000000000..bf55ca30d --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/PersonEditStepModel.java @@ -0,0 +1,58 @@ +/* + * 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.assets; + +import org.librecms.assets.PersonName; + +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("CmsPersonEditStepModel") +public class PersonEditStepModel { + + private List personName; + + private String birthdate; + + public List getPersonNames() { + return Collections.unmodifiableList(personName); + } + + protected void setPersonNames(final List personNames) { + this.personName = new ArrayList<>(personNames); + } + + public String getBirthdate() { + return birthdate; + } + + protected void setBirthdate(final String birthdate) { + this.birthdate = birthdate; + } + +} diff --git a/ccm-cms/src/main/resources/META-INF/resources/components/librecms/assetPicker.xhtml b/ccm-cms/src/main/resources/META-INF/resources/components/librecms/assetPicker.xhtml new file mode 100644 index 000000000..8b71165a1 --- /dev/null +++ b/ccm-cms/src/main/resources/META-INF/resources/components/librecms/assetPicker.xhtml @@ -0,0 +1,145 @@ +]> + + + + + + + + + + + + + + + + + + + + #{cc.attrs.dialogTitle} + + + #{cc.attrs.dialogTitle} + + + #{cc.attrs.dialogTitle} + + + #{cc.attrs.dialogTitle} + + + #{cc.attrs.dialogTitle} + + + #{cc.attrs.dialogTitle} + + + #{cc.attrs.dialogTitle} + + + + + + + + + + + + + + + + #{CmsAssetsStepsDefaultMessagesBundle['assetpicker.select']} + + + + + + + + #{CmsAssetsStepsDefaultMessagesBundle['assetpicker.column.name']} + #{CmsAssetsStepsDefaultMessagesBundle['assetpicker.column.type']} + #{CmsAssetsStepsDefaultMessagesBundle['assetpicker.column.action']} + + + + + + + + + + + + + + + + + diff --git a/ccm-cms/src/main/resources/META-INF/resources/components/librecms/assetPickerButton.xhtml b/ccm-cms/src/main/resources/META-INF/resources/components/librecms/assetPickerButton.xhtml new file mode 100644 index 000000000..bd41bcc7e --- /dev/null +++ b/ccm-cms/src/main/resources/META-INF/resources/components/librecms/assetPickerButton.xhtml @@ -0,0 +1,21 @@ +]> + + + + + + + + + + + diff --git a/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/assets/bookmark/create-bookmark.xhtml b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/assets/bookmark/create-bookmark.xhtml index 62bfc4f11..00054a480 100644 --- a/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/assets/bookmark/create-bookmark.xhtml +++ b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/assets/bookmark/create-bookmark.xhtml @@ -5,21 +5,21 @@ xmlns:libreccm="http://xmlns.jcp.org/jsf/composite/components/libreccm" xmlns:ui="http://xmlns.jcp.org/jsf/facelets"> - + #{CmsAssetsStepsDefaultMessagesBundle["bookmark.createform.title"]} - - #{message.value} - + - - + - + - - #{CmsAssetsStepsDefaultMessagesBundle['createform.cancel']} @@ -70,11 +70,11 @@ type="submit"> #{CmsAssetsStepsDefaultMessagesBundle['createform.submit']} - + - + - +