Project

General

Profile

Download (9.83 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.vaadin.component;
10

    
11
import java.util.Objects;
12
import java.util.Optional;
13
import java.util.UUID;
14

    
15
import org.vaadin.viritin.fields.LazyComboBox.FilterableCountProvider;
16
import org.vaadin.viritin.fields.LazyComboBox.FilterablePagingProvider;
17

    
18
import com.vaadin.data.Property;
19
import com.vaadin.data.Validator.InvalidValueException;
20
import com.vaadin.data.fieldgroup.FieldGroup;
21
import com.vaadin.data.util.converter.Converter.ConversionException;
22
import com.vaadin.server.AbstractErrorMessage.ContentMode;
23
import com.vaadin.server.ErrorMessage.ErrorLevel;
24
import com.vaadin.server.UserError;
25
import com.vaadin.ui.Button;
26
import com.vaadin.ui.Button.ClickListener;
27
import com.vaadin.ui.Component;
28
import com.vaadin.ui.CssLayout;
29
import com.vaadin.ui.Field;
30
import com.vaadin.ui.themes.ValoTheme;
31

    
32
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
33
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
34
import eu.etaxonomy.cdm.service.FilterableStringRepresentationPagingProvider;
35
import eu.etaxonomy.cdm.service.UserHelperAccess;
36
import eu.etaxonomy.cdm.vaadin.component.ButtonFactory;
37
import eu.etaxonomy.cdm.vaadin.event.NestedButtonStateUpdater;
38

    
39
/**
40
 * @author a.kohlbecker
41
 * @since May 24, 2017
42
 *
43
 */
44
public class WeaklyRelatedEntityCombobox<V extends IdentifiableEntity<?>> extends CompositeCustomField<String>
45
    implements WeaklyRelatedEntityField<V>, ReloadableSelect {
46

    
47
    private static final long serialVersionUID = 6277565876657520311L;
48

    
49
    public static final String PRIMARY_STYLE = "v-related-entity-combobox";
50

    
51
    private Class<V> type;
52

    
53
    private CssLayout container = new CssLayout();
54

    
55
    private ReloadableLazyComboBox<String> lazySelect;
56

    
57
    private Button addButton = ButtonFactory.CREATE_NEW.createButton();
58
    private Button editButton = ButtonFactory.EDIT_ITEM.createButton();
59

    
60
    private WeaklyRelatedEntityButtonUpdater buttonUpdater;
61

    
62
    private FilterableStringRepresentationPagingProvider<UUID> filterablePagingProvider;
63

    
64
    public WeaklyRelatedEntityCombobox(String caption, Class<V> type){
65
        this.type = type;
66
        setCaption(caption);
67
        lazySelect = new ReloadableLazyComboBox<String>(String.class);
68
        addStyledComponents(lazySelect, addButton, editButton);
69
        addSizedComponents(lazySelect, container);
70
        buttonUpdater = new WeaklyRelatedEntityButtonUpdater(this);
71
        lazySelect.addValueChangeListener(buttonUpdater);
72
        lazySelect.setValidationVisible(true);
73
        lazySelect.addValueChangeListener(e -> {
74
            // update the itemContainer immediately so that the edit button acts on the chosen item
75
            // TODO compare with ToOneRelatedEntityCombobox where getValue() is overwritten to call
76
            //  commitSelect();; would this help in this class also?
77
            try {
78
            lazySelect.commit();
79
            } catch (InvalidValueException ie){
80
                /* Ignore here */
81
            }
82
        });
83
    }
84

    
85

    
86
    /**
87
     * {@inheritDoc}
88
     */
89
    @Override
90
    protected Component initContent() {
91
        container.addComponents(lazySelect, addButton, editButton);
92
        setPrimaryStyleName(PRIMARY_STYLE);
93
        addDefaultStyles();
94
        return container;
95
    }
96

    
97
    /**
98
     * {@inheritDoc}
99
     */
100

    
101
    @Override
102
    public Class<String> getType() {
103
        return String.class;
104
    }
105

    
106
    /**
107
     * {@inheritDoc}
108
     */
109
    @Override
110
    protected void addDefaultStyles() {
111
        container.addStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP);
112
    }
113

    
114
    /**
115
     * {@inheritDoc}
116
     */
117
    @Override
118
    public Optional<FieldGroup> getFieldGroup() {
119
        return Optional.empty();
120
    }
121

    
122
    /**
123
     * @return the select
124
     */
125
    public ReloadableLazyComboBox<String> getSelect() {
126
        return lazySelect;
127
    }
128

    
129
    /**
130
     * {@inheritDoc}
131
     */
132
    public void loadFrom(FilterablePagingProvider<String> filterablePagingProvider, FilterableCountProvider filterableCountProvider, int pageLength) {
133

    
134
        this.filterablePagingProvider = (FilterableStringRepresentationPagingProvider<UUID>) filterablePagingProvider;
135
        lazySelect.loadFrom(filterablePagingProvider, filterableCountProvider, pageLength);
136
        buttonUpdater.updateButtons(getValue());
137
    }
138

    
139
    /**
140
     * reload the selected entity from the persistent storage
141
     */
142
    @Override
143
    public void reload() {
144
        filterablePagingProvider.clearIdCache();
145
        getSelect().reload();
146
    }
147

    
148

    
149
    /**
150
     * {@inheritDoc}
151
     */
152
    @Override
153
    public void setAddButtonEnabled(boolean enabled) {
154
        addButton.setEnabled(enabled);
155
    }
156

    
157

    
158
    /**
159
     * {@inheritDoc}
160
     */
161
    @Override
162
    public void addClickListenerAddEntity(ClickListener listener) {
163
        addButton.addClickListener(listener);
164
    }
165

    
166
    /**
167
     * {@inheritDoc}
168
     */
169
    @Override
170
    public void setEditButtonEnabled(boolean enabled) {
171
        editButton.setEnabled(enabled);
172
    }
173

    
174

    
175
    /**
176
     * {@inheritDoc}
177
     */
178
    @Override
179
    public void addClickListenerEditEntity(ClickListener listener) {
180
        editButton.addClickListener(listener);
181
    }
182

    
183
    @Override
184
    public void selectNewItem(String bean){
185
        setValue(bean);
186
    }
187

    
188

    
189
    public UUID getIdForValue(){
190
        return filterablePagingProvider.idFor(getValue());
191
    }
192

    
193

    
194
    /**
195
     * sets the selection to the <code>newFieldValue</code> only if the value can
196
     * be provided by the FilterablePagingProvider
197
     *
198
     */
199
    @Override
200
    public void setValue(String newFieldValue) throws com.vaadin.data.Property.ReadOnlyException, ConversionException {
201
        if(!Objects.equals(newFieldValue, lazySelect.getValue())){
202
            if(contains(newFieldValue)){
203
                lazySelect.setValue(newFieldValue);
204
                lazySelect.markAsDirty();
205
            }
206
        }
207
    }
208

    
209
    /**
210
     * @param newFieldValue
211
     * @return
212
     */
213
    private boolean contains(String newFieldValue) {
214
        UUID id = filterablePagingProvider.idFor(newFieldValue);
215
        return id != null;
216
    }
217

    
218

    
219
    @Override
220
    public boolean isValueInOptions(){
221
        return lazySelect.getOptions().contains(lazySelect.getValue());
222
    }
223

    
224
    @Override
225
    public void setPropertyDataSource(Property newDataSource) {
226
        lazySelect.setPropertyDataSource(newDataSource);
227
        if(buttonUpdater != null){
228
            buttonUpdater.updateButtons(lazySelect.getValue());
229
        }
230
    }
231

    
232
    /**
233
     * {@inheritDoc}
234
     */
235
    @Override
236
    public Property getPropertyDataSource() {
237
        return lazySelect.getPropertyDataSource();
238
    }
239

    
240
    /**
241
     * {@inheritDoc}
242
     */
243
    @Override
244
    public void setReadOnly(boolean readOnly) {
245
        super.setReadOnly(readOnly);
246
        setDeepReadOnly(readOnly, getContent(), null);
247
        if(buttonUpdater != null){
248
         buttonUpdater.updateButtons(lazySelect.getValue());
249
        }
250
    }
251

    
252

    
253
    @Override
254
    public void setRequired(boolean required) {
255
        super.setRequired(required);
256
        lazySelect.setRequired(required);
257
    }
258

    
259
    @Override
260
    public void setImmediate(boolean immediate){
261
        super.setImmediate(immediate);
262
        lazySelect.setImmediate(immediate);
263
    }
264

    
265
    @Override
266
    public void updateButtons(){
267
        buttonUpdater.updateButtons(getValue());
268
    }
269

    
270
    @Override
271
    public void commit() throws SourceException, InvalidValueException {
272
        lazySelect.commit();
273
    }
274

    
275
    /**
276
    *
277
    */
278
   public void commitSelect() {
279
       try {
280
           setComponentError(null);
281
           lazySelect.commit();
282
       } catch (InvalidValueException ex){
283
           UserError componentError = new UserError(ex.getHtmlMessage(), ContentMode.HTML, ErrorLevel.ERROR);
284
           lazySelect.setComponentError(componentError);
285
       }
286
   }
287

    
288

    
289

    
290
    /**
291
     * {@inheritDoc}
292
     * @deprecated NestedButtonStateUpdater should rather be instantiated in the RelatedEntityField instead of passing it as property
293
     */
294
    @Override
295
    @Deprecated
296
    public void setNestedButtonStateUpdater(NestedButtonStateUpdater<V> buttonUpdater) {
297
        // not needed
298
    }
299

    
300
    class WeaklyRelatedEntityButtonUpdater implements NestedButtonStateUpdater<String> {
301

    
302
        private static final long serialVersionUID = 4472031263172275012L;
303

    
304
        WeaklyRelatedEntityCombobox<V>  toOneRelatedEntityField;
305

    
306
        public WeaklyRelatedEntityButtonUpdater(WeaklyRelatedEntityCombobox<V> toOneRelatedEntityField){
307
            this.toOneRelatedEntityField = toOneRelatedEntityField;
308
            String stringValue = toOneRelatedEntityField.getValue();
309
            updateButtons(toOneRelatedEntityField.getValue());
310
            toOneRelatedEntityField.setEditButtonEnabled(false);
311
        }
312

    
313

    
314
        /**
315
         * {@inheritDoc}
316
         */
317
        @Override
318
        public void valueChange(com.vaadin.data.Property.ValueChangeEvent event) {
319

    
320
            String value = (String)event.getProperty().getValue();
321
            updateButtons(value);
322
        }
323

    
324
        /**
325
         * @param value
326
         */
327
        @Override
328
        public void updateButtons(String value) {
329

    
330
            UUID uuid = null;
331
            if(value != null && filterablePagingProvider != null){
332
                uuid = filterablePagingProvider.idFor(value);
333
            }
334
            boolean userIsAllowedToUpdate = uuid != null && UserHelperAccess.userHelper().userHasPermission(type, uuid, CRUD.UPDATE);
335
            boolean userIsAllowedToCreate = UserHelperAccess.userHelper().userHasPermission(type, CRUD.CREATE);
336
            boolean isReadOnlyField = ((Field)toOneRelatedEntityField).isReadOnly();
337

    
338
            toOneRelatedEntityField.setAddButtonEnabled(!isReadOnlyField && userIsAllowedToCreate);
339
            toOneRelatedEntityField.setEditButtonEnabled(!isReadOnlyField && userIsAllowedToUpdate);
340
        }
341
    }
342

    
343
}
(18-18/19)