Project

General

Profile

Download (15 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.reference;
10

    
11
import java.util.Collection;
12
import java.util.EnumSet;
13
import java.util.HashMap;
14
import java.util.LinkedHashMap;
15
import java.util.Map;
16
import java.util.Set;
17

    
18
import org.apache.log4j.Logger;
19
import org.springframework.context.annotation.Scope;
20
import org.springframework.security.core.GrantedAuthority;
21

    
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;
30

    
31
import eu.etaxonomy.cdm.model.common.AnnotationType;
32
import eu.etaxonomy.cdm.model.reference.Reference;
33
import eu.etaxonomy.cdm.model.reference.ReferencePropertyDefinitions;
34
import eu.etaxonomy.cdm.model.reference.ReferencePropertyDefinitions.UnimplemetedCaseException;
35
import eu.etaxonomy.cdm.model.reference.ReferenceType;
36
import eu.etaxonomy.cdm.vaadin.component.TextFieldNFix;
37
import eu.etaxonomy.cdm.vaadin.component.common.FilterableAnnotationsField;
38
import eu.etaxonomy.cdm.vaadin.component.common.TeamOrPersonField;
39
import eu.etaxonomy.cdm.vaadin.component.common.VerbatimTimePeriodField;
40
import eu.etaxonomy.cdm.vaadin.event.ReferenceEditorAction;
41
import eu.etaxonomy.cdm.vaadin.permission.AccessRestrictedView;
42
import eu.etaxonomy.cdm.vaadin.ui.RegistrationUIDefaults;
43
import eu.etaxonomy.cdm.vaadin.util.TeamOrPersonBaseCaptionGenerator;
44
import eu.etaxonomy.cdm.vaadin.util.converter.DoiConverter;
45
import eu.etaxonomy.cdm.vaadin.util.converter.UriConverter;
46
import eu.etaxonomy.vaadin.component.SwitchableTextField;
47
import eu.etaxonomy.vaadin.component.ToOneRelatedEntityCombobox;
48
import eu.etaxonomy.vaadin.event.EditorActionType;
49
import eu.etaxonomy.vaadin.mvp.AbstractCdmPopupEditor;
50
import eu.etaxonomy.vaadin.util.PropertyIdPath;
51

    
52
/**
53
 * @author a.kohlbecker
54
 * @since Apr 4, 2017
55
 *
56
 */
57
@SpringComponent
58
@Scope("prototype")
59
public class ReferencePopupEditor extends AbstractCdmPopupEditor<Reference, ReferenceEditorPresenter> implements ReferencePopupEditorView, AccessRestrictedView {
60

    
61
    private static final long serialVersionUID = -4347633563800758815L;
62

    
63
    private static final Logger logger = Logger.getLogger(ReferencePopupEditor.class);
64

    
65
    private TextField titleField;
66

    
67
    private final static int GRID_COLS = 4; // 12 would fits for 2,3, and 4 Components per row
68

    
69
    private final static int GRID_ROWS = 11;
70

    
71
    private ListSelect typeSelect;
72

    
73
    private ToOneRelatedEntityCombobox<Reference> inReferenceCombobox;
74

    
75
    private TeamOrPersonField authorshipField;
76

    
77
    private FilterableAnnotationsField annotationsListField;
78

    
79
    private AnnotationType[] editableAnotationTypes = RegistrationUIDefaults.EDITABLE_ANOTATION_TYPES;
80

    
81
    private EnumSet<ReferenceType> referenceTypes = EnumSet.allOf(ReferenceType.class);
82

    
83
    private static Map<String,String> propertyNameLabelMap = new HashMap<>();
84

    
85
    private int variableGridStartRow;
86

    
87
    private int variableGridLastRow;
88

    
89
    /**
90
     * Used to record the fields from the variable grid part in their original order.
91
     */
92
    private LinkedHashMap<String, Field<?>> adaptiveFields = new LinkedHashMap<>();
93

    
94
    static {
95
        propertyNameLabelMap.put("inReference", "In reference");
96
        propertyNameLabelMap.put("inJournal", "In journal");
97
        propertyNameLabelMap.put("inSeries", "In series");
98
        propertyNameLabelMap.put("inBook", "In book");
99
    }
100

    
101
    /**
102
     * @param layout
103
     * @param dtoType
104
     */
105
    public ReferencePopupEditor() {
106
        super(new GridLayout(GRID_COLS, GRID_ROWS), Reference.class);
107
    }
108

    
109
    @Override
110
    protected void initContent() {
111
        GridLayout grid = (GridLayout)getFieldLayout();
112
        grid.setSpacing(true);
113
        grid.setMargin(true);
114

    
115
        /*
116
        "type",
117
        "uri",
118
        "abbrevTitleCache",
119
        "protectedAbbrevTitleCache",
120
        "nomenclaturallyRelevant",
121
        "authorship",
122
        "referenceAbstract",
123
        "title",
124
        "abbrevTitle",
125
        "editor",
126
        "volume",
127
        "pages",
128
        "edition",
129
        "isbn",
130
        "issn",
131
        "doi",
132
        "seriesPart",
133
        "datePublished",
134
        "publisher",
135
        "placePublished",
136
        "institution",
137
        "school",
138
        "organization",
139
        "inReference"
140
         */
141
        int row = 0;
142
        VerbatimTimePeriodField timePeriodField = new VerbatimTimePeriodField("Date published");
143
        addField(timePeriodField, "datePublished", 0, row, 1, row);
144
        typeSelect = new ListSelect("Reference type");
145
        typeSelect.addItems(referenceTypes);
146
        typeSelect.setNullSelectionAllowed(false);
147
        typeSelect.setRows(1);
148
        typeSelect.addValueChangeListener(e -> updateFieldVisibility((ReferenceType)e.getProperty().getValue()));
149
        addField(typeSelect, "type", GRID_COLS - 1, row);
150
        grid.setComponentAlignment(typeSelect, Alignment.TOP_RIGHT);
151
        row++;
152

    
153
        SwitchableTextField titleCacheField = addSwitchableTextField("Reference cache", "titleCache", "protectedTitleCache", 0, row, GRID_COLS-1, row);
154
        titleCacheField.setWidth(100, Unit.PERCENTAGE);
155
        row++;
156

    
157
        SwitchableTextField abbrevTitleCacheField = addSwitchableTextField("Abbrev. cache", "abbrevTitleCache", "protectedAbbrevTitleCache", 0, row, GRID_COLS-1, row);
158
        abbrevTitleCacheField.setWidth(100, Unit.PERCENTAGE);
159
        row++;
160

    
161
        titleField = addTextField("Title", "title", 0, row, GRID_COLS-1, row);
162
        titleField.setWidth(100, Unit.PERCENTAGE);
163
        row++;
164
        addTextField("Nomenclatural title", "abbrevTitle", 0, row, GRID_COLS-1, row).setWidth(100, Unit.PERCENTAGE);
165
        row++;
166

    
167
        authorshipField = new TeamOrPersonField("Author(s)", TeamOrPersonBaseCaptionGenerator.CacheType.BIBLIOGRAPHIC_TITLE);
168
        authorshipField.setWidth(100,  Unit.PERCENTAGE);
169
        addField(authorshipField, "authorship", 0, row, GRID_COLS -1, row);
170
        row++;
171

    
172
        inReferenceCombobox = new ToOneRelatedEntityCombobox<Reference>("In-reference", Reference.class);
173
        inReferenceCombobox.setWidth(100, Unit.PERCENTAGE);
174
        inReferenceCombobox.addClickListenerAddEntity(e -> getViewEventBus().publish(this,
175
                new ReferenceEditorAction(EditorActionType.ADD, e.getButton(), inReferenceCombobox, this)
176
                ));
177
        inReferenceCombobox.addClickListenerEditEntity(e -> {
178
            if(inReferenceCombobox.getValue() != null){
179
                getViewEventBus().publish(this,
180
                    new ReferenceEditorAction(
181
                            EditorActionType.EDIT,
182
                            inReferenceCombobox.getValue().getUuid(),
183
                            e.getButton(),
184
                            inReferenceCombobox,
185
                            this)
186
                );
187
            }
188
            });
189
        addField(inReferenceCombobox, "inReference", 0, row, GRID_COLS -1, row);
190
        row++;
191

    
192
        variableGridStartRow = row;
193
        addTextField("Series", "seriesPart", 0, row).setWidth(100, Unit.PERCENTAGE);
194
        addTextField("Volume", "volume", 1, row).setWidth(100, Unit.PERCENTAGE);
195
        addTextField("Pages", "pages", 2, row).setWidth(100, Unit.PERCENTAGE);
196
        addTextField("Edition", "edition", 3, row).setWidth(100, Unit.PERCENTAGE);
197
        row++;
198

    
199
        addTextField("Place published", "placePublished", 0, row, 0, row).setWidth(100, Unit.PERCENTAGE);
200
        TextField publisherField = addTextField("Publisher", "publisher", 1, row, 1, row);
201
        publisherField.setWidth(100, Unit.PERCENTAGE);
202
        addTextField("Editor", "editor", 2, row).setWidth(100, Unit.PERCENTAGE);
203
        row++;
204

    
205
        addTextField("ISSN", "issn", 0, row).setWidth(100, Unit.PERCENTAGE);
206
        addTextField("ISBN", "isbn", 1, row).setWidth(100, Unit.PERCENTAGE);
207
        TextFieldNFix doiField = new TextFieldNFix("DOI");
208
        doiField.setConverter(new DoiConverter());
209
        doiField.setWidth(100, Unit.PERCENTAGE);
210
        addField(doiField, "doi", 2, row);
211
        TextFieldNFix uriField = new TextFieldNFix("Uri");
212
        uriField.setConverter(new UriConverter());
213
        uriField.setWidth(100, Unit.PERCENTAGE);
214
        addField(uriField, "uri", 3, row);
215

    
216

    
217
        variableGridLastRow = row;
218

    
219
        row++;
220
        annotationsListField = new FilterableAnnotationsField("Editorial notes");
221
        annotationsListField.setWidth(100, Unit.PERCENTAGE);
222
        annotationsListField.setAnnotationTypesVisible(editableAnotationTypes);
223
        addField(annotationsListField, "annotations", 0, row, GRID_COLS-1, row);
224

    
225

    
226
//        titleField.setRequired(true);
227
//        publisherField.setRequired(true);
228

    
229
        setAdvancedModeEnabled(true);
230
        registerAdvancedModeComponents(titleCacheField, abbrevTitleCacheField);
231
        registerAdvancedModeComponents(authorshipField.getCachFields());
232
        setAdvancedMode(false);
233

    
234
    }
235

    
236
    /**
237
     * @param value
238
     * @return
239
     */
240
    private Object updateFieldVisibility(ReferenceType referenceType) {
241

    
242
        GridLayout grid = (GridLayout)getFieldLayout();
243

    
244
        initAdaptiveFields();
245

    
246
        // clear the variable grid part
247
        for(int row = variableGridStartRow; row <= variableGridLastRow; row++){
248
            for(int x=0; x < grid.getColumns(); x++){
249
                grid.removeComponent(x, row);
250
            }
251
        }
252

    
253
        // set cursor at the beginning of the variable grid part
254
        grid.setCursorY(variableGridStartRow);
255
        grid.setCursorX(0);
256

    
257
        // place the fields which are required for the given referenceType in the variable grid part while
258
        // and retain the original order which is recorded in the adaptiveFields
259
        try {
260
            Map<String, String> fieldPropertyDefinition = ReferencePropertyDefinitions.fieldPropertyDefinition(referenceType);
261

    
262
            // Authors and inReference
263
            authorshipField.setVisible(fieldPropertyDefinition.containsKey("authorship"));
264
            String inRefCaption = fieldPropertyDefinition.get("inReference");
265
            inReferenceCombobox.setVisible(inRefCaption != null);
266
            if(inRefCaption != null){
267
                inReferenceCombobox.setCaption(propertyNameLabelMap.get(inRefCaption));
268
            }
269
            getField("title").setVisible(fieldPropertyDefinition.containsKey("title"));
270

    
271
            EnumSet<ReferenceType> hideNomTitle = EnumSet.of(ReferenceType.Article, ReferenceType.Section, ReferenceType.BookSection, ReferenceType.InProceedings);
272
//            EnumSet<ReferenceType> hideTitle = EnumSet.of(ReferenceType.Section, ReferenceType.BookSection);
273
            getField("abbrevTitle").setVisible(!hideNomTitle.contains(referenceType));
274

    
275
            for(String fieldName : adaptiveFields.keySet()){ // iterate over the LinkedHashMap to retain the original order of the fields
276
                if(fieldPropertyDefinition.containsKey(fieldName)){
277
                    Field<?> field = adaptiveFields.get(fieldName);
278
                    grid.addComponent(field);
279
                    String propertyName = fieldPropertyDefinition.get(fieldName);
280
                    if(propertyName != fieldName){
281
                        field.setCaption(propertyNameLabelMap.get(propertyName));
282
                    }
283
                }
284
            }
285
        } catch (UnimplemetedCaseException e) {
286
            logger.error(e);
287
            // enable all fields
288
            setAllFieldsVisible(true);
289
            // fix inReference label
290
            getField("inReference").setCaption(propertyNameLabelMap.get("inReference"));
291
        }
292

    
293

    
294

    
295
        return null;
296
    }
297

    
298
    /**
299
     * @param grid
300
     */
301
    protected void initAdaptiveFields() {
302
        GridLayout grid = (GridLayout)getFieldLayout();
303
        // initialize the map of adaptive fields
304
        if(adaptiveFields.isEmpty()){
305
            try{
306
                Map<String, String> fieldPropertyDefinition = ReferencePropertyDefinitions.fieldPropertyDefinition(null);
307
                Set<String> fieldNames = fieldPropertyDefinition.keySet();
308
                for(int row = variableGridStartRow; row <= variableGridLastRow; row++){
309
                    for(int x=0; x < grid.getColumns(); x++){
310
                        Component c = grid.getComponent(x, row);
311
                        logger.trace("initAdaptiveFields() - y: " + row + " x: " + x + "  component:" + (c != null ? c.getClass().getSimpleName(): "NULL"));
312
                        if(c != null && c instanceof Field){
313
                            Field<?> field = (Field<?>)c;
314
                            PropertyIdPath propertyIdPath = boundPropertyIdPath(field);
315
                            logger.trace("initAdaptiveFields() - " + field.getCaption() + " -> " + propertyIdPath);
316
                            if(propertyIdPath != null && fieldNames.contains(propertyIdPath.toString())){
317
                                adaptiveFields.put(propertyIdPath.toString(), field);
318
                            }
319
                        }
320
                    }
321
                }
322
            } catch (UnimplemetedCaseException e) {
323
                throw new RuntimeException(e);
324
            }
325
        }
326
    }
327

    
328
    protected void setAllFieldsVisible(boolean visible){
329
        GridLayout grid = (GridLayout)getFieldLayout();
330
        for(Component c : grid){
331
            if(AbstractField.class.isAssignableFrom(c.getClass())){
332
                c.setVisible(visible);
333
            }
334
        }
335
    }
336

    
337
    /**
338
     * {@inheritDoc}
339
     */
340
    @Override
341
    public String getWindowCaption() {
342
        return "Reference editor";
343
    }
344

    
345
    /**
346
     * {@inheritDoc}
347
     */
348
    @Override
349
    protected String getDefaultComponentStyles() {
350
        return "tiny";
351
    }
352

    
353
    /**
354
     * {@inheritDoc}            // TODO Auto-generated method stub
355
     */
356
    @Override
357
    public void focusFirst() {
358
        titleField.focus();
359
    }
360

    
361
    /**
362
     * {@inheritDoc}
363
     */
364
    @Override
365
    public boolean isResizable() {
366
        return false;
367
    }
368

    
369
    /**
370
     * {@inheritDoc}
371
     */
372
    @Override
373
    public boolean allowAnonymousAccess() {
374
        return false;
375
    }
376

    
377
    /**
378
     * {@inheritDoc}
379
     */
380
    @Override
381
    public Collection<Collection<GrantedAuthority>> allowedGrantedAuthorities() {
382
        return null;
383
    }
384

    
385
    @Override
386
    public ListSelect getTypeSelect() {
387
        return typeSelect;
388
    }
389

    
390
    /**
391
     * {@inheritDoc}
392
     */
393
    @Override
394
    public ToOneRelatedEntityCombobox<Reference> getInReferenceCombobox() {
395
        return inReferenceCombobox;
396
    }
397

    
398
    /**
399
     * {@inheritDoc}
400
     */
401
    @Override
402
    public TeamOrPersonField getAuthorshipField() {
403
        return authorshipField;
404
    }
405

    
406
    @Override
407
    public FilterableAnnotationsField getAnnotationsField() {
408
        return annotationsListField;
409
    }
410

    
411
    public void withReferenceTypes(EnumSet<ReferenceType> types){
412
        this.referenceTypes = types;
413
        if(typeSelect != null){
414
            typeSelect.removeAllItems();
415
            typeSelect.addItems(referenceTypes);
416
        }
417
    }
418

    
419

    
420
}
(2-2/3)