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.Collections;
51 import java.util.Iterator;
52 import java.util.List;
53 import java.util.Locale;
54 import java.util.Map;
55 import java.util.Objects;
56 import java.util.Optional;
57
58 import javax.inject.Inject;
59
60 import org.apache.commons.lang3.ObjectUtils;
61 import org.apache.commons.lang3.StringUtils;
62
63 import com.google.common.collect.Maps;
64 import com.vaadin.ui.Component;
65 import com.vaadin.v7.data.Item;
66 import com.vaadin.v7.ui.Field;
67
68
69
70
71
72
73
74
75
76
77
78
79
80 public class FormPresenterImpl implements FormPresenter {
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 cachedTabs.clear();
120 activeLocale = getInitialActiveLocale(uiContext, item);
121
122 buildForm((FormView) this.formView, formDefinition, item, parent, activeLocale);
123
124
125 if (uiContext instanceof SubAppContext) {
126 formView.setListener(newLocale -> {
127 if (newLocale != null && !ObjectUtils.equals(((SubAppContext) uiContext).getAuthoringLocale(), newLocale)) {
128 setLocale(newLocale);
129 }
130 });
131 }
132 }
133
134 @Override
135 public boolean isValid() {
136 return formView.isValid();
137 }
138
139 @Override
140 public void setLocale(Locale locale) {
141 if (uiContext instanceof SubAppContext && !ObjectUtils.equals(locale, this.activeLocale)) {
142 this.activeLocale = locale;
143 ((SubAppContext) uiContext).setAuthoringLocale(locale);
144 updateForm(locale);
145 }
146 }
147
148 protected void updateForm(Locale locale) {
149 List<FormSection> formSections = formView.getFormSections();
150 for (FormSection formSection : formSections) {
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 formSection.setCaption(tabDefinition.getLabel());
161 for (FieldDefinition fieldDefinition : tabDefinition.getFields()) {
162 Field<?> field = formBuilder.createField(fieldDefinition, itemDatasource, formTab);
163 if (field != null) {
164 formSection.addComponent(field);
165 final String helpDescription = fieldDefinition.getDescription();
166 if (StringUtils.isNotBlank(helpDescription) && !formBuilder.isMessageKey(helpDescription)) {
167 formSection.setComponentHelpDescription(field, helpDescription);
168 }
169 }
170 }
171 }
172 }
173
174 if (formView instanceof ResurfaceFormViewImpl) {
175 ((ResurfaceFormViewImpl) formView).updateFormView(formSections);
176 }
177 }
178
179 private void buildForm(FormView view, FormDefinition formDefinition, Item item, FormItem parent, Locale locale) {
180 final String description = formDefinition.getDescription();
181 final String label = formDefinition.getLabel();
182
183
184
185
186
187 if (StringUtils.isNotBlank(description) && !formBuilder.isMessageKey(description)) {
188 view.setDescription(description);
189 }
190
191 if (StringUtils.isNotBlank(label) && !formBuilder.isMessageKey(label)) {
192 view.setCaption(label);
193 }
194
195 setFormViewLocale(view, item);
196 buildReducedForm(formDefinition, view, item, parent);
197 }
198
199 private void buildReducedForm(FormDefinition formDefinition, FormViewReduced view, Item item, FormItem parent) {
200 final Form/Form.html#Form">Form form = new Form(formDefinition);
201 form.setParent(parent);
202 view.setItemDataSource(item);
203
204 boolean firstFieldIsBuilt = false;
205
206 for (TabDefinition tabDefinition : formDefinition.getTabs()) {
207 FormTab tab = buildFormTab(tabDefinition, item, form);
208 if (tab == null) continue;
209
210 Iterator<Component> fieldIt = tab.getContainer().iterator();
211 while (fieldIt.hasNext()) {
212 view.addField((Field<?>) fieldIt.next());
213 }
214
215 fieldIt = tab.getContainer().iterator();
216 if (!firstFieldIsBuilt && fieldIt.hasNext()) {
217 ((Component.Focusable) fieldIt.next()).focus();
218 firstFieldIsBuilt = true;
219 }
220
221 view.addFormSection(tabDefinition.getLabel(), tab.getContainer());
222 cachedTabs.put(tabDefinition.getName(), tab);
223 }
224 view.setShowAllEnabled(view.getFormSections().size() > 1);
225 }
226
227 private FormTab buildFormTab(TabDefinition tabDefinition, Item itemDatasource, Form parentForm) {
228 List<FieldDefinition> fields = tabDefinition.getFields();
229 if (fields == null || fields.isEmpty()) {
230 return null;
231 }
232 FormTabormTab.html#FormTab">FormTab tab = new FormTab(tabDefinition);
233 tab.setParent(parentForm);
234 tab.getContainer().setName(tabDefinition.getName());
235 for (final FieldDefinition fieldDefinition : fields) {
236 Field<?> field = formBuilder.createField(fieldDefinition, itemDatasource, tab);
237 if (field != null) {
238 tab.addField(field);
239 final String helpDescription = fieldDefinition.getDescription();
240 if (StringUtils.isNotBlank(helpDescription) && !formBuilder.isMessageKey(helpDescription)) {
241 tab.setComponentHelpDescription(field, helpDescription);
242 }
243 }
244 }
245 return tab;
246 }
247
248
249
250
251 private Locale getInitialActiveLocale(UiContext uiContext, Item item) {
252 if (uiContext instanceof SubAppContext) {
253 Locale authoringLocale = ((SubAppContext) uiContext).getAuthoringLocale();
254 Optional<Locale> locale = Optional.ofNullable(i18nAuthoringSupport.getAvailableLocales(item))
255 .orElse(Collections.emptyList())
256 .stream()
257 .filter(Objects::nonNull)
258 .filter(l -> l.equals(authoringLocale))
259 .findFirst();
260 if (locale.isPresent()) {
261 return authoringLocale;
262 } else {
263 return i18nAuthoringSupport.getDefaultLocale(item);
264 }
265 }
266 return i18nAuthoringSupport.getDefaultLocale(item);
267 }
268
269 private void setFormViewLocale(FormView view, Item item) {
270 if (formBuilder.hasI18nAwareFields(formDefinition)) {
271 view.setAvailableLocales(i18nAuthoringSupport.getAvailableLocales(item));
272 view.setCurrentLocale(activeLocale);
273 }
274 }
275 }