Project

General

Profile

Download (31.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.Collection;
12
import java.util.EnumSet;
13
import java.util.HashMap;
14
import java.util.List;
15
import java.util.Map;
16
import java.util.UUID;
17

    
18
import org.apache.commons.lang3.BooleanUtils;
19
import org.apache.log4j.Level;
20
import org.springframework.context.annotation.Scope;
21
import org.springframework.security.core.GrantedAuthority;
22

    
23
import com.vaadin.data.Property;
24
import com.vaadin.data.Property.ValueChangeListener;
25
import com.vaadin.shared.ui.label.ContentMode;
26
import com.vaadin.spring.annotation.SpringComponent;
27
import com.vaadin.ui.AbstractField;
28
import com.vaadin.ui.Alignment;
29
import com.vaadin.ui.CheckBox;
30
import com.vaadin.ui.GridLayout;
31
import com.vaadin.ui.Label;
32
import com.vaadin.ui.ListSelect;
33
import com.vaadin.ui.TextField;
34

    
35
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
36
import eu.etaxonomy.cdm.model.common.CdmBase;
37
import eu.etaxonomy.cdm.model.common.RelationshipBase.Direction;
38
import eu.etaxonomy.cdm.model.name.NameRelationshipType;
39
import eu.etaxonomy.cdm.model.name.Rank;
40
import eu.etaxonomy.cdm.model.name.TaxonName;
41
import eu.etaxonomy.cdm.model.reference.Reference;
42
import eu.etaxonomy.cdm.vaadin.component.common.TeamOrPersonField;
43
import eu.etaxonomy.cdm.vaadin.event.ReferenceEditorAction;
44
import eu.etaxonomy.cdm.vaadin.event.TaxonNameEditorAction;
45
import eu.etaxonomy.cdm.vaadin.model.name.NameRelationshipDTO;
46
import eu.etaxonomy.cdm.vaadin.model.name.TaxonNameDTO;
47
import eu.etaxonomy.cdm.vaadin.permission.AccessRestrictedView;
48
import eu.etaxonomy.cdm.vaadin.permission.CdmEditDeletePermissionTester;
49
import eu.etaxonomy.cdm.vaadin.util.TeamOrPersonBaseCaptionGenerator;
50
import eu.etaxonomy.cdm.vaadin.util.converter.SetToListConverter;
51
import eu.etaxonomy.vaadin.component.NameRelationField;
52
import eu.etaxonomy.vaadin.component.ReloadableLazyComboBox;
53
import eu.etaxonomy.vaadin.component.SwitchableTextField;
54
import eu.etaxonomy.vaadin.component.ToManyRelatedEntitiesComboboxSelect;
55
import eu.etaxonomy.vaadin.component.ToOneRelatedEntityCombobox;
56
import eu.etaxonomy.vaadin.event.EditorActionType;
57
import eu.etaxonomy.vaadin.mvp.AbstractCdmDTOPopupEditor;
58

    
59
/**
60
 * @author a.kohlbecker
61
 * @since May 22, 2017
62
 *
63
 */
64
@SpringComponent
65
@Scope("prototype")
66
public class TaxonNamePopupEditor extends AbstractCdmDTOPopupEditor<TaxonNameDTO, TaxonName, TaxonNameEditorPresenter> implements TaxonNamePopupEditorView, AccessRestrictedView {
67

    
68
    private static final long serialVersionUID = -7037436241474466359L;
69

    
70
    private final static int GRID_COLS = 4;
71

    
72
    private final static int GRID_ROWS = 16;
73

    
74
    private static final boolean HAS_BASIONYM_DEFAULT = false;
75

    
76
    private TextField genusOrUninomialField;
77

    
78
    private TextField infraGenericEpithetField;
79

    
80
    private TextField specificEpithetField;
81

    
82
    private TextField infraSpecificEpithetField;
83

    
84
    private SwitchableTextField fullTitleCacheFiled;
85

    
86
    private SwitchableTextField protectedNameCacheField;
87

    
88
    private ToOneRelatedEntityCombobox<Reference> nomReferenceCombobox;
89

    
90
    private TextField nomenclaturalReferenceDetail;
91

    
92
    private TeamOrPersonField exBasionymAuthorshipField;
93

    
94
    private TeamOrPersonField basionymAuthorshipField;
95

    
96
    private ToManyRelatedEntitiesComboboxSelect<TaxonName> basionymsComboboxSelect;
97

    
98
    private ToManyRelatedEntitiesComboboxSelect<TaxonName> replacedSynonymsComboboxSelect;
99

    
100
    private NameRelationField validationField;
101

    
102
    private CheckBox basionymToggle;
103

    
104
    private CheckBox replacedSynonymsToggle;
105

    
106
    private CheckBox validationToggle;
107

    
108
    private ListSelect rankSelect;
109

    
110
    private TeamOrPersonField combinationAuthorshipField;
111

    
112
    private TeamOrPersonField exCombinationAuthorshipField;
113

    
114
    private EnumSet<TaxonNamePopupEditorMode> modesActive = EnumSet.noneOf(TaxonNamePopupEditorMode.class);
115

    
116
    private Boolean isInferredCombinationAuthorship = null;
117

    
118
    private Boolean isInferredBasionymAuthorship = null;
119

    
120
    private Boolean isInferredExBasionymAuthorship = null;
121

    
122
    private Map<AbstractField, Property.ValueChangeListener> authorshipUpdateListeners = new HashMap<>();
123

    
124
    private Boolean isInferredExCombinationAuthorship;
125

    
126
    /**
127
     * @param layout
128
     * @param dtoType
129
     */
130
    public TaxonNamePopupEditor() {
131
        super(new GridLayout(GRID_COLS, GRID_ROWS), TaxonNameDTO.class);
132
    }
133

    
134
    /**
135
     * {@inheritDoc}
136
     */
137
    @Override
138
    public String getWindowCaption() {
139
        return "Name editor";
140
    }
141

    
142

    
143

    
144
    /**
145
     * {@inheritDoc}
146
     */
147
    @Override
148
    public int getWindowWidth() {
149
        return 800;
150
    }
151

    
152
    /**
153
     * {@inheritDoc}
154
     */
155
    @Override
156
    public void focusFirst() {
157
        // titleField.focus();
158

    
159
    }
160

    
161
    /**
162
     * {@inheritDoc}
163
     */
164
    @Override
165
    protected String getDefaultComponentStyles() {
166
        return "tiny";
167
    }
168

    
169
    /**
170
     * {@inheritDoc}
171
     */
172
    @Override
173
    protected void initContent() {
174

    
175
        GridLayout grid = (GridLayout)getFieldLayout();
176
        grid.setSizeFull();
177
        grid.setHideEmptyRowsAndColumns(true);
178
        grid.setSpacing(true);
179
        grid.setColumnExpandRatio(0, 0.3f);
180
        grid.setColumnExpandRatio(1, 0.3f);
181
        grid.setColumnExpandRatio(2, 0.3f);
182
        grid.setColumnExpandRatio(3, 0.0f);
183

    
184
        /*
185
         - nameType: preset, needs to be set in the presenter for new names
186
         - appendedPhrase: -> TODO field
187
         - nomenclaturalMicroReference:  -> TODO field
188
         - nomenclaturalReference ->  field but disabled for REGISTRY
189
         - rank -> SelectField which determines the visiblity of the other fields
190

    
191
         - fullTitleCache + protectedFullTitleCache -> SwitchableTextField : ADVANCED_MODE
192
         - nameCache + protectedNameCache -> SwitchableTextField : ADVANCED_MODE
193

    
194
         - homotypicalGroup -> hidden
195
         - typeDesignations -> hidden
196
         - descriptions -> hidden
197
         - taxonBases -> hidden
198
         - registrations -> hidden
199

    
200
         - relationsFromThisName-> TODO implement later
201
         - relationsToThisName -> TODO implement later
202

    
203
         - genusOrUninomial -> textField
204
         - infraGenericEpithet  -> textField
205
         - specificEpithet  -> textField
206
         - infraSpecificEpithet  -> textField
207

    
208
         - authorshipCache + protectedAuthorshipCache -> SwitchableTextField : only ADVANCED_MODE and disabled for REGISTRY
209
         - basionymAuthorship -> field but disabled for REGISTRY, basionym is set as nameRelationShip
210
         - combinationAuthorship -> field but disabled for REGISTRY author team of the reference
211
         - exCombinationAuthorship -> textField
212
         - exBasionymAuthorship -> textField
213

    
214
         - status -> TODO field
215
         - monomHybrid -> TODO implement hybrids later
216
         - binomHybrid -> TODO implement hybrids later
217
         - trinomHybrid -> TODO implement hybrids later
218

    
219
         - hybridParentRelations -> TODO implement hybrids later
220
         - hybridChildRelations -> TODO implement hybrids later
221
         - hybridFormula -> TODO implement hybrids later
222

    
223
         ** ViralName attributes **
224
         - acronym
225

    
226
         ** BacterialName attributes **
227
         - subGenusAuthorship
228
         - nameApprobation
229
         - breed
230
         - publicationYear
231
         - originalPublicationYear
232
         - cultivarName
233
        */
234

    
235
        int row = 0;
236

    
237
        rankSelect = new ListSelect("Rank");
238
        rankSelect.setNullSelectionAllowed(false);
239
        rankSelect.setRows(1);
240
        rankSelect.setWidth(100, Unit.PERCENTAGE);
241
        rankSelect.addValueChangeListener(e -> updateFieldVisibility());
242
        addField(rankSelect, "rank", 0, row, 1, row);
243
        grid.setComponentAlignment(rankSelect, Alignment.TOP_RIGHT);
244

    
245
        basionymToggle = new CheckBox("With basionym");
246
        basionymToggle.setValue(HAS_BASIONYM_DEFAULT);
247
        basionymToggle.addValueChangeListener(e -> {
248
            updateAuthorshipFields();
249
        });
250

    
251
        basionymToggle.setStyleName(getDefaultComponentStyles());
252
        grid.addComponent(basionymToggle, 2, row, 3, row);
253
        grid.setComponentAlignment(basionymToggle, Alignment.BOTTOM_LEFT);
254

    
255
        row++;
256
        replacedSynonymsToggle = new CheckBox("With replaced synonym");
257
        replacedSynonymsToggle.addValueChangeListener(e -> {
258
            boolean enable = e.getProperty().getValue() != null && (Boolean)e.getProperty().getValue();
259
            replacedSynonymsComboboxSelect.setVisible(enable);
260
        });
261
        grid.addComponent(replacedSynonymsToggle, 2, row, 3, row);
262
        grid.setComponentAlignment(replacedSynonymsToggle, Alignment.BOTTOM_LEFT);
263

    
264
        row++;
265
        validationToggle = new CheckBox("Validation");
266
        validationToggle.addValueChangeListener(e -> {
267
            updateAuthorshipFields();
268
            });
269
        grid.addComponent(validationToggle, 2, row, 3, row);
270
        grid.setComponentAlignment(validationToggle, Alignment.BOTTOM_LEFT);
271

    
272
        row++;
273
        // fullTitleCache
274
        fullTitleCacheFiled = addSwitchableTextField("Full title cache", "fullTitleCache", "protectedFullTitleCache", 0, row, GRID_COLS-1, row);
275
        fullTitleCacheFiled.setWidth(100, Unit.PERCENTAGE);
276
        row++;
277
        protectedNameCacheField = addSwitchableTextField("Name cache", "nameCache", "protectedNameCache", 0, row, GRID_COLS-1, row);
278
        protectedNameCacheField.setWidth(100, Unit.PERCENTAGE);
279
        row++;
280
        genusOrUninomialField = addTextField("Genus or uninomial", "genusOrUninomial", 0, row, 1, row);
281
        genusOrUninomialField.setWidth(200, Unit.PIXELS);
282
        infraGenericEpithetField = addTextField("Infrageneric epithet", "infraGenericEpithet", 2, row, 3, row);
283
        infraGenericEpithetField.setWidth(200, Unit.PIXELS);
284
        row++;
285
        specificEpithetField = addTextField("Specific epithet", "specificEpithet", 0, row, 1, row);
286
        specificEpithetField.setWidth(200, Unit.PIXELS);
287
        infraSpecificEpithetField = addTextField("Infraspecific epithet", "infraSpecificEpithet", 2, row, 3, row);
288
        infraSpecificEpithetField.setWidth(200, Unit.PIXELS);
289

    
290
        row++;
291
        grid.addComponent(new Label("Hint: <i>Edit nomenclatural authors in the nomenclatural reference.</i>", ContentMode.HTML), 0, row, 3, row);
292

    
293
        row++;
294
        combinationAuthorshipField = new TeamOrPersonField("Combination author(s)", TeamOrPersonBaseCaptionGenerator.CacheType.NOMENCLATURAL_TITLE);
295
        combinationAuthorshipField.setWidth(100,  Unit.PERCENTAGE);
296
        addField(combinationAuthorshipField, "combinationAuthorship", 0, row, GRID_COLS-1, row);
297

    
298
        row++;
299
        nomReferenceCombobox = new ToOneRelatedEntityCombobox<Reference>("Nomenclatural reference", Reference.class);
300
        nomReferenceCombobox.addClickListenerAddEntity(e -> getViewEventBus().publish(
301
                this,
302
                new ReferenceEditorAction(EditorActionType.ADD, null, nomReferenceCombobox, this)
303
                ));
304
        nomReferenceCombobox.addClickListenerEditEntity(e -> {
305
            if(nomReferenceCombobox.getValue() != null){
306
                getViewEventBus().publish(this,
307
                    new ReferenceEditorAction(
308
                            EditorActionType.EDIT,
309
                            nomReferenceCombobox.getValue().getUuid(),
310
                            e.getButton(),
311
                            nomReferenceCombobox,
312
                            this)
313
                );
314
            }
315
            });
316
        logger.setLevel(Level.DEBUG);
317
        nomReferenceCombobox.getSelect().addValueChangeListener(e -> logger.debug("nomReferenceCombobox value changed #1"));
318
        // nomReferenceCombobox.setWidth(300, Unit.PIXELS);
319
        nomReferenceCombobox.setWidth("100%");
320
        addField(nomReferenceCombobox, "nomenclaturalReference", 0, row, 2, row);
321
        nomenclaturalReferenceDetail = addTextField("Reference detail", "nomenclaturalMicroReference", 3, row, 3, row);
322
        nomenclaturalReferenceDetail.setWidth(100, Unit.PIXELS);
323

    
324
        // --------------- Basionyms
325
        row++;
326
        basionymsComboboxSelect = new ToManyRelatedEntitiesComboboxSelect<TaxonName>(TaxonName.class, "Basionym");
327
        basionymsComboboxSelect.setConverter(new SetToListConverter<TaxonName>());
328
        addField(basionymsComboboxSelect, "basionyms", 0, row, 3, row);
329
        basionymsComboboxSelect.setWidth(100, Unit.PERCENTAGE);
330
        basionymsComboboxSelect.withEditButton(true);
331
        basionymsComboboxSelect.setEditPermissionTester(new CdmEditDeletePermissionTester());
332
        basionymsComboboxSelect.setEditActionListener(e -> {
333

    
334
            Object fieldValue = e.getSource().getValue();
335
            UUID beanUuid = null;
336
            if(fieldValue != null){
337
                beanUuid = ((CdmBase)fieldValue).getUuid();
338

    
339
            }
340
            ReloadableLazyComboBox<TaxonName>  lazyCombobox = (ReloadableLazyComboBox<TaxonName>) e.getSource();
341
            getViewEventBus().publish(this, new TaxonNameEditorAction(e.getAction(), beanUuid, null, lazyCombobox, this));
342
        });
343
        grid.setComponentAlignment(basionymsComboboxSelect, Alignment.TOP_RIGHT);
344

    
345
        row++;
346
        basionymAuthorshipField = new TeamOrPersonField("Basionym author(s)", TeamOrPersonBaseCaptionGenerator.CacheType.NOMENCLATURAL_TITLE);
347
        basionymAuthorshipField.setWidth(100,  Unit.PERCENTAGE);
348
        addField(basionymAuthorshipField, "basionymAuthorship", 0, row, GRID_COLS-1, row);
349
        row++;
350
        exBasionymAuthorshipField = new TeamOrPersonField("Ex-basionym author(s)", TeamOrPersonBaseCaptionGenerator.CacheType.NOMENCLATURAL_TITLE);
351
        exBasionymAuthorshipField.setWidth(100,  Unit.PERCENTAGE);
352
        addField(exBasionymAuthorshipField, "exBasionymAuthorship", 0, row, GRID_COLS-1, row);
353

    
354
        // --------------- ReplacedSynonyms
355
        row++;
356
        replacedSynonymsComboboxSelect = new ToManyRelatedEntitiesComboboxSelect<TaxonName>(TaxonName.class, "Replaced synonyms");
357
        replacedSynonymsComboboxSelect.setConverter(new SetToListConverter<TaxonName>());
358
        addField(replacedSynonymsComboboxSelect, "replacedSynonyms", 0, row, 3, row);
359
        replacedSynonymsComboboxSelect.setWidth(100, Unit.PERCENTAGE);
360
        replacedSynonymsComboboxSelect.withEditButton(true);
361
        replacedSynonymsComboboxSelect.setEditPermissionTester(new CdmEditDeletePermissionTester());
362
        replacedSynonymsComboboxSelect.setEditActionListener(e -> {
363

    
364
            Object fieldValue = e.getSource().getValue();
365
            UUID beanUuid = null;
366
            if(fieldValue != null){
367
                beanUuid = ((CdmBase)fieldValue).getUuid();
368

    
369
            }
370
            ReloadableLazyComboBox<TaxonName>  lazyCombobox = (ReloadableLazyComboBox<TaxonName>) e.getSource();
371
            getViewEventBus().publish(this, new TaxonNameEditorAction(e.getAction(), beanUuid, null, lazyCombobox, this));
372
        });
373
        grid.setComponentAlignment(replacedSynonymsComboboxSelect, Alignment.TOP_RIGHT);
374

    
375
        // --------------- Validation
376
        row++;
377
        validationField = new NameRelationField("Validation", Direction.relatedTo, NameRelationshipType.VALIDATED_BY_NAME());
378
        validationField.setWidth(100, Unit.PERCENTAGE);
379
        ToOneRelatedEntityCombobox<TaxonName> validatedNameComboBox = validationField.getValidatedNameComboBox();
380
        validatedNameComboBox.addClickListenerAddEntity(e -> getViewEventBus().publish(
381
                this,
382
                new TaxonNameEditorAction(EditorActionType.ADD, null, validatedNameComboBox, this)
383
                ));
384
        validatedNameComboBox.addClickListenerAddEntity(e -> {
385
            if(validatedNameComboBox.getValue() != null){
386
                getViewEventBus().publish(this,
387
                    new TaxonNameEditorAction(
388
                            EditorActionType.EDIT,
389
                            validatedNameComboBox.getValue().getUuid(),
390
                            e.getButton(),
391
                            validatedNameComboBox,
392
                            this)
393
                );
394
            }
395
        });
396
        ToOneRelatedEntityCombobox<Reference> validationCitatonComboBox = validationField.getCitatonComboBox();
397
        validationCitatonComboBox.addClickListenerAddEntity(e -> getViewEventBus().publish(
398
                this,
399
                new ReferenceEditorAction(EditorActionType.ADD, null, validationCitatonComboBox, this)
400
                ));
401
        validationCitatonComboBox.addClickListenerAddEntity(e -> {
402
            if(validationCitatonComboBox.getValue() != null){
403
                getViewEventBus().publish(this,
404
                    new ReferenceEditorAction(
405
                            EditorActionType.EDIT,
406
                            validationCitatonComboBox.getValue().getUuid(),
407
                            e.getButton(),
408
                            validationCitatonComboBox,
409
                            this)
410
                );
411
            }
412
        });
413
        addField(validationField, "validationFor", 0, row, 3, row);
414
        grid.setComponentAlignment(validationField, Alignment.TOP_RIGHT);
415

    
416
        row++;
417
        exCombinationAuthorshipField = new TeamOrPersonField("Ex-combination author(s)", TeamOrPersonBaseCaptionGenerator.CacheType.NOMENCLATURAL_TITLE);
418
        exCombinationAuthorshipField.setWidth(100,  Unit.PERCENTAGE);
419
        addField(exCombinationAuthorshipField, "exCombinationAuthorship", 0, row, GRID_COLS-1, row);
420

    
421
        // -----------------------------------------------------------------------------
422

    
423
        setAdvancedModeEnabled(true);
424
        registerAdvancedModeComponents(fullTitleCacheFiled, protectedNameCacheField);
425

    
426
        registerAdvancedModeComponents(combinationAuthorshipField);
427
        registerAdvancedModeComponents(basionymAuthorshipField);
428
        registerAdvancedModeComponents(exBasionymAuthorshipField);
429
        registerAdvancedModeComponents(exCombinationAuthorshipField);
430

    
431
        registerAdvancedModeComponents(combinationAuthorshipField.getCachFields());
432
        registerAdvancedModeComponents(exCombinationAuthorshipField.getCachFields());
433
        registerAdvancedModeComponents(basionymAuthorshipField.getCachFields());
434
        registerAdvancedModeComponents(exBasionymAuthorshipField.getCachFields());
435

    
436
        setAdvancedMode(false);
437

    
438
    }
439

    
440
    protected TeamOrPersonBase inferBasiomynAuthors() {
441
        List<TaxonName> basionyms = basionymsComboboxSelect.getValue();
442
        if(!basionyms.isEmpty()){
443
            TaxonName basionym = basionyms.get(0);
444
            if(basionym.getCombinationAuthorship() != null){
445
                return basionym.getCombinationAuthorship();
446
            } else if(basionym.getNomenclaturalReference() != null){
447
                return basionym.getNomenclaturalReference().getAuthorship();
448
            }
449
        }
450
        return null;
451
    }
452

    
453
    protected TeamOrPersonBase inferExBasiomynAuthors() {
454
        List<TaxonName> basionyms = basionymsComboboxSelect.getValue();
455
        if(!basionyms.isEmpty()){
456
            TaxonName basionym = basionyms.get(0);
457
                return basionym.getExCombinationAuthorship();
458
        }
459
        return null;
460
    }
461

    
462
    protected TeamOrPersonBase inferCombinationAuthors() {
463
        Reference nomRef = nomReferenceCombobox.getValue();
464
        if(nomRef != null) {
465
            return nomRef.getAuthorship();
466
        }
467
        return null;
468
    }
469

    
470
    protected TeamOrPersonBase inferExCombinationAuthors() {
471
        NameRelationshipDTO nameRelationDTO = validationField.getValue();
472
        if(nameRelationDTO != null && nameRelationDTO.getOtherName() != null){
473
            TaxonName validatedName = nameRelationDTO.getOtherName();
474
            if(validatedName.getCombinationAuthorship() != null) {
475
                return validatedName.getCombinationAuthorship();
476
            } else if(validatedName.getNomenclaturalReference() != null){
477
                return validatedName.getNomenclaturalReference().getAuthorship();
478
            }
479
        }
480
        return null;
481
    }
482

    
483
    @Override
484
    protected void afterItemDataSourceSet() {
485
        TaxonNameDTO taxonNameDTO = getBean();
486
        boolean showBasionymSection = taxonNameDTO.getBasionyms().size() > 0
487
                || taxonNameDTO.getBasionymAuthorship() != null
488
                || taxonNameDTO.getExBasionymAuthorship() != null;
489
        basionymToggle.setValue(showBasionymSection);
490
        basionymToggle.setReadOnly(showBasionymSection);
491

    
492
        boolean showReplacedSynonyms = taxonNameDTO.getReplacedSynonyms().size() > 0;
493
        replacedSynonymsToggle.setValue(showReplacedSynonyms);
494
        replacedSynonymsToggle.setReadOnly(showReplacedSynonyms);
495
        replacedSynonymsComboboxSelect.setVisible(showReplacedSynonyms);
496

    
497
        boolean showValidationSection = taxonNameDTO.getValidationFor() != null || taxonNameDTO.getExCombinationAuthorship() != null;
498

    
499
        validationToggle.setValue(showValidationSection);
500
        validationToggle.setReadOnly(showValidationSection);
501
//        validationField.setVisible(showValidation);
502
//        exCombinationAuthorshipField.setVisible(showExAuthors);
503

    
504
        if(isModeEnabled(TaxonNamePopupEditorMode.AUTOFILL_AUTHORSHIP_DATA)){
505
            updateAuthorshipFields();
506
        }
507
        if(isModeEnabled(TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY) && getBean().getNomenclaturalReference() != null) {
508
            nomReferenceCombobox.setCaption("Selection limited to nomenclatural reference and sections");
509
        }
510
        if(isModeEnabled(TaxonNamePopupEditorMode.REQUIRE_NOMENCLATURALREFERENCE)) {
511
            if(combinationAuthorshipField.getValue() == null){
512
                nomReferenceCombobox.setRequired(true);
513
            } else {
514
                combinationAuthorshipField.addValueChangeListener(e -> {
515
                    if(e.getProperty().getValue() == null){
516
                        nomReferenceCombobox.setRequired(true);
517
                    }
518
                });
519
            }
520
        }
521

    
522
    }
523

    
524
    /**
525
     * Updates all authorship fields if the an authorship field is empty this method attempts to infer the
526
     * authors from the related nomenclatural reference or taxon name.
527
     * <p>
528
     * Finally the {@link #updateFieldVisibility()} is invoked.
529
     *
530
     * @param taxonName
531
     */
532
    @Override
533
    public void updateAuthorshipFields() {
534

    
535
        TaxonNameDTO taxonName = getBean();
536

    
537
        // ------------- CombinationAuthors
538
        isInferredCombinationAuthorship = updateAuthorshipFieldData(
539
                taxonName.getCombinationAuthorship(),
540
                inferCombinationAuthors(),
541
                combinationAuthorshipField,
542
                nomReferenceCombobox.getSelect(),
543
                isInferredCombinationAuthorship);
544

    
545

    
546
        // ------------- Basionym and ExBasionymAuthors
547
        if(BooleanUtils.isTrue(basionymToggle.getValue())){
548

    
549
            isInferredBasionymAuthorship = updateAuthorshipFieldData(
550
                    taxonName.getBasionymAuthorship(),
551
                    inferBasiomynAuthors(),
552
                    basionymAuthorshipField,
553
                    basionymsComboboxSelect,
554
                    isInferredBasionymAuthorship
555
                    );
556

    
557
            isInferredExBasionymAuthorship = updateAuthorshipFieldData(
558
                    taxonName.getExBasionymAuthorship(),
559
                    inferExBasiomynAuthors(),
560
                    exBasionymAuthorshipField,
561
                    basionymsComboboxSelect,
562
                    isInferredExBasionymAuthorship
563
                    );
564

    
565
        }
566

    
567
        // ------------- Validation and ExCombinationAuthors
568
        isInferredExCombinationAuthorship = updateAuthorshipFieldData(
569
                taxonName.getExCombinationAuthorship(),
570
                inferExCombinationAuthors(),
571
                exCombinationAuthorshipField,
572
                validationField.getValidatedNameComboBox(),
573
                isInferredExCombinationAuthorship
574
                );
575

    
576
        updateFieldVisibility();
577

    
578
    }
579

    
580
//    /**
581
//     *
582
//     */
583
//    protected void updateAuthorshipFieldsVisibility() {
584
//        combinationAuthorshipField.setVisible(!isInferredCombinationAuthorship);
585
//        if(BooleanUtils.isTrue(basionymToggle.getValue())){
586
//            basionymAuthorshipField.setVisible(!isInferredBasionymAuthorship);
587
//            exBasionymAuthorshipField.setVisible(!isInferredExBasionymAuthorship);
588
//        }
589
//    }
590

    
591
    /**
592
     *
593
     * @param authorship
594
     *    the value of the taxonName authorship field
595
     * @param inferredAuthors
596
     *    the value inferred from other fields which may be set as authorship to the taxon name
597
     * @param authorshipField
598
     *    the ui element to edit the taxonName authorship field
599
     * @param updateTriggerField
600
     * @param lastInferredAuthorshipState
601
     * @return
602
     */
603
    protected Boolean updateAuthorshipFieldData(TeamOrPersonBase<?> authorship, TeamOrPersonBase inferredAuthors,
604
            TeamOrPersonField authorshipField, AbstractField updateTriggerField,
605
            Boolean lastInferredAuthorshipState) {
606

    
607
        if(authorship == null){
608
            authorshipField.setValue(inferredAuthors);
609
            lastInferredAuthorshipState = true;
610
        } else {
611
            boolean authorshipMatch = authorship == inferredAuthors;
612
            if(lastInferredAuthorshipState == null){
613
                // initialization of authorshipState, this comes only into account when the editor is just being initialized
614
                lastInferredAuthorshipState = authorshipMatch;
615
            }
616
            if(!authorshipMatch && lastInferredAuthorshipState){
617
                // update the combinationAuthorshipField to follow changes of the nomenclatural reference in case it was autofilled before
618
                authorshipField.setValue(inferredAuthors);
619
                lastInferredAuthorshipState = true;
620
            }
621
        }
622

    
623
        if(updateTriggerField != null){
624
            // IMPORTANT!
625
            // this ChangeListener must be added at this very late point in the editor lifecycle so that it is called after
626
            // the ToOneRelatedEntityReloader which may have been added to the updateTriggerField in the presenters handleViewEntered() method.
627
            // Otherwise we risk multiple representation problems in the hibernate session
628
            if(!authorshipUpdateListeners.containsKey(updateTriggerField)){
629
                ValueChangeListener listener = e ->  {
630
                    logger.debug(" value changed #2");
631
                    updateAuthorshipFields();
632
                };
633
                updateTriggerField.addValueChangeListener(listener);
634
                authorshipUpdateListeners.put(updateTriggerField, listener);
635
            }
636
        }
637

    
638
        return lastInferredAuthorshipState;
639
    }
640

    
641
    /**
642
     * @param rank
643
     * @return
644
     */
645
    private void updateFieldVisibility() {
646

    
647
        // TODO use getField() instead and remove field references
648
        Rank rank = (Rank) rankSelect.getValue();
649

    
650
        boolean isSpeciesOrBelow = !rank.isHigher(Rank.SPECIES());
651
        Boolean withBasionymSection = BooleanUtils.isTrue(basionymToggle.getValue());
652
        Boolean withValidationSection = isSpeciesOrBelow && BooleanUtils.isTrue(validationToggle.getValue());
653

    
654
        specificEpithetField.setVisible(isSpeciesOrBelow);
655
        infraSpecificEpithetField.setVisible(rank.isInfraSpecific());
656
        infraGenericEpithetField.setVisible(rank.isInfraGeneric());
657

    
658
        basionymsComboboxSelect.setVisible(withBasionymSection);
659

    
660
        combinationAuthorshipField.setVisible(isInferredCombinationAuthorship != null && !isInferredCombinationAuthorship);
661
        basionymAuthorshipField.setVisible(withBasionymSection && isInferredBasionymAuthorship != null && !isInferredBasionymAuthorship);
662
        exBasionymAuthorshipField.setVisible(withBasionymSection && isInferredExBasionymAuthorship != null && !isInferredExBasionymAuthorship);
663

    
664
        validationField.setVisible(withValidationSection);
665
        exCombinationAuthorshipField.setVisible(withValidationSection && isInferredExCombinationAuthorship != null && !isInferredExCombinationAuthorship);
666

    
667

    
668
//        if(taxonName != null){
669
//            if(modesActive.contains(TaxonNamePopupEditorMode.AUTOFILL_AUTHORSHIP_DATA)){
670
//            }
671
//        }
672

    
673
        infraSpecificEpithetField.setVisible(rank.isInfraSpecific());
674
        specificEpithetField.setVisible(isSpeciesOrBelow);
675
        infraGenericEpithetField.setVisible(rank.isInfraGenericButNotSpeciesGroup());
676
        genusOrUninomialField.setCaption(isSpeciesOrBelow ? "Genus" : "Uninomial");
677
    }
678

    
679
    @Override
680
    public void cancel() {
681
        authorshipUpdateListeners.keySet().forEach(field -> field.removeValueChangeListener(authorshipUpdateListeners.get(field)));
682
        super.cancel();
683
    }
684

    
685
    /**
686
     * {@inheritDoc}
687
     */
688
    @Override
689
    public boolean allowAnonymousAccess() {
690
        return false;
691
    }
692

    
693
    /**
694
     * {@inheritDoc}
695
     */
696
    @Override
697
    public Collection<Collection<GrantedAuthority>> allowedGrantedAuthorities() {
698
        return null;
699
    }
700

    
701
    /**
702
     * {@inheritDoc}
703
     */
704
    @Override
705
    public ToOneRelatedEntityCombobox<Reference> getNomReferenceCombobox() {
706
        return nomReferenceCombobox;
707
    }
708

    
709
    /**
710
     * {@inheritDoc}
711
     */
712
    @Override
713
    public ToManyRelatedEntitiesComboboxSelect<TaxonName> getBasionymComboboxSelect() {
714
        return basionymsComboboxSelect;
715
    }
716

    
717
    /**
718
     * {@inheritDoc}
719
     */
720
    @Override
721
    public ToManyRelatedEntitiesComboboxSelect<TaxonName> getReplacedSynonymsComboboxSelect() {
722
        return replacedSynonymsComboboxSelect;
723
    }
724

    
725
    /**
726
     * {@inheritDoc}
727
     */
728
    @Override
729
    public ListSelect getRankSelect() {
730
        return rankSelect;
731
    }
732

    
733
    /**
734
     * @return the exBasionymAuthorshipField
735
     */
736
    @Override
737
    public TeamOrPersonField getExBasionymAuthorshipField() {
738
        return exBasionymAuthorshipField;
739
    }
740

    
741
    /**
742
     * @return the basionymAuthorshipField
743
     */
744
    @Override
745
    public TeamOrPersonField getBasionymAuthorshipField() {
746
        return basionymAuthorshipField;
747
    }
748

    
749
    /**
750
     * @return the combinationAuthorshipField
751
     */
752
    @Override
753
    public TeamOrPersonField getCombinationAuthorshipField() {
754
        return combinationAuthorshipField;
755
    }
756

    
757
    /**
758
     * @return the exCombinationAuthorshipField
759
     */
760
    @Override
761
    public TeamOrPersonField getExCombinationAuthorshipField() {
762
        return exCombinationAuthorshipField;
763
    }
764

    
765
    @Override
766
    public NameRelationField getValidationField(){
767
        return validationField;
768
    }
769

    
770
    @Override
771
    public void enableMode(TaxonNamePopupEditorMode mode){
772
            modesActive.add(mode);
773
    }
774

    
775
    @Override
776
    public boolean isModeEnabled(TaxonNamePopupEditorMode mode){
777
        return modesActive.contains(mode);
778
    }
779

    
780
    @Override
781
    public void disableMode(TaxonNamePopupEditorMode mode){
782
        modesActive.remove(mode);
783
    }
784

    
785
    @Override
786
    public EnumSet<TaxonNamePopupEditorMode> getModesActive(){
787
        return modesActive;
788
    }
789

    
790
    @Override
791
    public CheckBox getBasionymToggle() {
792
        return basionymToggle;
793
    }
794

    
795
    /**
796
     * {@inheritDoc}
797
     */
798
    @Override
799
    public void setReadOnly(boolean readOnly) {
800
        boolean basionymToggleReadonly = basionymToggle.isReadOnly();
801
        boolean validationToggleReadonly = validationToggle.isReadOnly();
802
        super.setReadOnly(readOnly);
803
        combinationAuthorshipField.setEditorReadOnly(readOnly);
804
        exCombinationAuthorshipField.setEditorReadOnly(readOnly);
805
        basionymAuthorshipField.setEditorReadOnly(readOnly);
806
        exBasionymAuthorshipField.setEditorReadOnly(readOnly);
807
        // preserve old readonly states if they were true
808
        if(basionymToggleReadonly){
809
            basionymToggle.setReadOnly(true);
810
        }
811
        if(validationToggleReadonly){
812
            validationToggle.setReadOnly(true);
813
        }
814
    }
815

    
816

    
817

    
818

    
819
}
(10-10/13)