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