1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.ui.editor;
35
36 import info.magnolia.objectfactory.ComponentProvider;
37 import info.magnolia.ui.datasource.PropertySetFactory;
38 import info.magnolia.ui.field.FieldBinder;
39 import info.magnolia.ui.field.UploadField;
40 import info.magnolia.ui.field.UploadFieldDefinition;
41 import info.magnolia.ui.field.factory.AbstractFieldFactory;
42 import info.magnolia.ui.field.factory.HiddenFieldFactory;
43 import info.magnolia.ui.vaadin.form.field.FieldLayout;
44
45 import java.io.File;
46 import java.util.Collections;
47 import java.util.HashMap;
48 import java.util.List;
49 import java.util.Map;
50 import java.util.Optional;
51
52 import javax.inject.Inject;
53
54 import org.apache.jackrabbit.JcrConstants;
55
56 import com.vaadin.data.Binder;
57 import com.vaadin.data.BinderValidationStatus;
58 import com.vaadin.data.HasValue;
59 import com.vaadin.data.PropertySet;
60 import com.vaadin.server.ClientConnector;
61 import com.vaadin.ui.Component;
62 import com.vaadin.ui.Composite;
63
64
65
66
67
68
69
70 public class UploadView<T> extends Composite implements EditorView<T>, Component.Focusable {
71
72 private static final String WIDTH = "width";
73 private static final String HEIGHT = "height";
74 private static final String FILE_NAME = "fileName";
75
76 private final UploadField uploadField;
77 private final Binder<T> binder;
78
79 @Inject
80 public UploadView(UploadViewDefinition<T> definition,
81 PropertySetFactory<T> propertySetFactory,
82 HiddenFieldFactory hiddenFieldFactory,
83 ComponentProvider componentProvider) {
84
85 UploadFieldDefinitioneldDefinition">UploadFieldDefinition uploadFieldDefinition = new UploadFieldDefinition();
86 uploadFieldDefinition.setRequiredErrorMessage(definition.getRequiredErrorMessage());
87 uploadFieldDefinition.setRequired(definition.isRequired());
88 uploadFieldDefinition.setValidators(definition.getValidators());
89 uploadFieldDefinition.setConverterClass(definition.getConverterClass());
90
91 Class<? extends AbstractFieldFactory<File, ? extends UploadFieldDefinition>> factoryClass = definition.getFactoryClass();
92 uploadField = (UploadField) componentProvider.newInstance(factoryClass).createField();
93
94 Map<String, Class> properties = new HashMap<>();
95 properties.put(WIDTH, Integer.class);
96 properties.put(HEIGHT, Integer.class);
97 properties.put(FILE_NAME, String.class);
98 properties.put(JcrConstants.JCR_DATA, File.class);
99
100
101 PropertySet<T> propertySet = propertySetFactory.withProperties(properties);
102 binder = Binder.withPropertySet(propertySet);
103 binder.forField(hiddenFieldFactory.createField()).bind(WIDTH);
104 binder.forField(hiddenFieldFactory.createField()).bind(HEIGHT);
105 binder.forField(hiddenFieldFactory.createField()).bind(FILE_NAME);
106
107 Binder.BindingBuilder<T, File> uploadFieldBinder = binder.forField(uploadField);
108 if (definition.isRequired()) {
109 final String errorMessage = definition.getRequiredErrorMessage();
110 uploadFieldBinder.asRequired();
111 uploadFieldBinder
112 .withValidationStatusHandler(statusChange -> findParent(uploadField, FieldLayout.class)
113 .ifPresent(fieldLayout -> fieldLayout.getValidationStatusHandler().accept(statusChange.isError() ? errorMessage : "")));
114 }
115
116 new FieldBinder.Default<File>(componentProvider).configureBinding(uploadFieldDefinition, uploadFieldBinder);
117 uploadFieldBinder.bind(JcrConstants.JCR_DATA);
118
119 uploadField.addValueChangeListener(event -> uploadField.getFileInfo().ifPresent(this::updateProperties));
120
121 setCompositionRoot(uploadField);
122 }
123
124 private <V extends Component> Optional<V> findParent(Component field, Class<V> parentClass) {
125 ClientConnector connector = field;
126 while (connector != null) {
127 if (parentClass.isInstance(connector)) {
128 return Optional.of((V) connector);
129 }
130 connector = connector.getParent();
131 }
132 return Optional.empty();
133 }
134
135 private void updateProperties(UploadField.FileInfo fileInfo) {
136 setPropertyValue(FILE_NAME, fileInfo.getName());
137 fileInfo.getImageInfo().ifPresent(imageInfo -> {
138 setPropertyValue(WIDTH, imageInfo.getWidth());
139 setPropertyValue(HEIGHT, imageInfo.getHeight());
140 });
141 }
142
143 private void setPropertyValue(String propertyName, Object value) {
144 binder.getBinding(propertyName)
145 .map(Binder.Binding::getField)
146 .ifPresent(field -> ((HasValue) field).setValue(value));
147 }
148
149 @Override
150 public List<BinderValidationStatus<?>> validate() {
151 return Collections.singletonList(binder.validate());
152 }
153
154 @Override
155 public void populate(T item) {
156 binder.readBean(item);
157 }
158
159 @Override
160 public void write(T item) {
161 binder.writeBeanIfValid(item);
162 }
163
164 @Override
165 public void focus() {
166 uploadField.focus();
167 }
168
169 @Override
170 public int getTabIndex() {
171 return 0;
172 }
173
174 @Override
175 public void setTabIndex(int tabIndex) {
176
177 }
178 }