2 * Copyright (C) 2017 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
9 package eu
.etaxonomy
.cdm
.vaadin
.view
.name
;
11 import java
.util
.Collection
;
12 import java
.util
.EnumSet
;
13 import java
.util
.HashMap
;
14 import java
.util
.List
;
16 import java
.util
.UUID
;
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 import org
.vaadin
.viritin
.fields
.LazyComboBox
;
24 import com
.vaadin
.data
.Property
;
25 import com
.vaadin
.data
.Property
.ValueChangeListener
;
26 import com
.vaadin
.shared
.ui
.label
.ContentMode
;
27 import com
.vaadin
.spring
.annotation
.SpringComponent
;
28 import com
.vaadin
.ui
.AbstractField
;
29 import com
.vaadin
.ui
.Alignment
;
30 import com
.vaadin
.ui
.CheckBox
;
31 import com
.vaadin
.ui
.GridLayout
;
32 import com
.vaadin
.ui
.Label
;
33 import com
.vaadin
.ui
.ListSelect
;
34 import com
.vaadin
.ui
.TextField
;
36 import eu
.etaxonomy
.cdm
.model
.agent
.TeamOrPersonBase
;
37 import eu
.etaxonomy
.cdm
.model
.common
.AnnotationType
;
38 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
39 import eu
.etaxonomy
.cdm
.model
.common
.RelationshipBase
.Direction
;
40 import eu
.etaxonomy
.cdm
.model
.name
.NameRelationshipType
;
41 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
42 import eu
.etaxonomy
.cdm
.model
.name
.TaxonName
;
43 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
44 import eu
.etaxonomy
.cdm
.vaadin
.component
.TextFieldNFix
;
45 import eu
.etaxonomy
.cdm
.vaadin
.component
.common
.FilterableAnnotationsField
;
46 import eu
.etaxonomy
.cdm
.vaadin
.component
.common
.TeamOrPersonField
;
47 import eu
.etaxonomy
.cdm
.vaadin
.event
.ReferenceEditorAction
;
48 import eu
.etaxonomy
.cdm
.vaadin
.event
.TaxonNameEditorAction
;
49 import eu
.etaxonomy
.cdm
.vaadin
.model
.name
.NameRelationshipDTO
;
50 import eu
.etaxonomy
.cdm
.vaadin
.model
.name
.TaxonNameDTO
;
51 import eu
.etaxonomy
.cdm
.vaadin
.permission
.AccessRestrictedView
;
52 import eu
.etaxonomy
.cdm
.vaadin
.permission
.CdmEditDeletePermissionTester
;
53 import eu
.etaxonomy
.cdm
.vaadin
.util
.TeamOrPersonBaseCaptionGenerator
;
54 import eu
.etaxonomy
.cdm
.vaadin
.util
.converter
.SetToListConverter
;
55 import eu
.etaxonomy
.vaadin
.component
.NameRelationField
;
56 import eu
.etaxonomy
.vaadin
.component
.ReloadableLazyComboBox
;
57 import eu
.etaxonomy
.vaadin
.component
.SwitchableTextField
;
58 import eu
.etaxonomy
.vaadin
.component
.ToManyRelatedEntitiesComboboxSelect
;
59 import eu
.etaxonomy
.vaadin
.component
.ToOneRelatedEntityCombobox
;
60 import eu
.etaxonomy
.vaadin
.event
.EditorActionType
;
61 import eu
.etaxonomy
.vaadin
.mvp
.AbstractCdmDTOPopupEditor
;
64 * @author a.kohlbecker
70 public class TaxonNamePopupEditor
extends AbstractCdmDTOPopupEditor
<TaxonNameDTO
, TaxonName
, TaxonNameEditorPresenter
>
71 implements TaxonNamePopupEditorView
, AccessRestrictedView
{
73 private static final long serialVersionUID
= -7037436241474466359L;
75 private final static int GRID_COLS
= 4;
77 private final static int GRID_ROWS
= 17;
79 private static final boolean HAS_BASIONYM_DEFAULT
= false;
81 private AbstractField
<String
> genusOrUninomialField
;
83 private AbstractField
<String
> infraGenericEpithetField
;
85 private AbstractField
<String
> specificEpithetField
;
87 private AbstractField
<String
> infraSpecificEpithetField
;
89 private SwitchableTextField fullTitleCacheFiled
;
91 private SwitchableTextField protectedNameCacheField
;
93 private ToOneRelatedEntityCombobox
<Reference
> nomReferenceCombobox
;
95 private TextField nomenclaturalReferenceDetail
;
97 private TeamOrPersonField exBasionymAuthorshipField
;
99 private TeamOrPersonField basionymAuthorshipField
;
101 private ToManyRelatedEntitiesComboboxSelect
<TaxonName
> basionymsComboboxSelect
;
103 private ToManyRelatedEntitiesComboboxSelect
<TaxonName
> replacedSynonymsComboboxSelect
;
105 private NameRelationField validationField
;
107 private CheckBox basionymToggle
;
109 private CheckBox replacedSynonymsToggle
;
111 private CheckBox validationToggle
;
113 private ListSelect rankSelect
;
115 private TeamOrPersonField combinationAuthorshipField
;
117 private TeamOrPersonField exCombinationAuthorshipField
;
119 private EnumSet
<TaxonNamePopupEditorMode
> modesActive
= EnumSet
.noneOf(TaxonNamePopupEditorMode
.class);
121 private Boolean isInferredCombinationAuthorship
= null;
123 private Boolean isInferredBasionymAuthorship
= null;
125 private Boolean isInferredExBasionymAuthorship
= null;
127 private Map
<AbstractField
, Property
.ValueChangeListener
> authorshipUpdateListeners
= new HashMap
<>();
129 private Boolean isInferredExCombinationAuthorship
;
131 private int specificEpithetFieldRow
;
133 private ValueChangeListener updateFieldVisibilityListener
= e
-> updateFieldVisibility();
135 private FilterableAnnotationsField annotationsListField
;
137 private AnnotationType
[] editableAnotationTypes
= new AnnotationType
[]{AnnotationType
.EDITORIAL()};
141 * By default AnnotationType.EDITORIAL() is enabled.
143 * @return the editableAnotationTypes
145 public AnnotationType
[] getEditableAnotationTypes() {
146 return editableAnotationTypes
;
150 * By default AnnotationType.EDITORIAL() is enabled.
153 * @param editableAnotationTypes the editableAnotationTypes to set
155 public void setEditableAnotationTypes(AnnotationType
... editableAnotationTypes
) {
156 this.editableAnotationTypes
= editableAnotationTypes
;
163 public TaxonNamePopupEditor() {
164 super(new GridLayout(GRID_COLS
, GRID_ROWS
), TaxonNameDTO
.class);
171 public String
getWindowCaption() {
172 return "Name editor";
180 public int getWindowWidth() {
188 public void focusFirst() {
189 // titleField.focus();
197 protected String
getDefaultComponentStyles() {
205 protected void initContent() {
207 GridLayout grid
= (GridLayout
)getFieldLayout();
209 grid
.setHideEmptyRowsAndColumns(true);
210 grid
.setSpacing(true);
211 grid
.setColumnExpandRatio(0, 0.3f
);
212 grid
.setColumnExpandRatio(1, 0.3f
);
213 grid
.setColumnExpandRatio(2, 0.3f
);
214 grid
.setColumnExpandRatio(3, 0.0f
);
217 - nameType: preset, needs to be set in the presenter for new names
218 - appendedPhrase: -> TODO field
219 - nomenclaturalMicroReference: -> TODO field
220 - nomenclaturalReference -> field but disabled for REGISTRY
221 - rank -> SelectField which determines the visiblity of the other fields
223 - fullTitleCache + protectedFullTitleCache -> SwitchableTextField : ADVANCED_MODE
224 - nameCache + protectedNameCache -> SwitchableTextField : ADVANCED_MODE
226 - homotypicalGroup -> hidden
227 - typeDesignations -> hidden
228 - descriptions -> hidden
229 - taxonBases -> hidden
230 - registrations -> hidden
232 - relationsFromThisName-> TODO implement later
233 - relationsToThisName -> TODO implement later
235 - genusOrUninomial -> textField
236 - infraGenericEpithet -> textField
237 - specificEpithet -> textField
238 - infraSpecificEpithet -> textField
240 - authorshipCache + protectedAuthorshipCache -> SwitchableTextField : only ADVANCED_MODE and disabled for REGISTRY
241 - basionymAuthorship -> field but disabled for REGISTRY, basionym is set as nameRelationShip
242 - combinationAuthorship -> field but disabled for REGISTRY author team of the reference
243 - exCombinationAuthorship -> textField
244 - exBasionymAuthorship -> textField
246 - status -> TODO field
247 - monomHybrid -> TODO implement hybrids later
248 - binomHybrid -> TODO implement hybrids later
249 - trinomHybrid -> TODO implement hybrids later
251 - hybridParentRelations -> TODO implement hybrids later
252 - hybridChildRelations -> TODO implement hybrids later
253 - hybridFormula -> TODO implement hybrids later
255 ** ViralName attributes **
258 ** BacterialName attributes **
263 - originalPublicationYear
269 rankSelect
= new ListSelect("Rank");
270 rankSelect
.setNullSelectionAllowed(false);
271 rankSelect
.setRows(1);
272 rankSelect
.setWidth(100, Unit
.PERCENTAGE
);
273 addField(rankSelect
, "rank", 0, row
, 1, row
);
274 grid
.setComponentAlignment(rankSelect
, Alignment
.TOP_RIGHT
);
276 basionymToggle
= new CheckBox("With basionym");
277 basionymToggle
.setValue(HAS_BASIONYM_DEFAULT
);
279 basionymToggle
.setStyleName(getDefaultComponentStyles());
280 grid
.addComponent(basionymToggle
, 2, row
, 3, row
);
281 grid
.setComponentAlignment(basionymToggle
, Alignment
.BOTTOM_LEFT
);
284 replacedSynonymsToggle
= new CheckBox("With replaced synonym");
285 grid
.addComponent(replacedSynonymsToggle
, 2, row
, 3, row
);
286 grid
.setComponentAlignment(replacedSynonymsToggle
, Alignment
.BOTTOM_LEFT
);
289 validationToggle
= new CheckBox("Validation");
291 grid
.addComponent(validationToggle
, 2, row
, 3, row
);
292 grid
.setComponentAlignment(validationToggle
, Alignment
.BOTTOM_LEFT
);
296 fullTitleCacheFiled
= addSwitchableTextField("Full title cache", "fullTitleCache", "protectedFullTitleCache", 0, row
, GRID_COLS
-1, row
);
297 fullTitleCacheFiled
.setWidth(100, Unit
.PERCENTAGE
);
299 protectedNameCacheField
= addSwitchableTextField("Name cache", "nameCache", "protectedNameCache", 0, row
, GRID_COLS
-1, row
);
300 protectedNameCacheField
.setWidth(100, Unit
.PERCENTAGE
);
302 if(isModeEnabled(TaxonNamePopupEditorMode
.VALIDATE_AGAINST_HIGHER_NAME_PART
)){
303 genusOrUninomialField
= addTextField("Genus or uninomial", "genusOrUninomial", 0, row
, 1, row
);
305 genusOrUninomialField
= new LazyComboBox
<String
>(String
.class);
306 addField(genusOrUninomialField
, "genusOrUninomial", 0, row
, 1, row
);
308 genusOrUninomialField
.setWidth(200, Unit
.PIXELS
);
309 infraGenericEpithetField
= addTextField("Infrageneric epithet", "infraGenericEpithet", 2, row
, 3, row
);
310 infraGenericEpithetField
.setWidth(200, Unit
.PIXELS
);
312 specificEpithetFieldRow
= row
;
313 specificEpithetField
= addTextField("Specific epithet", "specificEpithet", 0, row
, 1, row
);
314 specificEpithetField
.setWidth(200, Unit
.PIXELS
);
315 infraSpecificEpithetField
= addTextField("Infraspecific epithet", "infraSpecificEpithet", 2, row
, 3, row
);
316 infraSpecificEpithetField
.setWidth(200, Unit
.PIXELS
);
319 grid
.addComponent(new Label("Hint: <i>Edit nomenclatural authors in the nomenclatural reference.</i>", ContentMode
.HTML
), 0, row
, 3, row
);
322 combinationAuthorshipField
= new TeamOrPersonField("Combination author(s)", TeamOrPersonBaseCaptionGenerator
.CacheType
.NOMENCLATURAL_TITLE
);
323 combinationAuthorshipField
.setWidth(100, Unit
.PERCENTAGE
);
324 addField(combinationAuthorshipField
, "combinationAuthorship", 0, row
, GRID_COLS
-1, row
);
327 nomReferenceCombobox
= new ToOneRelatedEntityCombobox
<Reference
>("Nomenclatural reference", Reference
.class);
328 nomReferenceCombobox
.addClickListenerAddEntity(e
-> getViewEventBus().publish(
330 new ReferenceEditorAction(EditorActionType
.ADD
, null, nomReferenceCombobox
, this)
332 nomReferenceCombobox
.addClickListenerEditEntity(e
-> {
333 if(nomReferenceCombobox
.getValue() != null){
334 getViewEventBus().publish(this,
335 new ReferenceEditorAction(
336 EditorActionType
.EDIT
,
337 nomReferenceCombobox
.getValue().getUuid(),
339 nomReferenceCombobox
,
344 logger
.setLevel(Level
.DEBUG
);
345 // nomReferenceCombobox.getSelect().addValueChangeListener(e -> logger.debug("nomReferenceCombobox value changed #1"));
346 // nomReferenceCombobox.setWidth(300, Unit.PIXELS);
347 nomReferenceCombobox
.setWidth("100%");
348 addField(nomReferenceCombobox
, "nomenclaturalReference", 0, row
, 2, row
);
349 nomenclaturalReferenceDetail
= addTextField("Reference detail", "nomenclaturalMicroReference", 3, row
, 3, row
);
350 nomenclaturalReferenceDetail
.setWidth(100, Unit
.PIXELS
);
352 // --------------- Basionyms
354 basionymsComboboxSelect
= new ToManyRelatedEntitiesComboboxSelect
<TaxonName
>(TaxonName
.class, "Basionym");
355 basionymsComboboxSelect
.setConverter(new SetToListConverter
<TaxonName
>());
356 addField(basionymsComboboxSelect
, "basionyms", 0, row
, 3, row
);
357 basionymsComboboxSelect
.setWidth(100, Unit
.PERCENTAGE
);
358 basionymsComboboxSelect
.withEditButton(true);
359 basionymsComboboxSelect
.setEditPermissionTester(new CdmEditDeletePermissionTester());
360 basionymsComboboxSelect
.setEditActionListener(e
-> {
362 Object fieldValue
= e
.getSource().getValue();
363 UUID beanUuid
= null;
364 if(fieldValue
!= null){
365 beanUuid
= ((CdmBase
)fieldValue
).getUuid();
368 ReloadableLazyComboBox
<TaxonName
> lazyCombobox
= (ReloadableLazyComboBox
<TaxonName
>) e
.getSource();
369 getViewEventBus().publish(this, new TaxonNameEditorAction(e
.getAction(), beanUuid
, null, lazyCombobox
, this));
371 grid
.setComponentAlignment(basionymsComboboxSelect
, Alignment
.TOP_RIGHT
);
374 basionymAuthorshipField
= new TeamOrPersonField("Basionym author(s)", TeamOrPersonBaseCaptionGenerator
.CacheType
.NOMENCLATURAL_TITLE
);
375 basionymAuthorshipField
.setWidth(100, Unit
.PERCENTAGE
);
376 addField(basionymAuthorshipField
, "basionymAuthorship", 0, row
, GRID_COLS
-1, row
);
378 exBasionymAuthorshipField
= new TeamOrPersonField("Ex-basionym author(s)", TeamOrPersonBaseCaptionGenerator
.CacheType
.NOMENCLATURAL_TITLE
);
379 exBasionymAuthorshipField
.setWidth(100, Unit
.PERCENTAGE
);
380 addField(exBasionymAuthorshipField
, "exBasionymAuthorship", 0, row
, GRID_COLS
-1, row
);
382 // --------------- ReplacedSynonyms
384 replacedSynonymsComboboxSelect
= new ToManyRelatedEntitiesComboboxSelect
<TaxonName
>(TaxonName
.class, "Replaced synonyms");
385 replacedSynonymsComboboxSelect
.setConverter(new SetToListConverter
<TaxonName
>());
386 addField(replacedSynonymsComboboxSelect
, "replacedSynonyms", 0, row
, 3, row
);
387 replacedSynonymsComboboxSelect
.setWidth(100, Unit
.PERCENTAGE
);
388 replacedSynonymsComboboxSelect
.withEditButton(true);
389 replacedSynonymsComboboxSelect
.setEditPermissionTester(new CdmEditDeletePermissionTester());
390 replacedSynonymsComboboxSelect
.setEditActionListener(e
-> {
392 Object fieldValue
= e
.getSource().getValue();
393 UUID beanUuid
= null;
394 if(fieldValue
!= null){
395 beanUuid
= ((CdmBase
)fieldValue
).getUuid();
398 ReloadableLazyComboBox
<TaxonName
> lazyCombobox
= (ReloadableLazyComboBox
<TaxonName
>) e
.getSource();
399 getViewEventBus().publish(this, new TaxonNameEditorAction(e
.getAction(), beanUuid
, null, lazyCombobox
, this));
401 grid
.setComponentAlignment(replacedSynonymsComboboxSelect
, Alignment
.TOP_RIGHT
);
403 // --------------- Validation
405 validationField
= new NameRelationField("Validation", Direction
.relatedTo
, NameRelationshipType
.VALIDATED_BY_NAME());
406 validationField
.setWidth(100, Unit
.PERCENTAGE
);
407 ToOneRelatedEntityCombobox
<TaxonName
> validatedNameComboBox
= validationField
.getValidatedNameComboBox();
408 validatedNameComboBox
.addClickListenerAddEntity(e
-> getViewEventBus().publish(
410 new TaxonNameEditorAction(EditorActionType
.ADD
, null, validatedNameComboBox
, this)
412 validatedNameComboBox
.addClickListenerEditEntity(e
-> {
413 if(validatedNameComboBox
.getValue() != null){
414 getViewEventBus().publish(this,
415 new TaxonNameEditorAction(
416 EditorActionType
.EDIT
,
417 validatedNameComboBox
.getValue().getUuid(),
419 validatedNameComboBox
,
424 ToOneRelatedEntityCombobox
<Reference
> validationCitatonComboBox
= validationField
.getCitatonComboBox();
425 validationCitatonComboBox
.addClickListenerAddEntity(e
-> getViewEventBus().publish(
427 new ReferenceEditorAction(EditorActionType
.ADD
, null, validationCitatonComboBox
, this)
429 validationCitatonComboBox
.addClickListenerEditEntity(e
-> {
430 if(validationCitatonComboBox
.getValue() != null){
431 getViewEventBus().publish(this,
432 new ReferenceEditorAction(
433 EditorActionType
.EDIT
,
434 validationCitatonComboBox
.getValue().getUuid(),
436 validationCitatonComboBox
,
441 addField(validationField
, "validationFor", 0, row
, 3, row
);
442 grid
.setComponentAlignment(validationField
, Alignment
.TOP_RIGHT
);
445 exCombinationAuthorshipField
= new TeamOrPersonField("Ex-combination author(s)", TeamOrPersonBaseCaptionGenerator
.CacheType
.NOMENCLATURAL_TITLE
);
446 exCombinationAuthorshipField
.setWidth(100, Unit
.PERCENTAGE
);
447 addField(exCombinationAuthorshipField
, "exCombinationAuthorship", 0, row
, GRID_COLS
-1, row
);
450 annotationsListField
= new FilterableAnnotationsField("Editorial notes");
451 annotationsListField
.setWidth(100, Unit
.PERCENTAGE
);
452 annotationsListField
.setAnnotationTypesVisible(editableAnotationTypes
);
453 addField(annotationsListField
, "annotations", 0, row
, GRID_COLS
-1, row
);
455 // -----------------------------------------------------------------------------
457 setAdvancedModeEnabled(true);
458 registerAdvancedModeComponents(fullTitleCacheFiled
, protectedNameCacheField
);
460 registerAdvancedModeComponents(combinationAuthorshipField
);
461 registerAdvancedModeComponents(basionymAuthorshipField
);
462 registerAdvancedModeComponents(exBasionymAuthorshipField
);
463 registerAdvancedModeComponents(exCombinationAuthorshipField
);
465 registerAdvancedModeComponents(combinationAuthorshipField
.getCachFields());
466 registerAdvancedModeComponents(exCombinationAuthorshipField
.getCachFields());
467 registerAdvancedModeComponents(basionymAuthorshipField
.getCachFields());
468 registerAdvancedModeComponents(exBasionymAuthorshipField
.getCachFields());
470 setAdvancedMode(false);
474 protected TeamOrPersonBase
inferBasiomynAuthors() {
475 List
<TaxonName
> basionyms
= basionymsComboboxSelect
.getValue();
476 if(!basionyms
.isEmpty()){
477 TaxonName basionym
= basionyms
.get(0);
478 if(basionym
.getCombinationAuthorship() != null){
479 return basionym
.getCombinationAuthorship();
480 } else if(basionym
.getNomenclaturalReference() != null){
481 return basionym
.getNomenclaturalReference().getAuthorship();
487 protected TeamOrPersonBase
inferExBasiomynAuthors() {
488 List
<TaxonName
> basionyms
= basionymsComboboxSelect
.getValue();
489 if(!basionyms
.isEmpty()){
490 TaxonName basionym
= basionyms
.get(0);
491 return basionym
.getExCombinationAuthorship();
496 protected TeamOrPersonBase
inferCombinationAuthors() {
497 Reference nomRef
= nomReferenceCombobox
.getValue();
499 return nomRef
.getAuthorship();
504 protected TeamOrPersonBase
inferExCombinationAuthors() {
505 NameRelationshipDTO nameRelationDTO
= validationField
.getValue();
506 if(nameRelationDTO
!= null && nameRelationDTO
.getOtherName() != null){
507 TaxonName validatedName
= nameRelationDTO
.getOtherName();
508 if(validatedName
.getCombinationAuthorship() != null) {
509 return validatedName
.getCombinationAuthorship();
510 } else if(validatedName
.getNomenclaturalReference() != null){
511 return validatedName
.getNomenclaturalReference().getAuthorship();
518 protected void afterItemDataSourceSet() {
521 rankSelect
.addValueChangeListener(updateFieldVisibilityListener
);
522 basionymToggle
.addValueChangeListener(e
-> {
523 updateAuthorshipFields();
525 validationToggle
.addValueChangeListener(e
-> {
526 updateAuthorshipFields();
528 replacedSynonymsToggle
.addValueChangeListener(e
-> {
529 boolean enable
= e
.getProperty().getValue() != null && (Boolean
)e
.getProperty().getValue();
530 replacedSynonymsComboboxSelect
.setVisible(enable
);
534 TaxonNameDTO taxonNameDTO
= getBean();
535 boolean showBasionymSection
= taxonNameDTO
.getBasionyms().size() > 0
536 || taxonNameDTO
.getBasionymAuthorship() != null
537 || taxonNameDTO
.getExBasionymAuthorship() != null;
538 basionymToggle
.setValue(showBasionymSection
);
539 basionymToggle
.setReadOnly(showBasionymSection
);
541 boolean showReplacedSynonyms
= taxonNameDTO
.getReplacedSynonyms().size() > 0;
542 replacedSynonymsToggle
.setValue(showReplacedSynonyms
);
543 replacedSynonymsToggle
.setReadOnly(showReplacedSynonyms
);
544 replacedSynonymsComboboxSelect
.setVisible(showReplacedSynonyms
);
546 boolean showValidationSection
= taxonNameDTO
.getValidationFor() != null || taxonNameDTO
.getExCombinationAuthorship() != null;
548 validationToggle
.setValue(showValidationSection
);
549 validationToggle
.setReadOnly(showValidationSection
);
550 // validationField.setVisible(showValidation);
551 // exCombinationAuthorshipField.setVisible(showExAuthors);
553 if(isModeEnabled(TaxonNamePopupEditorMode
.AUTOFILL_AUTHORSHIP_DATA
)){
554 updateAuthorshipFields();
556 if(isModeEnabled(TaxonNamePopupEditorMode
.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY
) && getBean().getNomenclaturalReference() != null) {
557 nomReferenceCombobox
.setCaption("Selection limited to nomenclatural reference and sections");
559 if(isModeEnabled(TaxonNamePopupEditorMode
.REQUIRE_NOMENCLATURALREFERENCE
)) {
560 if(combinationAuthorshipField
.getValue() == null){
561 nomReferenceCombobox
.setRequired(true);
563 combinationAuthorshipField
.addValueChangeListener(e
-> {
564 if(e
.getProperty().getValue() == null){
565 nomReferenceCombobox
.setRequired(true);
574 * Updates all authorship fields if the an authorship field is empty this method attempts to infer the
575 * authors from the related nomenclatural reference or taxon name.
577 * Finally the {@link #updateFieldVisibility()} is invoked.
582 public void updateAuthorshipFields() {
584 TaxonNameDTO taxonName
= getBean();
586 // ------------- CombinationAuthors
587 isInferredCombinationAuthorship
= updateAuthorshipFieldData(
588 taxonName
.getCombinationAuthorship(),
589 inferCombinationAuthors(),
590 combinationAuthorshipField
,
591 nomReferenceCombobox
.getSelect(),
592 isInferredCombinationAuthorship
);
595 // ------------- Basionym and ExBasionymAuthors
596 if(BooleanUtils
.isTrue(basionymToggle
.getValue())){
598 isInferredBasionymAuthorship
= updateAuthorshipFieldData(
599 taxonName
.getBasionymAuthorship(),
600 inferBasiomynAuthors(),
601 basionymAuthorshipField
,
602 basionymsComboboxSelect
,
603 isInferredBasionymAuthorship
606 isInferredExBasionymAuthorship
= updateAuthorshipFieldData(
607 taxonName
.getExBasionymAuthorship(),
608 inferExBasiomynAuthors(),
609 exBasionymAuthorshipField
,
610 basionymsComboboxSelect
,
611 isInferredExBasionymAuthorship
616 // ------------- Validation and ExCombinationAuthors
617 isInferredExCombinationAuthorship
= updateAuthorshipFieldData(
618 taxonName
.getExCombinationAuthorship(),
619 inferExCombinationAuthors(),
620 exCombinationAuthorshipField
,
621 validationField
.getValidatedNameComboBox(),
622 isInferredExCombinationAuthorship
625 updateFieldVisibility();
632 // protected void updateAuthorshipFieldsVisibility() {
633 // combinationAuthorshipField.setVisible(!isInferredCombinationAuthorship);
634 // if(BooleanUtils.isTrue(basionymToggle.getValue())){
635 // basionymAuthorshipField.setVisible(!isInferredBasionymAuthorship);
636 // exBasionymAuthorshipField.setVisible(!isInferredExBasionymAuthorship);
643 * the value of the taxonName authorship field
644 * @param inferredAuthors
645 * the value inferred from other fields which may be set as authorship to the taxon name
646 * @param authorshipField
647 * the ui element to edit the taxonName authorship field
648 * @param updateTriggerField
649 * @param lastInferredAuthorshipState
652 protected Boolean
updateAuthorshipFieldData(TeamOrPersonBase
<?
> authorship
, TeamOrPersonBase inferredAuthors
,
653 TeamOrPersonField authorshipField
, AbstractField updateTriggerField
,
654 Boolean lastInferredAuthorshipState
) {
656 if(authorship
== null){
657 authorshipField
.setValue(inferredAuthors
);
658 lastInferredAuthorshipState
= true;
660 boolean authorshipMatch
= authorship
== inferredAuthors
;
661 if(lastInferredAuthorshipState
== null){
662 // initialization of authorshipState, this comes only into account when the editor is just being initialized
663 lastInferredAuthorshipState
= authorshipMatch
;
665 if(!authorshipMatch
&& lastInferredAuthorshipState
){
666 // update the combinationAuthorshipField to follow changes of the nomenclatural reference in case it was autofilled before
667 authorshipField
.setValue(inferredAuthors
);
668 lastInferredAuthorshipState
= true;
672 if(updateTriggerField
!= null){
674 // this ChangeListener must be added at this very late point in the editor lifecycle so that it is called after
675 // the ToOneRelatedEntityReloader which may have been added to the updateTriggerField in the presenters handleViewEntered() method.
676 // Otherwise we risk multiple representation problems in the hibernate session
677 if(!authorshipUpdateListeners
.containsKey(updateTriggerField
)){
678 ValueChangeListener listener
= e
-> {
679 logger
.debug(" value changed #2");
680 updateAuthorshipFields();
682 updateTriggerField
.addValueChangeListener(listener
);
683 authorshipUpdateListeners
.put(updateTriggerField
, listener
);
687 return lastInferredAuthorshipState
;
694 private void updateFieldVisibility() {
696 // TODO use getField() instead and remove field references
697 Rank rank
= (Rank
) rankSelect
.getValue();
699 boolean isSpeciesOrBelow
= !rank
.isHigher(Rank
.SPECIES());
700 Boolean withBasionymSection
= BooleanUtils
.isTrue(basionymToggle
.getValue());
701 Boolean withValidationSection
= isSpeciesOrBelow
&& BooleanUtils
.isTrue(validationToggle
.getValue());
703 if(isModeEnabled(TaxonNamePopupEditorMode
.VALIDATE_AGAINST_HIGHER_NAME_PART
)){
704 if(rank
.isInfraSpecific()) {
705 if(TextField
.class.isAssignableFrom(specificEpithetField
.getClass())) {
706 specificEpithetField
= replaceComponent("specificEpithet", specificEpithetField
, new LazyComboBox
<String
>(String
.class), 0, specificEpithetFieldRow
, 1, specificEpithetFieldRow
);
709 if(LazyComboBox
.class.isAssignableFrom(specificEpithetField
.getClass())) {
710 specificEpithetField
= replaceComponent("specificEpithet", specificEpithetField
, new TextFieldNFix(), 0, specificEpithetFieldRow
, 1, specificEpithetFieldRow
);
715 specificEpithetField
.setVisible(isSpeciesOrBelow
);
716 infraSpecificEpithetField
.setVisible(rank
.isInfraSpecific());
717 infraGenericEpithetField
.setVisible(rank
.isInfraGeneric());
719 basionymsComboboxSelect
.setVisible(withBasionymSection
);
721 combinationAuthorshipField
.setVisible(isInferredCombinationAuthorship
!= null && !isInferredCombinationAuthorship
);
722 basionymAuthorshipField
.setVisible(withBasionymSection
&& isInferredBasionymAuthorship
!= null && !isInferredBasionymAuthorship
);
723 exBasionymAuthorshipField
.setVisible(withBasionymSection
&& isInferredExBasionymAuthorship
!= null && !isInferredExBasionymAuthorship
);
725 validationField
.setVisible(withValidationSection
);
726 exCombinationAuthorshipField
.setVisible(withValidationSection
&& isInferredExCombinationAuthorship
!= null && !isInferredExCombinationAuthorship
);
729 // if(taxonName != null){
730 // if(modesActive.contains(TaxonNamePopupEditorMode.AUTOFILL_AUTHORSHIP_DATA)){
734 infraSpecificEpithetField
.setVisible(rank
.isInfraSpecific());
735 specificEpithetField
.setVisible(isSpeciesOrBelow
);
736 infraGenericEpithetField
.setVisible(rank
.isInfraGenericButNotSpeciesGroup());
737 genusOrUninomialField
.setCaption(isSpeciesOrBelow ?
"Genus" : "Uninomial");
742 public void cancel() {
743 authorshipUpdateListeners
.keySet().forEach(field
-> field
.removeValueChangeListener(authorshipUpdateListeners
.get(field
)));
744 rankSelect
.removeValueChangeListener(updateFieldVisibilityListener
);
752 public boolean allowAnonymousAccess() {
760 public Collection
<Collection
<GrantedAuthority
>> allowedGrantedAuthorities() {
768 public ToOneRelatedEntityCombobox
<Reference
> getNomReferenceCombobox() {
769 return nomReferenceCombobox
;
776 public ToManyRelatedEntitiesComboboxSelect
<TaxonName
> getBasionymComboboxSelect() {
777 return basionymsComboboxSelect
;
784 public ToManyRelatedEntitiesComboboxSelect
<TaxonName
> getReplacedSynonymsComboboxSelect() {
785 return replacedSynonymsComboboxSelect
;
792 public ListSelect
getRankSelect() {
800 public AbstractField
<String
> getGenusOrUninomialField(){
801 return genusOrUninomialField
;
805 * @return the exBasionymAuthorshipField
808 public TeamOrPersonField
getExBasionymAuthorshipField() {
809 return exBasionymAuthorshipField
;
813 * @return the basionymAuthorshipField
816 public TeamOrPersonField
getBasionymAuthorshipField() {
817 return basionymAuthorshipField
;
821 * @return the combinationAuthorshipField
824 public TeamOrPersonField
getCombinationAuthorshipField() {
825 return combinationAuthorshipField
;
829 * @return the exCombinationAuthorshipField
832 public TeamOrPersonField
getExCombinationAuthorshipField() {
833 return exCombinationAuthorshipField
;
837 public NameRelationField
getValidationField(){
838 return validationField
;
842 public void enableMode(TaxonNamePopupEditorMode mode
){
843 modesActive
.add(mode
);
847 public boolean isModeEnabled(TaxonNamePopupEditorMode mode
){
848 return modesActive
.contains(mode
);
852 public void disableMode(TaxonNamePopupEditorMode mode
){
853 modesActive
.remove(mode
);
857 public EnumSet
<TaxonNamePopupEditorMode
> getModesActive(){
862 public CheckBox
getBasionymToggle() {
863 return basionymToggle
;
867 public FilterableAnnotationsField
getAnnotationsField() {
868 return annotationsListField
;
875 public void setReadOnly(boolean readOnly
) {
876 boolean basionymToggleReadonly
= basionymToggle
.isReadOnly();
877 boolean validationToggleReadonly
= validationToggle
.isReadOnly();
878 super.setReadOnly(readOnly
);
879 combinationAuthorshipField
.setEditorReadOnly(readOnly
);
880 exCombinationAuthorshipField
.setEditorReadOnly(readOnly
);
881 basionymAuthorshipField
.setEditorReadOnly(readOnly
);
882 exBasionymAuthorshipField
.setEditorReadOnly(readOnly
);
883 // preserve old readonly states if they were true
884 if(basionymToggleReadonly
){
885 basionymToggle
.setReadOnly(true);
887 if(validationToggleReadonly
){
888 validationToggle
.setReadOnly(true);
895 * @return the infraGenericEpithetField
898 public AbstractField
<String
> getInfraGenericEpithetField() {
899 return infraGenericEpithetField
;
903 * @return the specificEpithetField
906 public AbstractField
<String
> getSpecificEpithetField() {
907 return specificEpithetField
;
911 * @return the infraSpecificEpithetField
914 public AbstractField
<String
> getInfraSpecificEpithetField() {
915 return infraSpecificEpithetField
;