Project

General

Profile

Download (38.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.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.cdm.vaadin.view.reference.RegistrationUiReferenceEditorFormConfigurator;
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
        getView().getRankSelect().setContainerDataSource(cdmBeanItemContainerFactory.buildBeanItemContainer(TermType.Rank));
124
        getView().getRankSelect().setItemCaptionPropertyId("label");
125

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

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

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

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

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

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

    
151

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

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

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

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

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

    
189

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

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

    
199
    private void updateOrthographicCorrectionRestriction() {
200

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

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

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

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

    
237
                "status.type",
238

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

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

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

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

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

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

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

    
295
        }
296

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

    
300
        return taxonName;
301
    }
302

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

    
312
    }
313

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

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

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

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

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

    
341
        referenceEditorPopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
342
        referenceEditorPopup.withDeleteButton(true);
343
        referenceEditorPopup.setBeanInstantiator(newReferenceInstantiator);
344
        // TODO this should be configurable per UI - RegistrationUiReferenceEditorFormConfigurator as spring bean, different spring profiles
345
        referenceEditorPopup.setEditorComponentsConfigurator(new RegistrationUiReferenceEditorFormConfigurator(newReferenceInstantiator != null));
346
        referenceEditorPopup.loadInEditor(null);
347
//        if(newReferenceInstantiator != null){
348
//            // this is a bit clumsy, we actually need to inject something like a view configurer
349
//            // which can enable, disable fields
350
//            referenceEditorPopup.getInReferenceCombobox().setEnabled(false);
351
//            referenceEditorPopup.getTypeSelect().setEnabled(false);
352
//        }
353
    }
354

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

    
358

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

    
364
        referenceEditorPopup.withDeleteButton(true);
365
        referenceEditorPopup.setBeanInstantiator(newReferenceInstantiator);
366
        // TODO this should be configurable per UI - RegistrationUiReferenceEditorFormConfigurator as spring bean, different spring profiles
367
        referenceEditorPopup.setEditorComponentsConfigurator(new RegistrationUiReferenceEditorFormConfigurator(newReferenceInstantiator != null));
368
        referenceEditorPopup.loadInEditor(event.getEntityUuid());
369
//        if(newReferenceInstantiator != null){
370
//            // this is a bit clumsy, we actually need to inject something like a view configurator
371
//            // which can enable, disable fields
372
//            referenceEditorPopup.getInReferenceCombobox().setEnabled(false);
373
//            referenceEditorPopup.getInReferenceCombobox().setEditButtonEnabled(false); // <-------
374
//            referenceEditorPopup.getTypeSelect().setEnabled(false);
375
//        }
376
    }
377

    
378
    @EventBusListenerMethod
379
    public void onFieldReplaceEvent(FieldReplaceEvent<String> event){
380

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

    
432
            }
433
        }
434

    
435
    }
436

    
437
    @EventBusListenerMethod
438
    public void onEntityChangeEvent(EntityChangeEvent<?> event){
439

    
440
        if(event.getSourceView() instanceof AbstractPopupEditor) {
441

    
442
            BoundField boundTargetField = boundTargetField((PopupView) event.getSourceView());
443

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

    
466
                        if(getView().getSpecificEpithetField() instanceof WeaklyRelatedEntityCombobox){
467
                            WeaklyRelatedEntityCombobox weaklyRelatedEntityCombobox = (WeaklyRelatedEntityCombobox)getView().getSpecificEpithetField();
468
                            if(event.isCreatedType()){
469
                                getView().getSpecificEpithetField().setValue(((TaxonName)event.getEntity()).getSpecificEpithet());
470
                                weaklyRelatedEntityCombobox.reload();
471
                            } else {
472
                                weaklyRelatedEntityCombobox.reload();
473
                            }
474
                            // NOTE: in contrast to the ToOneRelatedEntityCombobox the .discard() does not
475
                            // work here since no datasource is bound to the field, see weaklyRelatedEntityCombobox.reload()
476
                            weaklyRelatedEntityCombobox.updateButtons();
477
                        }
478
                    }
479
                } else
480
                if(boundTargetField.matchesPropertyIdPath("nomenclaturalReference")){
481
                    if(event.isCreateOrModifiedType()){
482
                        getCache().load(event.getEntity());
483
                        if(event.isCreatedType()){
484
                            getView().getNomReferenceCombobox().setValue((Reference) event.getEntity());
485
                        } else {
486
                            getView().getNomReferenceCombobox().reload(); // refreshSelectedValue(modifiedReference);
487
                        }
488
                        getView().getCombinationAuthorshipField().discard(); //refresh from the datasource
489
                        getView().updateAuthorshipFields();
490
                    }
491
                } else
492
                if(boundTargetField.matchesPropertyIdPath("validationFor.otherName") || boundTargetField.matchesPropertyIdPath("orthographicVariant.otherName")){
493
                    ReloadableLazyComboBox<TaxonName> otherNameField = asReloadableLazyComboBox(boundTargetField.getField(TaxonName.class));
494
                    TaxonName otherName = (TaxonName) event.getEntity();
495
                    if(event.isCreateOrModifiedType()){
496
                        getCache().load(otherName);
497
                        if(event.isCreatedType()){
498
                            // TODO use reloadWith((TaxonName) event.getEntity()); also in this case?
499
                            otherNameField.setValue(otherName);
500
                        } else {
501
                            otherNameField.reloadWith(otherName);
502
                        }
503

    
504
                    } else
505
                    if(event.isRemovedType()){
506
                        otherNameField.setValue(null);
507
                    }
508
                } else
509
                if(boundTargetField.matchesPropertyIdPath("basionyms")){
510
                    ReloadableLazyComboBox<TaxonName> basionymSourceField = asReloadableLazyComboBox(boundTargetField.getField(TaxonName.class));
511
                    if(event.isCreateOrModifiedType()){
512
                        getCache().load(event.getEntity());
513
                        if(event.isCreatedType()){
514
                            // TODO use reloadWith((TaxonName) event.getEntity()); also in this case?
515
                            basionymSourceField .setValue((TaxonName) event.getEntity());
516
                        } else {
517
                            basionymSourceField.reloadWith((TaxonName) event.getEntity());
518
                        }
519
                        getView().getBasionymAuthorshipField().discard(); //refresh from the datasource
520
                        getView().getExBasionymAuthorshipField().discard(); //refresh from the datasource
521
                        getView().updateAuthorshipFields();
522
                    } else
523
                    if(event.isRemovedType()){
524
                        basionymSourceField.setValue(null);
525
                        getView().updateAuthorshipFields();
526
                    }
527
                } else
528
                if(boundTargetField.matchesPropertyIdPath("replacedSynonyms")){
529
                    ReloadableLazyComboBox<TaxonName> replacedSynonyms = asReloadableLazyComboBox(boundTargetField.getField(TaxonName.class));
530
                    if(event.isCreateOrModifiedType()){
531
                        getCache().load(event.getEntity());
532
                        if(event.isCreatedType()){
533
                            // TODO use reloadWith((TaxonName) event.getEntity()); also in this case?
534
                            replacedSynonyms .setValue((TaxonName) event.getEntity());
535
                        } else {
536
                            replacedSynonyms.reloadWith((TaxonName) event.getEntity());
537
                        }
538
                        getView().getExCombinationAuthorshipField().discard(); //refresh from the datasource
539
                        getView().updateAuthorshipFields();
540
                    } else
541
                    if(event.isRemovedType()){
542
                        replacedSynonyms.setValue(null);
543
                        getView().updateAuthorshipFields();
544
                    }
545
                }
546

    
547
            }
548
        }
549
    }
550

    
551
    protected <CDM extends CdmBase> ReloadableLazyComboBox<CDM> asReloadableLazyComboBox(Field<CDM> field){
552

    
553
        if(field instanceof ToOneRelatedEntityCombobox){
554
            field = ((ToOneRelatedEntityCombobox<CDM>)field).getSelect();
555
        }
556
        return (ReloadableLazyComboBox<CDM>)field;
557
    }
558

    
559

    
560

    
561
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
562
    public void onTaxonNameEditorActionEdit(TaxonNameEditorAction event) {
563

    
564
        if(getView() == null || event.getSourceView() != getView() ){
565
            return;
566
        }
567

    
568
        PropertyIdPath boundPropertyId = boundPropertyIdPath(event.getTarget());
569

    
570
        if(boundPropertyId != null){
571
            if(boundPropertyId.matches("validationFor.otherName") || boundPropertyId.matches("basionyms") || boundPropertyId.matches("replacedSynonyms")  || boundPropertyId.matches("orthographicVariant.otherName")){
572
                TaxonNamePopupEditor namePopup = openPopupEditor(TaxonNamePopupEditor.class, event);
573
                namePopup.withDeleteButton(true);
574
                getView().getModesActive().stream()
575
                    .filter(m -> !TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY.equals(m))
576
                    .forEach(m -> namePopup.enableMode(m));
577
                if(boundPropertyId.matches("orthographicVariant.otherName") && getView().isModeEnabled(TaxonNamePopupEditorMode.ORTHOGRAPHIC_CORRECTION)){
578
                    namePopup.enableMode(TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY);
579
                    namePopup.disableMode(TaxonNamePopupEditorMode.VALIDATE_AGAINST_HIGHER_NAME_PART);
580
                    namePopup.getOrthographicVariantToggle().setVisible(false);
581
                }
582
                namePopup.loadInEditor(event.getEntityUuid());
583
            }
584
        }
585
    }
586

    
587
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
588
    public void onTaxonNameEditorActionStrRepEdit(TaxonNameEditorActionStrRep event) {
589

    
590
        if(getView() == null || event.getSourceView() != getView() ){
591
            return;
592
        }
593

    
594
        PropertyIdPath boundPropertyId = boundPropertyIdPath(event.getTarget());
595

    
596
        if(boundPropertyId != null){
597
            if(boundPropertyId.matches("genusOrUninomial") || boundPropertyId.matches("specificEpithet")){
598
                TaxonNamePopupEditor namePopup = openPopupEditor(TaxonNamePopupEditor.class, event);
599
                namePopup.withDeleteButton(true);
600
                getView().getModesActive().stream()
601
                    .filter(m -> !TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY.equals(m))
602
                    .forEach(m -> namePopup.enableMode(m));
603
                namePopup.loadInEditor(event.getEntityUuid());
604
            }
605
        }
606
    }
607

    
608
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
609
    public void onTaxonNameEditorActionAdd(TaxonNameEditorAction event) {
610

    
611
        if(getView() == null || event.getSourceView() != getView() ){
612
            return;
613
        }
614

    
615
        PropertyIdPath boundPropertyId = boundPropertyIdPath(event.getTarget());
616

    
617
        if(boundPropertyId != null){
618
            if(boundPropertyId.matches("validationFor.otherName") || boundPropertyId.matches("basionyms") || boundPropertyId.matches("replacedSynonyms") || boundPropertyId.matches("orthographicVariant.otherName")){
619
                TaxonNamePopupEditor namePopup = openPopupEditor(TaxonNamePopupEditor.class, event);
620
                namePopup.grantToCurrentUser(EnumSet.of(CRUD.UPDATE, CRUD.DELETE));
621
                namePopup.withDeleteButton(true);
622
                getView().getModesActive().stream()
623
                        .filter(m -> !TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY.equals(m))
624
                        .forEach(m -> namePopup.enableMode(m));
625
                if(boundPropertyId.matches("orthographicVariant.otherName") && getView().isModeEnabled(TaxonNamePopupEditorMode.ORTHOGRAPHIC_CORRECTION)){
626
                    namePopup.enableMode(TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY);
627
                    namePopup.disableMode(TaxonNamePopupEditorMode.VALIDATE_AGAINST_HIGHER_NAME_PART);
628
                    Reference nomrefPreset = (Reference)((AbstractPopupEditor<TaxonNameDTO, TaxonNameEditorPresenter>)getView()).getBean().getNomenclaturalReference();
629
                    namePopup.setCdmEntityInstantiator(new BeanInstantiator<TaxonName>() {
630

    
631
                        @Override
632
                        public TaxonName createNewBean() {
633
                            TaxonName newTaxonName = TaxonNameFactory.NewNameInstance(RegistrationUIDefaults.NOMENCLATURAL_CODE, Rank.SPECIES());
634
                            newTaxonName.setNomenclaturalReference(getRepo().getReferenceService().load(nomrefPreset.getUuid(), TaxonNameEditorPresenter.REFERENCE_INIT_STRATEGY ));
635
                            return newTaxonName;
636
                        }
637
                    });
638
                    namePopup.getOrthographicVariantToggle().setVisible(false);
639
                }
640
                namePopup.loadInEditor(null);
641
            }
642
        }
643
    }
644

    
645
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
646
    public void onTaxonNameEditorActionStrRepAdd(TaxonNameEditorActionStrRep event) {
647

    
648
        if(getView() == null || event.getSourceView() != getView() ){
649
            return;
650
        }
651

    
652
        PropertyIdPath boundPropertyId = boundPropertyIdPath(event.getTarget());
653

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

    
688
    /**
689
     * {@inheritDoc}
690
     */
691
    @Override
692
    protected TaxonNameDTO createDTODecorator(TaxonName cdmEntitiy) {
693
        return new TaxonNameDTO(cdmEntitiy);
694
    }
695

    
696
    /**
697
     * {@inheritDoc}
698
     */
699
    @Override
700
    protected BeanInstantiator<TaxonName> defaultCdmEntityInstantiator() {
701
        return new BeanInstantiator<TaxonName>() {
702

    
703
            @Override
704
            public TaxonName createNewBean() {
705
                return  TaxonNameFactory.NewNameInstance(RegistrationUIDefaults.NOMENCLATURAL_CODE, Rank.SPECIES());
706
            }
707
        };
708
    }
709

    
710

    
711

    
712

    
713
}
(10-10/14)