Project

General

Profile

Download (18.1 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.converter.SetToListConverter;
38
import eu.etaxonomy.vaadin.component.SwitchableTextField;
39
import eu.etaxonomy.vaadin.component.ToManyRelatedEntitiesComboboxSelect;
40
import eu.etaxonomy.vaadin.component.ToOneRelatedEntityCombobox;
41
import eu.etaxonomy.vaadin.event.EditorActionType;
42
import eu.etaxonomy.vaadin.mvp.AbstractCdmPopupEditor;
43
import eu.etaxonomy.vaadin.permission.EditPermissionTester;
44

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

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

    
56
    private final static int GRID_COLS = 4;
57

    
58
    private final static int GRID_ROWS = 13;
59

    
60
    private static final boolean HAS_BASIONYM_DEFAULT = false;
61

    
62
    private TextField genusOrUninomialField;
63

    
64
    private TextField infraGenericEpithetField;
65

    
66
    private TextField specificEpithetField;
67

    
68
    private TextField infraSpecificEpithetField;
69

    
70
    private SwitchableTextField fullTitleCacheFiled;
71

    
72
    private SwitchableTextField protectedNameCacheField;
73

    
74
    private ToOneRelatedEntityCombobox<Reference> nomReferenceCombobox;
75

    
76
    private TextField nomenclaturalReferenceDetail;
77

    
78
    private TeamOrPersonField exBasionymAuthorshipField;
79

    
80
    private TeamOrPersonField basionymAuthorshipField;
81

    
82
    private ToManyRelatedEntitiesComboboxSelect<TaxonName> basionymsComboboxSelect;
83

    
84
    private CheckBox basionymToggle;
85

    
86
    private CheckBox validationToggle;
87

    
88
    private ListSelect rankSelect;
89

    
90
    private TeamOrPersonField combinationAuthorshipField;
91

    
92
    private TeamOrPersonField exCombinationAuthorshipField;
93

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

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

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

    
112

    
113

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

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

    
129
    }
130

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

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

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

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

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

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

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

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

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

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

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

    
193
         ** ViralName attributes **
194
         - acronym
195

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

    
205
        int row = 0;
206

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

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

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

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

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

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

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

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

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

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

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

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

    
320

    
321

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

    
330
    }
331

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

    
338
        // TODO use getField() instead and remove field references
339

    
340
        TaxonName taxonName = getBean();
341
        Rank rank = taxonName.getRank();
342

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

    
347
        basionymAuthorshipField.setVisible(withBasionym != null && withBasionym);
348
        exBasionymAuthorshipField.setVisible(withBasionym);
349
        basionymsComboboxSelect.setVisible(withBasionym);
350

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

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

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

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

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

    
397
    }
398

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

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

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

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

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

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

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

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

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

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

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

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

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

    
491
    @Override
492
    public CheckBox getBasionymToggle() {
493
        return basionymToggle;
494
    }
495

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

    
513

    
514

    
515

    
516
}
(10-10/13)