Project

General

Profile

Download (18.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

    
14
import org.apache.commons.lang3.BooleanUtils;
15
import org.springframework.context.annotation.Scope;
16
import org.springframework.security.core.GrantedAuthority;
17

    
18
import com.vaadin.shared.ui.label.ContentMode;
19
import com.vaadin.spring.annotation.SpringComponent;
20
import com.vaadin.ui.Alignment;
21
import com.vaadin.ui.CheckBox;
22
import com.vaadin.ui.GridLayout;
23
import com.vaadin.ui.Label;
24
import com.vaadin.ui.ListSelect;
25
import com.vaadin.ui.TextField;
26

    
27
import eu.etaxonomy.cdm.model.common.CdmBase;
28
import eu.etaxonomy.cdm.model.name.Rank;
29
import eu.etaxonomy.cdm.model.name.TaxonName;
30
import eu.etaxonomy.cdm.model.reference.Reference;
31
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
32
import eu.etaxonomy.cdm.vaadin.component.common.TeamOrPersonField;
33
import eu.etaxonomy.cdm.vaadin.event.ReferenceEditorAction;
34
import eu.etaxonomy.cdm.vaadin.event.TaxonNameEditorAction;
35
import eu.etaxonomy.cdm.vaadin.security.AccessRestrictedView;
36
import eu.etaxonomy.cdm.vaadin.security.UserHelper;
37
import eu.etaxonomy.cdm.vaadin.util.TeamOrPersonBaseCaptionGenerator;
38
import eu.etaxonomy.cdm.vaadin.util.converter.SetToListConverter;
39
import eu.etaxonomy.vaadin.component.SwitchableTextField;
40
import eu.etaxonomy.vaadin.component.ToManyRelatedEntitiesComboboxSelect;
41
import eu.etaxonomy.vaadin.component.ToOneRelatedEntityCombobox;
42
import eu.etaxonomy.vaadin.event.EditorActionType;
43
import eu.etaxonomy.vaadin.mvp.AbstractCdmPopupEditor;
44
import eu.etaxonomy.vaadin.permission.EditPermissionTester;
45

    
46
/**
47
 * @author a.kohlbecker
48
 * @since May 22, 2017
49
 *
50
 */
51
@SpringComponent
52
@Scope("prototype")
53
public class TaxonNamePopupEditor extends AbstractCdmPopupEditor<TaxonName, TaxonNameEditorPresenter> implements TaxonNamePopupEditorView, AccessRestrictedView {
54

    
55
    private static final long serialVersionUID = -7037436241474466359L;
56

    
57
    private final static int GRID_COLS = 4;
58

    
59
    private final static int GRID_ROWS = 13;
60

    
61
    private static final boolean HAS_BASIONYM_DEFAULT = false;
62

    
63
    private TextField genusOrUninomialField;
64

    
65
    private TextField infraGenericEpithetField;
66

    
67
    private TextField specificEpithetField;
68

    
69
    private TextField infraSpecificEpithetField;
70

    
71
    private SwitchableTextField fullTitleCacheFiled;
72

    
73
    private SwitchableTextField protectedNameCacheField;
74

    
75
    private ToOneRelatedEntityCombobox<Reference> nomReferenceCombobox;
76

    
77
    private TextField nomenclaturalReferenceDetail;
78

    
79
    private TeamOrPersonField exBasionymAuthorshipField;
80

    
81
    private TeamOrPersonField basionymAuthorshipField;
82

    
83
    private ToManyRelatedEntitiesComboboxSelect<TaxonName> basionymsComboboxSelect;
84

    
85
    private CheckBox basionymToggle;
86

    
87
    private CheckBox validationToggle;
88

    
89
    private ListSelect rankSelect;
90

    
91
    private TeamOrPersonField combinationAuthorshipField;
92

    
93
    private TeamOrPersonField exCombinationAuthorshipField;
94

    
95
    private EnumSet<TaxonNamePopupEditorMode> modesActive = EnumSet.noneOf(TaxonNamePopupEditorMode.class);
96

    
97
    /**
98
     * @param layout
99
     * @param dtoType
100
     */
101
    public TaxonNamePopupEditor() {
102
        super(new GridLayout(GRID_COLS, GRID_ROWS), TaxonName.class);
103
    }
104

    
105
    /**
106
     * {@inheritDoc}
107
     */
108
    @Override
109
    public String getWindowCaption() {
110
        return "Name editor";
111
    }
112

    
113

    
114

    
115
    /**
116
     * {@inheritDoc}
117
     */
118
    @Override
119
    public int getWindowPixelWidth() {
120
        return 800;
121
    }
122

    
123
    /**
124
     * {@inheritDoc}
125
     */
126
    @Override
127
    public void focusFirst() {
128
        // titleField.focus();
129

    
130
    }
131

    
132
    /**
133
     * {@inheritDoc}
134
     */
135
    @Override
136
    protected String getDefaultComponentStyles() {
137
        return "tiny";
138
    }
139

    
140
    /**
141
     * {@inheritDoc}
142
     */
143
    @Override
144
    protected void initContent() {
145

    
146
        GridLayout grid = (GridLayout)getFieldLayout();
147
        grid.setSizeFull();
148
        grid.setHideEmptyRowsAndColumns(true);
149
        grid.setSpacing(true);
150
        grid.setColumnExpandRatio(0, 0.3f);
151
        grid.setColumnExpandRatio(1, 0.3f);
152
        grid.setColumnExpandRatio(2, 0.3f);
153
        grid.setColumnExpandRatio(3, 0.0f);
154

    
155
        /*
156
         - nameType: preset, needs to be set in the presenter for new names
157
         - appendedPhrase: -> TODO field
158
         - nomenclaturalMicroReference:  -> TODO field
159
         - nomenclaturalReference ->  field but disabled for REGISTRY
160
         - rank -> SelectField which determines the visiblity of the other fields
161

    
162
         - fullTitleCache + protectedFullTitleCache -> SwitchableTextField : ADVANCED_MODE
163
         - nameCache + protectedNameCache -> SwitchableTextField : ADVANCED_MODE
164

    
165
         - homotypicalGroup -> hidden
166
         - typeDesignations -> hidden
167
         - descriptions -> hidden
168
         - taxonBases -> hidden
169
         - registrations -> hidden
170

    
171
         - relationsFromThisName-> TODO implement later
172
         - relationsToThisName -> TODO implement later
173

    
174
         - genusOrUninomial -> textField
175
         - infraGenericEpithet  -> textField
176
         - specificEpithet  -> textField
177
         - infraSpecificEpithet  -> textField
178

    
179
         - authorshipCache + protectedAuthorshipCache -> SwitchableTextField : only ADVANCED_MODE and disabled for REGISTRY
180
         - basionymAuthorship -> field but disabled for REGISTRY, basionym is set as nameRelationShip
181
         - combinationAuthorship -> field but disabled for REGISTRY author team of the reference
182
         - exCombinationAuthorship -> textField
183
         - exBasionymAuthorship -> textField
184

    
185
         - status -> TODO field
186
         - monomHybrid -> TODO implement hybrids later
187
         - binomHybrid -> TODO implement hybrids later
188
         - trinomHybrid -> TODO implement hybrids later
189

    
190
         - hybridParentRelations -> TODO implement hybrids later
191
         - hybridChildRelations -> TODO implement hybrids later
192
         - hybridFormula -> TODO implement hybrids later
193

    
194
         ** ViralName attributes **
195
         - acronym
196

    
197
         ** BacterialName attributes **
198
         - subGenusAuthorship
199
         - nameApprobation
200
         - breed
201
         - publicationYear
202
         - originalPublicationYear
203
         - cultivarName
204
        */
205

    
206
        int row = 0;
207

    
208
        rankSelect = new ListSelect("Rank");
209
        rankSelect.setNullSelectionAllowed(false);
210
        rankSelect.setRows(1);
211
        rankSelect.setWidth(100, Unit.PERCENTAGE);
212
        rankSelect.addValueChangeListener(e -> updateFieldVisibility());
213
        addField(rankSelect, "rank", 0, row, 1, row);
214
        grid.setComponentAlignment(rankSelect, Alignment.TOP_RIGHT);
215

    
216
        basionymToggle = new CheckBox("With basionym");
217
        basionymToggle.setValue(HAS_BASIONYM_DEFAULT);
218
        basionymToggle.addValueChangeListener(e -> {
219
                updateFieldVisibility();
220
            });
221
        basionymToggle.setStyleName(getDefaultComponentStyles());
222
        grid.addComponent(basionymToggle, 2, row, 3, row);
223
        grid.setComponentAlignment(basionymToggle, Alignment.BOTTOM_LEFT);
224

    
225
        row++;
226
        validationToggle = new CheckBox("Validation");
227
        validationToggle.addValueChangeListener(e -> {
228
                boolean enable = e.getProperty().getValue() != null && (Boolean)e.getProperty().getValue();
229
                exCombinationAuthorshipField.setVisible(enable);
230
            });
231
        grid.addComponent(validationToggle, 2, row, 3, row);
232
        grid.setComponentAlignment(validationToggle, Alignment.BOTTOM_LEFT);
233

    
234
        row++;
235
        // fullTitleCache
236
        fullTitleCacheFiled = addSwitchableTextField("Full title cache", "fullTitleCache", "protectedFullTitleCache", 0, row, GRID_COLS-1, row);
237
        fullTitleCacheFiled.setWidth(100, Unit.PERCENTAGE);
238
        row++;
239
        protectedNameCacheField = addSwitchableTextField("Name cache", "nameCache", "protectedNameCache", 0, row, GRID_COLS-1, row);
240
        protectedNameCacheField.setWidth(100, Unit.PERCENTAGE);
241
        row++;
242
        genusOrUninomialField = addTextField("Genus or uninomial", "genusOrUninomial", 0, row, 1, row);
243
        genusOrUninomialField.setWidth(200, Unit.PIXELS);
244
        infraGenericEpithetField = addTextField("Infrageneric epithet", "infraGenericEpithet", 2, row, 3, row);
245
        infraGenericEpithetField.setWidth(200, Unit.PIXELS);
246
        row++;
247
        specificEpithetField = addTextField("Specific epithet", "specificEpithet", 0, row, 1, row);
248
        specificEpithetField.setWidth(200, Unit.PIXELS);
249
        infraSpecificEpithetField = addTextField("Infraspecific epithet", "infraSpecificEpithet", 2, row, 3, row);
250
        infraSpecificEpithetField.setWidth(200, Unit.PIXELS);
251

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

    
255
        row++;
256
        combinationAuthorshipField = new TeamOrPersonField("combination author(s)", TeamOrPersonBaseCaptionGenerator.CacheType.NOMENCLATURAL_TITLE);
257
        combinationAuthorshipField.setWidth(100,  Unit.PERCENTAGE);
258
        addField(combinationAuthorshipField, "combinationAuthorship", 0, row, GRID_COLS-1, row);
259

    
260
        row++;
261
        nomReferenceCombobox = new ToOneRelatedEntityCombobox<Reference>("Nomenclatural reference", Reference.class);
262
        nomReferenceCombobox.addClickListenerAddEntity(e -> getViewEventBus().publish(
263
                this,
264
                new ReferenceEditorAction(EditorActionType.ADD, null, nomReferenceCombobox, this)
265
                ));
266
        nomReferenceCombobox.addClickListenerEditEntity(e -> {
267
            if(nomReferenceCombobox.getValue() != null){
268
                getViewEventBus().publish(this,
269
                    new ReferenceEditorAction(
270
                            EditorActionType.EDIT,
271
                            nomReferenceCombobox.getValue().getId(),
272
                            nomReferenceCombobox,
273
                            this)
274
                );
275
            }
276
            });
277
        // nomReferenceCombobox.setWidth(300, Unit.PIXELS);
278
        nomReferenceCombobox.setWidth("100%");
279
        addField(nomReferenceCombobox, "nomenclaturalReference", 0, row, 2, row);
280
        nomenclaturalReferenceDetail = addTextField("Reference detail", "nomenclaturalMicroReference", 3, row, 3, row);
281
        nomenclaturalReferenceDetail.setWidth(100, Unit.PIXELS);
282

    
283
        row++;
284
        exCombinationAuthorshipField = new TeamOrPersonField("Ex-combination author(s)", TeamOrPersonBaseCaptionGenerator.CacheType.NOMENCLATURAL_TITLE);
285
        exCombinationAuthorshipField.setWidth(100,  Unit.PERCENTAGE);
286
        addField(exCombinationAuthorshipField, "exCombinationAuthorship", 0, row, GRID_COLS-1, row);
287

    
288
        // Basionym
289
        row++;
290
        basionymsComboboxSelect = new ToManyRelatedEntitiesComboboxSelect<TaxonName>(TaxonName.class, "Basionym");
291
        basionymsComboboxSelect.setConverter(new SetToListConverter<TaxonName>());
292
        addField(basionymsComboboxSelect, "basionyms", 0, row, 3, row);
293
        basionymsComboboxSelect.setWidth(100, Unit.PERCENTAGE);
294
        basionymsComboboxSelect.withEditButton(true);
295
        basionymsComboboxSelect.setEditPermissionTester(new EditPermissionTester() {
296

    
297
            @Override
298
            public boolean userHasEditPermission(Object bean) {
299
                return  UserHelper.fromSession().userHasPermission((CdmBase)bean, CRUD.UPDATE, CRUD.DELETE);
300
            }
301
        });
302
        basionymsComboboxSelect.setEditActionListener(e -> {
303

    
304
            Object fieldValue = e.getSource().getValue();
305
            Integer beanId = null;
306
            if(fieldValue != null){
307
                beanId = ((CdmBase)fieldValue).getId();
308

    
309
            }
310
            getViewEventBus().publish(this, new TaxonNameEditorAction(e.getAction(), beanId, e.getSource(), this));
311
        });
312
        grid.setComponentAlignment(basionymsComboboxSelect, Alignment.TOP_RIGHT);
313
        row++;
314
        basionymAuthorshipField = new TeamOrPersonField("Basionym author(s)", TeamOrPersonBaseCaptionGenerator.CacheType.NOMENCLATURAL_TITLE);
315
        basionymAuthorshipField.setWidth(100,  Unit.PERCENTAGE);
316
        addField(basionymAuthorshipField, "basionymAuthorship", 0, row, GRID_COLS-1, row);
317
        row++;
318
        exBasionymAuthorshipField = new TeamOrPersonField("Ex-basionym author(s)", TeamOrPersonBaseCaptionGenerator.CacheType.NOMENCLATURAL_TITLE);
319
        exBasionymAuthorshipField.setWidth(100,  Unit.PERCENTAGE);
320
        addField(exBasionymAuthorshipField, "exBasionymAuthorship", 0, row, GRID_COLS-1, row);
321

    
322

    
323

    
324
        setAdvancedModeEnabled(true);
325
        registerAdvancedModeComponents(fullTitleCacheFiled, protectedNameCacheField);
326
        registerAdvancedModeComponents(basionymAuthorshipField.getCachFields());
327
        registerAdvancedModeComponents(exBasionymAuthorshipField.getCachFields());
328
        registerAdvancedModeComponents(combinationAuthorshipField.getCachFields());
329
        registerAdvancedModeComponents(exCombinationAuthorshipField.getCachFields());
330
        setAdvancedMode(false);
331

    
332
    }
333

    
334
    /**
335
     * @param rank
336
     * @return
337
     */
338
    private void updateFieldVisibility() {
339

    
340
        // TODO use getField() instead and remove field references
341

    
342
        TaxonName taxonName = getBean();
343
        Rank rank = taxonName.getRank();
344

    
345
        boolean isSpeciesOrBelow = !rank.isHigher(Rank.SPECIES());
346
        Boolean withBasionym = BooleanUtils.isTrue(basionymToggle.getValue());
347
        Boolean withValidation = BooleanUtils.isTrue(validationToggle.getValue());
348

    
349
        basionymAuthorshipField.setVisible(withBasionym != null && withBasionym);
350
        exBasionymAuthorshipField.setVisible(withBasionym);
351
        basionymsComboboxSelect.setVisible(withBasionym);
352

    
353
        if(taxonName != null){
354
            if(modesActive.contains(TaxonNamePopupEditorMode.suppressReplacementAuthorshipData)){
355
                basionymAuthorshipField.setVisible(taxonName.getBasionymAuthorship() != null);
356
                exBasionymAuthorshipField.setVisible(taxonName.getExBasionymAuthorship() != null);
357
            }
358
        }
359

    
360
        infraSpecificEpithetField.setVisible(rank.isInfraSpecific());
361
        specificEpithetField.setVisible(isSpeciesOrBelow);
362
        infraGenericEpithetField.setVisible(rank.isInfraGenericButNotSpeciesGroup());
363
        genusOrUninomialField.setCaption(isSpeciesOrBelow ? "Genus" : "Uninomial");
364
        exCombinationAuthorshipField.setVisible(isSpeciesOrBelow && withValidation);
365
    }
366

    
367
    @Override
368
    protected void afterItemDataSourceSet() {
369
        TaxonName taxonName = getBean();
370
        boolean showBasionymSection = taxonName.getBasionyms().size() > 0
371
                || taxonName.getBasionymAuthorship() != null
372
                || taxonName.getExBasionymAuthorship() != null;
373
        basionymToggle.setValue(showBasionymSection);
374
        basionymToggle.setReadOnly(showBasionymSection);
375

    
376
        boolean showExAuthors = taxonName.getExCombinationAuthorship() != null;
377
        validationToggle.setValue(showExAuthors);
378
        validationToggle.setReadOnly(showExAuthors);
379
        exCombinationAuthorshipField.setVisible(showExAuthors);
380

    
381
        if(isModeEnabled(TaxonNamePopupEditorMode.suppressReplacementAuthorshipData)){
382
            combinationAuthorshipField.setVisible(taxonName.getCombinationAuthorship() != null);
383
        }
384
        if(isModeEnabled(TaxonNamePopupEditorMode.nomenclaturalReferenceSectionEditingOnly) && getBean().getNomenclaturalReference() != null) {
385
            nomReferenceCombobox.setCaption("Selection limited to nomenclatural reference and sections");
386
        }
387
        if(isModeEnabled(TaxonNamePopupEditorMode.requireNomenclaturalReference)) {
388
            if(combinationAuthorshipField.getValue() == null){
389
                nomReferenceCombobox.setRequired(true);
390
            } else {
391
                combinationAuthorshipField.addValueChangeListener(e -> {
392
                    if(e.getProperty().getValue() == null){
393
                        nomReferenceCombobox.setRequired(true);
394
                    }
395
                });
396
            }
397
        }
398

    
399
    }
400

    
401
    /**
402
     * {@inheritDoc}
403
     */
404
    @Override
405
    public boolean allowAnonymousAccess() {
406
        return false;
407
    }
408

    
409
    /**
410
     * {@inheritDoc}
411
     */
412
    @Override
413
    public Collection<Collection<GrantedAuthority>> allowedGrantedAuthorities() {
414
        return null;
415
    }
416

    
417
    /**
418
     * {@inheritDoc}
419
     */
420
    @Override
421
    public ToOneRelatedEntityCombobox<Reference> getNomReferenceCombobox() {
422
        return nomReferenceCombobox;
423
    }
424

    
425
    /**
426
     * {@inheritDoc}
427
     */
428
    @Override
429
    public ToManyRelatedEntitiesComboboxSelect<TaxonName> getBasionymComboboxSelect() {
430
        return basionymsComboboxSelect;
431
    }
432

    
433
    /**
434
     * {@inheritDoc}
435
     */
436
    @Override
437
    public ListSelect getRankSelect() {
438
        return rankSelect;
439
    }
440

    
441
    /**
442
     * @return the exBasionymAuthorshipField
443
     */
444
    @Override
445
    public TeamOrPersonField getExBasionymAuthorshipField() {
446
        return exBasionymAuthorshipField;
447
    }
448

    
449
    /**
450
     * @return the basionymAuthorshipField
451
     */
452
    @Override
453
    public TeamOrPersonField getBasionymAuthorshipField() {
454
        return basionymAuthorshipField;
455
    }
456

    
457
    /**
458
     * @return the combinationAuthorshipField
459
     */
460
    @Override
461
    public TeamOrPersonField getCombinationAuthorshipField() {
462
        return combinationAuthorshipField;
463
    }
464

    
465
    /**
466
     * @return the exCombinationAuthorshipField
467
     */
468
    @Override
469
    public TeamOrPersonField getExCombinationAuthorshipField() {
470
        return exCombinationAuthorshipField;
471
    }
472

    
473
    @Override
474
    public void enableMode(TaxonNamePopupEditorMode mode){
475
            modesActive.add(mode);
476
    }
477

    
478
    @Override
479
    public boolean isModeEnabled(TaxonNamePopupEditorMode mode){
480
        return modesActive.contains(mode);
481
    }
482

    
483
    @Override
484
    public void disableMode(TaxonNamePopupEditorMode mode){
485
        modesActive.remove(mode);
486
    }
487

    
488
    @Override
489
    public EnumSet<TaxonNamePopupEditorMode> getModesActive(){
490
        return modesActive;
491
    }
492

    
493
    @Override
494
    public CheckBox getBasionymToggle() {
495
        return basionymToggle;
496
    }
497

    
498
    /**
499
     * {@inheritDoc}
500
     */
501
    @Override
502
    public void setReadOnly(boolean readOnly) {
503
        boolean basionymToggleReadonly = basionymToggle.isReadOnly();
504
        boolean validationToggleReadonly = validationToggle.isReadOnly();
505
        super.setReadOnly(readOnly);
506
        // preserve old readonly states if they were true
507
        if(basionymToggleReadonly){
508
            basionymToggle.setReadOnly(true);
509
        }
510
        if(validationToggleReadonly){
511
            validationToggle.setReadOnly(true);
512
        }
513
    }
514

    
515

    
516

    
517

    
518
}
(10-10/13)