Project

General

Profile

Download (38.5 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.format.ReferenceEllypsisFormatter.LabelType;
29
import eu.etaxonomy.cdm.model.agent.AgentBase;
30
import eu.etaxonomy.cdm.model.agent.Person;
31
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
32
import eu.etaxonomy.cdm.model.common.AnnotationType;
33
import eu.etaxonomy.cdm.model.common.CdmBase;
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.model.term.TermType;
41
import eu.etaxonomy.cdm.persistence.dao.common.Restriction;
42
import eu.etaxonomy.cdm.persistence.dao.common.Restriction.Operator;
43
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
44
import eu.etaxonomy.cdm.service.CdmFilterablePagingProvider;
45
import eu.etaxonomy.cdm.service.TaxonNameStringFilterablePagingProvider;
46
import eu.etaxonomy.cdm.service.UserHelperAccess;
47
import eu.etaxonomy.cdm.service.initstrategies.AgentBaseInit;
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.util.ReferenceEllypsisCaptionGenerator;
59
import eu.etaxonomy.cdm.vaadin.view.reference.ReferencePopupEditor;
60
import eu.etaxonomy.cdm.vaadin.view.reference.RegistrationUiReferenceEditorFormConfigurator;
61
import eu.etaxonomy.vaadin.component.CompositeCustomField;
62
import eu.etaxonomy.vaadin.component.ReloadableLazyComboBox;
63
import eu.etaxonomy.vaadin.component.ToOneRelatedEntityCombobox;
64
import eu.etaxonomy.vaadin.component.WeaklyRelatedEntityCombobox;
65
import eu.etaxonomy.vaadin.component.WeaklyRelatedEntityField;
66
import eu.etaxonomy.vaadin.event.FieldReplaceEvent;
67
import eu.etaxonomy.vaadin.mvp.AbstractCdmDTOEditorPresenter;
68
import eu.etaxonomy.vaadin.mvp.AbstractPopupEditor;
69
import eu.etaxonomy.vaadin.mvp.BeanInstantiator;
70
import eu.etaxonomy.vaadin.mvp.BoundField;
71
import eu.etaxonomy.vaadin.ui.view.PopupView;
72
import eu.etaxonomy.vaadin.util.PropertyIdPath;
73

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

    
83

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

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

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

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

    
97
    private CdmFilterablePagingProvider<Reference, Reference> nomReferencePagingProvider;
98

    
99
    private Reference publishedUnit;
100

    
101
    private BeanInstantiator<Reference> newReferenceInstantiator;
102

    
103
    private TaxonNameStringFilterablePagingProvider genusOrUninomialPartPagingProvider;
104

    
105
    private TaxonNameStringFilterablePagingProvider specificEpithetPartPagingProvider;
106

    
107
    private Property.ValueChangeListener refreshSpecificEpithetComboBoxListener;
108

    
109
    private CdmFilterablePagingProvider<TaxonName, TaxonName> relatedNamePagingProvider;
110

    
111
    private CdmFilterablePagingProvider<TaxonName, TaxonName> orthographicVariantNamePagingProvider;
112

    
113
    private Restriction<Reference> orthographicCorrectionRestriction;
114

    
115
    private Integer taxonNameId;
116

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

    
123
        super.handleViewEntered();
124

    
125
        getView().getRankSelect().setContainerDataSource(cdmBeanItemContainerFactory.buildBeanItemContainer(TermType.Rank));
126
        getView().getRankSelect().setItemCaptionPropertyId("label");
127

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

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

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

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

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

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

    
156

    
157
        relatedNamePagingProvider = pagingProviderFactory.taxonNamesWithoutOrthophicIncorrect();
158
        relatedNamePagingProvider.setInitStrategy(RELATED_NAME_INIT_STRATEGY);
159
        getView().getBasionymComboboxSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<TaxonName>());
160
        getView().getBasionymComboboxSelect().setPagingProviders(relatedNamePagingProvider, relatedNamePagingProvider, relatedNamePagingProvider.getPageSize(), this);
161

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

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

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

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

    
193

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

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

    
203
    private void updateOrthographicCorrectionRestriction() {
204

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

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

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

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

    
241
                "status.type",
242

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

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

    
261
                "relationsFromThisName",
262
                "homotypicalGroup.typifiedNames"
263
        );
264

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

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

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

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

    
302
        }
303

    
304
        taxonNameId = Integer.valueOf(taxonName.getId());
305
        relatedNamePagingProvider.addRestriction(new Restriction<>("id", Operator.AND_NOT, null, taxonNameId));
306

    
307
        return taxonName;
308
    }
309

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

    
319
    }
320

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

    
331
    /**
332
     * {@inheritDoc}
333
     */
334
    @Override
335
    protected INameService getService() {
336
        return getRepo().getNameService();
337
    }
338

    
339
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
340
    public void onReferenceEditorActionAdd(ReferenceEditorAction event) {
341

    
342
        if(getView() == null || event.getSourceView() != getView() ){
343
            return;
344
        }
345

    
346
        ReferencePopupEditor referenceEditorPopup = openPopupEditor(ReferencePopupEditor.class, event);
347

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

    
362
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
363
    public void onReferenceEditorActionEdit(ReferenceEditorAction event) {
364

    
365

    
366
        if(!isFromOwnView(event)){
367
            return;
368
        }
369
        ReferencePopupEditor referenceEditorPopup = openPopupEditor(ReferencePopupEditor.class, event);
370

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

    
385
    @EventBusListenerMethod
386
    public void onFieldReplaceEvent(FieldReplaceEvent<String> event){
387

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

    
439
            }
440
        }
441

    
442
    }
443

    
444
    @EventBusListenerMethod
445
    public void onEntityChangeEvent(EntityChangeEvent<?> event){
446

    
447
        if(event.getSourceView() instanceof AbstractPopupEditor) {
448

    
449
            BoundField boundTargetField = boundTargetField((PopupView) event.getSourceView());
450

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

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

    
544
            }
545
        }
546
    }
547

    
548
    protected <CDM extends CdmBase> ReloadableLazyComboBox<CDM> asReloadableLazyComboBox(Field<CDM> field){
549

    
550
        if(field instanceof ToOneRelatedEntityCombobox){
551
            field = ((ToOneRelatedEntityCombobox<CDM>)field).getSelect();
552
        }
553
        return (ReloadableLazyComboBox<CDM>)field;
554
    }
555

    
556

    
557

    
558
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
559
    public void onTaxonNameEditorActionEdit(TaxonNameEditorAction event) {
560

    
561
        if(getView() == null || event.getSourceView() != getView() ){
562
            return;
563
        }
564

    
565
        PropertyIdPath boundPropertyId = boundPropertyIdPath(event.getTarget());
566

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

    
584
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Edit.class)
585
    public void onTaxonNameEditorActionStrRepEdit(TaxonNameEditorActionStrRep event) {
586

    
587
        if(getView() == null || event.getSourceView() != getView() ){
588
            return;
589
        }
590

    
591
        PropertyIdPath boundPropertyId = boundPropertyIdPath(event.getTarget());
592

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

    
605
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
606
    public void onTaxonNameEditorActionAdd(TaxonNameEditorAction event) {
607

    
608
        if(getView() == null || event.getSourceView() != getView() ){
609
            return;
610
        }
611

    
612
        PropertyIdPath boundPropertyId = boundPropertyIdPath(event.getTarget());
613

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

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

    
642
    @EventBusListenerMethod(filter = EditorActionTypeFilter.Add.class)
643
    public void onTaxonNameEditorActionStrRepAdd(TaxonNameEditorActionStrRep event) {
644

    
645
        if(getView() == null || event.getSourceView() != getView() ){
646
            return;
647
        }
648

    
649
        PropertyIdPath boundPropertyId = boundPropertyIdPath(event.getTarget());
650

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

    
685
    /**
686
     * {@inheritDoc}
687
     */
688
    @Override
689
    protected TaxonNameDTO createDTODecorator(TaxonName cdmEntitiy) {
690
        return new TaxonNameDTO(cdmEntitiy);
691
    }
692

    
693
    /**
694
     * {@inheritDoc}
695
     */
696
    @Override
697
    protected BeanInstantiator<TaxonName> defaultCdmEntityInstantiator() {
698
        return new BeanInstantiator<TaxonName>() {
699

    
700
            @Override
701
            public TaxonName createNewBean() {
702
                return  TaxonNameFactory.NewNameInstance(RegistrationUIDefaults.NOMENCLATURAL_CODE, Rank.SPECIES());
703
            }
704
        };
705
    }
706

    
707

    
708

    
709

    
710
}
(10-10/14)