Project

General

Profile

Download (17.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.security.core.GrantedAuthority;
16

    
17
import com.vaadin.shared.ui.label.ContentMode;
18
import com.vaadin.ui.Alignment;
19
import com.vaadin.ui.CheckBox;
20
import com.vaadin.ui.GridLayout;
21
import com.vaadin.ui.Label;
22
import com.vaadin.ui.ListSelect;
23
import com.vaadin.ui.TextField;
24

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

    
43
/**
44
 * @author a.kohlbecker
45
 * @since May 22, 2017
46
 *
47
 */
48
public class TaxonNamePopupEditor extends AbstractCdmPopupEditor<TaxonName, TaxonNameEditorPresenter> implements TaxonNamePopupEditorView, AccessRestrictedView {
49

    
50
    private static final long serialVersionUID = -7037436241474466359L;
51

    
52
    private final static int GRID_COLS = 4;
53

    
54
    private final static int GRID_ROWS = 13;
55

    
56
    private static final boolean HAS_BASIONYM_DEFAULT = false;
57

    
58
    private TextField genusOrUninomialField;
59

    
60
    private TextField infraGenericEpithetField;
61

    
62
    private TextField specificEpithetField;
63

    
64
    private TextField infraSpecificEpithetField;
65

    
66
    private SwitchableTextField fullTitleCacheFiled;
67

    
68
    private SwitchableTextField protectedNameCacheField;
69

    
70
    private ToOneRelatedEntityCombobox<Reference> nomReferenceCombobox;
71

    
72
    private TextField nomenclaturalReferenceDetail;
73

    
74
    private TeamOrPersonField exBasionymAuthorshipField;
75

    
76
    private TeamOrPersonField basionymAuthorshipField;
77

    
78
    private ToManyRelatedEntitiesComboboxSelect<TaxonName> basionymsComboboxSelect;
79

    
80
    private CheckBox basionymToggle;
81

    
82
    private CheckBox validationToggle;
83

    
84
    private ListSelect rankSelect;
85

    
86
    private TeamOrPersonField combinationAuthorshipField;
87

    
88
    private TeamOrPersonField exCombinationAuthorshipField;
89

    
90
    private EnumSet<TaxonNamePopupEditorMode> modesActive = EnumSet.noneOf(TaxonNamePopupEditorMode.class);
91

    
92
    /**
93
     * @param layout
94
     * @param dtoType
95
     */
96
    public TaxonNamePopupEditor() {
97
        super(new GridLayout(GRID_COLS, GRID_ROWS), TaxonName.class);
98
    }
99

    
100
    /**
101
     * {@inheritDoc}
102
     */
103
    @Override
104
    public String getWindowCaption() {
105
        return "Name editor";
106
    }
107

    
108

    
109

    
110
    /**
111
     * {@inheritDoc}
112
     */
113
    @Override
114
    public int getWindowPixelWidth() {
115
        return 800;
116
    }
117

    
118
    /**
119
     * {@inheritDoc}
120
     */
121
    @Override
122
    public void focusFirst() {
123
        // titleField.focus();
124

    
125
    }
126

    
127
    /**
128
     * {@inheritDoc}
129
     */
130
    @Override
131
    protected String getDefaultComponentStyles() {
132
        return "tiny";
133
    }
134

    
135
    /**
136
     * {@inheritDoc}
137
     */
138
    @Override
139
    protected void initContent() {
140

    
141
        GridLayout grid = (GridLayout)getFieldLayout();
142
        grid.setSizeFull();
143
        grid.setSpacing(true);
144
        grid.setColumnExpandRatio(0, 0.3f);
145
        grid.setColumnExpandRatio(1, 0.3f);
146
        grid.setColumnExpandRatio(2, 0.3f);
147
        grid.setColumnExpandRatio(3, 0.0f);
148

    
149
        /*
150
         - nameType: preset, needs to be set in the presenter for new names
151
         - appendedPhrase: -> TODO field
152
         - nomenclaturalMicroReference:  -> TODO field
153
         - nomenclaturalReference ->  field but disabled for REGISTRY
154
         - rank -> SelectField which determines the visiblity of the other fields
155

    
156
         - fullTitleCache + protectedFullTitleCache -> SwitchableTextField : ADVANCED_MODE
157
         - nameCache + protectedNameCache -> SwitchableTextField : ADVANCED_MODE
158

    
159
         - homotypicalGroup -> hidden
160
         - typeDesignations -> hidden
161
         - descriptions -> hidden
162
         - taxonBases -> hidden
163
         - registrations -> hidden
164

    
165
         - relationsFromThisName-> TODO implement later
166
         - relationsToThisName -> TODO implement later
167

    
168
         - genusOrUninomial -> textField
169
         - infraGenericEpithet  -> textField
170
         - specificEpithet  -> textField
171
         - infraSpecificEpithet  -> textField
172

    
173
         - authorshipCache + protectedAuthorshipCache -> SwitchableTextField : only ADVANCED_MODE and disabled for REGISTRY
174
         - basionymAuthorship -> field but disabled for REGISTRY, basionym is set as nameRelationShip
175
         - combinationAuthorship -> field but disabled for REGISTRY author team of the reference
176
         - exCombinationAuthorship -> textField
177
         - exBasionymAuthorship -> textField
178

    
179
         - status -> TODO field
180
         - monomHybrid -> TODO implement hybrids later
181
         - binomHybrid -> TODO implement hybrids later
182
         - trinomHybrid -> TODO implement hybrids later
183

    
184
         - hybridParentRelations -> TODO implement hybrids later
185
         - hybridChildRelations -> TODO implement hybrids later
186
         - hybridFormula -> TODO implement hybrids later
187

    
188
         ** ViralName attributes **
189
         - acronym
190

    
191
         ** BacterialName attributes **
192
         - subGenusAuthorship
193
         - nameApprobation
194
         - breed
195
         - publicationYear
196
         - originalPublicationYear
197
         - cultivarName
198
        */
199

    
200
        int row = 0;
201

    
202
        rankSelect = new ListSelect("Rank");
203
        rankSelect.setNullSelectionAllowed(false);
204
        rankSelect.setRows(1);
205
        rankSelect.setWidth(100, Unit.PERCENTAGE);
206
        rankSelect.addValueChangeListener(e -> updateFieldVisibility());
207
        addField(rankSelect, "rank", 0, row, 1, row);
208
        grid.setComponentAlignment(rankSelect, Alignment.TOP_RIGHT);
209

    
210
        basionymToggle = new CheckBox("With basionym");
211
        basionymToggle.setValue(HAS_BASIONYM_DEFAULT);
212
        basionymToggle.addValueChangeListener(e -> {
213
                updateFieldVisibility();
214
            });
215
        basionymToggle.setStyleName(getDefaultComponentStyles());
216
        grid.addComponent(basionymToggle, 2, row, 3, row);
217
        grid.setComponentAlignment(basionymToggle, Alignment.BOTTOM_LEFT);
218

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

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

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

    
249
        row++;
250
        combinationAuthorshipField = new TeamOrPersonField("combination author(s)");
251
        combinationAuthorshipField.setWidth(100,  Unit.PERCENTAGE);
252
        addField(combinationAuthorshipField, "combinationAuthorship", 0, row, GRID_COLS-1, row);
253

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

    
276
        row++;
277
        exCombinationAuthorshipField = new TeamOrPersonField("Ex-combination author(s)");
278
        exCombinationAuthorshipField.setWidth(100,  Unit.PERCENTAGE);
279
        addField(exCombinationAuthorshipField, "exCombinationAuthorship", 0, row, GRID_COLS-1, row);
280

    
281
        // Basionym
282
        row++;
283
        basionymsComboboxSelect = new ToManyRelatedEntitiesComboboxSelect<TaxonName>(TaxonName.class, "Basionym");
284
        basionymsComboboxSelect.setConverter(new SetToListConverter<TaxonName>());
285
        addField(basionymsComboboxSelect, "basionyms", 0, row, 3, row);
286
        basionymsComboboxSelect.setWidth(100, Unit.PERCENTAGE);
287
        basionymsComboboxSelect.withEditButton(true);
288
        basionymsComboboxSelect.setEditPermissionTester(new EditPermissionTester() {
289

    
290
            @Override
291
            public boolean userHasEditPermission(Object bean) {
292
                return  UserHelper.fromSession().userHasPermission((CdmBase)bean, CRUD.UPDATE, CRUD.DELETE);
293
            }
294
        });
295
        basionymsComboboxSelect.setEditActionListener(e -> {
296

    
297
            Object fieldValue = e.getSource().getValue();
298
            Integer beanId = null;
299
            if(fieldValue != null){
300
                beanId = ((CdmBase)fieldValue).getId();
301

    
302
            }
303
            eventBus.publishEvent(new TaxonNameEditorAction(e.getAction(), beanId, e.getSource(), this));
304
        });
305
        grid.setComponentAlignment(basionymsComboboxSelect, Alignment.TOP_RIGHT);
306
        row++;
307
        basionymAuthorshipField = new TeamOrPersonField("Basionym author(s)");
308
        basionymAuthorshipField.setWidth(100,  Unit.PERCENTAGE);
309
        addField(basionymAuthorshipField, "basionymAuthorship", 0, row, GRID_COLS-1, row);
310
        row++;
311
        exBasionymAuthorshipField = new TeamOrPersonField("Ex-basionym author(s)");
312
        exBasionymAuthorshipField.setWidth(100,  Unit.PERCENTAGE);
313
        addField(exBasionymAuthorshipField, "exBasionymAuthorship", 0, row, GRID_COLS-1, row);
314

    
315

    
316

    
317
        setAdvancedModeEnabled(true);
318
        registerAdvancedModeComponents(fullTitleCacheFiled, protectedNameCacheField);
319
        registerAdvancedModeComponents(basionymAuthorshipField.getCachFields());
320
        registerAdvancedModeComponents(exBasionymAuthorshipField.getCachFields());
321
        registerAdvancedModeComponents(combinationAuthorshipField.getCachFields());
322
        registerAdvancedModeComponents(exCombinationAuthorshipField.getCachFields());
323
        setAdvancedMode(false);
324

    
325
    }
326

    
327
    /**
328
     * @param rank
329
     * @return
330
     */
331
    private void updateFieldVisibility() {
332

    
333
        // TODO use getField() instead and remove field references
334

    
335
        TaxonName taxonName = getBean();
336
        Rank rank = taxonName.getRank();
337

    
338
        boolean isSpeciesOrBelow = !rank.isHigher(Rank.SPECIES());
339
        Boolean withBasionym = BooleanUtils.isTrue(basionymToggle.getValue());
340
        Boolean withValidation = BooleanUtils.isTrue(validationToggle.getValue());
341

    
342
        basionymAuthorshipField.setVisible(withBasionym != null && withBasionym);
343
        exBasionymAuthorshipField.setVisible(withBasionym);
344
        basionymsComboboxSelect.setVisible(withBasionym);
345

    
346
        if(taxonName != null){
347
            if(modesActive.contains(TaxonNamePopupEditorMode.suppressReplacementAuthorshipData)){
348
                basionymAuthorshipField.setVisible(taxonName.getBasionymAuthorship() != null);
349
                exBasionymAuthorshipField.setVisible(taxonName.getExBasionymAuthorship() != null);
350
            }
351
        }
352

    
353
        infraSpecificEpithetField.setVisible(rank.isInfraSpecific());
354
        specificEpithetField.setVisible(isSpeciesOrBelow);
355
        infraGenericEpithetField.setVisible(rank.isInfraGenericButNotSpeciesGroup());
356
        genusOrUninomialField.setCaption(isSpeciesOrBelow ? "Genus" : "Uninomial");
357
        exCombinationAuthorshipField.setVisible(isSpeciesOrBelow && withValidation);
358
    }
359

    
360
    @Override
361
    protected void afterItemDataSourceSet() {
362
        TaxonName taxonName = getBean();
363
        boolean showBasionymSection = taxonName.getBasionyms().size() > 0
364
                || taxonName.getBasionymAuthorship() != null
365
                || taxonName.getExBasionymAuthorship() != null;
366
        basionymToggle.setValue(showBasionymSection);
367
        basionymToggle.setReadOnly(showBasionymSection);
368

    
369
        boolean showExAuthors = taxonName.getExCombinationAuthorship() != null;
370
        validationToggle.setValue(showExAuthors);
371
        validationToggle.setReadOnly(showExAuthors);
372
        exCombinationAuthorshipField.setVisible(showExAuthors);
373

    
374
        if(isModeEnabled(TaxonNamePopupEditorMode.suppressReplacementAuthorshipData)){
375
            combinationAuthorshipField.setVisible(taxonName.getCombinationAuthorship() != null);
376
        }
377
        if(isModeEnabled(TaxonNamePopupEditorMode.nomenclaturalReferenceSectionEditingOnly) && getBean().getNomenclaturalReference() != null) {
378
            nomReferenceCombobox.setCaption("Selection limited to nomenclatural reference and sections");
379
        }
380

    
381
    }
382

    
383
    /**
384
     * {@inheritDoc}
385
     */
386
    @Override
387
    public boolean allowAnonymousAccess() {
388
        return false;
389
    }
390

    
391
    /**
392
     * {@inheritDoc}
393
     */
394
    @Override
395
    public Collection<Collection<GrantedAuthority>> allowedGrantedAuthorities() {
396
        return null;
397
    }
398

    
399
    /**
400
     * {@inheritDoc}
401
     */
402
    @Override
403
    public ToOneRelatedEntityCombobox<Reference> getNomReferenceCombobox() {
404
        return nomReferenceCombobox;
405
    }
406

    
407
    /**
408
     * {@inheritDoc}
409
     */
410
    @Override
411
    public ToManyRelatedEntitiesComboboxSelect<TaxonName> getBasionymComboboxSelect() {
412
        return basionymsComboboxSelect;
413
    }
414

    
415
    /**
416
     * {@inheritDoc}
417
     */
418
    @Override
419
    public ListSelect getRankSelect() {
420
        return rankSelect;
421
    }
422

    
423
    /**
424
     * @return the exBasionymAuthorshipField
425
     */
426
    @Override
427
    public TeamOrPersonField getExBasionymAuthorshipField() {
428
        return exBasionymAuthorshipField;
429
    }
430

    
431
    /**
432
     * @return the basionymAuthorshipField
433
     */
434
    @Override
435
    public TeamOrPersonField getBasionymAuthorshipField() {
436
        return basionymAuthorshipField;
437
    }
438

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

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

    
455
    @Override
456
    public void enableMode(TaxonNamePopupEditorMode mode){
457
            modesActive.add(mode);
458
    }
459

    
460
    @Override
461
    public boolean isModeEnabled(TaxonNamePopupEditorMode mode){
462
        return modesActive.contains(mode);
463
    }
464

    
465
    @Override
466
    public void disableMode(TaxonNamePopupEditorMode mode){
467
        modesActive.remove(mode);
468
    }
469

    
470
    @Override
471
    public EnumSet<TaxonNamePopupEditorMode> getModesActive(){
472
        return modesActive;
473
    }
474

    
475
    @Override
476
    public CheckBox getBasionymToggle() {
477
        return basionymToggle;
478
    }
479

    
480
    /**
481
     * {@inheritDoc}
482
     */
483
    @Override
484
    public void setReadOnly(boolean readOnly) {
485
        boolean basionymToggleReadonly = basionymToggle.isReadOnly();
486
        boolean validationToggleReadonly = validationToggle.isReadOnly();
487
        super.setReadOnly(readOnly);
488
        // preserve old readonly states if they were true
489
        if(basionymToggleReadonly){
490
            basionymToggle.setReadOnly(true);
491
        }
492
        if(validationToggleReadonly){
493
            validationToggle.setReadOnly(true);
494
        }
495
    }
496

    
497

    
498

    
499

    
500
}
(7-7/10)