Project

General

Profile

Download (46.8 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2017 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.vaadin.view.name;
10

    
11
import java.util.Arrays;
12
import java.util.EnumSet;
13
import java.util.HashMap;
14
import java.util.HashSet;
15
import java.util.List;
16
import java.util.Map;
17
import java.util.Optional;
18
import java.util.Set;
19
import java.util.UUID;
20

    
21
import org.apache.commons.lang.StringUtils;
22
import org.apache.log4j.Logger;
23
import org.hibernate.criterion.Restrictions;
24
import org.springframework.context.annotation.Scope;
25
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
26
import org.vaadin.viritin.fields.AbstractElementCollection;
27

    
28
import com.vaadin.data.Property;
29
import com.vaadin.data.util.BeanItemContainer;
30
import com.vaadin.spring.annotation.SpringComponent;
31
import com.vaadin.ui.AbstractField;
32
import com.vaadin.ui.AbstractSelect.ItemCaptionMode;
33
import com.vaadin.ui.Field;
34

    
35
import eu.etaxonomy.cdm.api.service.INameService;
36
import eu.etaxonomy.cdm.format.reference.ReferenceEllypsisFormatter;
37
import eu.etaxonomy.cdm.format.reference.ReferenceEllypsisFormatter.LabelType;
38
import eu.etaxonomy.cdm.model.agent.AgentBase;
39
import eu.etaxonomy.cdm.model.agent.Person;
40
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
41
import eu.etaxonomy.cdm.model.common.AnnotationType;
42
import eu.etaxonomy.cdm.model.common.CdmBase;
43
import eu.etaxonomy.cdm.model.common.Language;
44
import eu.etaxonomy.cdm.model.name.NomenclaturalCodeEdition;
45
import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
46
import eu.etaxonomy.cdm.model.name.Rank;
47
import eu.etaxonomy.cdm.model.name.TaxonName;
48
import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
49
import eu.etaxonomy.cdm.model.permission.CRUD;
50
import eu.etaxonomy.cdm.model.reference.Reference;
51
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
52
import eu.etaxonomy.cdm.model.reference.ReferenceType;
53
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
54
import eu.etaxonomy.cdm.model.term.TermType;
55
import eu.etaxonomy.cdm.persistence.dao.common.Restriction;
56
import eu.etaxonomy.cdm.persistence.dao.common.Restriction.Operator;
57
import eu.etaxonomy.cdm.persistence.dao.initializer.EntityInitStrategy;
58
import eu.etaxonomy.cdm.service.CdmFilterablePagingProvider;
59
import eu.etaxonomy.cdm.service.TaxonNameStringFilterablePagingProvider;
60
import eu.etaxonomy.cdm.service.UserHelperAccess;
61
import eu.etaxonomy.cdm.service.initstrategies.AgentBaseInit;
62
import eu.etaxonomy.cdm.vaadin.event.EditorActionTypeFilter;
63
import eu.etaxonomy.cdm.vaadin.event.EntityChangeEvent;
64
import eu.etaxonomy.cdm.vaadin.event.ReferenceEditorAction;
65
import eu.etaxonomy.cdm.vaadin.event.TaxonNameEditorAction;
66
import eu.etaxonomy.cdm.vaadin.event.TaxonNameEditorActionStrRep;
67
import eu.etaxonomy.cdm.vaadin.event.ToOneRelatedEntityButtonUpdater;
68
import eu.etaxonomy.cdm.vaadin.event.ToOneRelatedEntityReloader;
69
import eu.etaxonomy.cdm.vaadin.model.name.NomenclaturalStatusDTO;
70
import eu.etaxonomy.cdm.vaadin.model.name.TaxonNameDTO;
71
import eu.etaxonomy.cdm.vaadin.model.registration.RegistrationTermLists;
72
import eu.etaxonomy.cdm.vaadin.ui.RegistrationUIDefaults;
73
import eu.etaxonomy.cdm.vaadin.util.CdmTitleCacheCaptionGenerator;
74
import eu.etaxonomy.cdm.vaadin.util.ReferenceEllypsisCaptionGenerator;
75
import eu.etaxonomy.cdm.vaadin.view.reference.ReferencePopupEditor;
76
import eu.etaxonomy.cdm.vaadin.view.reference.RegistrationUiReferenceEditorFormConfigurator;
77
import eu.etaxonomy.vaadin.component.CompositeCustomField;
78
import eu.etaxonomy.vaadin.component.ReloadableLazyComboBox;
79
import eu.etaxonomy.vaadin.component.ToOneRelatedEntityCombobox;
80
import eu.etaxonomy.vaadin.component.WeaklyRelatedEntityCombobox;
81
import eu.etaxonomy.vaadin.component.WeaklyRelatedEntityField;
82
import eu.etaxonomy.vaadin.event.FieldReplaceEvent;
83
import eu.etaxonomy.vaadin.mvp.AbstractCdmDTOEditorPresenter;
84
import eu.etaxonomy.vaadin.mvp.AbstractPopupEditor;
85
import eu.etaxonomy.vaadin.mvp.BeanInstantiator;
86
import eu.etaxonomy.vaadin.mvp.BoundField;
87
import eu.etaxonomy.vaadin.ui.view.PopupView;
88
import eu.etaxonomy.vaadin.util.PropertyIdPath;
89

    
90
/**
91
 * @author a.kohlbecker
92
 * @since May 22, 2017
93
 *
94
 */
95
@SpringComponent
96
@Scope("prototype")
97
public class TaxonNameEditorPresenter
98
        extends AbstractCdmDTOEditorPresenter<TaxonNameDTO, TaxonName, TaxonNamePopupEditorView> {
99

    
100
    private static final long serialVersionUID = -3538980627079389221L;
101

    
102
    private static final EnumSet<CRUD> SUB_EDITOR_CRUD = EnumSet.of(CRUD.UPDATE, CRUD.DELETE);
103

    
104
    private static final List<String> RELATED_NAME_INIT_STRATEGY = Arrays.asList("$", "nomenclaturalSource.annotations",
105
            "relationsFromThisName", "relationsToThisName.type", "homotypicalGroup.typifiedNames");
106

    
107
    public static List<String> REFERENCE_INIT_STRATEGY = ReferenceEllypsisFormatter.INIT_STRATEGY;
108

    
109
    private static final Logger logger = Logger.getLogger(TaxonNameEditorPresenter.class);
110

    
111
    private CdmFilterablePagingProvider<Reference, Reference> nomReferencePagingProvider;
112

    
113
    private Reference publishedUnit;
114

    
115
    private BeanInstantiator<Reference> newReferenceInstantiator;
116

    
117
    private Map<ReferencePopupEditor, NomenclaturalStatusRow> statusTypeReferencePopupEditorsRowMap = new HashMap<>();
118

    
119
    private TaxonNameStringFilterablePagingProvider genusOrUninomialPartPagingProvider;
120

    
121
    private TaxonNameStringFilterablePagingProvider specificEpithetPartPagingProvider;
122

    
123
    private Property.ValueChangeListener refreshSpecificEpithetComboBoxListener;
124

    
125
    private CdmFilterablePagingProvider<TaxonName, TaxonName> relatedNamePagingProvider;
126

    
127
    private CdmFilterablePagingProvider<TaxonName, TaxonName> orthographicVariantNamePagingProvider;
128

    
129
    private Restriction<Reference> orthographicCorrectionRestriction;
130

    
131
    private Integer taxonNameId;
132

    
133
    /**
134
     * {@inheritDoc}
135
     */
136
    @SuppressWarnings("serial")
137
    @Override
138
    public void handleViewEntered() {
139

    
140
        super.handleViewEntered();
141

    
142
        List<NomenclaturalCodeEdition> nomCodes = NomenclaturalCodeEdition
143
                .forCode(RegistrationUIDefaults.NOMENCLATURAL_CODE);
144
        BeanItemContainer<NomenclaturalCodeEdition> codeEditionItemContainer = cdmBeanItemContainerFactory
145
                .buildEnumTermItemContainer(NomenclaturalCodeEdition.class,
146
                        nomCodes.toArray(new NomenclaturalCodeEdition[nomCodes.size()]));
147

    
148
        getView().getRankSelect()
149
                .setContainerDataSource(cdmBeanItemContainerFactory.buildTermItemContainer(TermType.Rank));
150
        getView().getRankSelect().setItemCaptionPropertyId("label");
151

    
152
        CdmFilterablePagingProvider<AgentBase, TeamOrPersonBase> termOrPersonPagingProvider = pagingProviderFactory
153
                .teamOrPersonPagingProvider();
154
        termOrPersonPagingProvider.setInitStrategy(AgentBaseInit.TEAM_OR_PERSON_INIT_STRATEGY);
155
        CdmFilterablePagingProvider<AgentBase, Person> personPagingProvider = pagingProviderFactory
156
                .personPagingProvider();
157

    
158
        getView().getCombinationAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
159
        getView().getCombinationAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
160

    
161
        getView().getExCombinationAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
162
        getView().getExCombinationAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
163

    
164
        getView().getBasionymAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
165
        getView().getBasionymAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
166

    
167
        getView().getExBasionymAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
168
        getView().getExBasionymAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
169

    
170
        nomReferencePagingProvider = pagingProviderFactory.referencePagingProvider();
171
        nomReferencePagingProvider.setInitStrategy(REFERENCE_INIT_STRATEGY);
172
        getView().getNomReferenceCombobox().loadFrom(nomReferencePagingProvider, nomReferencePagingProvider,
173
                nomReferencePagingProvider.getPageSize());
174
        getView().getNomReferenceCombobox().setNestedButtonStateUpdater(
175
                new ToOneRelatedEntityButtonUpdater<Reference>(getView().getNomReferenceCombobox()));
176
        getView().getNomReferenceCombobox().getSelect().setCaptionGenerator(new ReferenceEllypsisCaptionGenerator(
177
                LabelType.NOMENCLATURAL, getView().getNomReferenceCombobox().getSelect()));
178
        getView().getNomReferenceCombobox().getSelect()
179
                .addValueChangeListener(new ToOneRelatedEntityReloader<>(getView().getNomReferenceCombobox(), this));
180
        getView().getNomReferenceCombobox().getSelect()
181
                .addValueChangeListener(e -> updateOrthographicCorrectionRestriction());
182

    
183
        CdmFilterablePagingProvider<Reference, Reference> icbnCodesPagingProvider = pagingProviderFactory
184
                .referencePagingProvider();
185
        // @formatter:off
186
        // TODO use markers on references instead of isbn. The marker type
187
        // MarkerType.NOMENCLATURAL_RELEVANT() has already prepared (#7466)
188
        icbnCodesPagingProvider.getCriteria().add(Restrictions.in("isbn", new String[] {
189
                "3-904144-22-7",     // Saint Louis Code
190
                "3-906166-48-1",     // Vienna Code
191
                "978-3-87429-425-6", // Melbourne Code
192
                "978-3-946583-16-5", // Shenzhen Code
193
                "0-85301-006-4"      // ICZN 1999
194
                                     // ICNB
195
        }));
196
        // @formatter:on
197

    
198
        statusTypeReferencePopupEditorsRowMap.clear();
199
        getView().getNomStatusCollectionField().addElementAddedListener(e -> addNomenclaturalStatus(e.getElement()));
200
        getView().getNomStatusCollectionField()
201
                .setEditorInstantiator(new AbstractElementCollection.Instantiator<NomenclaturalStatusRow>() {
202

    
203
                    @Override
204
                    public NomenclaturalStatusRow create() {
205
                        NomenclaturalStatusRow row = new NomenclaturalStatusRow();
206

    
207
                        BeanItemContainer<DefinedTermBase> statusTypeItemContainer = cdmBeanItemContainerFactory.buildTermItemContainer(
208
                                RegistrationTermLists.NOMENCLATURAL_STATUS_TYPE_UUIDS()
209
                                );
210
                        row.type.setContainerDataSource(statusTypeItemContainer);
211
                        row.type.setItemCaptionMode(ItemCaptionMode.EXPLICIT);
212
                        for (DefinedTermBase term : statusTypeItemContainer.getItemIds()) {
213
                            row.type.setItemCaption(term,
214
                                    term.getPreferredRepresentation(Language.DEFAULT()).getAbbreviatedLabel());
215
                        }
216
                        row.type.setNullSelectionAllowed(false);
217

    
218
                        row.citation.loadFrom(icbnCodesPagingProvider, icbnCodesPagingProvider,
219
                                icbnCodesPagingProvider.getPageSize());
220
                        row.citation.getSelect().setCaptionGenerator(new ReferenceEllypsisCaptionGenerator(
221
                                LabelType.NOMENCLATURAL, row.citation.getSelect()));
222
                        row.citation.getSelect().addValueChangeListener(new ToOneRelatedEntityReloader<Reference>(
223
                                row.citation.getSelect(), TaxonNameEditorPresenter.this));
224
                        row.citation.addClickListenerAddEntity(e -> doReferenceEditorAdd(row));
225
                        row.citation.addClickListenerEditEntity(e -> {
226
                            if (row.citation.getValue() != null) {
227
                                doReferenceEditorEdit(row);
228
                            }
229
                        });
230
                        row.codeEdition.setContainerDataSource(codeEditionItemContainer);
231

    
232
                        getView().applyDefaultComponentStyle(row.components());
233

    
234
                        return row;
235
                    }
236
                });
237

    
238
        relatedNamePagingProvider = pagingProviderFactory.taxonNamesWithoutOrthophicIncorrect();
239
        relatedNamePagingProvider.setInitStrategy(RELATED_NAME_INIT_STRATEGY);
240
        getView().getBasionymComboboxSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<TaxonName>());
241
        getView().getBasionymComboboxSelect().setPagingProviders(relatedNamePagingProvider, relatedNamePagingProvider,
242
                relatedNamePagingProvider.getPageSize(), this);
243

    
244
        getView().getReplacedSynonymsComboboxSelect()
245
                .setCaptionGenerator(new CdmTitleCacheCaptionGenerator<TaxonName>());
246
        getView().getReplacedSynonymsComboboxSelect().setPagingProviders(relatedNamePagingProvider,
247
                relatedNamePagingProvider, relatedNamePagingProvider.getPageSize(), this);
248

    
249
        getView().getValidationField().getRelatedNameComboBox().getSelect()
250
                .setCaptionGenerator(new CdmTitleCacheCaptionGenerator<TaxonName>());
251
        getView().getValidationField().getRelatedNameComboBox().loadFrom(relatedNamePagingProvider,
252
                relatedNamePagingProvider, relatedNamePagingProvider.getPageSize());
253
        getView().getValidationField().getRelatedNameComboBox().getSelect().addValueChangeListener(
254
                new ToOneRelatedEntityReloader<>(getView().getValidationField().getRelatedNameComboBox(), this));
255
        getView().getValidationField().getCitatonComboBox().getSelect()
256
                .setCaptionGenerator(new ReferenceEllypsisCaptionGenerator(LabelType.BIBLIOGRAPHIC,
257
                        getView().getValidationField().getCitatonComboBox().getSelect()));
258
        getView().getValidationField().getCitatonComboBox().loadFrom(icbnCodesPagingProvider, icbnCodesPagingProvider,
259
                icbnCodesPagingProvider.getPageSize());
260
        getView().getValidationField().getCitatonComboBox().getSelect().addValueChangeListener(
261
                new ToOneRelatedEntityReloader<>(getView().getValidationField().getCitatonComboBox(), this));
262
        getView().getValidationField().getCodeEditionSelect().setContainerDataSource(codeEditionItemContainer);
263

    
264
        getView().getOrthographicVariantField().getRelatedNameComboBox().getSelect()
265
                .setCaptionGenerator(new CdmTitleCacheCaptionGenerator<TaxonName>());
266
        getView().getOrthographicVariantField().getRelatedNameComboBox().getSelect().addValueChangeListener(
267
                new ToOneRelatedEntityReloader<>(getView().getOrthographicVariantField().getRelatedNameComboBox(),
268
                        this));
269
        getView().getOrthographicVariantField().getRelatedNameComboBox().loadFrom(relatedNamePagingProvider,
270
                relatedNamePagingProvider, relatedNamePagingProvider.getPageSize());
271
        // The Mode TaxonNamePopupEditorMode.ORTHOGRAPHIC_CORRECTION will be
272
        // handled in the updateOrthographicCorrectionRestriction() method
273
        getView().getOrthographicVariantField().getCitatonComboBox().getSelect()
274
                .setCaptionGenerator(new ReferenceEllypsisCaptionGenerator(LabelType.BIBLIOGRAPHIC,
275
                        getView().getOrthographicVariantField().getCitatonComboBox().getSelect()));
276
        getView().getOrthographicVariantField().getCitatonComboBox().loadFrom(icbnCodesPagingProvider,
277
                icbnCodesPagingProvider, icbnCodesPagingProvider.getPageSize());
278
        getView().getOrthographicVariantField().getCitatonComboBox().getSelect().addValueChangeListener(
279
                new ToOneRelatedEntityReloader<>(getView().getOrthographicVariantField().getCitatonComboBox(), this));
280
        getView().getOrthographicVariantField().getCodeEditionSelect().setContainerDataSource(codeEditionItemContainer);
281

    
282
        getView().getAnnotationsField().setAnnotationTypeItemContainer(cdmBeanItemContainerFactory
283
                .buildVocabularyTermsItemContainer(AnnotationType.EDITORIAL().getVocabulary().getUuid()));
284
    }
285

    
286
    /**
287
     * @param element
288
     * @return
289
     */
290
    @Deprecated
291
    private void addNomenclaturalStatus(NomenclaturalStatusDTO element) {
292
        // Nothing to do
293
    }
294

    
295
    @Override
296
    protected void adaptDataProviders() {
297
        updateOrthographicCorrectionRestriction();
298
    }
299

    
300
    private void updateOrthographicCorrectionRestriction() {
301

    
302
        if (getView().isModeEnabled(TaxonNamePopupEditorMode.ORTHOGRAPHIC_CORRECTION)) {
303
            if (orthographicVariantNamePagingProvider == null) {
304
                orthographicVariantNamePagingProvider = new CdmFilterablePagingProvider<TaxonName, TaxonName>(
305
                        getRepo().getNameService());
306
                orthographicVariantNamePagingProvider.setInitStrategy(RELATED_NAME_INIT_STRATEGY);
307
                orthographicVariantNamePagingProvider
308
                        .addRestriction(new Restriction<>("id", Operator.AND_NOT, null, taxonNameId));
309
                getView().getOrthographicVariantField().getRelatedNameComboBox().loadFrom(
310
                        orthographicVariantNamePagingProvider, orthographicVariantNamePagingProvider,
311
                        orthographicVariantNamePagingProvider.getPageSize());
312
            }
313
            Reference nomReference = getView().getNomReferenceCombobox().getValue();
314
            if (nomReference == null && orthographicCorrectionRestriction != null) {
315
                orthographicVariantNamePagingProvider.getRestrictions().remove(orthographicCorrectionRestriction);
316
            } else {
317
                if (orthographicCorrectionRestriction == null) {
318
                    orthographicCorrectionRestriction = new Restriction<>("nomenclaturalSource.citation", Operator.AND,
319
                            null, nomReference);
320
                    orthographicVariantNamePagingProvider.addRestriction(orthographicCorrectionRestriction);
321
                } else {
322
                    orthographicCorrectionRestriction.setValues(Arrays.asList(nomReference));
323
                }
324
            }
325
            getView().getOrthographicVariantField().getRelatedNameComboBox().getSelect().refresh();
326
        }
327
    }
328

    
329
    @Override
330
    protected TaxonName loadCdmEntity(UUID identifier) {
331

    
332
        EntityInitStrategy initStrategy = new EntityInitStrategy(
333
                Arrays.asList(
334
                "$",
335
                "annotations.type",
336
                "annotations.*", // needed as log as we are using a table in FilterableAnnotationsField
337
                "rank.vocabulary", // needed for comparing ranks
338

    
339
                "nomenclaturalSource.citation",
340
                "nomenclaturalSource.annotations", // needed to allow access in AnnotatableEntity.checkEmpty()
341
                "nomenclaturalSource.markers",  // needed to allow access in AnnotatableEntity.checkEmpty()
342
                "nomenclaturalSource.links",  // needed to allow access in OriginalSourceBase.checkEmpty()
343

    
344
                "status.type",
345
                "status.source.citation",
346
                "status.source.annotations", // needed to allow access in AnnotatableEntity.checkEmpty()
347
                "status.source.markers", // needed to allow access in AnnotatableEntity.checkEmpty()
348
                "status.source.links", // needed to allow access in AnnotatableEntity.checkEmpty()
349

    
350
                "combinationAuthorship",
351
                "exCombinationAuthorship",
352
                "basionymAuthorship",
353
                "exBasionymAuthorship",
354

    
355
                // basionyms: relationsToThisName.fromName
356
                "relationsToThisName.type",
357
                "relationsToThisName.fromName.rank",
358
                "relationsToThisName.fromName.combinationAuthorship",
359
                "relationsToThisName.fromName.exCombinationAuthorship",
360
                "relationsToThisName.fromName.nomenclaturalSource.citation.authorship",
361
                "relationsToThisName.fromName.nomenclaturalSource.citation.inReference.authorship",
362
                "relationsToThisName.fromName.nomenclaturalSource.citation.inReference.inReference.inReference.authorship",
363
                "relationsToThisName.fromName.nomenclaturalSource.annotations", // needed to allow access in OriginalSourceBase.checkEmpty()
364
                "relationsToThisName.fromName.nomenclaturalSource.markers", // needed to allow access in OriginalSourceBase.checkEmpty()
365
                "relationsToThisName.fromName.nomenclaturalSource.links", // needed to allow access in OriginalSourceBase.checkEmpty()
366
                "relationsToThisName.fromName.relationsToThisName",
367
                "relationsToThisName.fromName.relationsFromThisName",
368
                "relationsToThisName.source.citation",
369
                "relationsToThisName.source.annotations", // needed to allow access in OriginalSourceBase.checkEmpty()
370
                "relationsToThisName.source.markers", // needed to allow access in OriginalSourceBase.checkEmpty()
371
                "relationsToThisName.source.links", // needed to allow access in OriginalSourceBase.checkEmpty()
372
                "relationsFromThisName",
373
                "homotypicalGroup.typifiedNames"
374
                )
375
              );
376
        initStrategy.extend("nomenclaturalSource.citation", ReferenceEllypsisFormatter.INIT_STRATEGY, false);
377
        initStrategy.extend("status.citation", ReferenceEllypsisFormatter.INIT_STRATEGY, false);
378
        initStrategy.extend("relationsToThisName.citation", ReferenceEllypsisFormatter.INIT_STRATEGY, false);
379

    
380
        TaxonName taxonName;
381
        if (identifier != null) {
382
            taxonName = getRepo().getNameService().load(identifier, initStrategy.getPropertyPaths());
383
        } else {
384
            taxonName = createCdmEntity();
385
        }
386

    
387
        if (getView().isModeEnabled(TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY)) {
388
            Reference nomRef = taxonName.getNomenclaturalReference();
389

    
390
            // getView().getNomReferenceCombobox().setEnabled(nomRef.isOfType(ReferenceType.Section));
391
            publishedUnit = nomRef;
392
            if (publishedUnit != null) {
393
                while (publishedUnit.isOfType(ReferenceType.Section) && publishedUnit.getInReference() != null) {
394
                    publishedUnit = nomRef.getInReference();
395
                }
396
                // reduce available references to those which are sections of
397
                // the publishedUnit and the publishedUnit itself
398
                // nomReferencePagingProvider
399
                nomReferencePagingProvider.getCriteria()
400
                        .add(Restrictions.or(
401
                                Restrictions.and(Restrictions.eq("inReference", publishedUnit),
402
                                        Restrictions.eq("type", ReferenceType.Section)),
403
                                Restrictions.idEq(publishedUnit.getId())));
404
            }
405
            // and remove the empty option
406
            getView().getNomReferenceCombobox().getSelect().setNullSelectionAllowed(false);
407

    
408
            // new Reference only a sub sections of the publishedUnit
409
            newReferenceInstantiator = new BeanInstantiator<Reference>() {
410
                @Override
411
                public Reference createNewBean() {
412
                    Reference newRef = ReferenceFactory.newSection();
413
                    newRef.setInReference(publishedUnit);
414
                    return newRef;
415
                }
416
            };
417

    
418
        }
419

    
420
        taxonNameId = Integer.valueOf(taxonName.getId());
421
        relatedNamePagingProvider.addRestriction(new Restriction<>("id", Operator.AND_NOT, null, taxonNameId));
422

    
423
        return taxonName;
424
    }
425

    
426
    @Override
427
    protected TaxonNameDTO preSaveBean(TaxonNameDTO bean) {
428
        // ---- sync the name.nomenclaturalStatus set with the modifications
429
        Set<NomenclaturalStatus> removeCandidates = new HashSet<>(bean.cdmEntity().getStatus());
430
        for (NomenclaturalStatusDTO statusDTO : bean.getStatus()) {
431
            if (statusDTO.getId() > 0) {
432
                Optional<NomenclaturalStatus> originalEntity = bean.cdmEntity().getStatus().stream()
433
                        .filter(s -> s.getId() == statusDTO.getId()).findFirst();
434
                if (originalEntity.isPresent()) {
435
                    statusDTO.update(originalEntity.get());
436
                    removeCandidates.remove(originalEntity.get());
437
                } else {
438
                    throw new RuntimeException("No original NomenclaturalStatus found for DTO with id="
439
                            + statusDTO.getId() + ". Was the TaxonName modified otherwise when opened in the editor?");
440
                }
441
            } else {
442
                // all new status with id = 0
443
                bean.cdmEntity().addStatus(statusDTO.update(null));
444
            }
445
        }
446
        for(NomenclaturalStatus toBeRemoved : removeCandidates) {
447
            bean.cdmEntity().removeStatus(toBeRemoved);
448
        }
449
        return super.preSaveBean(bean);
450
    }
451

    
452
    /**
453
     * {@inheritDoc}
454
     */
455
    @Override
456
    protected void guaranteePerEntityCRUDPermissions(UUID identifier) {
457
        if (crud != null) {
458
            newAuthorityCreated = UserHelperAccess.userHelper().createAuthorityForCurrentUser(TaxonName.class,
459
                    identifier, crud, null);
460
        }
461

    
462
    }
463

    
464
    /**
465
     * {@inheritDoc}
466
     */
467
    @Override
468
    protected void guaranteePerEntityCRUDPermissions(TaxonName bean) {
469
        if (crud != null) {
470
            newAuthorityCreated = UserHelperAccess.userHelper().createAuthorityForCurrentUser(bean, crud, null);
471
        }
472
    }
473

    
474
    /**
475
     * {@inheritDoc}
476
     */
477
    @Override
478
    protected INameService getService() {
479
        return getRepo().getNameService();
480
    }
481

    
482
    public void doReferenceEditorAdd(NomenclaturalStatusRow row) {
483

    
484
        ReferencePopupEditor referencePopupEditor = openPopupEditor(ReferencePopupEditor.class, null);
485

    
486
        referencePopupEditor.withReferenceTypes(RegistrationUIDefaults.MEDIA_REFERENCE_TYPES);
487
        referencePopupEditor.grantToCurrentUser(SUB_EDITOR_CRUD);
488
        referencePopupEditor.withDeleteButton(true);
489
        referencePopupEditor.loadInEditor(null);
490

    
491
        statusTypeReferencePopupEditorsRowMap.put(referencePopupEditor, row);
492
    }
493

    
494
    public void doReferenceEditorEdit(NomenclaturalStatusRow row) {
495

    
496
        ReferencePopupEditor referencePopupEditor = openPopupEditor(ReferencePopupEditor.class, null);
497
        referencePopupEditor.withReferenceTypes(RegistrationUIDefaults.MEDIA_REFERENCE_TYPES);
498
        referencePopupEditor.grantToCurrentUser(SUB_EDITOR_CRUD);
499
        referencePopupEditor.withDeleteButton(true);
500
        referencePopupEditor.loadInEditor(row.citation.getValue().getUuid());
501

    
502
        statusTypeReferencePopupEditorsRowMap.put(referencePopupEditor, row);
503
    }
504

    
505
    private void configureReferencePopupEditor(ReferencePopupEditor referenceEditorPopup, UUID referenceUUID) {
506

    
507
        boolean nomRefSectionEditingOnly = getView()
508
                .isModeEnabled(TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY);
509

    
510
        // TODO this should be configurable per UI -
511
        // RegistrationUiReferenceEditorFormConfigurator as spring bean,
512
        // different spring profiles
513
        boolean limitToSectionEditing = nomRefSectionEditingOnly && newReferenceInstantiator != null;
514
        RegistrationUiReferenceEditorFormConfigurator
515
                .create(limitToSectionEditing).configure(referenceEditorPopup, nomRefSectionEditingOnly ? newReferenceInstantiator : null);
516

    
517
        referenceEditorPopup.loadInEditor(referenceUUID);
518
        if (!nomRefSectionEditingOnly) {
519
            referenceEditorPopup.getTypeSelect().setValue(ReferenceType.Article);
520
        }
521
    }
522

    
523
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
524
    public void onReferenceEditorActionAdd(ReferenceEditorAction event) {
525

    
526
        if (getView() == null || event.getSourceView() != getView()) {
527
            return;
528
        }
529

    
530
        ReferencePopupEditor referenceEditorPopup = openPopupEditor(ReferencePopupEditor.class, event);
531

    
532
        referenceEditorPopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
533
        referenceEditorPopup.withDeleteButton(true);
534
        configureReferencePopupEditor(referenceEditorPopup, null);
535
    }
536

    
537
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
538
    public void onReferenceEditorActionEdit(ReferenceEditorAction event) {
539

    
540
        if (!isFromOwnView(event)) {
541
            return;
542
        }
543
        ReferencePopupEditor referenceEditorPopup = openPopupEditor(ReferencePopupEditor.class, event);
544

    
545
        referenceEditorPopup.withDeleteButton(true);
546
        configureReferencePopupEditor(referenceEditorPopup, event.getEntityUuid());
547
    }
548

    
549
    @EventBusListenerMethod
550
    public void onFieldReplaceEvent(FieldReplaceEvent<String> event) {
551

    
552
        PropertyIdPath boundPropertyIdPath = boundPropertyIdPath(event.getNewField());
553
        if (boundPropertyIdPath != null) {
554
            TaxonNameDTO taxonNamedto = ((AbstractPopupEditor<TaxonNameDTO, AbstractCdmDTOEditorPresenter<TaxonNameDTO, TaxonName, ?>>) getView())
555
                    .getBean();
556
            if (boundPropertyIdPath.matches("specificEpithet")) {
557
                AbstractField<String> genusOrUninomialField = getView().getGenusOrUninomialField();
558
                if (event.getNewField() instanceof CompositeCustomField) {
559
                    if (specificEpithetPartPagingProvider == null) {
560
                        specificEpithetPartPagingProvider = new TaxonNameStringFilterablePagingProvider(
561
                                getRepo().getNameService(), Rank.SPECIES());
562
                    }
563
                    specificEpithetPartPagingProvider.listenToFields(genusOrUninomialField, null, null, null);
564
                    specificEpithetPartPagingProvider.excludeNames(taxonNamedto.cdmEntity());
565
                    specificEpithetPartPagingProvider.updateFromFields();
566
                    WeaklyRelatedEntityCombobox<TaxonName> specificEpithetField = (WeaklyRelatedEntityCombobox<TaxonName>) event
567
                            .getNewField();
568
                    refreshSpecificEpithetComboBoxListener = e -> {
569
                        specificEpithetField.getSelect().refresh();
570
                        specificEpithetField.setValue(null);
571
                    };
572
                    specificEpithetField.loadFrom(specificEpithetPartPagingProvider, specificEpithetPartPagingProvider,
573
                            specificEpithetPartPagingProvider.getPageSize());
574
                    specificEpithetField.setValue(event.getOldField().getValue());
575
                    specificEpithetField.reload();
576
                    genusOrUninomialField.addValueChangeListener(refreshSpecificEpithetComboBoxListener);
577
                } else {
578
                    if (specificEpithetPartPagingProvider != null) {
579
                        specificEpithetPartPagingProvider.unlistenAllFields();
580
                    }
581
                    if (refreshSpecificEpithetComboBoxListener != null) {
582
                        genusOrUninomialField.removeValueChangeListener(refreshSpecificEpithetComboBoxListener);
583
                        refreshSpecificEpithetComboBoxListener = null;
584
                    }
585
                }
586
            } else if (boundPropertyIdPath.matches("genusOrUninomial")) {
587
                if (event.getNewField() instanceof CompositeCustomField) {
588
                    if (genusOrUninomialPartPagingProvider == null) {
589
                        genusOrUninomialPartPagingProvider = new TaxonNameStringFilterablePagingProvider(
590
                                getRepo().getNameService());
591
                    }
592
                    genusOrUninomialPartPagingProvider.listenToFields(null, getView().getInfraGenericEpithetField(),
593
                            getView().getSpecificEpithetField(), getView().getInfraSpecificEpithetField());
594
                    genusOrUninomialPartPagingProvider.excludeNames(taxonNamedto.cdmEntity());
595
                    WeaklyRelatedEntityCombobox<TaxonName> genusOrUninomialField = (WeaklyRelatedEntityCombobox<TaxonName>) event
596
                            .getNewField();
597
                    genusOrUninomialField.loadFrom(genusOrUninomialPartPagingProvider,
598
                            genusOrUninomialPartPagingProvider, genusOrUninomialPartPagingProvider.getPageSize());
599
                    genusOrUninomialField.setValue(event.getOldField().getValue());
600
                    genusOrUninomialField.reload();
601
                } else {
602
                    if (genusOrUninomialPartPagingProvider != null) {
603
                        genusOrUninomialPartPagingProvider.unlistenAllFields();
604
                    }
605
                }
606

    
607
            }
608
        }
609

    
610
    }
611

    
612
    @EventBusListenerMethod
613
    public void onEntityChangeEvent(EntityChangeEvent<?> event) {
614

    
615
        if (event.getSourceView() instanceof AbstractPopupEditor) {
616

    
617
            BoundField boundTargetField = boundTargetField((PopupView) event.getSourceView());
618

    
619
            if (boundTargetField != null) {
620
                if (boundTargetField.matchesPropertyIdPath("genusOrUninomial")) {
621
                    if (event.isCreateOrModifiedType()) {
622
                        getCache().load(event.getEntity());
623
                        if (getView().getGenusOrUninomialField() instanceof WeaklyRelatedEntityCombobox) {
624
                            WeaklyRelatedEntityCombobox<TaxonName> weaklyRelatedEntityCombobox = (WeaklyRelatedEntityCombobox<TaxonName>) getView()
625
                                    .getGenusOrUninomialField();
626
                            weaklyRelatedEntityCombobox.setValue(((TaxonName) event.getEntity()).getGenusOrUninomial());
627
                            // NOTE: in contrast to the ToOneRelatedEntityCombobox the .discard() does not
628
                            // work here since no datasource is bound to the field, see weaklyRelatedEntityCombobox.reload()
629
                            weaklyRelatedEntityCombobox.updateButtons();
630
                        }
631
                    }
632
                } else if (boundTargetField.matchesPropertyIdPath("specificEpithet")) {
633
                    if (event.isCreateOrModifiedType()) {
634
                        getCache().load(event.getEntity());
635
                        if (getView().getSpecificEpithetField() instanceof WeaklyRelatedEntityCombobox) {
636
                            WeaklyRelatedEntityCombobox<TaxonName> weaklyRelatedEntityCombobox = (WeaklyRelatedEntityCombobox<TaxonName>) getView()
637
                                    .getSpecificEpithetField();
638
                            getView().getSpecificEpithetField()
639
                                    .setValue(((TaxonName) event.getEntity()).getSpecificEpithet());
640
                            weaklyRelatedEntityCombobox.reload();
641
                            // NOTE: in contrast to the ToOneRelatedEntityCombobox the .discard() does not
642
                            // work here since no datasource is bound to the field, see weaklyRelatedEntityCombobox.reload()
643
                            weaklyRelatedEntityCombobox.updateButtons();
644
                        }
645
                    }
646
                } else if (boundTargetField.matchesPropertyIdPath("nomenclaturalReference")) {
647
                    if (event.isCreateOrModifiedType()) {
648
                        getCache().load(event.getEntity());
649
                        if (event.isCreatedType()) {
650
                            getView().getNomReferenceCombobox().setValue((Reference) event.getEntity());
651
                        } else {
652
                            getView().getNomReferenceCombobox().reload(); // refreshSelectedValue(modifiedReference);
653
                        }
654
                        getView().getCombinationAuthorshipField().discard(); //refresh from the datasource
655
                        getView().updateAuthorshipFields();
656
                    }
657
                } else if (boundTargetField.matchesPropertyIdPath("validationFor.otherName")
658
                        || boundTargetField.matchesPropertyIdPath("orthographicVariant.otherName")) {
659
                    ReloadableLazyComboBox<TaxonName> otherNameField = asReloadableLazyComboBox(
660
                            boundTargetField.getField(TaxonName.class));
661
                    TaxonName otherName = (TaxonName) event.getEntity();
662
                    if (event.isCreateOrModifiedType()) {
663
                        getCache().load(otherName);
664
                        if (event.isCreatedType()) {
665
                            // TODO use reloadWith((TaxonName)
666
                            // event.getEntity()); also in this case?
667
                            otherNameField.setValue(otherName);
668
                        } else {
669
                            otherNameField.reloadWith(otherName);
670
                        }
671

    
672
                    } else if (event.isRemovedType()) {
673
                        otherNameField.setValue(null);
674
                    }
675
                } else if (boundTargetField.matchesPropertyIdPath("basionyms")) {
676
                    ReloadableLazyComboBox<TaxonName> basionymSourceField = asReloadableLazyComboBox(
677
                            boundTargetField.getField(TaxonName.class));
678
                    if (event.isCreateOrModifiedType()) {
679
                        getCache().load(event.getEntity());
680
                        if (event.isCreatedType()) {
681
                            // TODO use reloadWith((TaxonName)
682
                            // event.getEntity()); also in this case?
683
                            basionymSourceField.setValue((TaxonName) event.getEntity());
684
                        } else {
685
                            basionymSourceField.reloadWith((TaxonName) event.getEntity());
686
                        }
687
                        getView().getBasionymAuthorshipField().discard(); //refresh from the datasource
688
                        getView().getExBasionymAuthorshipField().discard(); //refresh from the datasource
689
                        getView().updateAuthorshipFields();
690
                    } else if (event.isRemovedType()) {
691
                        basionymSourceField.setValue(null);
692
                        getView().updateAuthorshipFields();
693
                    }
694
                } else if (boundTargetField.matchesPropertyIdPath("replacedSynonyms")) {
695
                    ReloadableLazyComboBox<TaxonName> replacedSynonyms = asReloadableLazyComboBox(
696
                            boundTargetField.getField(TaxonName.class));
697
                    if (event.isCreateOrModifiedType()) {
698
                        getCache().load(event.getEntity());
699
                        if (event.isCreatedType()) {
700
                            // TODO use reloadWith((TaxonName)
701
                            // event.getEntity()); also in this case?
702
                            replacedSynonyms.setValue((TaxonName) event.getEntity());
703
                        } else {
704
                            replacedSynonyms.reloadWith((TaxonName) event.getEntity());
705
                        }
706
                        getView().getExCombinationAuthorshipField().discard(); //refresh from the datasource
707
                        getView().updateAuthorshipFields();
708
                    } else if (event.isRemovedType()) {
709
                        replacedSynonyms.setValue(null);
710
                        getView().updateAuthorshipFields();
711
                    }
712
                }
713

    
714
            }
715
        }
716
    }
717

    
718
    protected <CDM extends CdmBase> ReloadableLazyComboBox<CDM> asReloadableLazyComboBox(Field<CDM> field) {
719

    
720
        if (field instanceof ToOneRelatedEntityCombobox) {
721
            field = ((ToOneRelatedEntityCombobox<CDM>) field).getSelect();
722
        }
723
        return (ReloadableLazyComboBox<CDM>) field;
724
    }
725

    
726
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
727
    public void onTaxonNameEditorActionEdit(TaxonNameEditorAction event) {
728

    
729
        if (getView() == null || event.getSourceView() != getView()) {
730
            return;
731
        }
732

    
733
        PropertyIdPath boundPropertyId = boundPropertyIdPath(event.getTarget());
734

    
735
        if (boundPropertyId != null) {
736
            if (boundPropertyId.matches("validationFor.otherName") || boundPropertyId.matches("basionyms")
737
                    || boundPropertyId.matches("replacedSynonyms")
738
                    || boundPropertyId.matches("orthographicVariant.otherName")) {
739
                TaxonNamePopupEditor namePopup = openPopupEditor(TaxonNamePopupEditor.class, event);
740
                namePopup.withDeleteButton(true);
741
                getView().getModesActive().stream()
742
                        .filter(m -> !TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY.equals(m))
743
                        .forEach(m -> namePopup.enableMode(m));
744
                if (boundPropertyId.matches("orthographicVariant.otherName")
745
                        && getView().isModeEnabled(TaxonNamePopupEditorMode.ORTHOGRAPHIC_CORRECTION)) {
746
                    namePopup.enableMode(TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY);
747
                    namePopup.disableMode(TaxonNamePopupEditorMode.VALIDATE_AGAINST_HIGHER_NAME_PART);
748
                    namePopup.getOrthographicVariantToggle().setVisible(false);
749
                }
750
                namePopup.loadInEditor(event.getEntityUuid());
751
            }
752
        }
753
    }
754

    
755
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
756
    public void onTaxonNameEditorActionStrRepEdit(TaxonNameEditorActionStrRep event) {
757

    
758
        if (getView() == null || event.getSourceView() != getView()) {
759
            return;
760
        }
761

    
762
        PropertyIdPath boundPropertyId = boundPropertyIdPath(event.getTarget());
763

    
764
        if (boundPropertyId != null) {
765
            if (boundPropertyId.matches("genusOrUninomial") || boundPropertyId.matches("specificEpithet")) {
766
                TaxonNamePopupEditor namePopup = openPopupEditor(TaxonNamePopupEditor.class, event);
767
                namePopup.withDeleteButton(true);
768
                getView().getModesActive().stream()
769
                        .filter(m -> !TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY.equals(m))
770
                        .forEach(m -> namePopup.enableMode(m));
771
                namePopup.loadInEditor(event.getEntityUuid());
772
            }
773
        }
774
    }
775

    
776
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
777
    public void onTaxonNameEditorActionAdd(TaxonNameEditorAction event) {
778

    
779
        if (getView() == null || event.getSourceView() != getView()) {
780
            return;
781
        }
782

    
783
        PropertyIdPath boundPropertyId = boundPropertyIdPath(event.getTarget());
784

    
785
        if (boundPropertyId != null) {
786
            if (boundPropertyId.matches("validationFor.otherName") || boundPropertyId.matches("basionyms")
787
                    || boundPropertyId.matches("replacedSynonyms")
788
                    || boundPropertyId.matches("orthographicVariant.otherName")) {
789
                TaxonNamePopupEditor namePopup = openPopupEditor(TaxonNamePopupEditor.class, event);
790
                namePopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
791
                namePopup.withDeleteButton(true);
792
                getView().getModesActive().stream()
793
                        .filter(m -> !TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY.equals(m))
794
                        .forEach(m -> namePopup.enableMode(m));
795
                if (boundPropertyId.matches("orthographicVariant.otherName")
796
                        && getView().isModeEnabled(TaxonNamePopupEditorMode.ORTHOGRAPHIC_CORRECTION)) {
797
                    namePopup.enableMode(TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY);
798
                    namePopup.disableMode(TaxonNamePopupEditorMode.VALIDATE_AGAINST_HIGHER_NAME_PART);
799
                    Reference nomrefPreset = (Reference) ((AbstractPopupEditor<TaxonNameDTO, TaxonNameEditorPresenter>) getView())
800
                            .getBean().getNomenclaturalReference();
801
                    namePopup.setCdmEntityInstantiator(new BeanInstantiator<TaxonName>() {
802

    
803
                        @Override
804
                        public TaxonName createNewBean() {
805
                            TaxonName newTaxonName = TaxonNameFactory
806
                                    .NewNameInstance(RegistrationUIDefaults.NOMENCLATURAL_CODE, Rank.SPECIES());
807
                            newTaxonName.setNomenclaturalReference(getRepo().getReferenceService()
808
                                    .load(nomrefPreset.getUuid(), TaxonNameEditorPresenter.REFERENCE_INIT_STRATEGY));
809
                            return newTaxonName;
810
                        }
811
                    });
812
                    namePopup.getOrthographicVariantToggle().setVisible(false);
813
                }
814
                namePopup.loadInEditor(null);
815
            }
816
        }
817
    }
818

    
819
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
820
    public void onTaxonNameEditorActionStrRepAdd(TaxonNameEditorActionStrRep event) {
821

    
822
        if (getView() == null || event.getSourceView() != getView()) {
823
            return;
824
        }
825

    
826
        PropertyIdPath boundPropertyId = boundPropertyIdPath(event.getTarget());
827

    
828
        if (boundPropertyId != null) {
829
            if (boundPropertyId.matches("genusOrUninomial") || boundPropertyId.matches("specificEpithet")) {
830
                TaxonNamePopupEditor namePopup = openPopupEditor(TaxonNamePopupEditor.class, event);
831
                namePopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
832
                namePopup.withDeleteButton(true);
833
                getView().getModesActive().stream()
834
                        .filter(m -> !TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY.equals(m))
835
                        .forEach(m -> namePopup.enableMode(m));
836
                namePopup.loadInEditor(null);
837
                if (boundPropertyId.matches("genusOrUninomial")) {
838
                    namePopup.getRankSelect().setValue(Rank.GENUS());
839
                }
840
                if (boundPropertyId.matches("specificEpithet")) {
841
                    namePopup.getGenusOrUninomialField().setValue(getView().getGenusOrUninomialField().getValue());
842
                    namePopup.getRankSelect().setValue(Rank.SPECIES());
843
                }
844
                if (WeaklyRelatedEntityField.class.isAssignableFrom(event.getTarget().getClass())) {
845
                    WeaklyRelatedEntityField<TaxonName> taxoNameField = (WeaklyRelatedEntityField<TaxonName>) event
846
                            .getTarget();
847
                    if (!taxoNameField.isValueInOptions()) {
848
                        String nameString = event.getTarget().getValue();
849
                        if (StringUtils.isNotEmpty(nameString)) {
850
                            if (boundPropertyId.matches("genusOrUninomial")) {
851
                                namePopup.getGenusOrUninomialField().setValue(nameString);
852
                            }
853
                            if (boundPropertyId.matches("specificEpithet")) {
854
                                namePopup.getSpecificEpithetField().setValue(nameString);
855
                            }
856
                        }
857
                    }
858
                }
859
            }
860
        }
861
    }
862

    
863
    /**
864
     * {@inheritDoc}
865
     */
866
    @Override
867
    protected TaxonNameDTO createDTODecorator(TaxonName cdmEntitiy) {
868
        return new TaxonNameDTO(cdmEntitiy);
869
    }
870

    
871
    /**
872
     * {@inheritDoc}
873
     */
874
    @Override
875
    protected BeanInstantiator<TaxonName> defaultCdmEntityInstantiator() {
876
        return new BeanInstantiator<TaxonName>() {
877

    
878
            @Override
879
            public TaxonName createNewBean() {
880
                return TaxonNameFactory.NewNameInstance(RegistrationUIDefaults.NOMENCLATURAL_CODE, Rank.SPECIES());
881
            }
882
        };
883
    }
884

    
885
}
(14-14/18)