commit 98c2f4010c2b1ebca6c3e4c804f6e7e051031b4c
Author: Andreas Kohlbecker <a.kohlbecker@bgbm.org>
Date:   Mon Sep 24 17:48:21 2018 +0200

    ref #7783 using WeaklyRelatedEntityCombobox in TaxonNameEditor: add, edit buttons working and enabled state updating ok

diff --git a/src/main/java/eu/etaxonomy/cdm/service/FilterableStringRepresentationPagingProvider.java b/src/main/java/eu/etaxonomy/cdm/service/FilterableStringRepresentationPagingProvider.java
index ee08afc4..9878f62d 100644
--- a/src/main/java/eu/etaxonomy/cdm/service/FilterableStringRepresentationPagingProvider.java
+++ b/src/main/java/eu/etaxonomy/cdm/service/FilterableStringRepresentationPagingProvider.java
@@ -19,5 +19,10 @@ public interface FilterableStringRepresentationPagingProvider<IDTYPE> extends Fi
 
     public IDTYPE idFor(String stringRepresentation);
 
+    /**
+     *
+     */
+    public void clearIdCache();
+
 
 }
diff --git a/src/main/java/eu/etaxonomy/cdm/service/TaxonNameStringFilterablePagingProvider.java b/src/main/java/eu/etaxonomy/cdm/service/TaxonNameStringFilterablePagingProvider.java
index b283222e..17baffda 100644
--- a/src/main/java/eu/etaxonomy/cdm/service/TaxonNameStringFilterablePagingProvider.java
+++ b/src/main/java/eu/etaxonomy/cdm/service/TaxonNameStringFilterablePagingProvider.java
@@ -254,4 +254,12 @@ public class TaxonNameStringFilterablePagingProvider implements FilterableString
         }
         return lastPagedEntityUUIDs.get(stringRepresentation);
     }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void clearIdCache() {
+        lastPagedEntityUUIDs = null;
+    }
 }
diff --git a/src/main/java/eu/etaxonomy/cdm/vaadin/event/TaxonNameEditorActionStrRep.java b/src/main/java/eu/etaxonomy/cdm/vaadin/event/TaxonNameEditorActionStrRep.java
new file mode 100644
index 00000000..adb5fd12
--- /dev/null
+++ b/src/main/java/eu/etaxonomy/cdm/vaadin/event/TaxonNameEditorActionStrRep.java
@@ -0,0 +1,68 @@
+/**
+* Copyright (C) 2017 EDIT
+* European Distributed Institute of Taxonomy
+* http://www.e-taxonomy.eu
+*
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+package eu.etaxonomy.cdm.vaadin.event;
+
+import java.util.Stack;
+import java.util.UUID;
+
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Field;
+
+import eu.etaxonomy.vaadin.event.EditorActionType;
+import eu.etaxonomy.vaadin.mvp.AbstractView;
+
+/**
+ * Variant of the TaxonNameEditorAction with to be published from fields like the {@link eu.etaxonomy.vaadin.component.WeaklyRelatedEntityCombobox} which
+ * contain string representations of an entity instead of the whole entit.y
+ *
+ * @author a.kohlbecker
+ * @since Mar 22, 2017
+ *
+ */
+public class TaxonNameEditorActionStrRep extends AbstractEditorAction<String> {
+
+
+    public TaxonNameEditorActionStrRep(EditorActionType eventType) {
+        super(eventType);
+    }
+
+    /**
+     * @param action
+     * @param source
+     */
+    public TaxonNameEditorActionStrRep(EditorActionType action, Button source, Field<String> target, AbstractView sourceView) {
+        super(action, source, target, sourceView);
+    }
+
+    /**
+     * @param action
+     * @param entityId
+     * @param source
+     * @param sourceView
+     */
+    public TaxonNameEditorActionStrRep(EditorActionType action, UUID entityUuid, Button source, Field<String> target, AbstractView sourceView) {
+        super(action, entityUuid, source, target, sourceView);
+    }
+
+    /**
+     * @param action
+     * @param entityId
+     * @param source
+     * @param sourceView
+     * @param context
+     */
+    public TaxonNameEditorActionStrRep(EditorActionType action, UUID entityUuid, Button source, Field<String> target, AbstractView sourceView,
+            Stack<EditorActionContext> context) {
+        super(action, entityUuid, source, target, sourceView, context);
+    }
+
+
+
+
+}
diff --git a/src/main/java/eu/etaxonomy/cdm/vaadin/view/name/TaxonNameEditorPresenter.java b/src/main/java/eu/etaxonomy/cdm/vaadin/view/name/TaxonNameEditorPresenter.java
index 166da9c1..0c910660 100644
--- a/src/main/java/eu/etaxonomy/cdm/vaadin/view/name/TaxonNameEditorPresenter.java
+++ b/src/main/java/eu/etaxonomy/cdm/vaadin/view/name/TaxonNameEditorPresenter.java
@@ -13,6 +13,7 @@ import java.util.EnumSet;
 import java.util.List;
 import java.util.UUID;
 
+import org.apache.commons.lang.StringUtils;
 import org.apache.log4j.Logger;
 import org.hibernate.criterion.Restrictions;
 import org.springframework.context.annotation.Scope;
@@ -46,6 +47,7 @@ import eu.etaxonomy.cdm.vaadin.event.EditorActionTypeFilter;
 import eu.etaxonomy.cdm.vaadin.event.EntityChangeEvent;
 import eu.etaxonomy.cdm.vaadin.event.ReferenceEditorAction;
 import eu.etaxonomy.cdm.vaadin.event.TaxonNameEditorAction;
+import eu.etaxonomy.cdm.vaadin.event.TaxonNameEditorActionStrRep;
 import eu.etaxonomy.cdm.vaadin.event.ToOneRelatedEntityButtonUpdater;
 import eu.etaxonomy.cdm.vaadin.event.ToOneRelatedEntityReloader;
 import eu.etaxonomy.cdm.vaadin.model.name.TaxonNameDTO;
@@ -362,7 +364,6 @@ public class TaxonNameEditorPresenter extends AbstractCdmDTOEditorPresenter<Taxo
                                 getView().getInfraSpecificEpithetField()
                                );
                     WeaklyRelatedEntityCombobox<TaxonName> genusOrUninomialField = (WeaklyRelatedEntityCombobox<TaxonName>)event.getNewField();
-                    // FIXME genusOrUninomialField.setNestedButtonStateUpdater(new ToOneRelatedEntityButtonUpdater<TaxonName>(genusOrUninomialField));
                     genusOrUninomialField.loadFrom(genusOrUninomialPartPagingProvider, genusOrUninomialPartPagingProvider, genusOrUninomialPartPagingProvider.getPageSize());
                     genusOrUninomialField.setValue(event.getOldField().getValue());
                 }else {
@@ -384,9 +385,43 @@ public class TaxonNameEditorPresenter extends AbstractCdmDTOEditorPresenter<Taxo
             BoundField boundTargetField = boundTargetField((PopupView) event.getSourceView());
 
             if(boundTargetField != null){
-                if(boundTargetField.matchesPropertyIdPath("nomenclaturalReference")){
+                if(boundTargetField.matchesPropertyIdPath("genusOrUninomial")){
+                    if(event.isCreateOrModifiedType()){
+                        getCache().load(event.getEntity());
+                        if(getView().getGenusOrUninomialField() instanceof WeaklyRelatedEntityCombobox){
+                            WeaklyRelatedEntityCombobox<TaxonName> weaklyRelatedEntityCombobox = (WeaklyRelatedEntityCombobox<TaxonName>)getView().getGenusOrUninomialField();
+                            if(event.isCreatedType()){
+                                weaklyRelatedEntityCombobox.setValue(((TaxonName)event.getEntity()).getGenusOrUninomial());
+                                weaklyRelatedEntityCombobox.reload();
+                            } else {
+                                weaklyRelatedEntityCombobox.reload();
+                            }
+                            // NOTE: in constrast to the ToOneRelatedEntityCombobox the .discard() does not
+                            // work here since no datasource is bound to the field, see weaklyRelatedEntityCombobox.reload()
+                            weaklyRelatedEntityCombobox.updateButtons();
+                        }
+                    }
+                } else
+                if(boundTargetField.matchesPropertyIdPath("specificEpithet")){
                     if(event.isCreateOrModifiedType()){
+                        getCache().load(event.getEntity());
 
+                        if(getView().getSpecificEpithetField() instanceof WeaklyRelatedEntityCombobox){
+                            WeaklyRelatedEntityCombobox weaklyRelatedEntityCombobox = (WeaklyRelatedEntityCombobox)getView().getSpecificEpithetField();
+                            if(event.isCreatedType()){
+                                getView().getSpecificEpithetField().setValue(((TaxonName)event.getEntity()).getSpecificEpithet());
+                                weaklyRelatedEntityCombobox.reload();
+                            } else {
+                                weaklyRelatedEntityCombobox.reload();
+                            }
+                            // NOTE: in constrast to the ToOneRelatedEntityCombobox the .discard() does not
+                            // work here since no datasource is bound to the field, see weaklyRelatedEntityCombobox.reload()
+                            weaklyRelatedEntityCombobox.updateButtons();
+                        }
+                    }
+                } else
+                if(boundTargetField.matchesPropertyIdPath("nomenclaturalReference")){
+                    if(event.isCreateOrModifiedType()){
                         getCache().load(event.getEntity());
                         if(event.isCreatedType()){
                             getView().getNomReferenceCombobox().setValue((Reference) event.getEntity());
@@ -396,7 +431,7 @@ public class TaxonNameEditorPresenter extends AbstractCdmDTOEditorPresenter<Taxo
                         getView().getCombinationAuthorshipField().discard(); //refresh from the datasource
                         getView().updateAuthorshipFields();
                     }
-                }
+                } else
                 if(boundTargetField.matchesPropertyIdPath("validationFor.otherName")){
                     ReloadableLazyComboBox<TaxonName> otherNameField = asReloadableLazyComboBox(boundTargetField.getField(TaxonName.class));
                     if(event.isCreateOrModifiedType()){
@@ -472,15 +507,35 @@ public class TaxonNameEditorPresenter extends AbstractCdmDTOEditorPresenter<Taxo
 
         if(boundPropertyId != null){
             if(boundPropertyId.matches("validationFor.otherName") || boundPropertyId.matches("basionyms") || boundPropertyId.matches("replacedSynonyms")){
-                TaxonNamePopupEditor validatedNamePopup = openPopupEditor(TaxonNamePopupEditor.class, event);
-                validatedNamePopup.withDeleteButton(true);
+                TaxonNamePopupEditor namePopup = openPopupEditor(TaxonNamePopupEditor.class, event);
+                namePopup.withDeleteButton(true);
                 getView().getModesActive().stream()
                     .filter(m -> !TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY.equals(m))
-                    .forEach(m -> validatedNamePopup.enableMode(m));
-                validatedNamePopup.loadInEditor(event.getEntityUuid());
+                    .forEach(m -> namePopup.enableMode(m));
+                namePopup.loadInEditor(event.getEntityUuid());
             }
         }
+    }
+
+    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
+    public void onTaxonNameEditorActionStrRepEdit(TaxonNameEditorActionStrRep event) {
+
+        if(getView() == null || event.getSourceView() != getView() ){
+            return;
+        }
+
+        PropertyIdPath boundPropertyId = boundPropertyIdPath(event.getTarget());
 
+        if(boundPropertyId != null){
+            if(boundPropertyId.matches("genusOrUninomial") || boundPropertyId.matches("specificEpithet")){
+                TaxonNamePopupEditor namePopup = openPopupEditor(TaxonNamePopupEditor.class, event);
+                namePopup.withDeleteButton(true);
+                getView().getModesActive().stream()
+                    .filter(m -> !TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY.equals(m))
+                    .forEach(m -> namePopup.enableMode(m));
+                namePopup.loadInEditor(event.getEntityUuid());
+            }
+        }
     }
 
     @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
@@ -494,13 +549,47 @@ public class TaxonNameEditorPresenter extends AbstractCdmDTOEditorPresenter<Taxo
 
         if(boundPropertyId != null){
             if(boundPropertyId.matches("validationFor.otherName") || boundPropertyId.matches("basionyms") || boundPropertyId.matches("replacedSynonyms")){
-                TaxonNamePopupEditor validatedNamePopup = openPopupEditor(TaxonNamePopupEditor.class, event);
-                validatedNamePopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
-                validatedNamePopup.withDeleteButton(true);
+                TaxonNamePopupEditor namePopup = openPopupEditor(TaxonNamePopupEditor.class, event);
+                namePopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
+                namePopup.withDeleteButton(true);
                 getView().getModesActive().stream()
                         .filter(m -> !TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY.equals(m))
-                        .forEach(m -> validatedNamePopup.enableMode(m));
-                validatedNamePopup.loadInEditor(null);
+                        .forEach(m -> namePopup.enableMode(m));
+                namePopup.loadInEditor(null);
+            }
+        }
+    }
+
+    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
+    public void onTaxonNameEditorActionStrRepAdd(TaxonNameEditorActionStrRep event) {
+
+        if(getView() == null || event.getSourceView() != getView() ){
+            return;
+        }
+
+        PropertyIdPath boundPropertyId = boundPropertyIdPath(event.getTarget());
+
+        if(boundPropertyId != null){
+            if(boundPropertyId.matches("genusOrUninomial") || boundPropertyId.matches("specificEpithet")){
+                TaxonNamePopupEditor namePopup = openPopupEditor(TaxonNamePopupEditor.class, event);
+                namePopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
+                namePopup.withDeleteButton(true);
+                String nameString = event.getTarget().getValue();
+                getView().getModesActive().stream()
+                        .filter(m -> !TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY.equals(m))
+                        .forEach(m -> namePopup.enableMode(m));
+                namePopup.loadInEditor(null);
+                if(StringUtils.isNotEmpty(nameString)){
+                    if(boundPropertyId.matches("genusOrUninomial")){
+                        namePopup.getGenusOrUninomialField().setValue(nameString);
+                        namePopup.getRankSelect().setValue(Rank.GENUS());
+                    }
+                    if(boundPropertyId.matches("specificEpithet")){
+                        namePopup.getSpecificEpithetField().setValue(nameString);
+                        namePopup.getGenusOrUninomialField().setValue(getView().getGenusOrUninomialField().getValue());
+                        namePopup.getRankSelect().setValue(Rank.SPECIES());
+                    }
+                }
             }
         }
     }
diff --git a/src/main/java/eu/etaxonomy/cdm/vaadin/view/name/TaxonNamePopupEditor.java b/src/main/java/eu/etaxonomy/cdm/vaadin/view/name/TaxonNamePopupEditor.java
index 509c6d3a..886c20c2 100644
--- a/src/main/java/eu/etaxonomy/cdm/vaadin/view/name/TaxonNamePopupEditor.java
+++ b/src/main/java/eu/etaxonomy/cdm/vaadin/view/name/TaxonNamePopupEditor.java
@@ -44,6 +44,7 @@ import eu.etaxonomy.cdm.vaadin.component.common.FilterableAnnotationsField;
 import eu.etaxonomy.cdm.vaadin.component.common.TeamOrPersonField;
 import eu.etaxonomy.cdm.vaadin.event.ReferenceEditorAction;
 import eu.etaxonomy.cdm.vaadin.event.TaxonNameEditorAction;
+import eu.etaxonomy.cdm.vaadin.event.TaxonNameEditorActionStrRep;
 import eu.etaxonomy.cdm.vaadin.model.name.NameRelationshipDTO;
 import eu.etaxonomy.cdm.vaadin.model.name.TaxonNameDTO;
 import eu.etaxonomy.cdm.vaadin.permission.AccessRestrictedView;
@@ -705,7 +706,23 @@ public class TaxonNamePopupEditor extends AbstractCdmDTOPopupEditor<TaxonNameDTO
         if(isModeEnabled(TaxonNamePopupEditorMode.VALIDATE_AGAINST_HIGHER_NAME_PART)){
             if(isSpeciesOrBelow) {
                 if(TextField.class.isAssignableFrom(genusOrUninomialField.getClass())){
-                    WeaklyRelatedEntityCombobox<TaxonName> combobox = new WeaklyRelatedEntityCombobox<TaxonName>("-> this caption will be relpaced <-", TaxonName.class);
+                    WeaklyRelatedEntityCombobox<TaxonName> combobox = new WeaklyRelatedEntityCombobox<TaxonName>("-> this caption will be replaced <-", TaxonName.class);
+                    combobox.addClickListenerAddEntity(e -> getViewEventBus().publish(
+                            this,
+                            new TaxonNameEditorActionStrRep(EditorActionType.ADD, e.getButton(), combobox, this)
+                        ));
+                    combobox.addClickListenerEditEntity(e -> {
+                        if(combobox.getValue() != null){
+                            getViewEventBus().publish(this,
+                                new TaxonNameEditorActionStrRep(
+                                        EditorActionType.EDIT,
+                                        combobox.getIdForValue(),
+                                        e.getButton(),
+                                        combobox,
+                                        this)
+                            );
+                        }
+                    });
                     genusOrUninomialField = replaceComponent("genusOrUninomial", genusOrUninomialField, combobox, 0, genusOrUninomialRow, 1, genusOrUninomialRow);
                 }
             } else {
@@ -718,8 +735,24 @@ public class TaxonNamePopupEditor extends AbstractCdmDTOPopupEditor<TaxonNameDTO
         if(isModeEnabled(TaxonNamePopupEditorMode.VALIDATE_AGAINST_HIGHER_NAME_PART)){
             if(rank.isInfraSpecific()) {
                 if(TextField.class.isAssignableFrom(specificEpithetField.getClass())) {
-                    WeaklyRelatedEntityCombobox<TaxonName> combobox = new WeaklyRelatedEntityCombobox<TaxonName>("-> this caption will be relpaced <-", TaxonName.class);
+                    WeaklyRelatedEntityCombobox<TaxonName> combobox = new WeaklyRelatedEntityCombobox<TaxonName>("-> this caption will be replaced <-", TaxonName.class);
                     specificEpithetField = replaceComponent("specificEpithet", specificEpithetField, combobox, 0, specificEpithetFieldRow, 1, specificEpithetFieldRow);
+                    combobox.addClickListenerAddEntity(e -> getViewEventBus().publish(
+                            this,
+                            new TaxonNameEditorActionStrRep(EditorActionType.ADD, e.getButton(), combobox, this)
+                        ));
+                    combobox.addClickListenerEditEntity(e -> {
+                        if(combobox.getValue() != null){
+                            getViewEventBus().publish(this,
+                                new TaxonNameEditorActionStrRep(
+                                        EditorActionType.EDIT,
+                                        combobox.getIdForValue(),
+                                        e.getButton(),
+                                        combobox,
+                                        this)
+                            );
+                        }
+                    });
                 }
             } else {
                 if(ToOneRelatedEntityCombobox.class.isAssignableFrom(specificEpithetField.getClass())) {
diff --git a/src/main/java/eu/etaxonomy/vaadin/component/WeaklyRelatedEntityCombobox.java b/src/main/java/eu/etaxonomy/vaadin/component/WeaklyRelatedEntityCombobox.java
index 949de0e0..4304e02d 100644
--- a/src/main/java/eu/etaxonomy/vaadin/component/WeaklyRelatedEntityCombobox.java
+++ b/src/main/java/eu/etaxonomy/vaadin/component/WeaklyRelatedEntityCombobox.java
@@ -61,7 +61,7 @@ public class WeaklyRelatedEntityCombobox<V extends IdentifiableEntity<?>> extend
         lazySelect = new ReloadableLazyComboBox<String>(String.class);
         addStyledComponents(lazySelect, addButton, editButton);
         addSizedComponents(lazySelect, container);
-        buttonUpdater = new WeaklyRelatedEntityButtonUpdater(this, type);
+        buttonUpdater = new WeaklyRelatedEntityButtonUpdater(this);
         lazySelect.addValueChangeListener(buttonUpdater);
         lazySelect.addValueChangeListener(e -> {
             // update the itemContainer immediately so that the edit button acts on the chosen item
@@ -128,9 +128,11 @@ public class WeaklyRelatedEntityCombobox<V extends IdentifiableEntity<?>> extend
      */
     @Override
     public void reload() {
+        filterablePagingProvider.clearIdCache();
         getSelect().reload();
     }
 
+
     /**
      * {@inheritDoc}
      */
@@ -181,6 +183,10 @@ public class WeaklyRelatedEntityCombobox<V extends IdentifiableEntity<?>> extend
         return lazySelect.getValue();
     }
 
+    public UUID getIdForValue(){
+        return filterablePagingProvider.idFor(getValue());
+    }
+
 
     /**
      * {@inheritDoc}
@@ -220,6 +226,11 @@ public class WeaklyRelatedEntityCombobox<V extends IdentifiableEntity<?>> extend
         }
     }
 
+    @Override
+    public void updateButtons(){
+        buttonUpdater.updateButtons(getValue());
+    }
+
     /**
      * {@inheritDoc}
      * @deprecated NestedButtonStateUpdater should rather be instantiated in the RelatedEntityField instead of passing it as property
@@ -236,12 +247,8 @@ public class WeaklyRelatedEntityCombobox<V extends IdentifiableEntity<?>> extend
 
         WeaklyRelatedEntityCombobox<V>  toOneRelatedEntityField;
 
-        private Class<V> type;
-
-
-        public WeaklyRelatedEntityButtonUpdater(WeaklyRelatedEntityCombobox<V> toOneRelatedEntityField, Class<V> type){
+        public WeaklyRelatedEntityButtonUpdater(WeaklyRelatedEntityCombobox<V> toOneRelatedEntityField){
             this.toOneRelatedEntityField = toOneRelatedEntityField;
-            this.type = type;
             String stringValue = toOneRelatedEntityField.getValue();
             updateButtons(toOneRelatedEntityField.getValue());
             toOneRelatedEntityField.setEditButtonEnabled(false);
diff --git a/src/main/java/eu/etaxonomy/vaadin/component/WeaklyRelatedEntityField.java b/src/main/java/eu/etaxonomy/vaadin/component/WeaklyRelatedEntityField.java
index 6f48fda6..92b36e73 100644
--- a/src/main/java/eu/etaxonomy/vaadin/component/WeaklyRelatedEntityField.java
+++ b/src/main/java/eu/etaxonomy/vaadin/component/WeaklyRelatedEntityField.java
@@ -56,4 +56,9 @@ public interface WeaklyRelatedEntityField<V extends IdentifiableEntity> {
 
     public Class<String> getType();
 
+    /**
+     * Update the enabled state of the add and edit buttons
+     */
+    public void updateButtons();
+
 }
