Project

General

Profile

Download (10.6 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.component.common;
10

    
11
import java.util.EnumSet;
12
import java.util.List;
13

    
14
import org.vaadin.teemu.switchui.Switch;
15
import org.vaadin.viritin.fields.LazyComboBox;
16

    
17
import com.vaadin.data.Validator.InvalidValueException;
18
import com.vaadin.data.fieldgroup.BeanFieldGroup;
19
import com.vaadin.data.fieldgroup.FieldGroup;
20
import com.vaadin.ui.Button;
21
import com.vaadin.ui.Component;
22
import com.vaadin.ui.CssLayout;
23
import com.vaadin.ui.Field;
24
import com.vaadin.ui.TextField;
25
import com.vaadin.ui.themes.ValoTheme;
26

    
27
import eu.etaxonomy.cdm.model.agent.Person;
28
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
29
import eu.etaxonomy.cdm.vaadin.component.TextFieldNFix;
30
import eu.etaxonomy.cdm.vaadin.security.UserHelper;
31
import eu.etaxonomy.vaadin.component.CompositeCustomField;
32
import eu.etaxonomy.vaadin.component.SwitchButton;
33

    
34
/**
35
 * @author a.kohlbecker
36
 * @since May 11, 2017
37
 *
38
 */
39
public class PersonField extends CompositeCustomField<Person> {
40

    
41
    private static final long serialVersionUID = 8346575511284469356L;
42

    
43
    private static final String PRIMARY_STYLE = "v-person-field";
44

    
45
    /**
46
     * do not allow entities which are having only <code>null</code> values in all fields
47
     * {@link #getValue()} would return <code>null</code> in this case.
48
     */
49
    boolean allowNewEmptyEntity = true;
50

    
51
    private LazyComboBox<Person> personSelect = new LazyComboBox<Person>(Person.class);
52

    
53
    private Button personSelectConfirmButton = new Button("OK");
54
    private Button newPersonButton = new Button("New");
55

    
56
    private BeanFieldGroup<Person> fieldGroup = new BeanFieldGroup<>(Person.class);
57

    
58
    enum Mode {
59
        CACHE_MODE, DETAILS_MODE;
60

    
61
        public String toCssClass() {
62
            return name().toLowerCase().replace("_", "-");
63
        }
64
    }
65

    
66
    private Mode currentMode = null;
67

    
68
    private float baseWidth = 100 / 9;
69

    
70
    private CssLayout root = new CssLayout();
71
    private CssLayout selectOrNewContainer = new CssLayout();
72

    
73
    private TextField cacheField = new TextFieldNFix();
74
    private CssLayout detailsContainer = new CssLayout();
75
    private TextField initialsField = new TextFieldNFix();
76
    private TextField firstNameField = new TextFieldNFix();
77
    private TextField lastNameField = new TextFieldNFix();
78
    private TextField prefixField = new TextFieldNFix();
79
    private TextField suffixField = new TextFieldNFix();
80
    private SwitchButton unlockSwitch = new SwitchButton();
81

    
82
    private boolean onCommit = false;
83

    
84

    
85
    /**
86
     * @param caption
87
     */
88
    public PersonField(String caption) {
89

    
90
        this();
91
        setCaption(caption);
92
    }
93

    
94
    /**
95
     * @param caption
96
     */
97
    public PersonField() {
98

    
99
        root.setPrimaryStyleName(PRIMARY_STYLE);
100

    
101
        // select existing or create new person
102
        addStyledComponents(personSelect, personSelectConfirmButton, newPersonButton);
103
        personSelect.addValueChangeListener(e -> {
104
            if(personSelect.getValue() != null){
105
                personSelectConfirmButton.setEnabled(true);
106
            }
107
        });
108
        personSelectConfirmButton.setEnabled(false);
109
        personSelectConfirmButton.addClickListener(e -> {
110
            setValue(personSelect.getValue());
111
            personSelect.clear();
112
        });
113
        selectOrNewContainer.addComponents(personSelect, personSelectConfirmButton, newPersonButton);
114
        newPersonButton.addClickListener(e -> {
115
            setValue(Person.NewInstance());
116
        });
117

    
118
        // edit person
119
        addStyledComponent(cacheField);
120
        addStyledComponents(initialsField);
121
        addStyledComponent(firstNameField);
122
        addStyledComponent(lastNameField);
123
        addStyledComponent(prefixField);
124
        addStyledComponent(suffixField);
125
        addStyledComponent(unlockSwitch);
126

    
127
        addSizedComponent(root);
128
    }
129

    
130
    /**
131
     *
132
     */
133
    private void checkUserPermissions(Person newValue) {
134
        boolean userCanEdit = UserHelper.fromSession().userHasPermission(newValue, "DELETE", "UPDATE");
135
        boolean isUnsavedEnitity = newValue.getId() == 0;
136
        setEnabled(isUnsavedEnitity || userCanEdit);
137
    }
138

    
139
    private void setMode(Mode mode){
140
        if(mode.equals(currentMode)){
141
            return;
142
        }
143
        if(currentMode != null){
144
            String removeMode = currentMode.toCssClass();
145
            root.removeStyleName(removeMode);
146
        }
147
        String newMode = mode.toCssClass();
148
        root.addStyleName(newMode);
149
        currentMode = mode;
150
    }
151

    
152

    
153
    /**
154
     * {@inheritDoc}
155
     */
156
    @Override
157
    protected Component initContent() {
158

    
159
        selectOrNewContainer.setWidth(100, Unit.PERCENTAGE);
160
        personSelect.setWidthUndefined();
161

    
162
        root.addComponent(cacheField);
163
        root.addComponent(unlockSwitch);
164
        root.addComponent(selectOrNewContainer);
165

    
166
        cacheField.setWidth(100, Unit.PERCENTAGE);
167

    
168
        prefixField.setWidth(baseWidth, Unit.PERCENTAGE);
169
        prefixField.setInputPrompt("Prefix");
170

    
171
        initialsField.setWidth(baseWidth, Unit.PERCENTAGE);
172
        initialsField.setInputPrompt("Initials");
173

    
174
        firstNameField.setWidth(baseWidth * 3, Unit.PERCENTAGE);
175
        firstNameField.setInputPrompt("Family name");
176

    
177
        lastNameField.setWidth(baseWidth * 3, Unit.PERCENTAGE);
178
        lastNameField.setInputPrompt("Other/given names");
179

    
180
        suffixField.setWidth(baseWidth, Unit.PERCENTAGE);
181
        suffixField.setInputPrompt("Suffix");
182

    
183
        detailsContainer.setStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP);
184
        detailsContainer.addComponent(prefixField);
185
        detailsContainer.addComponent(initialsField);
186
        detailsContainer.addComponent(firstNameField);
187
        detailsContainer.addComponent(lastNameField);
188
        detailsContainer.addComponent(suffixField);
189
        root.addComponent(detailsContainer);
190

    
191
        unlockSwitch.addValueChangeListener(e -> {
192
            if(refreshMode()){
193
                switch (currentMode) {
194
                    case CACHE_MODE:
195
                        cacheField.focus();
196
                        break;
197
                    case DETAILS_MODE:
198
                        firstNameField.focus();
199
                        break;
200
                    default:
201
                        break;
202

    
203
                }
204
            }
205
        });
206
        unlockSwitch.setValueSetLister(e -> {
207
            refreshMode();
208
        });
209

    
210
        addDefaultStyles();
211
        setMode(Mode.DETAILS_MODE);
212

    
213
        fieldGroup.bind(cacheField, "titleCache");
214
        fieldGroup.bind(prefixField, "prefix");
215
        fieldGroup.bind(initialsField, "initials");
216
        fieldGroup.bind(firstNameField, "firstname");
217
        fieldGroup.bind(lastNameField, "lastname");
218
        fieldGroup.bind(suffixField, "suffix");
219
        fieldGroup.bind(unlockSwitch, "protectedTitleCache");
220
        fieldGroup.setBuffered(false);
221

    
222
        updateVisibilities(getValue());
223

    
224
        return root;
225
    }
226

    
227
    /**
228
     *
229
     * @return true if the mode has changed
230
     */
231
    protected boolean refreshMode() {
232
        Mode lastMode = currentMode;
233
        setMode(unlockSwitch.getValue() ? Mode.CACHE_MODE: Mode.DETAILS_MODE);
234
        return !lastMode.equals(currentMode);
235
    }
236

    
237
    /**
238
     * {@inheritDoc}
239
     */
240
    @Override
241
    public Class<? extends Person> getType() {
242
        return Person.class;
243
    }
244

    
245
    @Override
246
    public void setValue(Person person){
247
        super.setValue(person);
248
        personSelect.setValue(person);
249
    }
250

    
251
    /**
252
     * {@inheritDoc}
253
     */
254
    @Override
255
    protected void setInternalValue(Person newValue) {
256

    
257
        super.setInternalValue(newValue);
258
        fieldGroup.setItemDataSource(newValue);
259
        checkUserPermissions(newValue);
260
        updateVisibilities(newValue);
261
    }
262

    
263
    /**
264
     *
265
     */
266
    private void updateVisibilities(Person person) {
267

    
268
        selectOrNewContainer.setVisible(person == null);
269

    
270
        detailsContainer.setVisible(person != null);
271
        unlockSwitch.setVisible(person != null);
272
        cacheField.setVisible(person != null);
273

    
274
    }
275

    
276
    @Override
277
    protected void addDefaultStyles(){
278
        cacheField.addStyleName("cache-field");
279
        detailsContainer.addStyleName("details-fields");
280
        unlockSwitch.addStyleName(Switch.DOM_STYLE);
281
    }
282

    
283
    /**
284
     * {@inheritDoc}
285
     */
286
    @Override
287
    public FieldGroup getFieldGroup() {
288
        return fieldGroup;
289
    }
290

    
291

    
292
    /**
293
     * {@inheritDoc}
294
     */
295
    @Override
296
    protected List<Field> nullValueCheckIgnoreFields() {
297

    
298
        List<Field>ignoreFields = super.nullValueCheckIgnoreFields();
299
        ignoreFields.add(unlockSwitch);
300

    
301
        if(unlockSwitch.getValue().booleanValue() == false){
302
            if(getValue().getId() == 0){
303
                // only it the entity is unsaved!
304
                ignoreFields.add(cacheField);
305
                cacheField.setValue(null);
306
            }
307
        }
308
        return ignoreFields;
309
    }
310

    
311
    /**
312
     * {@inheritDoc}
313
     */
314
    @Override
315
    public void commit() throws SourceException, InvalidValueException {
316

    
317
        super.commit();
318

    
319
        Person bean =  getValue();
320
        if(bean != null){
321
            boolean isUnsaved = bean.getId() == 0;
322
            if(isUnsaved && !(hasNullContent() && !allowNewEmptyEntity)){
323
                UserHelper.fromSession().createAuthorityForCurrentUser(bean, EnumSet.of(CRUD.UPDATE, CRUD.DELETE), null);
324
            }
325
        }
326
    }
327

    
328
    /**
329
     * {@inheritDoc}
330
     *
331
     * @return returns <code>null</code> in case the edited entity is unsaved and if
332
     * it only has null values.
333
     */
334
    @Override
335
    public Person getValue() {
336
        Person bean = super.getValue();
337
        if(bean == null){
338
            return null;
339
        }
340
       // boolean isUnsaved = bean.getId() == 0;
341
//        if(isUnsaved && hasNullContent() && !allowNewEmptyEntity) {
342
//            return null;
343
//        }
344
        return bean;
345
    }
346

    
347
    /**
348
     * @return the personSelect
349
     */
350
    public LazyComboBox<Person> getPersonSelect() {
351
        return personSelect;
352
    }
353

    
354
    /**
355
     * @param personSelect the personSelect to set
356
     */
357
    public void setPersonSelect(LazyComboBox<Person> personSelect) {
358
        this.personSelect = personSelect;
359
    }
360

    
361
    /**
362
     * @return the allowNewEmptyEntity
363
     */
364
    public boolean isAllowNewEmptyEntity() {
365
        return allowNewEmptyEntity;
366
    }
367

    
368
    /**
369
     * @param allowNewEmptyEntity the allowNewEmptyEntity to set
370
     */
371
    public void setAllowNewEmptyEntity(boolean allowNewEmptyEntity) {
372
        this.allowNewEmptyEntity = allowNewEmptyEntity;
373
    }
374

    
375

    
376

    
377
}
(3-3/5)