Project

General

Profile

Download (36.9 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

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

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

    
80

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

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

    
90
    private static final long serialVersionUID = -3538980627079389221L;
91

    
92
    private static final Logger logger = Logger.getLogger(TaxonNameEditorPresenter.class);
93

    
94
    private CdmFilterablePagingProvider<Reference, Reference> nomReferencePagingProvider;
95

    
96
    private Reference publishedUnit;
97

    
98
    private BeanInstantiator<Reference> newReferenceInstantiator;
99

    
100
    private TaxonNameStringFilterablePagingProvider genusOrUninomialPartPagingProvider;
101

    
102
    private TaxonNameStringFilterablePagingProvider specificEpithetPartPagingProvider;
103

    
104
    private Property.ValueChangeListener refreshSpecificEpithetComboBoxListener;
105

    
106
    private CdmFilterablePagingProvider<TaxonName, TaxonName> relatedNamePagingProvider;
107

    
108
    private CdmFilterablePagingProvider<TaxonName, TaxonName> orthographicVariantNamePagingProvider;
109

    
110
    private Restriction<Reference> orthographicCorrectionRestriction;
111

    
112
    private Integer taxonNameId;
113

    
114
    /**
115
     * {@inheritDoc}
116
     */
117
    @Override
118
    public void handleViewEntered() {
119

    
120
        super.handleViewEntered();
121

    
122
        getView().getRankSelect().setContainerDataSource(cdmBeanItemContainerFactory.buildBeanItemContainer(TermType.Rank));
123
        getView().getRankSelect().setItemCaptionPropertyId("label");
124

    
125
        CdmFilterablePagingProvider<AgentBase, TeamOrPersonBase> termOrPersonPagingProvider = new CdmFilterablePagingProvider<AgentBase, TeamOrPersonBase>(getRepo().getAgentService(), TeamOrPersonBase.class);
126
        termOrPersonPagingProvider.setInitStrategy(AgentBaseInit.TEAM_OR_PERSON_INIT_STRATEGY);
127
        CdmFilterablePagingProvider<AgentBase, Person> personPagingProvider = new CdmFilterablePagingProvider<AgentBase, Person>(getRepo().getAgentService(), Person.class);
128

    
129
        getView().getCombinationAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
130
        getView().getCombinationAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
131

    
132
        getView().getExCombinationAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
133
        getView().getExCombinationAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
134

    
135
        getView().getBasionymAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
136
        getView().getBasionymAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
137

    
138
        getView().getExBasionymAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
139
        getView().getExBasionymAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
140

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

    
150

    
151
        relatedNamePagingProvider = pagingProviderFactory.taxonNamesWithoutOrthophicIncorrect();
152
        relatedNamePagingProvider.setInitStrategy(RELATED_NAME_INIT_STRATEGY);
153
        getView().getBasionymComboboxSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<TaxonName>());
154
        getView().getBasionymComboboxSelect().setPagingProviders(relatedNamePagingProvider, relatedNamePagingProvider, relatedNamePagingProvider.getPageSize(), this);
155

    
156
        getView().getReplacedSynonymsComboboxSelect().setCaptionGenerator( new CdmTitleCacheCaptionGenerator<TaxonName>());
157
        getView().getReplacedSynonymsComboboxSelect().setPagingProviders(relatedNamePagingProvider, relatedNamePagingProvider, relatedNamePagingProvider.getPageSize(), this);
158

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

    
173
        getView().getValidationField().getRelatedNameComboBox().getSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<TaxonName>());
174
        getView().getValidationField().getRelatedNameComboBox().loadFrom(relatedNamePagingProvider, relatedNamePagingProvider, relatedNamePagingProvider.getPageSize());
175
        getView().getValidationField().getRelatedNameComboBox().getSelect().addValueChangeListener(new ToOneRelatedEntityReloader<>(getView().getValidationField().getRelatedNameComboBox(), this));
176
        getView().getValidationField().getCitatonComboBox().getSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<Reference>());
177
        getView().getValidationField().getCitatonComboBox().loadFrom(icbnCodesPagingProvider, icbnCodesPagingProvider, icbnCodesPagingProvider.getPageSize());
178
        getView().getValidationField().getCitatonComboBox().getSelect().addValueChangeListener(new ToOneRelatedEntityReloader<>(getView().getValidationField().getCitatonComboBox(), this));
179

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

    
188

    
189
        getView().getAnnotationsField().setAnnotationTypeItemContainer(cdmBeanItemContainerFactory.buildTermItemContainer(
190
                AnnotationType.EDITORIAL().getUuid(), AnnotationType.TECHNICAL().getUuid()));
191
    }
192

    
193
    @Override
194
    protected void adaptDataProviders() {
195
        updateOrthographicCorrectionRestriction();
196
    }
197

    
198
    private void updateOrthographicCorrectionRestriction() {
199

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

    
222
    @Override
223
    protected TaxonName loadCdmEntity(UUID identifier) {
224

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

    
231
                "nomenclaturalReference.authorship",
232
                "nomenclaturalReference.inReference.authorship",
233
                "nomenclaturalReference.inReference.inReference.authorship",
234
                "nomenclaturalReference.inReference.inReference.inReference.authorship",
235

    
236
                "status.type",
237

    
238
                "combinationAuthorship",
239
                "exCombinationAuthorship",
240
                "basionymAuthorship",
241
                "exBasionymAuthorship",
242

    
243
                // basionyms: relationsToThisName.fromName
244
                "relationsToThisName.type",
245
                "relationsToThisName.fromName.rank",
246
                "relationsToThisName.fromName.combinationAuthorship",
247
                "relationsToThisName.fromName.exCombinationAuthorship",
248
                "relationsToThisName.fromName.nomenclaturalReference.authorship",
249
                "relationsToThisName.fromName.nomenclaturalReference.inReference.authorship",
250
                "relationsToThisName.fromName.nomenclaturalReference.inReference.inReference.inReference.authorship",
251
                "relationsToThisName.fromName.relationsToThisName",
252
                "relationsToThisName.fromName.relationsFromThisName",
253
                "relationsToThisName.citation",
254

    
255
                "relationsFromThisName",
256
                "homotypicalGroup.typifiedNames"
257
        );
258

    
259
        TaxonName taxonName;
260
        if(identifier != null){
261
            taxonName = getRepo().getNameService().load(identifier, initStrategy);
262
        } else {
263
            taxonName = createCdmEntity();
264
        }
265

    
266
        if(getView().isModeEnabled(TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY)){
267
            Reference nomRef = taxonName.getNomenclaturalReference();
268

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

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

    
294
        }
295

    
296
        taxonNameId = Integer.valueOf(taxonName.getId());
297
        relatedNamePagingProvider.addRestriction(new Restriction<>("id", Operator.AND_NOT, null, taxonNameId));
298

    
299
        return taxonName;
300
    }
301

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

    
311
    }
312

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

    
323
    /**
324
     * {@inheritDoc}
325
     */
326
    @Override
327
    protected INameService getService() {
328
        return getRepo().getNameService();
329
    }
330

    
331
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
332
    public void onReferenceEditorActionAdd(ReferenceEditorAction event) {
333

    
334
        if(getView() == null || event.getSourceView() != getView() ){
335
            return;
336
        }
337

    
338
        ReferencePopupEditor referenceEditorPopup = openPopupEditor(ReferencePopupEditor.class, event);
339

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

    
352
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
353
    public void onReferenceEditorActionEdit(ReferenceEditorAction event) {
354

    
355

    
356
        if(!isFromOwnView(event)){
357
            return;
358
        }
359
        ReferencePopupEditor referenceEditorPopup = openPopupEditor(ReferencePopupEditor.class, event);
360

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

    
372
    @EventBusListenerMethod
373
    public void onFieldReplaceEvent(FieldReplaceEvent<String> event){
374

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

    
426
            }
427
        }
428

    
429
    }
430

    
431
    @EventBusListenerMethod
432
    public void onEntityChangeEvent(EntityChangeEvent<?> event){
433

    
434
        if(event.getSourceView() instanceof AbstractPopupEditor) {
435

    
436
            BoundField boundTargetField = boundTargetField((PopupView) event.getSourceView());
437

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

    
455
                        if(getView().getSpecificEpithetField() instanceof WeaklyRelatedEntityCombobox){
456
                            WeaklyRelatedEntityCombobox weaklyRelatedEntityCombobox = (WeaklyRelatedEntityCombobox)getView().getSpecificEpithetField();
457
                            if(event.isCreatedType()){
458
                                getView().getSpecificEpithetField().setValue(((TaxonName)event.getEntity()).getSpecificEpithet());
459
                                weaklyRelatedEntityCombobox.reload();
460
                            } else {
461
                                weaklyRelatedEntityCombobox.reload();
462
                            }
463
                            // NOTE: in contrast to the ToOneRelatedEntityCombobox the .discard() does not
464
                            // work here since no datasource is bound to the field, see weaklyRelatedEntityCombobox.reload()
465
                            weaklyRelatedEntityCombobox.updateButtons();
466
                        }
467
                    }
468
                } else
469
                if(boundTargetField.matchesPropertyIdPath("nomenclaturalReference")){
470
                    if(event.isCreateOrModifiedType()){
471
                        getCache().load(event.getEntity());
472
                        if(event.isCreatedType()){
473
                            getView().getNomReferenceCombobox().setValue((Reference) event.getEntity());
474
                        } else {
475
                            getView().getNomReferenceCombobox().reload(); // refreshSelectedValue(modifiedReference);
476
                        }
477
                        getView().getCombinationAuthorshipField().discard(); //refresh from the datasource
478
                        getView().updateAuthorshipFields();
479
                    }
480
                } else
481
                if(boundTargetField.matchesPropertyIdPath("validationFor.otherName") || boundTargetField.matchesPropertyIdPath("orthographicVariant.otherName")){
482
                    ReloadableLazyComboBox<TaxonName> otherNameField = asReloadableLazyComboBox(boundTargetField.getField(TaxonName.class));
483
                    TaxonName otherName = (TaxonName) event.getEntity();
484
                    if(event.isCreateOrModifiedType()){
485
                        getCache().load(otherName);
486
                        if(event.isCreatedType()){
487
                            otherNameField.setValue(otherName);
488
                        } else {
489
                            otherNameField.reload();
490
                        }
491

    
492
                    } else
493
                    if(event.isRemovedType()){
494
                        otherNameField.setValue(null);
495
                    }
496
                } else
497
                if(boundTargetField.matchesPropertyIdPath("basionyms")){
498
                    ReloadableLazyComboBox<TaxonName> basionymSourceField = asReloadableLazyComboBox(boundTargetField.getField(TaxonName.class));
499
                    if(event.isCreateOrModifiedType()){
500
                        getCache().load(event.getEntity());
501
                        if(event.isCreatedType()){
502
                            basionymSourceField .setValue((TaxonName) event.getEntity());
503
                        } else {
504
                            basionymSourceField.reload();
505
                        }
506
                        getView().getBasionymAuthorshipField().discard(); //refresh from the datasource
507
                        getView().getExBasionymAuthorshipField().discard(); //refresh from the datasource
508
                        getView().updateAuthorshipFields();
509
                    } else
510
                    if(event.isRemovedType()){
511
                        basionymSourceField.setValue(null);
512
                        getView().updateAuthorshipFields();
513
                    }
514
                } else
515
                if(boundTargetField.matchesPropertyIdPath("replacedSynonyms")){
516
                    ReloadableLazyComboBox<TaxonName> replacedSynonyms = asReloadableLazyComboBox(boundTargetField.getField(TaxonName.class));
517
                    if(event.isCreateOrModifiedType()){
518
                        getCache().load(event.getEntity());
519
                        if(event.isCreatedType()){
520
                            replacedSynonyms .setValue((TaxonName) event.getEntity());
521
                        } else {
522
                            replacedSynonyms.reload();
523
                        }
524
                        getView().getExCombinationAuthorshipField().discard(); //refresh from the datasource
525
                        getView().updateAuthorshipFields();
526
                    } else
527
                    if(event.isRemovedType()){
528
                        replacedSynonyms.setValue(null);
529
                        getView().updateAuthorshipFields();
530
                    }
531
                }
532

    
533
            }
534
        }
535
    }
536

    
537
    protected <CDM extends CdmBase> ReloadableLazyComboBox<CDM> asReloadableLazyComboBox(Field<CDM> field){
538

    
539
        if(field instanceof ToOneRelatedEntityCombobox){
540
            field = ((ToOneRelatedEntityCombobox<CDM>)field).getSelect();
541
        }
542
        return (ReloadableLazyComboBox<CDM>)field;
543
    }
544

    
545

    
546

    
547
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
548
    public void onTaxonNameEditorActionEdit(TaxonNameEditorAction event) {
549

    
550
        if(getView() == null || event.getSourceView() != getView() ){
551
            return;
552
        }
553

    
554
        PropertyIdPath boundPropertyId = boundPropertyIdPath(event.getTarget());
555

    
556
        if(boundPropertyId != null){
557
            if(boundPropertyId.matches("validationFor.otherName") || boundPropertyId.matches("basionyms") || boundPropertyId.matches("replacedSynonyms")  || boundPropertyId.matches("orthographicVariant.otherName")){
558
                TaxonNamePopupEditor namePopup = openPopupEditor(TaxonNamePopupEditor.class, event);
559
                namePopup.withDeleteButton(true);
560
                getView().getModesActive().stream()
561
                    .filter(m -> !TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY.equals(m))
562
                    .forEach(m -> namePopup.enableMode(m));
563
                if(boundPropertyId.matches("orthographicVariant.otherName") && getView().isModeEnabled(TaxonNamePopupEditorMode.ORTHOGRAPHIC_CORRECTION)){
564
                    namePopup.enableMode(TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY);
565
                    namePopup.disableMode(TaxonNamePopupEditorMode.VALIDATE_AGAINST_HIGHER_NAME_PART);
566
                    namePopup.getOrthographicVariantToggle().setVisible(false);
567
                }
568
                namePopup.loadInEditor(event.getEntityUuid());
569
            }
570
        }
571
    }
572

    
573
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
574
    public void onTaxonNameEditorActionStrRepEdit(TaxonNameEditorActionStrRep event) {
575

    
576
        if(getView() == null || event.getSourceView() != getView() ){
577
            return;
578
        }
579

    
580
        PropertyIdPath boundPropertyId = boundPropertyIdPath(event.getTarget());
581

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

    
594
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
595
    public void onTaxonNameEditorActionAdd(TaxonNameEditorAction event) {
596

    
597
        if(getView() == null || event.getSourceView() != getView() ){
598
            return;
599
        }
600

    
601
        PropertyIdPath boundPropertyId = boundPropertyIdPath(event.getTarget());
602

    
603
        if(boundPropertyId != null){
604
            if(boundPropertyId.matches("validationFor.otherName") || boundPropertyId.matches("basionyms") || boundPropertyId.matches("replacedSynonyms") || boundPropertyId.matches("orthographicVariant.otherName")){
605
                TaxonNamePopupEditor namePopup = openPopupEditor(TaxonNamePopupEditor.class, event);
606
                namePopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
607
                namePopup.withDeleteButton(true);
608
                getView().getModesActive().stream()
609
                        .filter(m -> !TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY.equals(m))
610
                        .forEach(m -> namePopup.enableMode(m));
611
                if(boundPropertyId.matches("orthographicVariant.otherName") && getView().isModeEnabled(TaxonNamePopupEditorMode.ORTHOGRAPHIC_CORRECTION)){
612
                    namePopup.enableMode(TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY);
613
                    namePopup.disableMode(TaxonNamePopupEditorMode.VALIDATE_AGAINST_HIGHER_NAME_PART);
614
                    Reference nomrefPreset = (Reference)((AbstractPopupEditor<TaxonNameDTO, TaxonNameEditorPresenter>)getView()).getBean().getNomenclaturalReference();
615
                    namePopup.setCdmEntityInstantiator(new BeanInstantiator<TaxonName>() {
616

    
617
                        @Override
618
                        public TaxonName createNewBean() {
619
                            TaxonName newTaxonName = TaxonNameFactory.NewNameInstance(RegistrationUIDefaults.NOMENCLATURAL_CODE, Rank.SPECIES());
620
                            newTaxonName.setNomenclaturalReference(getRepo().getReferenceService().load(nomrefPreset.getUuid(), TaxonNameEditorPresenter.REFERENCE_INIT_STRATEGY ));
621
                            return newTaxonName;
622
                        }
623
                    });
624
                    namePopup.getOrthographicVariantToggle().setVisible(false);
625
                }
626
                namePopup.loadInEditor(null);
627
            }
628
        }
629
    }
630

    
631
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
632
    public void onTaxonNameEditorActionStrRepAdd(TaxonNameEditorActionStrRep event) {
633

    
634
        if(getView() == null || event.getSourceView() != getView() ){
635
            return;
636
        }
637

    
638
        PropertyIdPath boundPropertyId = boundPropertyIdPath(event.getTarget());
639

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

    
674
    /**
675
     * {@inheritDoc}
676
     */
677
    @Override
678
    protected TaxonNameDTO createDTODecorator(TaxonName cdmEntitiy) {
679
        return new TaxonNameDTO(cdmEntitiy);
680
    }
681

    
682
    /**
683
     * {@inheritDoc}
684
     */
685
    @Override
686
    protected BeanInstantiator<TaxonName> defaultCdmEntityInstantiator() {
687
        return new BeanInstantiator<TaxonName>() {
688

    
689
            @Override
690
            public TaxonName createNewBean() {
691
                return  TaxonNameFactory.NewNameInstance(RegistrationUIDefaults.NOMENCLATURAL_CODE, Rank.SPECIES());
692
            }
693
        };
694
    }
695

    
696

    
697

    
698

    
699
}
(10-10/14)