Project

General

Profile

Download (12.1 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.viritin.fields.LazyComboBox;
15

    
16
import com.vaadin.data.Validator.InvalidValueException;
17
import com.vaadin.data.fieldgroup.BeanFieldGroup;
18
import com.vaadin.data.fieldgroup.FieldGroup;
19
import com.vaadin.data.util.BeanItem;
20
import com.vaadin.server.FontAwesome;
21
import com.vaadin.server.UserError;
22
import com.vaadin.ui.Button;
23
import com.vaadin.ui.Component;
24
import com.vaadin.ui.CssLayout;
25
import com.vaadin.ui.Field;
26
import com.vaadin.ui.themes.ValoTheme;
27

    
28
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
29
import eu.etaxonomy.cdm.model.agent.AgentBase;
30
import eu.etaxonomy.cdm.model.agent.Person;
31
import eu.etaxonomy.cdm.model.agent.Team;
32
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
33
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
34
import eu.etaxonomy.cdm.service.CdmFilterablePagingProvider;
35
import eu.etaxonomy.cdm.vaadin.event.ToOneRelatedEntityReloader;
36
import eu.etaxonomy.cdm.vaadin.security.UserHelper;
37
import eu.etaxonomy.cdm.vaadin.util.CdmTitleCacheCaptionGenerator;
38
import eu.etaxonomy.cdm.vaadin.util.converter.CdmBaseDeproxyConverter;
39
import eu.etaxonomy.cdm.vaadin.view.name.CachingPresenter;
40
import eu.etaxonomy.vaadin.component.CompositeCustomField;
41
import eu.etaxonomy.vaadin.component.EntityFieldInstantiator;
42
import eu.etaxonomy.vaadin.component.SwitchableTextField;
43
import eu.etaxonomy.vaadin.component.ToManyRelatedEntitiesListSelect;
44

    
45
/**
46
 * @author a.kohlbecker
47
 * @since May 11, 2017
48
 *
49
 */
50
public class TeamOrPersonField extends CompositeCustomField<TeamOrPersonBase<?>> {
51

    
52
    private static final long serialVersionUID = 660806402243118112L;
53

    
54
    private static final String PRIMARY_STYLE = "v-team-or-person-field";
55

    
56
    private CssLayout root = new CssLayout();
57
    private CssLayout toolBar= new CssLayout();
58
    private CssLayout compositeWrapper = new CssLayout();
59

    
60
    private LazyComboBox<TeamOrPersonBase> teamOrPersonSelect = new LazyComboBox<TeamOrPersonBase>(TeamOrPersonBase.class);
61

    
62
    private Button selectConfirmButton = new Button("OK");
63
    private Button removeButton = new Button(FontAwesome.REMOVE);
64
    private Button personButton = new Button(FontAwesome.USER);
65
    private Button teamButton = new Button(FontAwesome.USERS);
66

    
67
    // Fields for case when value is a Person
68
    private PersonField personField = new PersonField();
69

    
70
    // Fields for case when value is a Team
71
    private SwitchableTextField titleField = new SwitchableTextField("Team (bibliographic)");
72
    private SwitchableTextField nomenclaturalTitleField = new SwitchableTextField("Team (nomenclatural)");
73
    private ToManyRelatedEntitiesListSelect<Person, PersonField> personsListEditor = new ToManyRelatedEntitiesListSelect<Person, PersonField>(Person.class, PersonField.class, "Teammembers");
74

    
75
    private BeanFieldGroup<Team> fieldGroup  = new BeanFieldGroup<>(Team.class);
76

    
77
    private CdmFilterablePagingProvider<AgentBase, Person> pagingProviderPerson;
78

    
79
    public TeamOrPersonField(String caption){
80

    
81
        setCaption(caption);
82

    
83
        teamOrPersonSelect.setCaptionGenerator(new CdmTitleCacheCaptionGenerator<TeamOrPersonBase>());
84

    
85

    
86
        addStyledComponent(teamOrPersonSelect);
87
        addStyledComponent(personField);
88
        addStyledComponent(titleField);
89
        addStyledComponent(nomenclaturalTitleField);
90
        addStyledComponent(personsListEditor);
91
        addStyledComponents(selectConfirmButton, removeButton, personButton, teamButton);
92

    
93

    
94
        addSizedComponent(root);
95
        addSizedComponent(compositeWrapper);
96
        addSizedComponent(personField);
97
        addSizedComponent(titleField);
98
        addSizedComponent(nomenclaturalTitleField);
99
        addSizedComponent(personsListEditor);
100

    
101
        setConverter(new CdmBaseDeproxyConverter<TeamOrPersonBase<?>>());
102

    
103
        updateToolBarButtonStates();
104
    }
105

    
106
    /**
107
     * {@inheritDoc}
108
     */
109
    @Override
110
    protected Component initContent() {
111

    
112
        teamOrPersonSelect.addValueChangeListener(e -> {
113
            selectConfirmButton.setEnabled(teamOrPersonSelect.getValue() != null);
114
        });
115
        teamOrPersonSelect.setWidthUndefined();
116

    
117
        selectConfirmButton.setEnabled(teamOrPersonSelect.getValue() != null);
118
        selectConfirmButton.addClickListener(e -> {
119
            setValue(teamOrPersonSelect.getValue());
120
            teamOrPersonSelect.clear();
121
            updateToolBarButtonStates();
122
        });
123
        removeButton.addClickListener(e -> {
124
            setValue(null);
125
            updateToolBarButtonStates();
126
        });
127
        removeButton.setDescription("Remove");
128

    
129
        personButton.addClickListener(e -> {
130
            setValue(Person.NewInstance()); // FIXME add SelectField or open select dialog, use ToOneSelect field!!
131
            updateToolBarButtonStates();
132
        });
133
        personButton.setDescription("Add person");
134
        teamButton.addClickListener(e -> {
135
            setValue(Team.NewInstance()); // FIXME add SelectField or open select dialog, use ToOneSelect field!!
136
            updateToolBarButtonStates();
137
        });
138
        teamButton.setDescription("Add team");
139

    
140
        toolBar.setStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP + " toolbar");
141
        toolBar.addComponents(teamOrPersonSelect, selectConfirmButton,  removeButton, personButton, teamButton);
142

    
143
        compositeWrapper.setStyleName("margin-wrapper");
144
        compositeWrapper.addComponent(toolBar);
145

    
146
        root.setPrimaryStyleName(PRIMARY_STYLE);
147
        root.addComponent(compositeWrapper);
148
        return root;
149
    }
150

    
151
    /**
152
     * {@inheritDoc}
153
     */
154
    @Override
155
    public Class getType() {
156
        return TeamOrPersonBase.class;
157
    }
158

    
159
    private void updateToolBarButtonStates(){
160
        TeamOrPersonBase<?> val = getInternalValue();
161
        boolean userCanCreate = UserHelper.fromSession().userHasPermission(Person.class, "CREATE");
162

    
163
        teamOrPersonSelect.setVisible(val == null);
164
        selectConfirmButton.setVisible(val == null);
165
        removeButton.setVisible(val != null);
166
        personButton.setEnabled(userCanCreate && val == null);
167
        teamButton.setEnabled(userCanCreate && val == null);
168
    }
169

    
170
    /**
171
     * {@inheritDoc}
172
     */
173
    @Override
174
    protected void setInternalValue(TeamOrPersonBase<?> newValue) {
175

    
176
        super.setInternalValue(newValue);
177

    
178
        newValue = HibernateProxyHelper.deproxy(newValue);
179

    
180
        compositeWrapper.removeAllComponents();
181
        compositeWrapper.addComponent(toolBar);
182

    
183
        if(newValue != null) {
184

    
185
            if(Person.class.isAssignableFrom(newValue.getClass())){
186
                // value is a Person:
187
                compositeWrapper.addComponent(personField);
188

    
189
                personField.setValue((Person) newValue);
190
                personField.registerParentFieldGroup(fieldGroup);
191

    
192
            }
193
            else if(Team.class.isAssignableFrom(newValue.getClass())){
194
                // otherwise it a Team
195

    
196
                compositeWrapper.addComponents(titleField, nomenclaturalTitleField, personsListEditor);
197

    
198
                titleField.bindTo(fieldGroup, "titleCache", "protectedTitleCache");
199
                nomenclaturalTitleField.bindTo(fieldGroup, "nomenclaturalTitle", "protectedNomenclaturalTitleCache");
200
                fieldGroup.setItemDataSource(new BeanItem<Team>((Team)newValue));
201
                fieldGroup.bind(personsListEditor, "teamMembers"); // here personField is set readonly since setTeamMembers does not exist
202
                personsListEditor.setReadOnly(false); // fixing the readonly state
203

    
204
                personsListEditor.registerParentFieldGroup(fieldGroup);
205

    
206
            } else {
207
                setComponentError(new UserError("TeamOrPersonField Error: Unsupported value type: " + newValue.getClass().getName()));
208
            }
209

    
210
        }
211

    
212
        updateToolBarButtonStates();
213
    }
214

    
215
    private void checkUserPermissions(TeamOrPersonBase<?> newValue) {
216
        boolean userCanEdit = UserHelper.fromSession().userHasPermission(newValue, "DELETE", "UPDATE");
217
        setEnabled(userCanEdit);
218
        personsListEditor.setEnabled(userCanEdit);
219
    }
220

    
221
    /**
222
     * {@inheritDoc}
223
     */
224
    @Override
225
    protected void addDefaultStyles() {
226
        // no default styles here
227
    }
228

    
229
    /**
230
     * {@inheritDoc}
231
     */
232
    @Override
233
    public FieldGroup getFieldGroup() {
234
        return fieldGroup;
235
    }
236

    
237
    public Component[] getCachFields(){
238
        return new Component[]{titleField, nomenclaturalTitleField};
239
    }
240

    
241
    /**
242
     * @return the teamOrPersonSelect
243
     */
244
    public LazyComboBox<TeamOrPersonBase> getTeamOrPersonSelect() {
245
        return teamOrPersonSelect;
246
    }
247

    
248
    /**
249
     * {@inheritDoc}
250
     */
251
    @SuppressWarnings("unchecked")
252
    @Override
253
    public void commit() throws SourceException, InvalidValueException {
254

    
255
        //need to commit the subfields propagation through the fielGroups is not enough
256
        personField.commit();
257
        personsListEditor.commit();
258
        super.commit();
259

    
260
        TeamOrPersonBase<?> bean = getValue();
261
        if(bean != null && bean instanceof Team){
262

    
263
            boolean isUnsaved = bean.getId() == 0;
264
            if(isUnsaved){
265
                UserHelper.fromSession().createAuthorityForCurrentUser(bean, EnumSet.of(CRUD.UPDATE, CRUD.DELETE), null);
266
            }
267
        }
268

    
269
        if(hasNullContent()){
270
            getPropertyDataSource().setValue(null);
271
            setValue(null);
272

    
273
        }
274
    }
275

    
276
    /**
277
     * {@inheritDoc}
278
     */
279
    @Override
280
    protected List<Field> nullValueCheckIgnoreFields() {
281

    
282
        List<Field> ignoreFields =  super.nullValueCheckIgnoreFields();
283
        ignoreFields.add(personField);
284
        ignoreFields.add(nomenclaturalTitleField.getUnlockSwitch());
285
        if(nomenclaturalTitleField.getUnlockSwitch().getValue().booleanValue() == false){
286
            ignoreFields.add(nomenclaturalTitleField.getTextField());
287
        }
288
        ignoreFields.add(titleField.getUnlockSwitch());
289
        if(titleField.getUnlockSwitch().getValue().booleanValue() == false){
290
            ignoreFields.add(titleField.getTextField());
291
        }
292
        return ignoreFields;
293
    }
294

    
295
    /**
296
     * {@inheritDoc}
297
     */
298
    @Override
299
    public boolean hasNullContent() {
300

    
301
        TeamOrPersonBase<?> bean = getValue();
302
        if(bean == null) {
303
            return true;
304
        }
305
        if(bean instanceof Team){
306
            // --- Team
307
            return super.hasNullContent();
308
        } else {
309
            // --- Person
310
            return personField.hasNullContent();
311
        }
312
    }
313

    
314
    public void setFilterableTeamPagingProvider(CdmFilterablePagingProvider<AgentBase, TeamOrPersonBase> pagingProvider, CachingPresenter cachingPresenter){
315
        teamOrPersonSelect.loadFrom(pagingProvider, pagingProvider, pagingProvider.getPageSize());
316
        ToOneRelatedEntityReloader<TeamOrPersonBase> teamOrPersonReloader = new ToOneRelatedEntityReloader<TeamOrPersonBase>(teamOrPersonSelect, cachingPresenter);
317
        teamOrPersonSelect.addValueChangeListener(teamOrPersonReloader );
318
    }
319

    
320
    public void setFilterablePersonPagingProvider(CdmFilterablePagingProvider<AgentBase, Person> pagingProvider, CachingPresenter cachingPresenter){
321

    
322
        teamOrPersonSelect.addValueChangeListener(new ToOneRelatedEntityReloader<TeamOrPersonBase>(teamOrPersonSelect, cachingPresenter));
323

    
324
        personsListEditor.setEntityFieldInstantiator(new EntityFieldInstantiator<PersonField>() {
325

    
326
            @Override
327
            public PersonField createNewInstance() {
328
                PersonField f = new PersonField();
329
                f.setAllowNewEmptyEntity(true); // otherwise new entities can not be added to the personsListEditor
330
                f.getPersonSelect().loadFrom(pagingProvider, pagingProvider, pagingProvider.getPageSize());
331
                f.getPersonSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<Person>());
332
                f.getPersonSelect().addValueChangeListener(new ToOneRelatedEntityReloader<Person>(f.getPersonSelect(), cachingPresenter));
333
                return f;
334
            }
335
        });
336
    }
337

    
338
}
(4-4/5)