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.dialog.formdialog;
35
36 import info.magnolia.objectfactory.Components;
37 import info.magnolia.ui.api.app.SubAppContext;
38 import info.magnolia.ui.api.context.UiContext;
39 import info.magnolia.ui.api.i18n.I18NAuthoringSupport;
40 import info.magnolia.ui.form.Form;
41 import info.magnolia.ui.form.FormItem;
42 import info.magnolia.ui.form.FormPresenter;
43 import info.magnolia.ui.form.FormTab;
44 import info.magnolia.ui.form.definition.FormDefinition;
45 import info.magnolia.ui.form.definition.TabDefinition;
46 import info.magnolia.ui.form.field.definition.FieldDefinition;
47 import info.magnolia.ui.vaadin.form.FormSection;
48 import info.magnolia.ui.vaadin.form.FormViewReduced;
49
50 import java.util.Iterator;
51 import java.util.List;
52 import java.util.Locale;
53 import java.util.Map;
54 import java.util.Optional;
55
56 import javax.inject.Inject;
57
58 import org.apache.commons.lang3.ObjectUtils;
59 import org.apache.commons.lang3.StringUtils;
60
61 import com.google.common.collect.Maps;
62 import com.vaadin.ui.Component;
63 import com.vaadin.v7.data.Item;
64 import com.vaadin.v7.ui.Field;
65
66
67
68
69
70
71
72
73
74
75
76
77
78 public class FormPresenterImpl implements FormPresenter {
79
80 private final Map<String, Field<?>> cachedFields = Maps.newHashMap();
81
82 private final Map<String, FormTab> cachedTabs = Maps.newHashMap();
83
84 private final I18NAuthoringSupport i18nAuthoringSupport;
85
86 private final FormBuilder formBuilder;
87
88 private final UiContext uiContext;
89
90 private FormDefinition formDefinition;
91
92 private FormViewReduced formView;
93
94 private Locale activeLocale;
95
96 private Item itemDatasource;
97
98 @Inject
99 public FormPresenterImpl(FormBuilder formBuilder, UiContext uiContext, I18NAuthoringSupport i18nAuthoringSupport) {
100 this.i18nAuthoringSupport = i18nAuthoringSupport;
101 this.formBuilder = formBuilder;
102 this.uiContext = uiContext;
103 }
104
105
106
107
108 @Deprecated
109 public FormPresenterImpl(FormBuilder formBuilder, UiContext uiContext) {
110 this(formBuilder, uiContext, Components.getComponent(I18NAuthoringSupport.class));
111 }
112
113 @Override
114 public void presentView(FormViewReduced formView, FormDefinition formDefinition, Item item, FormItem parent) {
115 this.formView = formView;
116 this.itemDatasource = item;
117 this.formDefinition = formDefinition;
118
119 cachedFields.clear();
120 cachedTabs.clear();
121 activeLocale = getCurrentAuthoringLocale(uiContext, item);
122
123 buildForm((FormView) this.formView, formDefinition, item, parent, activeLocale);
124
125
126 if (uiContext instanceof SubAppContext) {
127 formView.setListener(newLocale -> {
128 if (newLocale != null && !ObjectUtils.equals(((SubAppContext) uiContext).getAuthoringLocale(), newLocale)) {
129 setLocale(newLocale);
130 }
131 });
132 }
133 }
134
135 @Override
136 public boolean isValid() {
137 return formView.isValid();
138 }
139
140 @Override
141 public void setLocale(Locale locale) {
142 if (uiContext instanceof SubAppContext && !ObjectUtils.equals(locale, this.activeLocale)) {
143 this.activeLocale = locale;
144 ((SubAppContext) uiContext).setAuthoringLocale(locale);
145 updateForm(locale);
146 }
147 }
148
149 protected void updateForm(Locale locale) {
150 for (FormSection formSection : formView.getFormSections()) {
151 String tabName = formSection.getName();
152 Optional<TabDefinition> matchingTab = formDefinition.getTabs().stream()
153 .filter(tabDefinition -> tabDefinition.getName().equals(tabName))
154 .findFirst();
155
156 if (matchingTab.isPresent()) {
157 TabDefinition tabDefinition = matchingTab.get();
158 FormTab formTab = cachedTabs.get(tabDefinition.getName());
159 formSection.removeAllComponents();
160 for (FieldDefinition fieldDefinition : tabDefinition.getFields()) {
161 Field<?> field = getCachedField(fieldDefinition, locale);
162 if (field == null) {
163 field = createField(fieldDefinition, itemDatasource, formTab, locale);
164 putToCache(fieldDefinition, field, locale);
165 }
166 if (field != null) {
167 formSection.addComponent(field);
168 }
169 }
170 }
171 }
172 }
173
174 private void buildForm(FormView view, FormDefinition formDefinition, Item item, FormItem parent, Locale locale) {
175 final String description = formDefinition.getDescription();
176 final String label = formDefinition.getLabel();
177
178
179
180
181
182 if (StringUtils.isNotBlank(description) && !formBuilder.isMessageKey(description)) {
183 view.setDescription(description);
184 }
185
186 if (StringUtils.isNotBlank(label) && !formBuilder.isMessageKey(label)) {
187 view.setCaption(label);
188 }
189
190 buildReducedForm(formDefinition, view, item, parent, locale);
191
192 if (formBuilder.hasI18nAwareFields(formDefinition)) {
193 view.setAvailableLocales(i18nAuthoringSupport.getAvailableLocales(item));
194 view.setCurrentLocale(locale);
195 }
196 }
197
198 private void buildReducedForm(FormDefinition formDefinition, FormViewReduced view, Item item, FormItem parent, Locale locale) {
199 final Form form = new Form(formDefinition);
200 form.setParent(parent);
201 view.setItemDataSource(item);
202
203 boolean firstFieldIsBuilt = false;
204
205 for (TabDefinition tabDefinition : formDefinition.getTabs()) {
206 FormTab tab = buildFormTab(tabDefinition, item, form, locale);
207 if (tab == null) continue;
208
209 Iterator<Component> fieldIt = tab.getContainer().iterator();
210 while (fieldIt.hasNext()) {
211 view.addField((Field<?>) fieldIt.next());
212 }
213
214 fieldIt = tab.getContainer().iterator();
215 if (!firstFieldIsBuilt && fieldIt.hasNext()) {
216 ((Component.Focusable) fieldIt.next()).focus();
217 firstFieldIsBuilt = true;
218 }
219
220 view.addFormSection(tabDefinition.getLabel(), tab.getContainer());
221 cachedTabs.put(tabDefinition.getName(), tab);
222 }
223 view.setShowAllEnabled(view.getFormSections().size() > 1);
224 }
225
226 private FormTab buildFormTab(TabDefinition tabDefinition, Item itemDatasource, Form parentForm, Locale locale) {
227 List<FieldDefinition> fields = tabDefinition.getFields();
228 if (fields == null || fields.isEmpty()) {
229 return null;
230 }
231 FormTab tab = new FormTab(tabDefinition);
232 tab.setParent(parentForm);
233 tab.getContainer().setName(tabDefinition.getName());
234 for (final FieldDefinition fieldDefinition : fields) {
235
236 Field<?> field = getCachedField(fieldDefinition, locale);
237 if (field == null) {
238 field = createField(fieldDefinition, itemDatasource, tab, locale);
239 }
240
241 if (field != null) {
242 tab.addField(field);
243 final String helpDescription = fieldDefinition.getDescription();
244 if (StringUtils.isNotBlank(helpDescription) && !formBuilder.isMessageKey(helpDescription)) {
245 tab.setComponentHelpDescription(field, helpDescription);
246 }
247 }
248 }
249 return tab;
250 }
251
252
253
254
255 private Locale getCurrentAuthoringLocale(UiContext uiContext, Item item) {
256 if (uiContext instanceof SubAppContext && ((SubAppContext) uiContext).getAuthoringLocale() != null) {
257 return ((SubAppContext) uiContext).getAuthoringLocale();
258 } else {
259 return i18nAuthoringSupport.getDefaultLocale(item);
260 }
261 }
262
263
264
265
266 private Field<?> createField(FieldDefinition fieldDefinition, Item item, FormTab parentTab, Locale locale) {
267 Field<?> field = formBuilder.createField(fieldDefinition, item, parentTab);
268
269 if (field != null) {
270 String cachedFieldName = getCachedFieldName(fieldDefinition, locale);
271 cachedFields.put(cachedFieldName, field);
272 }
273 return field;
274 }
275
276 private String getCachedFieldName(FieldDefinition fieldDefinition, Locale locale) {
277 if (!formBuilder.isI18nAware(fieldDefinition) || locale == null) {
278 return fieldDefinition.getName();
279 }
280 String cachedFieldName = fieldDefinition.getName() + "_" + locale.getDisplayLanguage();
281 if (!locale.getDisplayCountry().isEmpty()) {
282 cachedFieldName += "_" + locale.getDisplayCountry();
283 }
284
285 return cachedFieldName;
286 }
287
288 private Field<?> getCachedField(FieldDefinition fieldDefinition, Locale locale) {
289 return cachedFields.get(getCachedFieldName(fieldDefinition, locale));
290 }
291
292 private void putToCache(FieldDefinition fieldDefinition, Field<?> field, Locale locale) {
293 cachedFields.put(getCachedFieldName(fieldDefinition, locale), field);
294 }
295 }