commit 51d6bc3c703209cc0af89380800c364d876d6ed2
Author: Andreas Kohlbecker <a.kohlbecker@bgbm.org>
Date:   Mon Jan 29 17:30:42 2018 +0100

    fix #6740 NameTypeDesignationEditor save operation working

diff --git a/src/main/java/eu/etaxonomy/cdm/vaadin/view/name/NameTypeDesignationPopupEditor.java b/src/main/java/eu/etaxonomy/cdm/vaadin/view/name/NameTypeDesignationPopupEditor.java
index 76f381f6..114e1a19 100644
--- a/src/main/java/eu/etaxonomy/cdm/vaadin/view/name/NameTypeDesignationPopupEditor.java
+++ b/src/main/java/eu/etaxonomy/cdm/vaadin/view/name/NameTypeDesignationPopupEditor.java
@@ -132,6 +132,7 @@ public class NameTypeDesignationPopupEditor extends AbstractCdmPopupEditor<NameT
         typifiedNamesComboboxSelect = new ToManyRelatedEntitiesComboboxSelect<TaxonName>(TaxonName.class, "Typified names");
         typifiedNamesComboboxSelect.setConverter(new SetToListConverter<TaxonName>());
         addField(typifiedNamesComboboxSelect, "typifiedNames", 0, row, 3, row);
+        typifiedNamesComboboxSelect.setReadOnly(false); // FIXME this does not help
 
         row++;
         citationCombobox = new ToOneRelatedEntityCombobox<Reference>("Citation", Reference.class);
diff --git a/src/main/java/eu/etaxonomy/cdm/vaadin/view/name/NameTypeDesignationPresenter.java b/src/main/java/eu/etaxonomy/cdm/vaadin/view/name/NameTypeDesignationPresenter.java
index c3777ba0..d976f64d 100644
--- a/src/main/java/eu/etaxonomy/cdm/vaadin/view/name/NameTypeDesignationPresenter.java
+++ b/src/main/java/eu/etaxonomy/cdm/vaadin/view/name/NameTypeDesignationPresenter.java
@@ -9,6 +9,7 @@
 package eu.etaxonomy.cdm.vaadin.view.name;
 
 import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
 
 import eu.etaxonomy.cdm.api.service.IService;
@@ -21,6 +22,7 @@ import eu.etaxonomy.cdm.vaadin.component.CdmBeanItemContainerFactory;
 import eu.etaxonomy.cdm.vaadin.event.ToOneRelatedEntityButtonUpdater;
 import eu.etaxonomy.cdm.vaadin.event.ToOneRelatedEntityReloader;
 import eu.etaxonomy.cdm.vaadin.security.UserHelper;
+import eu.etaxonomy.cdm.vaadin.util.CdmTitleCacheCaptionGenerator;
 import eu.etaxonomy.vaadin.mvp.AbstractCdmEditorPresenter;
 
 /**
@@ -31,6 +33,8 @@ import eu.etaxonomy.vaadin.mvp.AbstractCdmEditorPresenter;
 public class NameTypeDesignationPresenter
         extends AbstractCdmEditorPresenter<NameTypeDesignation, NameTypeDesignationEditorView> {
 
+    HashSet<TaxonName> typifiedNamesAsLoaded;
+
     /**
      * {@inheritDoc}
      */
@@ -54,6 +58,9 @@ public class NameTypeDesignationPresenter
                 typeDesignation = NameTypeDesignation.NewInstance();
             }
         }
+
+        typifiedNamesAsLoaded = new HashSet<>(typeDesignation.getTypifiedNames());
+
         return typeDesignation;
     }
 
@@ -69,6 +76,7 @@ public class NameTypeDesignationPresenter
         CdmBeanItemContainerFactory selectFactory = new CdmBeanItemContainerFactory(getRepo());
         getView().getTypeStatusSelect().setContainerDataSource(selectFactory.buildBeanItemContainer(NameTypeDesignationStatus.class));
 
+        getView().getCitationCombobox().getSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<Reference>());
         CdmFilterablePagingProvider<Reference,Reference> referencePagingProvider = new CdmFilterablePagingProvider<Reference, Reference>(getRepo().getReferenceService());
         getView().getCitationCombobox().loadFrom(referencePagingProvider, referencePagingProvider, referencePagingProvider.getPageSize());
         getView().getCitationCombobox().getSelect().addValueChangeListener(new ToOneRelatedEntityButtonUpdater<Reference>(getView().getCitationCombobox()));
@@ -112,4 +120,34 @@ public class NameTypeDesignationPresenter
         return null;
     }
 
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected NameTypeDesignation handleTransientProperties(NameTypeDesignation bean) {
+
+        // the typifiedNames can only be set on the name side, so we need to
+        // handle changes explicitly here
+        HashSet<TaxonName> typifiedNames = new HashSet<>(bean.getTypifiedNames());
+
+        // handle adds
+        for(TaxonName name : typifiedNames){
+            if(!name.getTypeDesignations().contains(bean)){
+                name.addTypeDesignation(bean, false);
+            }
+        }
+        // handle removed
+        for(TaxonName name : typifiedNamesAsLoaded){
+            if(!typifiedNames.contains(name)){
+                name.removeTypeDesignation(bean);
+            }
+            // FIXME do we need to save the names here or is the delete cascaded from the typedesignation to the name?
+        }
+
+        return bean;
+    }
+
+
+
 }
diff --git a/src/main/java/eu/etaxonomy/cdm/vaadin/view/registration/RegistrationWorkingsetPresenter.java b/src/main/java/eu/etaxonomy/cdm/vaadin/view/registration/RegistrationWorkingsetPresenter.java
index 906e17ee..c914cb74 100644
--- a/src/main/java/eu/etaxonomy/cdm/vaadin/view/registration/RegistrationWorkingsetPresenter.java
+++ b/src/main/java/eu/etaxonomy/cdm/vaadin/view/registration/RegistrationWorkingsetPresenter.java
@@ -14,6 +14,8 @@ import java.util.EnumSet;
 import java.util.List;
 import java.util.UUID;
 
+import org.hibernate.Session;
+import org.hibernate.Transaction;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.event.EventListener;
 import org.springframework.security.core.Authentication;
@@ -31,6 +33,7 @@ import eu.etaxonomy.cdm.api.service.IRegistrationService;
 import eu.etaxonomy.cdm.api.service.idminter.IdentifierMinter.Identifier;
 import eu.etaxonomy.cdm.api.service.idminter.RegistrationIdentifierMinter;
 import eu.etaxonomy.cdm.model.common.User;
+import eu.etaxonomy.cdm.model.name.NameTypeDesignation;
 import eu.etaxonomy.cdm.model.name.Rank;
 import eu.etaxonomy.cdm.model.name.Registration;
 import eu.etaxonomy.cdm.model.name.RegistrationStatus;
@@ -63,6 +66,7 @@ import eu.etaxonomy.cdm.vaadin.view.name.TaxonNamePopupEditorMode;
 import eu.etaxonomy.cdm.vaadin.view.name.TypeDesignationWorkingsetEditorIdSet;
 import eu.etaxonomy.cdm.vaadin.view.reference.ReferencePopupEditor;
 import eu.etaxonomy.vaadin.mvp.AbstractPresenter;
+import eu.etaxonomy.vaadin.mvp.BeanInstantiator;
 import eu.etaxonomy.vaadin.ui.view.DoneWithPopupEvent;
 import eu.etaxonomy.vaadin.ui.view.DoneWithPopupEvent.Reason;
 
@@ -386,14 +390,19 @@ public class RegistrationWorkingsetPresenter extends AbstractPresenter<Registrat
             popup.withDeleteButton(true);
             popup.loadInEditor(new TypeDesignationWorkingsetEditorIdSet(event.getRegistrationId(), event.getEntityId()));
             if(event.getSourceComponent() != null){
-                // TODO document this !!!!!!!!!!!
+                // propagate readonly state from source component to popup
                 popup.setReadOnly(event.getSourceComponent().isReadOnly());
             }
         } else {
             NameTypeDesignationPopupEditor popup = getNavigationManager().showInPopup(NameTypeDesignationPopupEditor.class);
             popup.withDeleteButton(true);
             popup.loadInEditor(event.getEntityId());
+
+            popup.getCitationCombobox().setEnabled(false);
+            popup.getTypifiedNamesComboboxSelect().setEnabled(false);
+
             if(event.getSourceComponent() != null){
+                // propagate readonly state from source component to popup
                 popup.setReadOnly(event.getSourceComponent().isReadOnly());
             }
             newNameTypeDesignationTarget = workingset.getRegistrationDTO(event.getRegistrationId()).get();
@@ -428,15 +437,32 @@ public class RegistrationWorkingsetPresenter extends AbstractPresenter<Registrat
             popup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
             popup.loadInEditor(identifierSet);
             popup.withDeleteButton(true);
+            if(event.getSourceComponent() != null){
+                // propagate readonly state from source component to popup
+                popup.setReadOnly(event.getSourceComponent().isReadOnly());
+            }
         } else {
             NameTypeDesignationPopupEditor popup = getNavigationManager().showInPopup(NameTypeDesignationPopupEditor.class);
             popup.withDeleteButton(true);
             popup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
+            newNameTypeDesignationTarget = workingset.getRegistrationDTO(event.getRegistrationId()).get();
+            popup.setBeanInstantiator(new BeanInstantiator<NameTypeDesignation>() {
+
+                @Override
+                public NameTypeDesignation createNewBean() {
+                    NameTypeDesignation nameTypeDesignation  = NameTypeDesignation.NewInstance();
+                    nameTypeDesignation.setCitation(newNameTypeDesignationTarget.getCitation());
+                    nameTypeDesignation.getTypifiedNames().add(newNameTypeDesignationTarget.getTypifiedName());
+                    return nameTypeDesignation;
+                }
+            });
             popup.loadInEditor(null);
+            popup.getCitationCombobox().setEnabled(false);
+            popup.getTypifiedNamesComboboxSelect().setEnabled(false);
             if(event.getSourceComponent() != null){
+                // propagate readonly state from source component to popup
                 popup.setReadOnly(event.getSourceComponent().isReadOnly());
             }
-            newNameTypeDesignationTarget = workingset.getRegistrationDTO(event.getRegistrationId()).get();
         }
     }
 
@@ -469,10 +495,18 @@ public class RegistrationWorkingsetPresenter extends AbstractPresenter<Registrat
         } else if(event.getPopup() instanceof NameTypeDesignationPopupEditor){
             if(event.getReason().equals(Reason.SAVE)){
                 UUID uuid = ((NameTypeDesignationPopupEditor)event.getPopup()).getBean().getUuid();
-                TypeDesignationBase<?> nameTypeDesignation = getRepo().getNameService().loadTypeDesignation(uuid, null);
-                Registration registration = getRepo().getRegistrationService().load(newNameTypeDesignationTarget.getId(), Arrays.asList("$", "typeDesignations"));
+
+                Session session = getRepo().getSessionFactory().openSession();
+                Transaction txstate = session.beginTransaction();
+                TypeDesignationBase<?> nameTypeDesignation = getRepo().getNameService().loadTypeDesignation(uuid, Arrays.asList(""));
+                // only load the typeDesignations with the registration so that the typified name can  not be twice in the session
+                // otherwise multiple representation problems might occur
+                Registration registration = getRepo().getRegistrationService().load(newNameTypeDesignationTarget.getUuid(), Arrays.asList("typeDesignations"));
                 registration.getTypeDesignations().add(nameTypeDesignation);
-                getRepo().getRegistrationService().saveOrUpdate(registration);
+                session.merge(registration);
+                txstate.commit();
+                session.close();
+
                 newNameTypeDesignationTarget = null;
                 refreshView(true);
             } else if(event.getReason().equals(Reason.CANCEL)){
diff --git a/src/main/java/eu/etaxonomy/vaadin/mvp/AbstractPopupEditor.java b/src/main/java/eu/etaxonomy/vaadin/mvp/AbstractPopupEditor.java
index ae425ae4..59c82f26 100644
--- a/src/main/java/eu/etaxonomy/vaadin/mvp/AbstractPopupEditor.java
+++ b/src/main/java/eu/etaxonomy/vaadin/mvp/AbstractPopupEditor.java
@@ -48,7 +48,6 @@ import eu.etaxonomy.cdm.database.PermissionDeniedException;
 import eu.etaxonomy.cdm.vaadin.component.TextFieldNFix;
 import eu.etaxonomy.vaadin.component.NestedFieldGroup;
 import eu.etaxonomy.vaadin.component.SwitchableTextField;
-import eu.etaxonomy.vaadin.mvp.event.EditorCancelEvent;
 import eu.etaxonomy.vaadin.mvp.event.EditorDeleteEvent;
 import eu.etaxonomy.vaadin.mvp.event.EditorPreSaveEvent;
 import eu.etaxonomy.vaadin.mvp.event.EditorSaveEvent;
@@ -279,7 +278,6 @@ public abstract class AbstractPopupEditor<DTO extends Object, P extends Abstract
     @Override
     public void cancel() {
         fieldGroup.discard();
-        eventBus.publishEvent(new EditorCancelEvent<DTO>(this, getBean()));
         eventBus.publishEvent(new DoneWithPopupEvent(this, Reason.CANCEL));
     }
 
@@ -287,7 +285,7 @@ public abstract class AbstractPopupEditor<DTO extends Object, P extends Abstract
      * @return
      */
     private void delete() {
-        eventBus.publishEvent(new EditorDeleteEvent(this, fieldGroup.getItemDataSource().getBean()));
+        eventBus.publishEvent(new EditorDeleteEvent<DTO>(this, fieldGroup.getItemDataSource().getBean()));
         eventBus.publishEvent(new DoneWithPopupEvent(this, Reason.DELETE));
     }
 
