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.cms.i18n.I18nContentSupport;
37 import info.magnolia.objectfactory.ComponentProvider;
38 import info.magnolia.ui.api.app.SubAppContext;
39 import info.magnolia.ui.api.context.UiContext;
40 import info.magnolia.ui.api.i18n.I18NAuthoringSupport;
41 import info.magnolia.ui.api.view.View;
42 import info.magnolia.ui.form.Form;
43 import info.magnolia.ui.form.FormItem;
44 import info.magnolia.ui.form.FormTab;
45 import info.magnolia.ui.form.definition.FormDefinition;
46 import info.magnolia.ui.form.definition.TabDefinition;
47 import info.magnolia.ui.form.field.definition.CompositeFieldDefinition;
48 import info.magnolia.ui.form.field.definition.ConfiguredFieldDefinition;
49 import info.magnolia.ui.form.field.definition.FieldDefinition;
50 import info.magnolia.ui.form.field.definition.MultiValueFieldDefinition;
51 import info.magnolia.ui.form.field.factory.FieldFactory;
52 import info.magnolia.ui.form.field.factory.FieldFactoryFactory;
53 import info.magnolia.ui.vaadin.form.FormViewReduced;
54 import info.magnolia.ui.vaadin.richtext.TextAreaStretcher;
55
56 import java.util.Iterator;
57 import java.util.List;
58 import java.util.Locale;
59
60 import javax.inject.Inject;
61
62 import org.apache.commons.lang3.StringUtils;
63 import org.vaadin.aceeditor.AceEditor;
64 import org.vaadin.openesignforms.ckeditor.CKEditorTextField;
65
66 import com.vaadin.data.Item;
67 import com.vaadin.ui.AbstractComponent;
68 import com.vaadin.ui.AbstractField;
69 import com.vaadin.ui.Component;
70 import com.vaadin.ui.CssLayout;
71 import com.vaadin.ui.Field;
72 import com.vaadin.ui.TextArea;
73
74
75
76
77 public class FormBuilder {
78
79 private final FieldFactoryFactory fieldFactoryFactory;
80 private final I18NAuthoringSupport i18nAuthoringSupport;
81 private final UiContext uiContext;
82 private final ComponentProvider componentProvider;
83
84 @Inject
85 public FormBuilder(FieldFactoryFactory fieldFactoryFactory, I18NAuthoringSupport i18nAuthoringSupport, UiContext uiContext, ComponentProvider componentProvider) {
86 this.fieldFactoryFactory = fieldFactoryFactory;
87 this.i18nAuthoringSupport = i18nAuthoringSupport;
88 this.uiContext = uiContext;
89 this.componentProvider = componentProvider;
90 }
91
92
93
94
95 @Deprecated
96 public FormBuilder(FieldFactoryFactory fieldFactoryFactory, I18NAuthoringSupport i18nAuthoringSupport, ComponentProvider componentProvider) {
97 this(fieldFactoryFactory, i18nAuthoringSupport, componentProvider.getComponent(UiContext.class), componentProvider);
98 }
99
100
101
102
103 @Deprecated
104 public FormBuilder(FieldFactoryFactory fieldFactoryFactory, I18nContentSupport i18nContentSupport, I18NAuthoringSupport i18nAuthoringSupport, ComponentProvider componentProvider) {
105 this(fieldFactoryFactory, i18nAuthoringSupport, componentProvider.getComponent(UiContext.class), componentProvider);
106 }
107
108
109
110
111 public void buildForm(FormView view, FormDefinition formDefinition, Item item, FormItem parent) {
112 final String description = formDefinition.getDescription();
113 final String label = formDefinition.getLabel();
114
115
116
117
118
119 if (StringUtils.isNotBlank(description) && !isMessageKey(description)) {
120 view.setDescription(description);
121 }
122
123 if (StringUtils.isNotBlank(label) && !isMessageKey(label)) {
124 view.setCaption(label);
125 }
126
127 buildReducedForm(formDefinition, view, item, parent);
128
129 if (hasI18nAwareFields(formDefinition)) {
130 List<Locale> locales = i18nAuthoringSupport.getAvailableLocales(item);
131 view.setAvailableLocales(locales);
132
133 if (uiContext instanceof SubAppContext && ((SubAppContext) uiContext).getAuthoringLocale() != null) {
134 view.setCurrentLocale(((SubAppContext) uiContext).getAuthoringLocale());
135 } else {
136 view.setCurrentLocale(i18nAuthoringSupport.getDefaultLocale(item));
137 }
138 }
139 }
140
141 public View buildView(FormDefinition formDefinition, Item item) {
142
143 final CssLayout view = new CssLayout();
144 view.setSizeFull();
145
146 for (TabDefinition tabDefinition : formDefinition.getTabs()) {
147 List<FieldDefinition> fields = tabDefinition.getFields();
148 if (fields.size() == 0) {
149 continue;
150 }
151 for (final FieldDefinition fieldDefinition : fields) {
152 final FieldFactory formField = fieldFactoryFactory.createFieldFactory(fieldDefinition, item);
153 if (formField == null) {
154 continue;
155 }
156 formField.setComponentProvider(componentProvider);
157
158 final View fieldView = formField.getView();
159
160 view.addComponent(fieldView.asVaadinComponent());
161
162 }
163 }
164 return new View() {
165 @Override
166 public Component asVaadinComponent() {
167 return view;
168 }
169 };
170 }
171
172 public void buildReducedForm(FormDefinition formDefinition, FormViewReduced view, Item item, FormItem parent) {
173 final Form form = new Form(formDefinition);
174 form.setParent(parent);
175 view.setItemDataSource(item);
176
177 boolean firstFieldIsBuilt = false;
178
179 for (TabDefinition tabDefinition : formDefinition.getTabs()) {
180 FormTab tab = buildFormTab(tabDefinition, item, form);
181 if (tab == null) continue;
182
183 Iterator<Component> fieldIt = tab.getContainer().iterator();
184 while (fieldIt.hasNext()) {
185 view.addField((Field<?>) fieldIt.next());
186 }
187
188 fieldIt = tab.getContainer().iterator();
189 if (!firstFieldIsBuilt && fieldIt.hasNext()) {
190 ((Component.Focusable) fieldIt.next()).focus();
191 firstFieldIsBuilt = true;
192 }
193
194 view.addFormSection(tabDefinition.getLabel(), tab.getContainer());
195 }
196 view.setShowAllEnabled(view.getFormSections().size() > 1);
197 }
198
199 public FormTab buildFormTab(TabDefinition tabDefinition, Item itemDatasource, Form parentForm) {
200 List<FieldDefinition> fields = tabDefinition.getFields();
201 if (fields == null || fields.isEmpty()) {
202 return null;
203 }
204 FormTab tab = new FormTab(tabDefinition);
205 tab.setParent(parentForm);
206 tab.getContainer().setName(tabDefinition.getName());
207 for (final FieldDefinition fieldDefinition : fields) {
208 final Field<?> field = createField(fieldDefinition, itemDatasource, tab);
209 if (field != null) {
210 tab.addField(field);
211 final String helpDescription = fieldDefinition.getDescription();
212 if (StringUtils.isNotBlank(helpDescription) && !isMessageKey(helpDescription)) {
213 tab.setComponentHelpDescription(field, helpDescription);
214 }
215 }
216 }
217 return tab;
218 }
219
220 public Field<?> createField(FieldDefinition fieldDefinition, Item itemDatasource, FormTab parentTab) {
221 final FieldFactory fieldFactory = fieldFactoryFactory.createFieldFactory(fieldDefinition, itemDatasource);
222 if (fieldFactory == null) {
223 return null;
224 }
225
226 fieldFactory.setComponentProvider(componentProvider);
227 if (parentTab != null) {
228 fieldFactory.setParent(parentTab);
229 }
230
231 final Field<?> field = fieldFactory.createField();
232 if (field instanceof AbstractComponent) {
233 ((AbstractComponent) field).setImmediate(true);
234 }
235
236
237 if (field instanceof AbstractField) {
238 ((AbstractField) field).setValidationVisible(false);
239 }
240
241 if (field instanceof TextArea || field instanceof CKEditorTextField || field instanceof AceEditor) {
242 TextAreaStretcher.extend(field);
243 }
244
245 return field;
246 }
247
248 private boolean hasI18nAwareFields(FormDefinition formDefinition) {
249
250 for (TabDefinition tab : formDefinition.getTabs()) {
251 for (FieldDefinition field : tab.getFields()) {
252 if (isI18nAware(field)) {
253 return true;
254 }
255 }
256 }
257 return false;
258 }
259
260 private boolean isI18nAware(FieldDefinition field) {
261 if (field.isI18n()) {
262 return true;
263 }
264 if (field instanceof CompositeFieldDefinition) {
265 for (ConfiguredFieldDefinition configuredFieldDefinition : ((CompositeFieldDefinition) field).getFields()) {
266 if (isI18nAware(configuredFieldDefinition)) {
267 return true;
268 }
269 }
270 } else if (field instanceof MultiValueFieldDefinition) {
271 field = ((MultiValueFieldDefinition) field).getField();
272 return isI18nAware(field);
273 }
274 return false;
275 }
276
277
278
279
280 @Deprecated
281 private boolean isMessageKey(final String text) {
282 return !text.contains(" ") && text.contains(".") && !text.endsWith(".");
283 }
284 }