Project

General

Profile

Download (37.3 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.common.TermType;
34
import eu.etaxonomy.cdm.model.name.Rank;
35
import eu.etaxonomy.cdm.model.name.TaxonName;
36
import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
37
import eu.etaxonomy.cdm.model.reference.Reference;
38
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
39
import eu.etaxonomy.cdm.model.reference.ReferenceType;
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.component.CdmBeanItemContainerFactory;
48
import eu.etaxonomy.cdm.vaadin.event.EditorActionTypeFilter;
49
import eu.etaxonomy.cdm.vaadin.event.EntityChangeEvent;
50
import eu.etaxonomy.cdm.vaadin.event.ReferenceEditorAction;
51
import eu.etaxonomy.cdm.vaadin.event.TaxonNameEditorAction;
52
import eu.etaxonomy.cdm.vaadin.event.TaxonNameEditorActionStrRep;
53
import eu.etaxonomy.cdm.vaadin.event.ToOneRelatedEntityButtonUpdater;
54
import eu.etaxonomy.cdm.vaadin.event.ToOneRelatedEntityReloader;
55
import eu.etaxonomy.cdm.vaadin.model.name.TaxonNameDTO;
56
import eu.etaxonomy.cdm.vaadin.ui.RegistrationUIDefaults;
57
import eu.etaxonomy.cdm.vaadin.util.CdmTitleCacheCaptionGenerator;
58
import eu.etaxonomy.cdm.vaadin.view.reference.ReferencePopupEditor;
59
import eu.etaxonomy.vaadin.component.CompositeCustomField;
60
import eu.etaxonomy.vaadin.component.ReloadableLazyComboBox;
61
import eu.etaxonomy.vaadin.component.ToOneRelatedEntityCombobox;
62
import eu.etaxonomy.vaadin.component.WeaklyRelatedEntityCombobox;
63
import eu.etaxonomy.vaadin.component.WeaklyRelatedEntityField;
64
import eu.etaxonomy.vaadin.event.FieldReplaceEvent;
65
import eu.etaxonomy.vaadin.mvp.AbstractCdmDTOEditorPresenter;
66
import eu.etaxonomy.vaadin.mvp.AbstractPopupEditor;
67
import eu.etaxonomy.vaadin.mvp.BeanInstantiator;
68
import eu.etaxonomy.vaadin.mvp.BoundField;
69
import eu.etaxonomy.vaadin.ui.view.PopupView;
70
import eu.etaxonomy.vaadin.util.PropertyIdPath;
71

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

    
81

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

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

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

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

    
95
    private CdmFilterablePagingProvider<Reference, Reference> nomReferencePagingProvider;
96

    
97
    private Reference publishedUnit;
98

    
99
    private BeanInstantiator<Reference> newReferenceInstantiator;
100

    
101
    private TaxonNameStringFilterablePagingProvider genusOrUninomialPartPagingProvider;
102

    
103
    private TaxonNameStringFilterablePagingProvider specificEpithetPartPagingProvider;
104

    
105
    private Property.ValueChangeListener refreshSpecificEpithetComboBoxListener;
106

    
107
    private CdmFilterablePagingProvider<TaxonName, TaxonName> relatedNamePagingProvider;
108

    
109
    private CdmFilterablePagingProvider<TaxonName, TaxonName> orthographicVariantNamePagingProvider;
110

    
111
    private Restriction<Reference> orthographicCorrectionRestriction;
112

    
113
    private Integer taxonNameId;
114

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

    
121
        super.handleViewEntered();
122

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

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

    
131
        getView().getCombinationAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
132
        getView().getCombinationAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
133

    
134
        getView().getExCombinationAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
135
        getView().getExCombinationAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
136

    
137
        getView().getBasionymAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
138
        getView().getBasionymAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
139

    
140
        getView().getExBasionymAuthorshipField().setFilterableTeamPagingProvider(termOrPersonPagingProvider, this);
141
        getView().getExBasionymAuthorshipField().setFilterablePersonPagingProvider(personPagingProvider, this);
142

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

    
152

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

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

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

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

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

    
190

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

    
195
    @Override
196
    protected void adaptDataProviders() {
197
        updateOrthographicCorrectionRestriction();
198
    }
199

    
200
    private void updateOrthographicCorrectionRestriction() {
201

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

    
224
    @Override
225
    protected TaxonName loadCdmEntity(UUID identifier) {
226

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

    
233
                "nomenclaturalReference.authorship",
234
                "nomenclaturalReference.inReference.authorship",
235
                "nomenclaturalReference.inReference.inReference.authorship",
236
                "nomenclaturalReference.inReference.inReference.inReference.authorship",
237

    
238
                "status.type",
239

    
240
                "combinationAuthorship",
241
                "exCombinationAuthorship",
242
                "basionymAuthorship",
243
                "exBasionymAuthorship",
244

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

    
257
                "relationsFromThisName",
258
                "homotypicalGroup.typifiedNames"
259
        );
260

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

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

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

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

    
296
        }
297

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

    
301
        return taxonName;
302
    }
303

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

    
313
    }
314

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

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

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

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

    
340
        ReferencePopupEditor referenceEditorPopup = openPopupEditor(ReferencePopupEditor.class, event);
341

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

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

    
357

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

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

    
374
    @EventBusListenerMethod
375
    public void onFieldReplaceEvent(FieldReplaceEvent<String> event){
376

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

    
428
            }
429
        }
430

    
431
    }
432

    
433
    @EventBusListenerMethod
434
    public void onEntityChangeEvent(EntityChangeEvent<?> event){
435

    
436
        if(event.getSourceView() instanceof AbstractPopupEditor) {
437

    
438
            BoundField boundTargetField = boundTargetField((PopupView) event.getSourceView());
439

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

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

    
538
            }
539
        }
540
    }
541

    
542
    protected <CDM extends CdmBase> ReloadableLazyComboBox<CDM> asReloadableLazyComboBox(Field<CDM> field){
543

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

    
550

    
551

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

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

    
559
        PropertyIdPath boundPropertyId = boundPropertyIdPath(event.getTarget());
560

    
561
        if(boundPropertyId != null){
562
            if(boundPropertyId.matches("validationFor.otherName") || boundPropertyId.matches("basionyms") || boundPropertyId.matches("replacedSynonyms")  || boundPropertyId.matches("orthographicVariant.otherName")){
563
                TaxonNamePopupEditor namePopup = openPopupEditor(TaxonNamePopupEditor.class, event);
564
                namePopup.withDeleteButton(true);
565
                getView().getModesActive().stream()
566
                    .filter(m -> !TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY.equals(m))
567
                    .forEach(m -> namePopup.enableMode(m));
568
                if(boundPropertyId.matches("orthographicVariant.otherName") && getView().isModeEnabled(TaxonNamePopupEditorMode.ORTHOGRAPHIC_CORRECTION)){
569
                    namePopup.enableMode(TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY);
570
                    namePopup.disableMode(TaxonNamePopupEditorMode.VALIDATE_AGAINST_HIGHER_NAME_PART);
571
                    namePopup.getOrthographicVariantToggle().setVisible(false);
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
                if(boundPropertyId.matches("orthographicVariant.otherName") && getView().isModeEnabled(TaxonNamePopupEditorMode.ORTHOGRAPHIC_CORRECTION)){
617
                    namePopup.enableMode(TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY);
618
                    namePopup.disableMode(TaxonNamePopupEditorMode.VALIDATE_AGAINST_HIGHER_NAME_PART);
619
                    Reference nomrefPreset = (Reference)((AbstractPopupEditor<TaxonNameDTO, TaxonNameEditorPresenter>)getView()).getBean().getNomenclaturalReference();
620
                    namePopup.setCdmEntityInstantiator(new BeanInstantiator<TaxonName>() {
621

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

    
636
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
637
    public void onTaxonNameEditorActionStrRepAdd(TaxonNameEditorActionStrRep event) {
638

    
639
        if(getView() == null || event.getSourceView() != getView() ){
640
            return;
641
        }
642

    
643
        PropertyIdPath boundPropertyId = boundPropertyIdPath(event.getTarget());
644

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

    
679
    /**
680
     * {@inheritDoc}
681
     */
682
    @Override
683
    protected TaxonNameDTO createDTODecorator(TaxonName cdmEntitiy) {
684
        return new TaxonNameDTO(cdmEntitiy);
685
    }
686

    
687
    /**
688
     * {@inheritDoc}
689
     */
690
    @Override
691
    protected BeanInstantiator<TaxonName> defaultCdmEntityInstantiator() {
692
        return new BeanInstantiator<TaxonName>() {
693

    
694
            @Override
695
            public TaxonName createNewBean() {
696
                return  TaxonNameFactory.NewNameInstance(RegistrationUIDefaults.NOMENCLATURAL_CODE, Rank.SPECIES());
697
            }
698
        };
699
    }
700

    
701

    
702

    
703

    
704
}
(10-10/14)