Project

General

Profile

Download (8.79 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 com.vaadin.data.Validator.InvalidValueException;
15
import com.vaadin.data.fieldgroup.BeanFieldGroup;
16
import com.vaadin.data.fieldgroup.FieldGroup;
17
import com.vaadin.data.util.BeanItem;
18
import com.vaadin.server.FontAwesome;
19
import com.vaadin.server.UserError;
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.themes.ValoTheme;
25

    
26
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
27
import eu.etaxonomy.cdm.model.agent.Person;
28
import eu.etaxonomy.cdm.model.agent.Team;
29
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
30
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
31
import eu.etaxonomy.cdm.vaadin.security.UserHelper;
32
import eu.etaxonomy.cdm.vaadin.util.converter.CdmBaseDeproxyConverter;
33
import eu.etaxonomy.vaadin.component.CompositeCustomField;
34
import eu.etaxonomy.vaadin.component.SwitchableTextField;
35
import eu.etaxonomy.vaadin.component.ToManyRelatedEntitiesListSelect;
36

    
37
/**
38
 * @author a.kohlbecker
39
 * @since May 11, 2017
40
 *
41
 */
42
public class TeamOrPersonField extends CompositeCustomField<TeamOrPersonBase<?>> {
43

    
44
    private static final long serialVersionUID = 660806402243118112L;
45

    
46
    private static final String PRIMARY_STYLE = "v-team-or-person-field";
47

    
48
    private CssLayout root = new CssLayout();
49
    private CssLayout toolBar= new CssLayout();
50
    private CssLayout compositeWrapper = new CssLayout();
51

    
52
    private Button removeButton = new Button(FontAwesome.REMOVE);
53
    private Button personButton = new Button(FontAwesome.USER);
54
    private Button teamButton = new Button(FontAwesome.USERS);
55

    
56
    // Fields for case when value is a Person
57
    private PersonField personField = new PersonField();
58

    
59
    // Fields for case when value is a Team
60
    private SwitchableTextField titleField = new SwitchableTextField("Team (bibliographic)");
61
    private SwitchableTextField nomenclaturalTitleField = new SwitchableTextField("Team (nomenclatural)");
62
    private ToManyRelatedEntitiesListSelect<Person, PersonField> personsListEditor = new ToManyRelatedEntitiesListSelect<Person, PersonField>(Person.class, PersonField.class, "Teammembers");
63

    
64
    private BeanFieldGroup<Team> fieldGroup  = new BeanFieldGroup<>(Team.class);
65

    
66
    public TeamOrPersonField(String caption){
67

    
68
        setCaption(caption);
69

    
70
        addStyledComponent(personField);
71
        addStyledComponent(titleField);
72
        addStyledComponent(nomenclaturalTitleField);
73
        addStyledComponent(personsListEditor);
74
        addStyledComponents(removeButton, personButton, teamButton);
75

    
76

    
77
        addSizedComponent(root);
78
        addSizedComponent(compositeWrapper);
79
        addSizedComponent(personField);
80
        addSizedComponent(titleField);
81
        addSizedComponent(nomenclaturalTitleField);
82
        addSizedComponent(personsListEditor);
83

    
84
        setConverter(new CdmBaseDeproxyConverter<TeamOrPersonBase<?>>());
85

    
86
        updateToolBarButtonStates();
87
    }
88

    
89
    /**
90
     * {@inheritDoc}
91
     */
92
    @Override
93
    protected Component initContent() {
94

    
95
        removeButton.addClickListener(e -> {
96
            setValue(null);
97
            updateToolBarButtonStates();
98
        });
99
        removeButton.setDescription("Remove");
100

    
101
        personButton.addClickListener(e -> {
102
            setValue(Person.NewInstance()); // FIXME add SelectField or open select dialog, use ToOneSelect field!!
103
            updateToolBarButtonStates();
104
        });
105
        personButton.setDescription("Add person");
106
        teamButton.addClickListener(e -> {
107
            setValue(Team.NewInstance()); // FIXME add SelectField or open select dialog, use ToOneSelect field!!
108
            updateToolBarButtonStates();
109
        });
110
        teamButton.setDescription("Add team");
111

    
112
        toolBar.setStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP + " toolbar");
113
        toolBar.addComponents(removeButton, personButton, teamButton);
114

    
115
        compositeWrapper.setStyleName("margin-wrapper");
116
        compositeWrapper.addComponent(toolBar);
117

    
118
        root.setPrimaryStyleName(PRIMARY_STYLE);
119
        root.addComponent(compositeWrapper);
120
        return root;
121
    }
122

    
123
    /**
124
     * {@inheritDoc}
125
     */
126
    @Override
127
    public Class getType() {
128
        return TeamOrPersonBase.class;
129
    }
130

    
131
    private void updateToolBarButtonStates(){
132
        TeamOrPersonBase<?> val = getInternalValue();
133
        boolean userCanCreate = UserHelper.fromSession().userHasPermission(Person.class, "CREATE");
134
        removeButton.setEnabled(val != null);
135
        personButton.setEnabled(userCanCreate && val == null);
136
        teamButton.setEnabled(userCanCreate && val == null);
137
    }
138

    
139
    /**
140
     * {@inheritDoc}
141
     */
142
    @Override
143
    protected void setInternalValue(TeamOrPersonBase<?> newValue) {
144

    
145
        super.setInternalValue(newValue);
146

    
147
        newValue = HibernateProxyHelper.deproxy(newValue);
148

    
149
        compositeWrapper.removeAllComponents();
150
        compositeWrapper.addComponent(toolBar);
151

    
152
        if(newValue == null) {
153
            return;
154
        }
155

    
156
        if(Person.class.isAssignableFrom(newValue.getClass())){
157
            // value is a Person:
158
            compositeWrapper.addComponent(personField);
159

    
160
            personField.setValue((Person) newValue);
161
            personField.registerParentFieldGroup(fieldGroup);
162

    
163
        }
164
        else if(Team.class.isAssignableFrom(newValue.getClass())){
165
            // otherwise it a Team
166

    
167
            compositeWrapper.addComponents(titleField, nomenclaturalTitleField, personsListEditor);
168

    
169
            titleField.bindTo(fieldGroup, "titleCache", "protectedTitleCache");
170
            nomenclaturalTitleField.bindTo(fieldGroup, "nomenclaturalTitle", "protectedNomenclaturalTitleCache");
171
            fieldGroup.setItemDataSource(new BeanItem<Team>((Team)newValue));
172
            fieldGroup.bind(personsListEditor, "teamMembers");
173

    
174
            personsListEditor.registerParentFieldGroup(fieldGroup);
175

    
176

    
177
        } else {
178
            setComponentError(new UserError("TeamOrPersonField Error: Unsupported value type: " + newValue.getClass().getName()));
179
        }
180

    
181
        updateToolBarButtonStates();
182
    }
183

    
184
    private void checkUserPermissions(TeamOrPersonBase<?> newValue) {
185
        boolean userCanEdit = UserHelper.fromSession().userHasPermission(newValue, "DELETE", "UPDATE");
186
        setEnabled(userCanEdit);
187
        personsListEditor.setEnabled(userCanEdit);
188
    }
189

    
190
    /**
191
     * {@inheritDoc}
192
     */
193
    @Override
194
    protected void addDefaultStyles() {
195
        // no default styles here
196
    }
197

    
198
    /**
199
     * {@inheritDoc}
200
     */
201
    @Override
202
    public FieldGroup getFieldGroup() {
203
        return fieldGroup;
204
    }
205

    
206
    public Component[] getCachFields(){
207
        return new Component[]{titleField, nomenclaturalTitleField};
208
    }
209

    
210
    /**
211
     * {@inheritDoc}
212
     */
213
    @SuppressWarnings("unchecked")
214
    @Override
215
    public void commit() throws SourceException, InvalidValueException {
216

    
217
        //need to commit the subfields propagation through the fielGroups is not enough
218
        personField.commit();
219
        personsListEditor.commit();
220
        super.commit();
221

    
222
        TeamOrPersonBase<?> bean = getValue();
223
        if(bean != null && bean instanceof Team){
224

    
225
            boolean isUnsaved = bean.getId() == 0;
226
            if(isUnsaved){
227
                UserHelper.fromSession().createAuthorityForCurrentUser(bean, EnumSet.of(CRUD.UPDATE, CRUD.DELETE), null);
228
            }
229
        }
230

    
231
        if(hasNullContent()){
232
            getPropertyDataSource().setValue(null);
233
            setValue(null);
234

    
235
        }
236
    }
237

    
238
    /**
239
     * {@inheritDoc}
240
     */
241
    @Override
242
    protected List<Field> nullValueCheckIgnoreFields() {
243
        List<Field> ignoreFields =  super.nullValueCheckIgnoreFields();
244
        ignoreFields.add(personField);
245
        ignoreFields.add(nomenclaturalTitleField.getUnlockSwitch());
246
        if(nomenclaturalTitleField.getUnlockSwitch().getValue().booleanValue() == false){
247
            ignoreFields.add(nomenclaturalTitleField.getTextField());
248
        }
249
        ignoreFields.add(titleField.getUnlockSwitch());
250
        if(titleField.getUnlockSwitch().getValue().booleanValue() == false){
251
            ignoreFields.add(titleField.getTextField());
252
        }
253
        return ignoreFields;
254
    }
255

    
256
    /**
257
     * {@inheritDoc}
258
     */
259
    @Override
260
    public boolean hasNullContent() {
261

    
262
        TeamOrPersonBase<?> bean = getValue();
263
        if(bean == null) {
264
            return true;
265
        }
266
        if(bean instanceof Team){
267
            // --- Team
268
            return super.hasNullContent();
269
        } else {
270
            // --- Person
271
            return personField.hasNullContent();
272
        }
273
    }
274

    
275
}
(4-4/5)