From 944ebafc046fdf631f75e8b686df4346b3931ca6 Mon Sep 17 00:00:00 2001 From: jensp Date: Wed, 24 Jul 2019 11:05:04 +0000 Subject: [PATCH] CCM NG: Asset editing current status git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@6150 8810af33-2d31-482b-a856-94f89814c4df --- .../assets/AbstractAssetFormController.java | 15 ++++ .../cms/ui/assets/AssetFormController.java | 58 ++++++++++++-- .../forms/AbstractContactableEntityForm.java | 80 +++++++++++++------ ...stractContactableEntityFormController.java | 47 ++++++++--- .../org/librecms/assets/ContactEntryKey.java | 8 ++ .../ContactEntryKeyByLabelComparator.java | 6 +- .../assets/ContactEntryKeyRepository.java | 38 +++++++-- .../org/librecms/CmsResources.properties | 8 ++ .../org/librecms/CmsResources_de.properties | 8 ++ .../org/librecms/CmsResources_fr.properties | 8 ++ 10 files changed, 227 insertions(+), 49 deletions(-) diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AbstractAssetFormController.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AbstractAssetFormController.java index 66aa3860b..bfc75ce83 100644 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AbstractAssetFormController.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AbstractAssetFormController.java @@ -99,4 +99,19 @@ public class AbstractAssetFormController { return new ArrayList<>(l10nManager.creatableLocales(result)); } + @Transactional(Transactional.TxType.REQUIRED) + public void updateAsset(final Asset asset, + final String displayName, + final String title, + final Locale selectedLocale) { + + Objects.requireNonNull(asset, "Can't update null"); + + final Asset selected = assetRepository + .findById(asset.getObjectId()) + .orElseThrow(() -> new IllegalArgumentException(String.format( + "No Asset with ID %d found.", asset.getObjectId()))); + + } + } diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFormController.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFormController.java index 6ddf9cf85..cfa78c933 100644 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFormController.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFormController.java @@ -18,17 +18,65 @@ */ package com.arsdigita.cms.ui.assets; -import javax.enterprise.context.RequestScoped; +import org.librecms.contentsection.Asset; + +import java.util.List; +import java.util.Locale; +import java.util.Map; /** * - * Controller for the asset forms + * Interface for the CDI backend for the forms to manage assets.To avoid + * problems with transactions etc. + * + * the Bebop based forms should access any other CDI beans beside the + * approbriate implementation of this interface. To minimize the efford to + * create an implementation the {@link AbstractAssetFormController} class should + * be used. This class provides basic implementations for most methods. * + * Implementations of the methods defined by this interface should annotated with + * {@code @Transactional(Transactional.TxType.REQUIRED)}. + * * @author Jens Pelzetter + * + * @param The type asset managed by this controller. */ -@RequestScoped -class AssetFormController { - +public interface AssetFormController { + + /** + * Gets the data for the forms from the asset. + * + * @param asset The asset. + * @param selectedLocale The selected locale + * + * @return The values of the properties of the asset for the the selected + * locale. + */ + Map getData(T asset, Locale selectedLocale); + + /** + * Updates the asset with the provided data and saves the changes. + * + * @param asset + * @param selectedLocale + * @param data + */ + void setData(T asset, Locale selectedLocale, Map data); + /** + * Determines in which locales the provided asset is available. + * + * @param asset The asset. + * @return A list of the locales for which the asset has data. + */ + List availableLocales(T asset); + /** + * Determines for which the provided asset has no data. + * + * @param asset The asset. + * @return A list of the locales for which the asset has data yet. + */ + List creatableLocales(T asset); + } diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/AbstractContactableEntityForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/AbstractContactableEntityForm.java index 3c6396d2b..5fc395e45 100644 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/AbstractContactableEntityForm.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/AbstractContactableEntityForm.java @@ -19,6 +19,7 @@ package com.arsdigita.cms.ui.assets.forms; import com.arsdigita.bebop.ActionLink; +import com.arsdigita.bebop.BoxPanel; import com.arsdigita.bebop.Component; import com.arsdigita.bebop.ControlLink; import com.arsdigita.bebop.FormProcessException; @@ -37,6 +38,7 @@ import com.arsdigita.bebop.event.TableActionEvent; import com.arsdigita.bebop.event.TableActionListener; import com.arsdigita.bebop.form.Option; import com.arsdigita.bebop.form.SingleSelect; +import com.arsdigita.bebop.form.Submit; import com.arsdigita.bebop.form.TextField; import com.arsdigita.bebop.parameters.StringParameter; import com.arsdigita.bebop.table.TableCellRenderer; @@ -58,6 +60,7 @@ import org.librecms.assets.ContactEntryKeyByLabelComparator; import org.librecms.assets.ContactEntryKey; import org.librecms.assets.ContactEntryKeyRepository; import org.librecms.assets.ContactableEntity; +import org.librecms.assets.ContactableEntityManager; import org.librecms.assets.PostalAddress; import java.util.Iterator; @@ -92,7 +95,7 @@ public abstract class AbstractContactableEntityForm private TextField contactEntryValueField; - private ActionLink addContactEntryLink; + private Submit addContactEntryLink; private AssetSearchWidget postalAddressSearchWidget; @@ -108,7 +111,7 @@ public abstract class AbstractContactableEntityForm addPropertyWidgets(); - contactEntriesContainer = new SimpleContainer() { + contactEntriesContainer = new BoxPanel(BoxPanel.VERTICAL) { @Override public boolean isVisible(final PageState state) { @@ -144,13 +147,11 @@ public abstract class AbstractContactableEntityForm ); contactEntriesContainer.add(contactEntryValueField); - addContactEntryLink = new ActionLink( + addContactEntryLink = new Submit( new GlobalizedMessage( "cms.ui.authoring.assets.contactable.contactentries.add", CMS_BUNDLE) ); - addContactEntryLink - .addActionListener(new AddContactEntryActionListener()); contactEntriesContainer.add(addContactEntryLink); contactEntriesContainer.add(new Label( @@ -179,6 +180,50 @@ public abstract class AbstractContactableEntityForm } } + @Override + public void process(final FormSectionEvent event) + throws FormProcessException { + + if (addContactEntryLink.equals(event.getSource())) { + + final PageState state = event.getPageState(); + + final ContactableEntity selected = getSelectedAsset(state) + .orElseThrow(() -> new FormProcessException( + new GlobalizedMessage( + "cms.ui.assets.none_selected", CMS_BUNDLE))); + + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final ContactableEntityManager contactableEntityManager = cdiUtil + .findBean(ContactableEntityManager.class); + final ContactEntryKeyRepository keyRepository = cdiUtil + .findBean(ContactEntryKeyRepository.class); + + final String key = (String) contactEntryKeySelect + .getValue(state); + final String value = (String) contactEntryValueField.getValue(state); + + final ContactEntryKey entryKey = keyRepository + .findByEntryKey(key) + .orElseThrow(() -> new FormProcessException( + new GlobalizedMessage( + "cms.ui.assets.contactable.illegal_entry_key", CMS_BUNDLE))); + + final ContactEntry entry = new ContactEntry(); + entry.setKey(entryKey); + entry.setValue(value); + entry.setOrder(selected.getContactEntries().size()); + + contactableEntityManager + .addContactEntryToContactableEntity(entry, selected); + + contactEntryKeySelect.setValue(state, null); + contactEntryValueField.setValue(state, ""); + } else { + super.process(event); + } + } + @Override public void register(final Page page) { @@ -378,21 +423,17 @@ public abstract class AbstractContactableEntityForm target.addOption( new Option("", - new Label(new GlobalizedMessage("cms.ui.select_one"), - CMS_BUNDLE)) + new Label(new GlobalizedMessage("cms.ui.select_one", + CMS_BUNDLE))) ); final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); - final ContactEntryKeyRepository keyRepo = cdiUtil - .findBean(ContactEntryKeyRepository.class); + final AbstractContactableEntityFormController controller = cdiUtil + .findBean(AbstractContactableEntityFormController.class); final GlobalizationHelper globalizationHelper = cdiUtil .findBean(GlobalizationHelper.class); - final List keys = keyRepo - .findAll() - .stream() - .sorted(new ContactEntryKeyByLabelComparator(globalizationHelper - .getNegotiatedLocale())) - .collect(Collectors.toList()); + final List keys = controller + .findAvailableContactEntryKeys(); for (final ContactEntryKey key : keys) { @@ -406,13 +447,4 @@ public abstract class AbstractContactableEntityForm } - private class AddContactEntryActionListener implements ActionListener { - - @Override - public void actionPerformed(ActionEvent e) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - } - } diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/AbstractContactableEntityFormController.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/AbstractContactableEntityFormController.java index d513ae1f7..589401485 100644 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/AbstractContactableEntityFormController.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/AbstractContactableEntityFormController.java @@ -18,14 +18,20 @@ */ package com.arsdigita.cms.ui.assets.forms; +import org.libreccm.l10n.GlobalizationHelper; import org.librecms.assets.ContactEntry; +import org.librecms.assets.ContactEntryKey; +import org.librecms.assets.ContactEntryKeyByLabelComparator; +import org.librecms.assets.ContactEntryKeyRepository; import org.librecms.assets.ContactableEntity; import org.librecms.assets.ContactableEntityManager; import org.librecms.assets.ContactableEntityRepository; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import java.util.Objects; +import java.util.stream.Collectors; import javax.enterprise.context.RequestScoped; import javax.inject.Inject; @@ -40,32 +46,38 @@ public class AbstractContactableEntityFormController { @Inject private ContactableEntityRepository contactableEntityRepository; - + @Inject private ContactableEntityManager contactableEntityManager; + @Inject + private ContactEntryKeyRepository keyRepository; + + @Inject + private GlobalizationHelper globalizationHelper; + @Transactional(Transactional.TxType.REQUIRED) public List getContactEntries( final ContactableEntity contactable) { - + Objects.requireNonNull(contactable, "Can't get contact entries from null."); - + final ContactableEntity entity = contactableEntityRepository - .findById(contactable.getObjectId()) - .orElseThrow(() -> new IllegalArgumentException(String.format( + .findById(contactable.getObjectId()) + .orElseThrow(() -> new IllegalArgumentException(String.format( "No ContactEntity with ID %d found.", - contactable.getObjectId()))); - + contactable.getObjectId()))); + final List entries = new ArrayList<>(); - for(final ContactEntry entry : entity.getContactEntries()) { - + for (final ContactEntry entry : entity.getContactEntries()) { + entries.add(entry); } - + return entries; } - + @Transactional(Transactional.TxType.REQUIRED) public void addContactEntry(final ContactEntry contactEntry, final ContactableEntity toContactableEntity) { @@ -81,14 +93,25 @@ public class AbstractContactableEntityFormController { final int index) { if (contactableEntity.getContactEntries().size() > index) { - + final ContactEntry contactEntry = contactableEntity .getContactEntries() .get(index); contactableEntityManager.removeContactEntryFromContactableEntity( contactEntry, contactableEntity); } + } + @Transactional(Transactional.TxType.REQUIRED) + public List findAvailableContactEntryKeys() { + + final Locale locale = globalizationHelper.getNegotiatedLocale(); + + return keyRepository + .findAll() + .stream() + .sorted(new ContactEntryKeyByLabelComparator(locale)) + .collect(Collectors.toList()); } } 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 47cc6471e..bc22d943a 100644 --- a/ccm-cms/src/main/java/org/librecms/assets/ContactEntryKey.java +++ b/ccm-cms/src/main/java/org/librecms/assets/ContactEntryKey.java @@ -31,6 +31,8 @@ import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; import javax.persistence.Table; import static org.librecms.CmsConstants.*; @@ -42,6 +44,12 @@ import static org.librecms.CmsConstants.*; @Entity @Audited @Table(name = "CONTACT_ENTRY_KEYS", schema = DB_SCHEMA) +@NamedQueries({ + @NamedQuery( + name = "ContactEntryKey.findByEntryKey", + query = "SELECT k FROM ContactEntryKey k WHERE k.entryKey = :entryKey" + ) +}) public class ContactEntryKey implements Comparable, Serializable { diff --git a/ccm-cms/src/main/java/org/librecms/assets/ContactEntryKeyByLabelComparator.java b/ccm-cms/src/main/java/org/librecms/assets/ContactEntryKeyByLabelComparator.java index 5d358d498..1600dcc50 100644 --- a/ccm-cms/src/main/java/org/librecms/assets/ContactEntryKeyByLabelComparator.java +++ b/ccm-cms/src/main/java/org/librecms/assets/ContactEntryKeyByLabelComparator.java @@ -51,7 +51,11 @@ public class ContactEntryKeyByLabelComparator final String localized1 = getLocalizedValue(label1); final String localized2 = getLocalizedValue(label2); - return localized1.compareTo(localized2); + if (localized1 == null) { + return -1; + } else { + return localized1.compareTo(localized2); + } } private String getLocalizedValue(final LocalizedString source) { diff --git a/ccm-cms/src/main/java/org/librecms/assets/ContactEntryKeyRepository.java b/ccm-cms/src/main/java/org/librecms/assets/ContactEntryKeyRepository.java index 3d6ef8979..9bafedbdb 100644 --- a/ccm-cms/src/main/java/org/librecms/assets/ContactEntryKeyRepository.java +++ b/ccm-cms/src/main/java/org/librecms/assets/ContactEntryKeyRepository.java @@ -20,40 +20,64 @@ package org.librecms.assets; import org.libreccm.core.AbstractEntityRepository; +import java.util.Objects; +import java.util.Optional; + import javax.enterprise.context.RequestScoped; +import javax.persistence.NoResultException; +import javax.transaction.Transactional; /** * * @author Jens Pelzetter */ @RequestScoped -public class ContactEntryKeyRepository - extends AbstractEntityRepository{ +public class ContactEntryKeyRepository + extends AbstractEntityRepository { private static final long serialVersionUID = 1L; @Override public Class getEntityClass() { - + return ContactEntryKey.class; } @Override public String getIdAttributeName() { - + return "keyId"; } @Override public Long getIdOfEntity(final ContactEntryKey entity) { - + return entity.getKeyId(); } @Override public boolean isNew(final ContactEntryKey entity) { - + return entity.getKeyId() == 0; } - + + @Transactional(Transactional.TxType.REQUIRED) + public Optional findByEntryKey(final String entryKey) { + + try { + return Optional.of( + getEntityManager() + .createNamedQuery("ContactEntryKey.findByEntryKey", + ContactEntryKey.class) + .setParameter("entryKey", + Objects.requireNonNull( + entryKey, + "Can't find a ContactEntry for key null." + )) + .getSingleResult()); + } catch (NoResultException ex) { + return Optional.empty(); + } + } + } diff --git a/ccm-cms/src/main/resources/org/librecms/CmsResources.properties b/ccm-cms/src/main/resources/org/librecms/CmsResources.properties index 1113dfadf..1b9e64da4 100644 --- a/ccm-cms/src/main/resources/org/librecms/CmsResources.properties +++ b/ccm-cms/src/main/resources/org/librecms/CmsResources.properties @@ -541,3 +541,11 @@ cms.ui.pages.item_page_model=Page Model for item page cms.ui.pages.tab.pages=Pages cms.ui.pages.tab.page_models=Page Models cms.ui.assets.organization.name=Name of the organization +cms.ui.authoring.assets.contactable.contactentries.nonecms.ui.authoring.assets.contactable.contactentries.key=Type +cms.ui.authoring.assets.contactable.contactentries.value=Value +cms.ui.authoring.assets.contactable.postaladdress\ =Postal address +cms.ui.assets.none_selected=No assets selected +cms.ui.assets.contactable.illegal_entry_key=Illegal value for contact entry key. +cms.ui.authoring.assets.contactable.contactentries.none=No contact entries +cms.ui.authoring.assets.contactable.contactentries.key=Type +cms.ui.authoring.assets.contactable.contactentries.add=Add diff --git a/ccm-cms/src/main/resources/org/librecms/CmsResources_de.properties b/ccm-cms/src/main/resources/org/librecms/CmsResources_de.properties index 5d096acf9..172c4934a 100644 --- a/ccm-cms/src/main/resources/org/librecms/CmsResources_de.properties +++ b/ccm-cms/src/main/resources/org/librecms/CmsResources_de.properties @@ -538,3 +538,11 @@ cms.ui.pages.item_page_model=Page Model f\u00fcr Item Seite cms.ui.pages.tab.pages=Seiten cms.ui.pages.tab.page_models=Page Models cms.ui.assets.organization.name=Name der Organization +cms.ui.authoring.assets.contactable.contactentries.nonecms.ui.authoring.assets.contactable.contactentries.key=Typ +cms.ui.authoring.assets.contactable.contactentries.value=Wert +cms.ui.authoring.assets.contactable.postaladdress\ =Post Adresse +cms.ui.assets.none_selected=Kein aktives Asset +cms.ui.assets.contactable.illegal_entry_key=Unzul\u00e4ssiger Eintragsschl\u00fcssel +cms.ui.authoring.assets.contactable.contactentries.none=Keine Eintr\u00e4ge +cms.ui.authoring.assets.contactable.contactentries.key=Typ +cms.ui.authoring.assets.contactable.contactentries.add=Hinzuf\u00fcgen diff --git a/ccm-cms/src/main/resources/org/librecms/CmsResources_fr.properties b/ccm-cms/src/main/resources/org/librecms/CmsResources_fr.properties index 48d036edc..3df8ba180 100644 --- a/ccm-cms/src/main/resources/org/librecms/CmsResources_fr.properties +++ b/ccm-cms/src/main/resources/org/librecms/CmsResources_fr.properties @@ -500,3 +500,11 @@ cms.ui.pages.item_page_model=Page Model for item page cms.ui.pages.tab.pages=Pages cms.ui.pages.tab.page_models=Page Models cms.ui.assets.organization.name=Name of the organization +cms.ui.authoring.assets.contactable.contactentries.nonecms.ui.authoring.assets.contactable.contactentries.key=Type +cms.ui.authoring.assets.contactable.contactentries.value=Value +cms.ui.authoring.assets.contactable.postaladdress\ =Postal address +cms.ui.assets.none_selected=No assets selected +cms.ui.assets.contactable.illegal_entry_key=Illegal value for contact entry key. +cms.ui.authoring.assets.contactable.contactentries.none=No contact entries +cms.ui.authoring.assets.contactable.contactentries.key=Type +cms.ui.authoring.assets.contactable.contactentries.add=Add