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
.reference
;
11 import java
.util
.Collection
;
12 import java
.util
.EnumSet
;
13 import java
.util
.HashMap
;
14 import java
.util
.LinkedHashMap
;
18 import org
.apache
.log4j
.Logger
;
19 import org
.springframework
.context
.annotation
.Scope
;
20 import org
.springframework
.security
.core
.GrantedAuthority
;
22 import com
.vaadin
.spring
.annotation
.SpringComponent
;
23 import com
.vaadin
.ui
.AbstractField
;
24 import com
.vaadin
.ui
.Alignment
;
25 import com
.vaadin
.ui
.Component
;
26 import com
.vaadin
.ui
.Field
;
27 import com
.vaadin
.ui
.GridLayout
;
28 import com
.vaadin
.ui
.ListSelect
;
29 import com
.vaadin
.ui
.TextField
;
31 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
32 import eu
.etaxonomy
.cdm
.model
.reference
.ReferencePropertyDefinitions
;
33 import eu
.etaxonomy
.cdm
.model
.reference
.ReferencePropertyDefinitions
.UnimplemetedCaseException
;
34 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceType
;
35 import eu
.etaxonomy
.cdm
.vaadin
.component
.TextFieldNFix
;
36 import eu
.etaxonomy
.cdm
.vaadin
.component
.common
.TeamOrPersonField
;
37 import eu
.etaxonomy
.cdm
.vaadin
.component
.common
.VerbatimTimePeriodField
;
38 import eu
.etaxonomy
.cdm
.vaadin
.event
.ReferenceEditorAction
;
39 import eu
.etaxonomy
.cdm
.vaadin
.permission
.AccessRestrictedView
;
40 import eu
.etaxonomy
.cdm
.vaadin
.util
.TeamOrPersonBaseCaptionGenerator
;
41 import eu
.etaxonomy
.cdm
.vaadin
.util
.converter
.DoiConverter
;
42 import eu
.etaxonomy
.cdm
.vaadin
.util
.converter
.UriConverter
;
43 import eu
.etaxonomy
.vaadin
.component
.SwitchableTextField
;
44 import eu
.etaxonomy
.vaadin
.component
.ToOneRelatedEntityCombobox
;
45 import eu
.etaxonomy
.vaadin
.event
.EditorActionType
;
46 import eu
.etaxonomy
.vaadin
.mvp
.AbstractCdmPopupEditor
;
47 import eu
.etaxonomy
.vaadin
.util
.PropertyIdPath
;
50 * @author a.kohlbecker
56 public class ReferencePopupEditor
extends AbstractCdmPopupEditor
<Reference
, ReferenceEditorPresenter
> implements ReferencePopupEditorView
, AccessRestrictedView
{
58 private static final long serialVersionUID
= -4347633563800758815L;
60 private static final Logger logger
= Logger
.getLogger(ReferencePopupEditor
.class);
62 private TextField titleField
;
64 private final static int GRID_COLS
= 4; // 12 would fits for 2,3, and 4 Components per row
66 private final static int GRID_ROWS
= 10;
68 private ListSelect typeSelect
;
70 private ToOneRelatedEntityCombobox
<Reference
> inReferenceCombobox
;
72 private TeamOrPersonField authorshipField
;
74 private EnumSet
<ReferenceType
> referenceTypes
= EnumSet
.allOf(ReferenceType
.class);
76 private static Map
<String
,String
> propertyNameLabelMap
= new HashMap
<>();
78 private int variableGridStartRow
;
80 private int variableGridLastRow
;
83 * Used to record the fields from the variable grid part in their original order.
85 private LinkedHashMap
<String
, Field
<?
>> adaptiveFields
= new LinkedHashMap
<>();
88 propertyNameLabelMap
.put("inReference", "In reference");
89 propertyNameLabelMap
.put("inJournal", "In journal");
90 propertyNameLabelMap
.put("inSeries", "In series");
91 propertyNameLabelMap
.put("inBook", "In book");
98 public ReferencePopupEditor() {
99 super(new GridLayout(GRID_COLS
, GRID_ROWS
), Reference
.class);
103 protected void initContent() {
104 GridLayout grid
= (GridLayout
)getFieldLayout();
105 grid
.setSpacing(true);
106 grid
.setMargin(true);
112 "protectedAbbrevTitleCache",
113 "nomenclaturallyRelevant",
135 VerbatimTimePeriodField timePeriodField
= new VerbatimTimePeriodField("Date published");
136 addField(timePeriodField
, "datePublished", 0, row
, 1, row
);
137 typeSelect
= new ListSelect("Reference type");
138 typeSelect
.addItems(referenceTypes
);
139 typeSelect
.setNullSelectionAllowed(false);
140 typeSelect
.setRows(1);
141 typeSelect
.addValueChangeListener(e
-> updateFieldVisibility((ReferenceType
)e
.getProperty().getValue()));
142 addField(typeSelect
, "type", GRID_COLS
- 1, row
);
143 grid
.setComponentAlignment(typeSelect
, Alignment
.TOP_RIGHT
);
146 SwitchableTextField titleCacheField
= addSwitchableTextField("Reference cache", "titleCache", "protectedTitleCache", 0, row
, GRID_COLS
-1, row
);
147 titleCacheField
.setWidth(100, Unit
.PERCENTAGE
);
150 SwitchableTextField abbrevTitleCacheField
= addSwitchableTextField("Abbrev. cache", "abbrevTitleCache", "protectedAbbrevTitleCache", 0, row
, GRID_COLS
-1, row
);
151 abbrevTitleCacheField
.setWidth(100, Unit
.PERCENTAGE
);
154 titleField
= addTextField("Title", "title", 0, row
, GRID_COLS
-1, row
);
155 titleField
.setWidth(100, Unit
.PERCENTAGE
);
157 addTextField("Nomenclatural title", "abbrevTitle", 0, row
, GRID_COLS
-1, row
).setWidth(100, Unit
.PERCENTAGE
);
160 authorshipField
= new TeamOrPersonField("Author(s)", TeamOrPersonBaseCaptionGenerator
.CacheType
.BIBLIOGRAPHIC_TITLE
);
161 authorshipField
.setWidth(100, Unit
.PERCENTAGE
);
162 addField(authorshipField
, "authorship", 0, row
, GRID_COLS
-1, row
);
165 inReferenceCombobox
= new ToOneRelatedEntityCombobox
<Reference
>("In-reference", Reference
.class);
166 inReferenceCombobox
.setWidth(100, Unit
.PERCENTAGE
);
167 inReferenceCombobox
.addClickListenerAddEntity(e
-> getViewEventBus().publish(this,
168 new ReferenceEditorAction(EditorActionType
.ADD
, e
.getButton(), inReferenceCombobox
, this)
170 inReferenceCombobox
.addClickListenerEditEntity(e
-> {
171 if(inReferenceCombobox
.getValue() != null){
172 getViewEventBus().publish(this,
173 new ReferenceEditorAction(
174 EditorActionType
.EDIT
,
175 inReferenceCombobox
.getValue().getUuid(),
182 addField(inReferenceCombobox
, "inReference", 0, row
, GRID_COLS
-1, row
);
185 variableGridStartRow
= row
;
186 addTextField("Series", "seriesPart", 0, row
).setWidth(100, Unit
.PERCENTAGE
);
187 addTextField("Volume", "volume", 1, row
).setWidth(100, Unit
.PERCENTAGE
);
188 addTextField("Pages", "pages", 2, row
).setWidth(100, Unit
.PERCENTAGE
);
189 addTextField("Edition", "edition", 3, row
).setWidth(100, Unit
.PERCENTAGE
);
192 addTextField("Place published", "placePublished", 0, row
, 0, row
).setWidth(100, Unit
.PERCENTAGE
);
193 TextField publisherField
= addTextField("Publisher", "publisher", 1, row
, 1, row
);
194 publisherField
.setWidth(100, Unit
.PERCENTAGE
);
195 addTextField("Editor", "editor", 2, row
).setWidth(100, Unit
.PERCENTAGE
);
198 addTextField("ISSN", "issn", 0, row
).setWidth(100, Unit
.PERCENTAGE
);
199 addTextField("ISBN", "isbn", 1, row
).setWidth(100, Unit
.PERCENTAGE
);
200 TextFieldNFix doiField
= new TextFieldNFix("DOI");
201 doiField
.setConverter(new DoiConverter());
202 doiField
.setWidth(100, Unit
.PERCENTAGE
);
203 addField(doiField
, "doi", 2, row
);
204 TextFieldNFix uriField
= new TextFieldNFix("Uri");
205 uriField
.setConverter(new UriConverter());
206 uriField
.setWidth(100, Unit
.PERCENTAGE
);
207 addField(uriField
, "uri", 3, row
);
210 variableGridLastRow
= row
;
212 // titleField.setRequired(true);
213 // publisherField.setRequired(true);
215 setAdvancedModeEnabled(true);
216 registerAdvancedModeComponents(titleCacheField
, abbrevTitleCacheField
);
217 registerAdvancedModeComponents(authorshipField
.getCachFields());
218 setAdvancedMode(false);
226 private Object
updateFieldVisibility(ReferenceType referenceType
) {
228 GridLayout grid
= (GridLayout
)getFieldLayout();
230 initAdaptiveFields();
232 // clear the variable grid part
233 for(int row
= variableGridStartRow
; row
<= variableGridLastRow
; row
++){
234 for(int x
=0; x
< grid
.getColumns(); x
++){
235 grid
.removeComponent(x
, row
);
239 // set cursor at the beginning of the variable grid part
240 grid
.setCursorY(variableGridStartRow
);
243 // place the fields which are required for the given referenceType in the variable grid part while
244 // and retain the original order which is recorded in the adaptiveFields
246 Map
<String
, String
> fieldPropertyDefinition
= ReferencePropertyDefinitions
.fieldPropertyDefinition(referenceType
);
248 for(String fieldName
: adaptiveFields
.keySet()){ // iterate over the LinkedHashMap to retain the original order of the fields
249 if(fieldPropertyDefinition
.containsKey(fieldName
)){
250 Field
<?
> field
= adaptiveFields
.get(fieldName
);
251 grid
.addComponent(field
);
252 String propertyName
= fieldPropertyDefinition
.get(fieldName
);
253 if(propertyName
!= fieldName
){
254 field
.setCaption(propertyNameLabelMap
.get(propertyName
));
258 } catch (UnimplemetedCaseException e
) {
261 setAllFieldsVisible(true);
262 // fix inReference label
263 getField("inReference").setCaption(propertyNameLabelMap
.get("inReference"));
266 EnumSet
<ReferenceType
> hideNomTitle
= EnumSet
.of(ReferenceType
.Article
, ReferenceType
.Section
, ReferenceType
.BookSection
, ReferenceType
.InProceedings
, ReferenceType
.PrintSeries
);
267 EnumSet
<ReferenceType
> hideTitle
= EnumSet
.of(ReferenceType
.Section
, ReferenceType
.BookSection
);
268 getField("abbrevTitle").setVisible(!hideNomTitle
.contains(referenceType
));
269 getField("title").setVisible(!hideTitle
.contains(referenceType
));
277 protected void initAdaptiveFields() {
278 GridLayout grid
= (GridLayout
)getFieldLayout();
279 // initialize the map of adaptive fields
280 if(adaptiveFields
.isEmpty()){
282 Map
<String
, String
> fieldPropertyDefinition
= ReferencePropertyDefinitions
.fieldPropertyDefinition(null);
283 Set
<String
> fieldNames
= fieldPropertyDefinition
.keySet();
284 for(int row
= variableGridStartRow
; row
<= variableGridLastRow
; row
++){
285 for(int x
=0; x
< grid
.getColumns(); x
++){
286 Component c
= grid
.getComponent(x
, row
);
287 logger
.debug("initAdaptiveFields() - y: " + row
+ " x: " + x
+ " component:" + (c
!= null ? c
.getClass().getSimpleName(): "NULL"));
288 if(c
!= null && c
instanceof Field
){
289 Field
<?
> field
= (Field
<?
>)c
;
290 PropertyIdPath propertyIdPath
= boundPropertyIdPath(field
);
291 logger
.debug("initAdaptiveFields() - " + field
.getCaption() + " -> " + propertyIdPath
);
292 if(propertyIdPath
!= null && fieldNames
.contains(propertyIdPath
.toString())){
293 adaptiveFields
.put(propertyIdPath
.toString(), field
);
298 } catch (UnimplemetedCaseException e
) {
299 throw new RuntimeException(e
);
304 protected void setAllFieldsVisible(boolean visible
){
305 GridLayout grid
= (GridLayout
)getFieldLayout();
306 for(Component c
: grid
){
307 if(AbstractField
.class.isAssignableFrom(c
.getClass())){
308 c
.setVisible(visible
);
317 public String
getWindowCaption() {
318 return "Reference editor";
325 protected String
getDefaultComponentStyles() {
333 public void focusFirst() {
341 public boolean isResizable() {
349 public boolean allowAnonymousAccess() {
357 public Collection
<Collection
<GrantedAuthority
>> allowedGrantedAuthorities() {
362 public ListSelect
getTypeSelect() {
370 public ToOneRelatedEntityCombobox
<Reference
> getInReferenceCombobox() {
371 return inReferenceCombobox
;
378 public TeamOrPersonField
getAuthorshipField() {
379 return authorshipField
;
382 public void withReferenceTypes(EnumSet
<ReferenceType
> types
){
383 this.referenceTypes
= types
;
384 if(typeSelect
!= null){
385 typeSelect
.removeAllItems();
386 typeSelect
.addItems(referenceTypes
);