Project

General

Profile

Download (37 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.List;
14
import java.util.UUID;
15

    
16
import org.apache.commons.lang.StringUtils;
17
import org.apache.log4j.Logger;
18
import org.hibernate.criterion.Restrictions;
19
import org.springframework.context.annotation.Scope;
20
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
21

    
22
import com.vaadin.data.Property;
23
import com.vaadin.spring.annotation.SpringComponent;
24
import com.vaadin.ui.AbstractField;
25
import com.vaadin.ui.Field;
26
import com.vaadin.ui.Notification;
27
import com.vaadin.ui.Notification.Type;
28

    
29
import eu.etaxonomy.cdm.api.service.INameService;
30
import eu.etaxonomy.cdm.model.agent.AgentBase;
31
import eu.etaxonomy.cdm.model.agent.Person;
32
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
33
import eu.etaxonomy.cdm.model.common.AnnotationType;
34
import eu.etaxonomy.cdm.model.common.CdmBase;
35
import eu.etaxonomy.cdm.model.common.TermType;
36
import eu.etaxonomy.cdm.model.name.Rank;
37
import eu.etaxonomy.cdm.model.name.TaxonName;
38
import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
39
import eu.etaxonomy.cdm.model.reference.Reference;
40
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
41
import eu.etaxonomy.cdm.model.reference.ReferenceType;
42
import eu.etaxonomy.cdm.persistence.dao.common.Restriction;
43
import eu.etaxonomy.cdm.persistence.dao.common.Restriction.Operator;
44
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
45
import eu.etaxonomy.cdm.service.CdmFilterablePagingProvider;
46
import eu.etaxonomy.cdm.service.TaxonNameStringFilterablePagingProvider;
47
import eu.etaxonomy.cdm.service.UserHelperAccess;
48
import eu.etaxonomy.cdm.service.initstrategies.AgentBaseInit;
49
import eu.etaxonomy.cdm.vaadin.component.CdmBeanItemContainerFactory;
50
import eu.etaxonomy.cdm.vaadin.event.EditorActionTypeFilter;
51
import eu.etaxonomy.cdm.vaadin.event.EntityChangeEvent;
52
import eu.etaxonomy.cdm.vaadin.event.ReferenceEditorAction;
53
import eu.etaxonomy.cdm.vaadin.event.TaxonNameEditorAction;
54
import eu.etaxonomy.cdm.vaadin.event.TaxonNameEditorActionStrRep;
55
import eu.etaxonomy.cdm.vaadin.event.ToOneRelatedEntityButtonUpdater;
56
import eu.etaxonomy.cdm.vaadin.event.ToOneRelatedEntityReloader;
57
import eu.etaxonomy.cdm.vaadin.model.name.TaxonNameDTO;
58
import eu.etaxonomy.cdm.vaadin.ui.RegistrationUIDefaults;
59
import eu.etaxonomy.cdm.vaadin.util.CdmTitleCacheCaptionGenerator;
60
import eu.etaxonomy.cdm.vaadin.view.reference.ReferencePopupEditor;
61
import eu.etaxonomy.vaadin.component.CompositeCustomField;
62
import eu.etaxonomy.vaadin.component.ReloadableLazyComboBox;
63
import eu.etaxonomy.vaadin.component.ToOneRelatedEntityCombobox;
64
import eu.etaxonomy.vaadin.component.WeaklyRelatedEntityCombobox;
65
import eu.etaxonomy.vaadin.component.WeaklyRelatedEntityField;
66
import eu.etaxonomy.vaadin.event.FieldReplaceEvent;
67
import eu.etaxonomy.vaadin.mvp.AbstractCdmDTOEditorPresenter;
68
import eu.etaxonomy.vaadin.mvp.AbstractPopupEditor;
69
import eu.etaxonomy.vaadin.mvp.BeanInstantiator;
70
import eu.etaxonomy.vaadin.mvp.BoundField;
71
import eu.etaxonomy.vaadin.ui.view.PopupView;
72
import eu.etaxonomy.vaadin.util.PropertyIdPath;
73

    
74
/**
75
 * @author a.kohlbecker
76
 * @since May 22, 2017
77
 *
78
 */
79
@SpringComponent
80
@Scope("prototype")
81
public class TaxonNameEditorPresenter extends AbstractCdmDTOEditorPresenter<TaxonNameDTO, TaxonName, TaxonNamePopupEditorView> {
82

    
83

    
84
    private static final List<String> RELATED_NAME_INIT_STRATEGY = Arrays.asList(
85
            "$",
86
            "relationsFromThisName",
87
            "relationsToThisName.type",
88
            "homotypicalGroup.typifiedNames"
89
            );
90

    
91
    public static final List<String> REFERENCE_INIT_STRATEGY = Arrays.asList("authorship", "inReference.authorship", "inReference.inReference.authorship", "inReference.inReference.inReference.authorship");
92

    
93
    private static final long serialVersionUID = -3538980627079389221L;
94

    
95
    private static final Logger logger = Logger.getLogger(TaxonNameEditorPresenter.class);
96

    
97
    private CdmFilterablePagingProvider<Reference, Reference> nomReferencePagingProvider;
98

    
99
    private Reference publishedUnit;
100

    
101
    private BeanInstantiator<Reference> newReferenceInstantiator;
102

    
103
    private TaxonNameStringFilterablePagingProvider genusOrUninomialPartPagingProvider;
104

    
105
    private TaxonNameStringFilterablePagingProvider specificEpithetPartPagingProvider;
106

    
107
    private Property.ValueChangeListener refreshSpecificEpithetComboBoxListener;
108

    
109
    private CdmFilterablePagingProvider<TaxonName, TaxonName> relatedNamePagingProvider;
110

    
111
    private CdmFilterablePagingProvider<TaxonName, TaxonName> orthographicVariantNamePagingProvider;
112

    
113
    private Restriction<Reference> orthographicCorrectionRestriction;
114

    
115
    private Integer taxonNameId;
116

    
117
    /**
118
     * {@inheritDoc}
119
     */
120
    @Override
121
    public void handleViewEntered() {
122

    
123
        super.handleViewEntered();
124

    
125
        CdmBeanItemContainerFactory selectFieldFactory = new CdmBeanItemContainerFactory(getRepo());
126
        getView().getRankSelect().setContainerDataSource(selectFieldFactory.buildBeanItemContainer(TermType.Rank));
127
        getView().getRankSelect().setItemCaptionPropertyId("label");
128

    
129
        CdmFilterablePagingProvider<AgentBase, TeamOrPersonBase> termOrPersonPagingProvider = new CdmFilterablePagingProvider<AgentBase, TeamOrPersonBase>(getRepo().getAgentService(), TeamOrPersonBase.class);
130
        termOrPersonPagingProvider.setInitStrategy(AgentBaseInit.TEAM_OR_PERSON_INIT_STRATEGY);
131
        CdmFilterablePagingProvider<AgentBase, Person> personPagingProvider = new CdmFilterablePagingProvider<AgentBase, Person>(getRepo().getAgentService(), Person.class);
132

    
133
        getView().getCombinationAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
134
        getView().getCombinationAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
135

    
136
        getView().getExCombinationAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
137
        getView().getExCombinationAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
138

    
139
        getView().getBasionymAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
140
        getView().getBasionymAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
141

    
142
        getView().getExBasionymAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
143
        getView().getExBasionymAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
144

    
145
        getView().getNomReferenceCombobox().getSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<Reference>());
146
        nomReferencePagingProvider = pagingProviderFactory.referencePagingProvider();
147
        nomReferencePagingProvider.setInitStrategy(REFERENCE_INIT_STRATEGY);
148
        getView().getNomReferenceCombobox().loadFrom(nomReferencePagingProvider, nomReferencePagingProvider, nomReferencePagingProvider.getPageSize());
149
        getView().getNomReferenceCombobox().setNestedButtonStateUpdater(new ToOneRelatedEntityButtonUpdater<Reference>(getView().getNomReferenceCombobox()));
150
        getView().getNomReferenceCombobox().getSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<Reference>());
151
        getView().getNomReferenceCombobox().getSelect().addValueChangeListener(new ToOneRelatedEntityReloader<>(getView().getNomReferenceCombobox(), this));
152
        getView().getNomReferenceCombobox().getSelect().addValueChangeListener( e -> updateOrthographicCorrectionRestriction());
153

    
154

    
155
        relatedNamePagingProvider = new CdmFilterablePagingProvider<TaxonName, TaxonName>(getRepo().getNameService());
156
        relatedNamePagingProvider.setInitStrategy(RELATED_NAME_INIT_STRATEGY);
157
        getView().getBasionymComboboxSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<TaxonName>());
158
        getView().getBasionymComboboxSelect().setPagingProviders(relatedNamePagingProvider, relatedNamePagingProvider, relatedNamePagingProvider.getPageSize(), this);
159

    
160
        getView().getReplacedSynonymsComboboxSelect().setCaptionGenerator( new CdmTitleCacheCaptionGenerator<TaxonName>());
161
        getView().getReplacedSynonymsComboboxSelect().setPagingProviders(relatedNamePagingProvider, relatedNamePagingProvider, relatedNamePagingProvider.getPageSize(), this);
162

    
163
        CdmFilterablePagingProvider<Reference, Reference> icbnCodesPagingProvider = pagingProviderFactory.referencePagingProvider();
164
        icbnCodesPagingProvider.setInitStrategy(REFERENCE_INIT_STRATEGY);
165
        // @formatter:off
166
        // TODO use markers on references instead of isbn. The marker type MarkerType.NOMENCLATURAL_RELEVANT() has already prepared (#7466)
167
        icbnCodesPagingProvider.getCriteria().add(Restrictions.in("isbn", new String[]{
168
                "3-904144-22-7",     // Saint Louis Code
169
                "3-906166-48-1",     // Vienna Code
170
                "978-3-87429-425-6", // Melbourne Code
171
                "978-3-946583-16-5", // Shenzhen Code
172
                "0-85301-006-4"      // ICZN 1999
173
                // ICNB
174
        }));
175
        // @formatter:on
176

    
177
        getView().getValidationField().getRelatedNameComboBox().getSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<TaxonName>());
178
        getView().getValidationField().getRelatedNameComboBox().loadFrom(relatedNamePagingProvider, relatedNamePagingProvider, relatedNamePagingProvider.getPageSize());
179
        getView().getValidationField().getRelatedNameComboBox().getSelect().addValueChangeListener(new ToOneRelatedEntityReloader<>(getView().getValidationField().getRelatedNameComboBox(), this));
180
        getView().getValidationField().getCitatonComboBox().getSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<Reference>());
181
        getView().getValidationField().getCitatonComboBox().loadFrom(icbnCodesPagingProvider, icbnCodesPagingProvider, icbnCodesPagingProvider.getPageSize());
182
        getView().getValidationField().getCitatonComboBox().getSelect().addValueChangeListener(new ToOneRelatedEntityReloader<>(getView().getValidationField().getCitatonComboBox(), this));
183

    
184
        getView().getOrthographicVariantField().getRelatedNameComboBox().getSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<TaxonName>());
185
        getView().getOrthographicVariantField().getRelatedNameComboBox().getSelect().addValueChangeListener(new ToOneRelatedEntityReloader<>(getView().getOrthographicVariantField().getRelatedNameComboBox(), this));
186
        getView().getOrthographicVariantField().getRelatedNameComboBox().loadFrom(relatedNamePagingProvider, relatedNamePagingProvider, relatedNamePagingProvider.getPageSize());
187
        // The Mode TaxonNamePopupEditorMode.ORTHOGRAPHIC_CORRECTION will be handled in the updateOrthographicCorrectionRestriction() method
188
        getView().getOrthographicVariantField().getCitatonComboBox().getSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<Reference>());
189
        getView().getOrthographicVariantField().getCitatonComboBox().loadFrom(icbnCodesPagingProvider, icbnCodesPagingProvider, icbnCodesPagingProvider.getPageSize());
190
        getView().getOrthographicVariantField().getCitatonComboBox().getSelect().addValueChangeListener(new ToOneRelatedEntityReloader<>(getView().getOrthographicVariantField().getCitatonComboBox(), this));
191

    
192

    
193
        getView().getAnnotationsField().setAnnotationTypeItemContainer(selectFieldFactory.buildTermItemContainer(
194
                AnnotationType.EDITORIAL().getUuid(), AnnotationType.TECHNICAL().getUuid()));
195
    }
196

    
197
    @Override
198
    protected void adaptDataProviders() {
199
        updateOrthographicCorrectionRestriction();
200
    }
201

    
202
    private void updateOrthographicCorrectionRestriction() {
203

    
204
        if(getView().isModeEnabled(TaxonNamePopupEditorMode.ORTHOGRAPHIC_CORRECTION)){
205
            if(orthographicVariantNamePagingProvider == null){
206
                orthographicVariantNamePagingProvider = new CdmFilterablePagingProvider<TaxonName, TaxonName>(getRepo().getNameService());
207
                orthographicVariantNamePagingProvider.setInitStrategy(RELATED_NAME_INIT_STRATEGY);
208
                orthographicVariantNamePagingProvider.addRestriction(new Restriction<>("id", Operator.AND_NOT, null, taxonNameId));
209
                getView().getOrthographicVariantField().getRelatedNameComboBox().loadFrom(orthographicVariantNamePagingProvider, orthographicVariantNamePagingProvider, orthographicVariantNamePagingProvider.getPageSize());
210
            }
211
            Reference nomReference = getView().getNomReferenceCombobox().getValue();
212
            if(nomReference == null && orthographicCorrectionRestriction != null){
213
                orthographicVariantNamePagingProvider.getRestrictions().remove(orthographicCorrectionRestriction);
214
            } else {
215
                if(orthographicCorrectionRestriction == null){
216
                    orthographicCorrectionRestriction = new Restriction<>("nomenclaturalReference", Operator.AND, null, nomReference);
217
                    orthographicVariantNamePagingProvider.addRestriction(orthographicCorrectionRestriction);
218
                } else{
219
                    orthographicCorrectionRestriction.setValues(Arrays.asList(nomReference));
220
                }
221
            }
222
            getView().getOrthographicVariantField().getRelatedNameComboBox().getSelect().refresh();
223
        }
224
    }
225

    
226
    @Override
227
    protected TaxonName loadCdmEntity(UUID identifier) {
228

    
229
        List<String> initStrategy = Arrays.asList(
230
                "$",
231
                "annotations.type",
232
                "annotations.*", // needed as log as we are using a table in FilterableAnnotationsField
233
                "rank.vocabulary", // needed for comparing ranks
234

    
235
                "nomenclaturalReference.authorship",
236
                "nomenclaturalReference.inReference.authorship",
237
                "nomenclaturalReference.inReference.inReference.authorship",
238
                "nomenclaturalReference.inReference.inReference.inReference.authorship",
239

    
240
                "status.type",
241

    
242
                "combinationAuthorship",
243
                "exCombinationAuthorship",
244
                "basionymAuthorship",
245
                "exBasionymAuthorship",
246

    
247
                // basionyms: relationsToThisName.fromName
248
                "relationsToThisName.type",
249
                "relationsToThisName.fromName.rank",
250
                "relationsToThisName.fromName.combinationAuthorship",
251
                "relationsToThisName.fromName.exCombinationAuthorship",
252
                "relationsToThisName.fromName.nomenclaturalReference.authorship",
253
                "relationsToThisName.fromName.nomenclaturalReference.inReference.authorship",
254
                "relationsToThisName.fromName.nomenclaturalReference.inReference.inReference.inReference.authorship",
255
                "relationsToThisName.fromName.relationsToThisName",
256
                "relationsToThisName.fromName.relationsFromThisName",
257
                "relationsToThisName.citation",
258

    
259
                "relationsFromThisName",
260
                "homotypicalGroup.typifiedNames"
261
        );
262

    
263
        TaxonName taxonName;
264
        if(identifier != null){
265
            taxonName = getRepo().getNameService().load(identifier, initStrategy);
266
        } else {
267
            taxonName = createCdmEntity();
268
        }
269

    
270
        if(getView().isModeEnabled(TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY)){
271
            Reference nomRef = taxonName.getNomenclaturalReference();
272

    
273
            //getView().getNomReferenceCombobox().setEnabled(nomRef.isOfType(ReferenceType.Section));
274
            publishedUnit = nomRef;
275
            while(publishedUnit.isOfType(ReferenceType.Section) && publishedUnit.getInReference() != null){
276
                publishedUnit = nomRef.getInReference();
277
            }
278
            // reduce available references to those which are sections of the publishedUnit and the publishedUnit itself
279
            // nomReferencePagingProvider
280
            nomReferencePagingProvider.getCriteria().add(Restrictions.or(
281
                    Restrictions.and(Restrictions.eq("inReference", publishedUnit), Restrictions.eq("type", ReferenceType.Section)),
282
                    Restrictions.idEq(publishedUnit.getId())
283
                    )
284
            );
285
            // and remove the empty option
286
            getView().getNomReferenceCombobox().getSelect().setNullSelectionAllowed(false);
287

    
288
            // new Reference only a sub sections of the publishedUnit
289
            newReferenceInstantiator = new BeanInstantiator<Reference>() {
290
                @Override
291
                public Reference createNewBean() {
292
                    Reference newRef = ReferenceFactory.newSection();
293
                    newRef.setInReference(publishedUnit);
294
                    return newRef;
295
                }
296
            };
297

    
298
        }
299

    
300
        taxonNameId = Integer.valueOf(taxonName.getId());
301
        relatedNamePagingProvider.addRestriction(new Restriction<>("id", Operator.AND_NOT, null, taxonNameId));
302

    
303
        return taxonName;
304
    }
305

    
306
    /**
307
     * {@inheritDoc}
308
     */
309
    @Override
310
    protected void guaranteePerEntityCRUDPermissions(UUID identifier) {
311
        if(crud != null){
312
            newAuthorityCreated = UserHelperAccess.userHelper().createAuthorityForCurrentUser(TaxonName.class, identifier, crud, null);
313
        }
314

    
315
    }
316

    
317
    /**
318
     * {@inheritDoc}
319
     */
320
    @Override
321
    protected void guaranteePerEntityCRUDPermissions(TaxonName bean) {
322
        if(crud != null){
323
            newAuthorityCreated = UserHelperAccess.userHelper().createAuthorityForCurrentUser(bean, crud, null);
324
        }
325
    }
326

    
327
    /**
328
     * {@inheritDoc}
329
     */
330
    @Override
331
    protected INameService getService() {
332
        return getRepo().getNameService();
333
    }
334

    
335
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
336
    public void onReferenceEditorActionAdd(ReferenceEditorAction event) {
337

    
338
        if(getView() == null || event.getSourceView() != getView() ){
339
            return;
340
        }
341

    
342
        ReferencePopupEditor referenceEditorPopup = openPopupEditor(ReferencePopupEditor.class, event);
343

    
344
        referenceEditorPopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
345
        referenceEditorPopup.withDeleteButton(true);
346
        referenceEditorPopup.setBeanInstantiator(newReferenceInstantiator);
347
        referenceEditorPopup.loadInEditor(null);
348
        if(newReferenceInstantiator != null){
349
            // this is a bit clumsy, we actually need to inject something like a view configurer
350
            // which can enable, disable fields
351
            referenceEditorPopup.getInReferenceCombobox().setEnabled(false);
352
            referenceEditorPopup.getTypeSelect().setEnabled(false);
353
        }
354
    }
355

    
356
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
357
    public void onReferenceEditorActionEdit(ReferenceEditorAction event) {
358

    
359

    
360
        if(!isFromOwnView(event)){
361
            return;
362
        }
363
        ReferencePopupEditor referenceEditorPopup = openPopupEditor(ReferencePopupEditor.class, event);
364

    
365
        referenceEditorPopup.withDeleteButton(true);
366
        referenceEditorPopup.setBeanInstantiator(newReferenceInstantiator);
367
        referenceEditorPopup.loadInEditor(event.getEntityUuid());
368
        if(newReferenceInstantiator != null){
369
            // this is a bit clumsy, we actually need to inject something like a view configurator
370
            // which can enable, disable fields
371
            referenceEditorPopup.getInReferenceCombobox().setEnabled(false);
372
            referenceEditorPopup.getTypeSelect().setEnabled(false);
373
        }
374
    }
375

    
376
    @EventBusListenerMethod
377
    public void onFieldReplaceEvent(FieldReplaceEvent<String> event){
378

    
379
        PropertyIdPath boundPropertyIdPath = boundPropertyIdPath(event.getNewField());
380
        if(boundPropertyIdPath != null){
381
            TaxonNameDTO taxonNamedto = ((AbstractPopupEditor<TaxonNameDTO, AbstractCdmDTOEditorPresenter<TaxonNameDTO, TaxonName,?>>)getView()).getBean();
382
            if(boundPropertyIdPath.matches("specificEpithet")){
383
                AbstractField<String> genusOrUninomialField = getView().getGenusOrUninomialField();
384
                if(event.getNewField() instanceof CompositeCustomField){
385
                    if(specificEpithetPartPagingProvider == null){
386
                        specificEpithetPartPagingProvider = new TaxonNameStringFilterablePagingProvider(getRepo().getNameService(), Rank.SPECIES());
387
                    }
388
                    specificEpithetPartPagingProvider.listenToFields(
389
                            genusOrUninomialField,
390
                            null, null, null);
391
                    specificEpithetPartPagingProvider.excludeNames(taxonNamedto.cdmEntity());
392
                    specificEpithetPartPagingProvider.updateFromFields();
393
                    WeaklyRelatedEntityCombobox<TaxonName> specificEpithetField = (WeaklyRelatedEntityCombobox<TaxonName>)event.getNewField();
394
                    refreshSpecificEpithetComboBoxListener = e -> { specificEpithetField.getSelect().refresh(); specificEpithetField.setValue(null);};
395
                    specificEpithetField.loadFrom(specificEpithetPartPagingProvider, specificEpithetPartPagingProvider, specificEpithetPartPagingProvider.getPageSize());
396
                    specificEpithetField.setValue(event.getOldField().getValue());
397
                    specificEpithetField.reload();
398
                    genusOrUninomialField.addValueChangeListener(refreshSpecificEpithetComboBoxListener);
399
                } else {
400
                    if(specificEpithetPartPagingProvider != null){
401
                        specificEpithetPartPagingProvider.unlistenAllFields();
402
                    }
403
                    if(refreshSpecificEpithetComboBoxListener != null){
404
                        genusOrUninomialField.removeValueChangeListener(refreshSpecificEpithetComboBoxListener);
405
                        refreshSpecificEpithetComboBoxListener = null;
406
                    }
407
                }
408
            } else if(boundPropertyIdPath.matches("genusOrUninomial")) {
409
                if(event.getNewField() instanceof CompositeCustomField){
410
                    if(genusOrUninomialPartPagingProvider  == null){
411
                        genusOrUninomialPartPagingProvider = new TaxonNameStringFilterablePagingProvider(getRepo().getNameService());
412
                    }
413
                    genusOrUninomialPartPagingProvider.listenToFields(
414
                                null,
415
                                getView().getInfraGenericEpithetField(),
416
                                getView().getSpecificEpithetField(),
417
                                getView().getInfraSpecificEpithetField()
418
                               );
419
                    genusOrUninomialPartPagingProvider.excludeNames(taxonNamedto.cdmEntity());
420
                    WeaklyRelatedEntityCombobox<TaxonName> genusOrUninomialField = (WeaklyRelatedEntityCombobox<TaxonName>)event.getNewField();
421
                    genusOrUninomialField.loadFrom(genusOrUninomialPartPagingProvider, genusOrUninomialPartPagingProvider, genusOrUninomialPartPagingProvider.getPageSize());
422
                    genusOrUninomialField.setValue(event.getOldField().getValue());
423
                    genusOrUninomialField.reload();
424
                }else {
425
                    if(genusOrUninomialPartPagingProvider != null){
426
                        genusOrUninomialPartPagingProvider.unlistenAllFields();
427
                    }
428
                }
429

    
430
            }
431
        }
432

    
433
    }
434

    
435
    @EventBusListenerMethod
436
    public void onEntityChangeEvent(EntityChangeEvent<?> event){
437

    
438
        if(event.getSourceView() instanceof AbstractPopupEditor) {
439

    
440
            BoundField boundTargetField = boundTargetField((PopupView) event.getSourceView());
441

    
442
            if(boundTargetField != null){
443
                if(boundTargetField.matchesPropertyIdPath("genusOrUninomial")){
444
                    if(event.isCreateOrModifiedType()){
445
                        getCache().load(event.getEntity());
446
                        if(getView().getGenusOrUninomialField() instanceof WeaklyRelatedEntityCombobox){
447
                            WeaklyRelatedEntityCombobox<TaxonName> weaklyRelatedEntityCombobox = (WeaklyRelatedEntityCombobox<TaxonName>)getView().getGenusOrUninomialField();
448
                            if(event.isCreatedType()){
449
                                weaklyRelatedEntityCombobox.setValue(((TaxonName)event.getEntity()).getGenusOrUninomial());
450
                                weaklyRelatedEntityCombobox.reload();
451
                            } else {
452
                                weaklyRelatedEntityCombobox.reload();
453
                            }
454
                            // NOTE: in constrast to the ToOneRelatedEntityCombobox the .discard() does not
455
                            // work here since no datasource is bound to the field, see weaklyRelatedEntityCombobox.reload()
456
                            weaklyRelatedEntityCombobox.updateButtons();
457
                        }
458
                    }
459
                } else
460
                if(boundTargetField.matchesPropertyIdPath("specificEpithet")){
461
                    if(event.isCreateOrModifiedType()){
462
                        getCache().load(event.getEntity());
463

    
464
                        if(getView().getSpecificEpithetField() instanceof WeaklyRelatedEntityCombobox){
465
                            WeaklyRelatedEntityCombobox weaklyRelatedEntityCombobox = (WeaklyRelatedEntityCombobox)getView().getSpecificEpithetField();
466
                            if(event.isCreatedType()){
467
                                getView().getSpecificEpithetField().setValue(((TaxonName)event.getEntity()).getSpecificEpithet());
468
                                weaklyRelatedEntityCombobox.reload();
469
                            } else {
470
                                weaklyRelatedEntityCombobox.reload();
471
                            }
472
                            // NOTE: in constrast to the ToOneRelatedEntityCombobox the .discard() does not
473
                            // work here since no datasource is bound to the field, see weaklyRelatedEntityCombobox.reload()
474
                            weaklyRelatedEntityCombobox.updateButtons();
475
                        }
476
                    }
477
                } else
478
                if(boundTargetField.matchesPropertyIdPath("nomenclaturalReference")){
479
                    if(event.isCreateOrModifiedType()){
480
                        getCache().load(event.getEntity());
481
                        if(event.isCreatedType()){
482
                            getView().getNomReferenceCombobox().setValue((Reference) event.getEntity());
483
                        } else {
484
                            getView().getNomReferenceCombobox().reload(); // refreshSelectedValue(modifiedReference);
485
                        }
486
                        getView().getCombinationAuthorshipField().discard(); //refresh from the datasource
487
                        getView().updateAuthorshipFields();
488
                    }
489
                } else
490
                if(boundTargetField.matchesPropertyIdPath("validationFor.otherName")){
491
                    ReloadableLazyComboBox<TaxonName> otherNameField = asReloadableLazyComboBox(boundTargetField.getField(TaxonName.class));
492
                    if(event.isCreateOrModifiedType()){
493
                        getCache().load(event.getEntity());
494
                        if(event.isCreatedType()){
495
                            otherNameField.setValue((TaxonName) event.getEntity());
496
                        } else {
497
                            otherNameField.reload();
498
                        }
499
                    } else
500
                    if(event.isRemovedType()){
501
                        otherNameField.setValue(null);
502
                    }
503
                } else
504
                if(boundTargetField.matchesPropertyIdPath("basionyms")){
505
                    ReloadableLazyComboBox<TaxonName> basionymSourceField = asReloadableLazyComboBox(boundTargetField.getField(TaxonName.class));
506
                    if(event.isCreateOrModifiedType()){
507
                        getCache().load(event.getEntity());
508
                        if(event.isCreatedType()){
509
                            basionymSourceField .setValue((TaxonName) event.getEntity());
510
                        } else {
511
                            basionymSourceField.reload();
512
                        }
513
                        getView().getBasionymAuthorshipField().discard(); //refresh from the datasource
514
                        getView().getExBasionymAuthorshipField().discard(); //refresh from the datasource
515
                        getView().updateAuthorshipFields();
516
                    } else
517
                    if(event.isRemovedType()){
518
                        basionymSourceField.setValue(null);
519
                        getView().updateAuthorshipFields();
520
                    }
521
                } else
522
                if(boundTargetField.matchesPropertyIdPath("replacedSynonyms")){
523
                    ReloadableLazyComboBox<TaxonName> replacedSynonyms = asReloadableLazyComboBox(boundTargetField.getField(TaxonName.class));
524
                    if(event.isCreateOrModifiedType()){
525
                        getCache().load(event.getEntity());
526
                        if(event.isCreatedType()){
527
                            replacedSynonyms .setValue((TaxonName) event.getEntity());
528
                        } else {
529
                            replacedSynonyms.reload();
530
                        }
531
                        getView().getExCombinationAuthorshipField().discard(); //refresh from the datasource
532
                        getView().updateAuthorshipFields();
533
                    } else
534
                    if(event.isRemovedType()){
535
                        replacedSynonyms.setValue(null);
536
                        getView().updateAuthorshipFields();
537
                    }
538
                }
539

    
540
            }
541
        }
542
    }
543

    
544
    protected <CDM extends CdmBase> ReloadableLazyComboBox<CDM> asReloadableLazyComboBox(Field<CDM> field){
545

    
546
        if(field instanceof ToOneRelatedEntityCombobox){
547
            field = ((ToOneRelatedEntityCombobox<CDM>)field).getSelect();
548
        }
549
        return (ReloadableLazyComboBox<CDM>)field;
550
    }
551

    
552

    
553

    
554
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
555
    public void onTaxonNameEditorActionEdit(TaxonNameEditorAction event) {
556

    
557
        if(getView() == null || event.getSourceView() != getView() ){
558
            return;
559
        }
560

    
561
        PropertyIdPath boundPropertyId = boundPropertyIdPath(event.getTarget());
562

    
563
        if(boundPropertyId != null){
564
            if(boundPropertyId.matches("validationFor.otherName") || boundPropertyId.matches("basionyms") || boundPropertyId.matches("replacedSynonyms")  || boundPropertyId.matches("orthographicVariant.otherName")){
565
                TaxonNamePopupEditor namePopup = openPopupEditor(TaxonNamePopupEditor.class, event);
566
                namePopup.withDeleteButton(true);
567
                getView().getModesActive().stream()
568
                    .filter(m -> !TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY.equals(m))
569
                    .forEach(m -> namePopup.enableMode(m));
570
                if(boundPropertyId.matches("orthographicVariant.otherName") && getView().isModeEnabled(TaxonNamePopupEditorMode.ORTHOGRAPHIC_CORRECTION)){
571
                    namePopup.enableMode(TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY);
572
                }
573
                namePopup.loadInEditor(event.getEntityUuid());
574
            }
575
        }
576
    }
577

    
578
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
579
    public void onTaxonNameEditorActionStrRepEdit(TaxonNameEditorActionStrRep event) {
580

    
581
        if(getView() == null || event.getSourceView() != getView() ){
582
            return;
583
        }
584

    
585
        PropertyIdPath boundPropertyId = boundPropertyIdPath(event.getTarget());
586

    
587
        if(boundPropertyId != null){
588
            if(boundPropertyId.matches("genusOrUninomial") || boundPropertyId.matches("specificEpithet")){
589
                TaxonNamePopupEditor namePopup = openPopupEditor(TaxonNamePopupEditor.class, event);
590
                namePopup.withDeleteButton(true);
591
                getView().getModesActive().stream()
592
                    .filter(m -> !TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY.equals(m))
593
                    .forEach(m -> namePopup.enableMode(m));
594
                namePopup.loadInEditor(event.getEntityUuid());
595
            }
596
        }
597
    }
598

    
599
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
600
    public void onTaxonNameEditorActionAdd(TaxonNameEditorAction event) {
601

    
602
        if(getView() == null || event.getSourceView() != getView() ){
603
            return;
604
        }
605

    
606
        PropertyIdPath boundPropertyId = boundPropertyIdPath(event.getTarget());
607

    
608
        if(boundPropertyId != null){
609
            if(boundPropertyId.matches("validationFor.otherName") || boundPropertyId.matches("basionyms") || boundPropertyId.matches("replacedSynonyms") || boundPropertyId.matches("orthographicVariant.otherName")){
610
                TaxonNamePopupEditor namePopup = openPopupEditor(TaxonNamePopupEditor.class, event);
611
                namePopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
612
                namePopup.withDeleteButton(true);
613
                getView().getModesActive().stream()
614
                        .filter(m -> !TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY.equals(m))
615
                        .forEach(m -> namePopup.enableMode(m));
616
                Reference nomrefPreset = null;
617
                if(boundPropertyId.matches("orthographicVariant.otherName") && getView().isModeEnabled(TaxonNamePopupEditorMode.ORTHOGRAPHIC_CORRECTION)){
618
                    namePopup.enableMode(TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY);
619
                    nomrefPreset = (Reference)((AbstractPopupEditor<TaxonNameDTO, TaxonNameEditorPresenter>)getView()).getBean().getNomenclaturalReference();
620
                    if(nomrefPreset != null){
621
                        // show warning and skip
622
                        Notification.show("The nomenclatural reference needs to be set before creating a new ortographic correction is possible.", Type.HUMANIZED_MESSAGE);
623
                        try {
624
                            namePopup.destroy();
625
                        } catch (Exception e) {
626
                            throw new RuntimeException(e);
627
                        }
628
                        return;
629
                    }
630
                }
631
                namePopup.loadInEditor(null);
632
                if(nomrefPreset != null){
633
                    namePopup.getNomReferenceCombobox().setValue(nomrefPreset);
634
                }
635
            }
636
        }
637
    }
638

    
639
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
640
    public void onTaxonNameEditorActionStrRepAdd(TaxonNameEditorActionStrRep event) {
641

    
642
        if(getView() == null || event.getSourceView() != getView() ){
643
            return;
644
        }
645

    
646
        PropertyIdPath boundPropertyId = boundPropertyIdPath(event.getTarget());
647

    
648
        if(boundPropertyId != null){
649
            if(boundPropertyId.matches("genusOrUninomial") || boundPropertyId.matches("specificEpithet")){
650
                TaxonNamePopupEditor namePopup = openPopupEditor(TaxonNamePopupEditor.class, event);
651
                namePopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
652
                namePopup.withDeleteButton(true);
653
                getView().getModesActive().stream()
654
                .filter(m -> !TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY.equals(m))
655
                .forEach(m -> namePopup.enableMode(m));
656
                namePopup.loadInEditor(null);
657
                if(boundPropertyId.matches("genusOrUninomial")){
658
                    namePopup.getRankSelect().setValue(Rank.GENUS());
659
                }
660
                if(boundPropertyId.matches("specificEpithet")){
661
                    namePopup.getGenusOrUninomialField().setValue(getView().getGenusOrUninomialField().getValue());
662
                    namePopup.getRankSelect().setValue(Rank.SPECIES());
663
                }
664
                if(WeaklyRelatedEntityField.class.isAssignableFrom(event.getTarget().getClass())){
665
                    WeaklyRelatedEntityField<TaxonName> taxoNameField = (WeaklyRelatedEntityField<TaxonName>)event.getTarget();
666
                    if(!taxoNameField.isValueInOptions()){
667
                        String nameString = event.getTarget().getValue();
668
                        if(StringUtils.isNotEmpty(nameString)){
669
                            if(boundPropertyId.matches("genusOrUninomial")){
670
                                namePopup.getGenusOrUninomialField().setValue(nameString);
671
                            }
672
                            if(boundPropertyId.matches("specificEpithet")){
673
                                namePopup.getSpecificEpithetField().setValue(nameString);
674
                            }
675
                        }
676
                    }
677
                }
678
            }
679
        }
680
    }
681

    
682
    /**
683
     * {@inheritDoc}
684
     */
685
    @Override
686
    protected TaxonNameDTO createDTODecorator(TaxonName cdmEntitiy) {
687
        return new TaxonNameDTO(cdmEntitiy);
688
    }
689

    
690
    /**
691
     * {@inheritDoc}
692
     */
693
    @Override
694
    protected BeanInstantiator<TaxonName> defaultCdmEntityInstantiator() {
695
        return new BeanInstantiator<TaxonName>() {
696

    
697
            @Override
698
            public TaxonName createNewBean() {
699
                return  TaxonNameFactory.NewNameInstance(RegistrationUIDefaults.NOMENCLATURAL_CODE, Rank.SPECIES());
700
            }
701
        };
702
    }
703

    
704

    
705

    
706

    
707
}
(9-9/13)