ref #7783 implementing WeaklyRelatedEntityCombobox according PagingProvider
authorAndreas Kohlbecker <a.kohlbecker@bgbm.org>
Mon, 24 Sep 2018 10:13:39 +0000 (12:13 +0200)
committerAndreas Kohlbecker <a.kohlbecker@bgbm.org>
Mon, 24 Sep 2018 10:14:00 +0000 (12:14 +0200)
src/main/java/eu/etaxonomy/cdm/service/FilterableStringRepresentationPagingProvider.java [new file with mode: 0644]
src/main/java/eu/etaxonomy/cdm/service/TaxonNameStringFilterablePagingProvider.java
src/main/java/eu/etaxonomy/cdm/vaadin/view/name/TaxonNameEditorPresenter.java
src/main/java/eu/etaxonomy/cdm/vaadin/view/name/TaxonNamePopupEditor.java
src/main/java/eu/etaxonomy/vaadin/component/WeaklyRelatedEntityCombobox.java [new file with mode: 0644]
src/main/java/eu/etaxonomy/vaadin/component/WeaklyRelatedEntityField.java [new file with mode: 0644]

diff --git a/src/main/java/eu/etaxonomy/cdm/service/FilterableStringRepresentationPagingProvider.java b/src/main/java/eu/etaxonomy/cdm/service/FilterableStringRepresentationPagingProvider.java
new file mode 100644 (file)
index 0000000..ee08afc
--- /dev/null
@@ -0,0 +1,23 @@
+/**
+* Copyright (C) 2018 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.service;
+
+import org.vaadin.viritin.fields.LazyComboBox.FilterablePagingProvider;
+
+/**
+ * @author a.kohlbecker
+ * @since Sep 24, 2018
+ *
+ */
+public interface FilterableStringRepresentationPagingProvider<IDTYPE> extends FilterablePagingProvider<String> {
+
+    public IDTYPE idFor(String stringRepresentation);
+
+
+}
index 4f2caa665ec467e0e0f1b360b5b7abdadf5a183e..b283222e7214eead68d59e4cdbf33f445bb72b43 100644 (file)
@@ -13,11 +13,11 @@ import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.UUID;
 
 import org.apache.log4j.Logger;
 import org.hibernate.criterion.Criterion;
 import org.vaadin.viritin.fields.LazyComboBox.FilterableCountProvider;
-import org.vaadin.viritin.fields.LazyComboBox.FilterablePagingProvider;
 
 import com.vaadin.data.Property.ValueChangeListener;
 import com.vaadin.ui.AbstractField;
@@ -32,11 +32,16 @@ import eu.etaxonomy.cdm.persistence.query.MatchMode;
 import eu.etaxonomy.cdm.persistence.query.OrderHint;
 
 /**
+ * IMPORTANT !!!
+ *
+ * The string representations returned as rankSpecificNamePart must be unique in the database since these are being used as weak references between e.g.
+ * genus name and the TaxonName entity for this genus.
+ *
  * @author a.kohlbecker
  * @since Jun 7, 2017
  *
  */
-public class TaxonNameStringFilterablePagingProvider implements FilterablePagingProvider<String>, FilterableCountProvider {
+public class TaxonNameStringFilterablePagingProvider implements FilterableStringRepresentationPagingProvider<UUID>, FilterableCountProvider {
 
     private static final List<String> DEFAULT_INIT_STRATEGY = Arrays.asList("$");
 
@@ -58,6 +63,8 @@ public class TaxonNameStringFilterablePagingProvider implements FilterablePaging
 
     private Map<AbstractField<String>, ValueChangeListener> registeredToFields = new HashMap<>();
 
+    private Map<String, UUID> lastPagedEntityUUIDs;
+
 
     public TaxonNameStringFilterablePagingProvider(INameService service) {
         this(service, Rank.GENUS(), null);
@@ -169,8 +176,15 @@ public class TaxonNameStringFilterablePagingProvider implements FilterablePaging
             logger.trace("findEntities() - page: " + taxonNamePager.getCurrentIndex() + "/" + taxonNamePager.getPagesAvailable() + " totalRecords: " + taxonNamePager.getCount() + "\n" + taxonNamePager.getRecords());
         }
         List<String> namePartStrings = new ArrayList<>(taxonNamePager.getRecords().size());
+        lastPagedEntityUUIDs = new HashMap<>(taxonNamePager.getRecords().size());
         for(TaxonNameParts tnp : taxonNamePager.getRecords()){
-               namePartStrings.add(tnp.rankSpecificNamePart());
+               String rankSpecificNamePart = tnp.rankSpecificNamePart();
+               String namePartKey = rankSpecificNamePart;
+               if(lastPagedEntityUUIDs.containsKey(namePartKey)){
+                   namePartKey = rankSpecificNamePart + " DUPLICATE[" + tnp.getTaxonNameUuid() + "]";
+               }
+               namePartStrings.add(namePartKey);
+               lastPagedEntityUUIDs.put(namePartKey, tnp.getTaxonNameUuid());
         }
         return namePartStrings;
     }
@@ -214,10 +228,30 @@ public class TaxonNameStringFilterablePagingProvider implements FilterablePaging
         return criteria;
     }
 
+    /**
+     * @return the lastPagedEntityUUIDs
+     */
+    public Map<String, UUID> getLastPagedEntityUUIDs() {
+        return lastPagedEntityUUIDs;
+    }
+
+
     public class UnknownFieldException extends Exception {
 
         private static final long serialVersionUID = 1L;
 
 
     }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public UUID idFor(String stringRepresentation) {
+        if(lastPagedEntityUUIDs == null){
+            findEntities(0, stringRepresentation);
+        }
+        return lastPagedEntityUUIDs.get(stringRepresentation);
+    }
 }
index 6a2e2272ed918984c22622cd0508bbd845d3b759..166da9c12f1846307d159e68b28a6ea3bfe72000 100644 (file)
@@ -17,7 +17,6 @@ import org.apache.log4j.Logger;
 import org.hibernate.criterion.Restrictions;
 import org.springframework.context.annotation.Scope;
 import org.vaadin.spring.events.annotation.EventBusListenerMethod;
-import org.vaadin.viritin.fields.LazyComboBox;
 
 import com.vaadin.data.Property;
 import com.vaadin.spring.annotation.SpringComponent;
@@ -53,8 +52,10 @@ import eu.etaxonomy.cdm.vaadin.model.name.TaxonNameDTO;
 import eu.etaxonomy.cdm.vaadin.ui.RegistrationUIDefaults;
 import eu.etaxonomy.cdm.vaadin.util.CdmTitleCacheCaptionGenerator;
 import eu.etaxonomy.cdm.vaadin.view.reference.ReferencePopupEditor;
+import eu.etaxonomy.vaadin.component.CompositeCustomField;
 import eu.etaxonomy.vaadin.component.ReloadableLazyComboBox;
 import eu.etaxonomy.vaadin.component.ToOneRelatedEntityCombobox;
+import eu.etaxonomy.vaadin.component.WeaklyRelatedEntityCombobox;
 import eu.etaxonomy.vaadin.event.FieldReplaceEvent;
 import eu.etaxonomy.vaadin.mvp.AbstractCdmDTOEditorPresenter;
 import eu.etaxonomy.vaadin.mvp.AbstractPopupEditor;
@@ -327,19 +328,19 @@ public class TaxonNameEditorPresenter extends AbstractCdmDTOEditorPresenter<Taxo
         if(boundPropertyIdPath != null){
             if(boundPropertyIdPath.matches("specificEpithet")){
                 AbstractField<String> genusOrUninomialField = getView().getGenusOrUninomialField();
-                if(event.getNewField() instanceof LazyComboBox){
-
-                    if(specificEpithetPartPagingProvider  == null){
+                if(event.getNewField() instanceof CompositeCustomField){
+                    if(specificEpithetPartPagingProvider == null){
                         specificEpithetPartPagingProvider = new TaxonNameStringFilterablePagingProvider(getRepo().getNameService(), Rank.SPECIES());
                     }
                     specificEpithetPartPagingProvider.listenToFields(
                             genusOrUninomialField,
                             null, null, null);
                     specificEpithetPartPagingProvider.updateFromFields();
-                    LazyComboBox<String> specificEpithetField = (LazyComboBox<String>)event.getNewField();
-                    refreshSpecificEpithetComboBoxListener = e -> { specificEpithetField.refresh(); specificEpithetField.setValue(null);};
-                    genusOrUninomialField.addValueChangeListener(refreshSpecificEpithetComboBoxListener);
+                    WeaklyRelatedEntityCombobox<TaxonName> specificEpithetField = (WeaklyRelatedEntityCombobox<TaxonName>)event.getNewField();
+                    refreshSpecificEpithetComboBoxListener = e -> { specificEpithetField.getSelect().refresh(); specificEpithetField.setValue(null);};
                     specificEpithetField.loadFrom(specificEpithetPartPagingProvider, specificEpithetPartPagingProvider, specificEpithetPartPagingProvider.getPageSize());
+                    specificEpithetField.setValue(event.getOldField().getValue());
+                    genusOrUninomialField.addValueChangeListener(refreshSpecificEpithetComboBoxListener);
                 } else {
                     if(specificEpithetPartPagingProvider != null){
                         specificEpithetPartPagingProvider.unlistenAllFields();
@@ -350,7 +351,7 @@ public class TaxonNameEditorPresenter extends AbstractCdmDTOEditorPresenter<Taxo
                     }
                 }
             } else if(boundPropertyIdPath.matches("genusOrUninomial")) {
-                if(event.getNewField() instanceof LazyComboBox){
+                if(event.getNewField() instanceof CompositeCustomField){
                     if(genusOrUninomialPartPagingProvider  == null){
                         genusOrUninomialPartPagingProvider = new TaxonNameStringFilterablePagingProvider(getRepo().getNameService());
                     }
@@ -360,9 +361,10 @@ public class TaxonNameEditorPresenter extends AbstractCdmDTOEditorPresenter<Taxo
                                 getView().getSpecificEpithetField(),
                                 getView().getInfraSpecificEpithetField()
                                );
-                    LazyComboBox<String> genusOrUninomialField = (LazyComboBox<String>)event.getNewField();
+                    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 {
                     if(genusOrUninomialPartPagingProvider != null){
                         genusOrUninomialPartPagingProvider.unlistenAllFields();
index 3370c5c08460738b758319d53a9a54d9882e293a..509c6d3a3eff10b23dbb140d77ce47be2dcd98ce 100644 (file)
@@ -18,7 +18,6 @@ import java.util.UUID;
 import org.apache.commons.lang3.BooleanUtils;
 import org.springframework.context.annotation.Scope;
 import org.springframework.security.core.GrantedAuthority;
-import org.vaadin.viritin.fields.LazyComboBox;
 
 import com.vaadin.data.Property;
 import com.vaadin.data.Property.ValueChangeListener;
@@ -57,6 +56,7 @@ import eu.etaxonomy.vaadin.component.ReloadableLazyComboBox;
 import eu.etaxonomy.vaadin.component.SwitchableTextField;
 import eu.etaxonomy.vaadin.component.ToManyRelatedEntitiesComboboxSelect;
 import eu.etaxonomy.vaadin.component.ToOneRelatedEntityCombobox;
+import eu.etaxonomy.vaadin.component.WeaklyRelatedEntityCombobox;
 import eu.etaxonomy.vaadin.event.EditorActionType;
 import eu.etaxonomy.vaadin.mvp.AbstractCdmDTOPopupEditor;
 
@@ -705,10 +705,11 @@ public class TaxonNamePopupEditor extends AbstractCdmDTOPopupEditor<TaxonNameDTO
         if(isModeEnabled(TaxonNamePopupEditorMode.VALIDATE_AGAINST_HIGHER_NAME_PART)){
             if(isSpeciesOrBelow) {
                 if(TextField.class.isAssignableFrom(genusOrUninomialField.getClass())){
-                    genusOrUninomialField = replaceComponent("genusOrUninomial", genusOrUninomialField, new LazyComboBox<String>(String.class), 0, genusOrUninomialRow, 1, genusOrUninomialRow);
+                    WeaklyRelatedEntityCombobox<TaxonName> combobox = new WeaklyRelatedEntityCombobox<TaxonName>("-> this caption will be relpaced <-", TaxonName.class);
+                    genusOrUninomialField = replaceComponent("genusOrUninomial", genusOrUninomialField, combobox, 0, genusOrUninomialRow, 1, genusOrUninomialRow);
                 }
             } else {
-                if(LazyComboBox.class.isAssignableFrom(genusOrUninomialField.getClass())) {
+                if(ToOneRelatedEntityCombobox.class.isAssignableFrom(genusOrUninomialField.getClass())) {
                     genusOrUninomialField = replaceComponent("genusOrUninomial", genusOrUninomialField, new TextFieldNFix(), 0, genusOrUninomialRow, 1, genusOrUninomialRow);
                 }
             }
@@ -717,10 +718,11 @@ public class TaxonNamePopupEditor extends AbstractCdmDTOPopupEditor<TaxonNameDTO
         if(isModeEnabled(TaxonNamePopupEditorMode.VALIDATE_AGAINST_HIGHER_NAME_PART)){
             if(rank.isInfraSpecific()) {
                 if(TextField.class.isAssignableFrom(specificEpithetField.getClass())) {
-                     specificEpithetField = replaceComponent("specificEpithet", specificEpithetField, new LazyComboBox<String>(String.class), 0, specificEpithetFieldRow, 1, specificEpithetFieldRow);
+                    WeaklyRelatedEntityCombobox<TaxonName> combobox = new WeaklyRelatedEntityCombobox<TaxonName>("-> this caption will be relpaced <-", TaxonName.class);
+                    specificEpithetField = replaceComponent("specificEpithet", specificEpithetField, combobox, 0, specificEpithetFieldRow, 1, specificEpithetFieldRow);
                 }
             } else {
-                if(LazyComboBox.class.isAssignableFrom(specificEpithetField.getClass())) {
+                if(ToOneRelatedEntityCombobox.class.isAssignableFrom(specificEpithetField.getClass())) {
                     specificEpithetField = replaceComponent("specificEpithet", specificEpithetField, new TextFieldNFix(), 0, specificEpithetFieldRow, 1, specificEpithetFieldRow);
                }
             }
diff --git a/src/main/java/eu/etaxonomy/vaadin/component/WeaklyRelatedEntityCombobox.java b/src/main/java/eu/etaxonomy/vaadin/component/WeaklyRelatedEntityCombobox.java
new file mode 100644 (file)
index 0000000..949de0e
--- /dev/null
@@ -0,0 +1,282 @@
+/**
+* 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.vaadin.component;
+
+import java.util.UUID;
+
+import org.vaadin.viritin.fields.LazyComboBox.FilterableCountProvider;
+import org.vaadin.viritin.fields.LazyComboBox.FilterablePagingProvider;
+
+import com.vaadin.data.Property;
+import com.vaadin.data.fieldgroup.FieldGroup;
+import com.vaadin.data.util.converter.Converter.ConversionException;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.CssLayout;
+import com.vaadin.ui.Field;
+import com.vaadin.ui.themes.ValoTheme;
+
+import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
+import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
+import eu.etaxonomy.cdm.service.FilterableStringRepresentationPagingProvider;
+import eu.etaxonomy.cdm.service.UserHelperAccess;
+import eu.etaxonomy.cdm.vaadin.component.ButtonFactory;
+import eu.etaxonomy.cdm.vaadin.event.NestedButtonStateUpdater;
+
+/**
+ * @author a.kohlbecker
+ * @since May 24, 2017
+ *
+ */
+public class WeaklyRelatedEntityCombobox<V extends IdentifiableEntity<?>> extends CompositeCustomField<String>
+    implements WeaklyRelatedEntityField<V>, ReloadableSelect {
+
+    private static final long serialVersionUID = 6277565876657520311L;
+
+    public static final String PRIMARY_STYLE = "v-related-entity-combobox";
+
+    private Class<V> type;
+
+    private CssLayout container = new CssLayout();
+
+    private ReloadableLazyComboBox<String> lazySelect;
+
+    private Button addButton = ButtonFactory.CREATE_NEW.createButton();
+    private Button editButton = ButtonFactory.EDIT_ITEM.createButton();
+
+    private WeaklyRelatedEntityButtonUpdater buttonUpdater;
+
+    private FilterableStringRepresentationPagingProvider<UUID> filterablePagingProvider;
+
+    public WeaklyRelatedEntityCombobox(String caption, Class<V> type){
+        this.type = type;
+        setCaption(caption);
+        lazySelect = new ReloadableLazyComboBox<String>(String.class);
+        addStyledComponents(lazySelect, addButton, editButton);
+        addSizedComponents(lazySelect, container);
+        buttonUpdater = new WeaklyRelatedEntityButtonUpdater(this, type);
+        lazySelect.addValueChangeListener(buttonUpdater);
+        lazySelect.addValueChangeListener(e -> {
+            // update the itemContainer immediately so that the edit button acts on the chosen item
+            lazySelect.commit();
+        });
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Component initContent() {
+        container.addComponents(lazySelect, addButton, editButton);
+        setPrimaryStyleName(PRIMARY_STYLE);
+        addDefaultStyles();
+        return container;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+
+    @Override
+    public Class<String> getType() {
+        return String.class;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void addDefaultStyles() {
+        container.addStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public FieldGroup getFieldGroup() {
+        return null;
+    }
+
+    /**
+     * @return the select
+     */
+    public ReloadableLazyComboBox<String> getSelect() {
+        return lazySelect;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void loadFrom(FilterablePagingProvider<String> filterablePagingProvider, FilterableCountProvider filterableCountProvider, int pageLength) {
+
+        this.filterablePagingProvider = (FilterableStringRepresentationPagingProvider<UUID>) filterablePagingProvider;
+        lazySelect.loadFrom(filterablePagingProvider, filterableCountProvider, pageLength);
+        buttonUpdater.updateButtons(getValue());
+    }
+
+    /**
+     * reload the selected entity from the persistent storage
+     */
+    @Override
+    public void reload() {
+        getSelect().reload();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setAddButtonEnabled(boolean enabled) {
+        addButton.setEnabled(enabled);
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void addClickListenerAddEntity(ClickListener listener) {
+        addButton.addClickListener(listener);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setEditButtonEnabled(boolean enabled) {
+        editButton.setEnabled(enabled);
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void addClickListenerEditEntity(ClickListener listener) {
+        editButton.addClickListener(listener);
+    }
+
+    @Override
+    public void selectNewItem(String bean){
+        setValue(bean);
+    }
+
+    /**
+     * Returns always currently selected item by
+     *
+     * {@inheritDoc}
+     */
+    @Override
+    public String getValue() {
+        lazySelect.commit();
+        return lazySelect.getValue();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setValue(String newFieldValue) throws com.vaadin.data.Property.ReadOnlyException, ConversionException {
+        lazySelect.refresh();
+        lazySelect.setValue(newFieldValue);
+        lazySelect.markAsDirty();
+    }
+
+    @Override
+    public void setPropertyDataSource(Property newDataSource) {
+        lazySelect.setPropertyDataSource(newDataSource);
+        if(buttonUpdater != null){
+            buttonUpdater.updateButtons(lazySelect.getValue());
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Property getPropertyDataSource() {
+        return lazySelect.getPropertyDataSource();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setReadOnly(boolean readOnly) {
+        super.setReadOnly(readOnly);
+        setDeepReadOnly(readOnly, getContent(), null);
+        if(buttonUpdater != null){
+         buttonUpdater.updateButtons(lazySelect.getValue());
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     * @deprecated NestedButtonStateUpdater should rather be instantiated in the RelatedEntityField instead of passing it as property
+     */
+    @Override
+    @Deprecated
+    public void setNestedButtonStateUpdater(NestedButtonStateUpdater<V> buttonUpdater) {
+        // not needed
+    }
+
+    class WeaklyRelatedEntityButtonUpdater implements NestedButtonStateUpdater<String> {
+
+        private static final long serialVersionUID = 4472031263172275012L;
+
+        WeaklyRelatedEntityCombobox<V>  toOneRelatedEntityField;
+
+        private Class<V> type;
+
+
+        public WeaklyRelatedEntityButtonUpdater(WeaklyRelatedEntityCombobox<V> toOneRelatedEntityField, Class<V> type){
+            this.toOneRelatedEntityField = toOneRelatedEntityField;
+            this.type = type;
+            String stringValue = toOneRelatedEntityField.getValue();
+            updateButtons(toOneRelatedEntityField.getValue());
+            toOneRelatedEntityField.setEditButtonEnabled(false);
+        }
+
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void valueChange(com.vaadin.data.Property.ValueChangeEvent event) {
+
+            String value = (String)event.getProperty().getValue();
+            updateButtons(value);
+        }
+
+        /**
+         * @param value
+         */
+        @Override
+        public void updateButtons(String value) {
+
+            UUID uuid = null;
+            if(value != null && filterablePagingProvider != null){
+                uuid = filterablePagingProvider.idFor(value);
+            }
+            boolean userIsAllowedToUpdate = uuid != null && UserHelperAccess.userHelper().userHasPermission(type, uuid, CRUD.UPDATE);
+            boolean userIsAllowedToCreate = UserHelperAccess.userHelper().userHasPermission(type, CRUD.CREATE);
+            boolean isReadOnlyField = ((Field)toOneRelatedEntityField).isReadOnly();
+
+            toOneRelatedEntityField.setAddButtonEnabled(!isReadOnlyField && userIsAllowedToCreate);
+            toOneRelatedEntityField.setEditButtonEnabled(!isReadOnlyField && userIsAllowedToUpdate);
+        }
+    }
+
+
+
+}
diff --git a/src/main/java/eu/etaxonomy/vaadin/component/WeaklyRelatedEntityField.java b/src/main/java/eu/etaxonomy/vaadin/component/WeaklyRelatedEntityField.java
new file mode 100644 (file)
index 0000000..6f48fda
--- /dev/null
@@ -0,0 +1,59 @@
+/**
+* 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.vaadin.component;
+
+import com.vaadin.ui.Button.ClickListener;
+
+import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
+import eu.etaxonomy.cdm.vaadin.event.NestedButtonStateUpdater;
+
+/**
+ * @author a.kohlbecker
+ * @since May 25, 2017
+ *
+ */
+public interface WeaklyRelatedEntityField<V extends IdentifiableEntity> {
+
+    public void setNestedButtonStateUpdater(NestedButtonStateUpdater<V> buttonUpdater);
+
+    /**
+     * Set the enabled state of the edit button
+     *
+     * @param enabled
+     */
+    public void setEditButtonEnabled(boolean enabled);
+
+    /**
+     * Adds the click listener to the add-entity-button.
+     *
+     * @param listener
+     *            the Listener to be added.
+     */
+    public void addClickListenerAddEntity(ClickListener listener);
+
+    /**
+     * Set the enabled state of the add button
+     *
+     * @param enabled
+     */
+    public void setAddButtonEnabled(boolean enabled);
+
+    /**
+     * Adds the click listener to the edit-entity-button.
+     *
+     * @param listener
+     *            the Listener to be added.
+     */
+    public void addClickListenerEditEntity(ClickListener listener);
+
+    public void selectNewItem(String stringRepresentation);
+
+    public Class<String> getType();
+
+}