1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.primefaces.extensions.component.dynaform;
23
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.Map;
27
28 import javax.faces.FacesException;
29 import javax.faces.application.ResourceDependency;
30 import javax.faces.component.ContextCallback;
31 import javax.faces.component.UIComponent;
32 import javax.faces.component.UINamingContainer;
33 import javax.faces.component.visit.VisitCallback;
34 import javax.faces.component.visit.VisitContext;
35 import javax.faces.context.FacesContext;
36 import javax.faces.event.PhaseId;
37
38 import org.primefaces.component.api.Widget;
39 import org.primefaces.extensions.component.base.AbstractDynamicData;
40 import org.primefaces.extensions.model.common.KeyData;
41 import org.primefaces.extensions.model.dynaform.DynaFormControl;
42 import org.primefaces.extensions.model.dynaform.DynaFormModel;
43
44
45
46
47
48
49
50
51 @ResourceDependency(library = "primefaces", name = "jquery/jquery.js")
52 @ResourceDependency(library = "primefaces", name = "jquery/jquery-plugins.js")
53 @ResourceDependency(library = "primefaces", name = "core.js")
54 @ResourceDependency(library = "primefaces-extensions", name = "primefaces-extensions.js")
55 @ResourceDependency(library = "primefaces-extensions", name = "dynaform/dynaform.css")
56 @ResourceDependency(library = "primefaces-extensions", name = "dynaform/dynaform.js")
57 public class DynaForm extends AbstractDynamicData implements Widget {
58
59 public static final String COMPONENT_TYPE = "org.primefaces.extensions.component.DynaForm";
60 public static final String COMPONENT_FAMILY = "org.primefaces.extensions.component";
61 private static final String DEFAULT_RENDERER = "org.primefaces.extensions.component.DynaFormRenderer";
62
63 private Map<String, UIDynaFormControl> cells;
64
65
66
67
68
69
70
71 @SuppressWarnings("java:S115")
72 protected enum PropertyKeys {
73
74 widgetVar,
75 autoSubmit,
76 openExtended,
77 buttonBarPosition,
78 style,
79 styleClass,
80 columnClasses
81
82 }
83
84 public DynaForm() {
85 setRendererType(DEFAULT_RENDERER);
86 }
87
88 @Override
89 public String getFamily() {
90 return COMPONENT_FAMILY;
91 }
92
93 public String getWidgetVar() {
94 return (String) getStateHelper().eval(PropertyKeys.widgetVar, null);
95 }
96
97 public void setWidgetVar(final String widgetVar) {
98 getStateHelper().put(PropertyKeys.widgetVar, widgetVar);
99 }
100
101 public boolean isAutoSubmit() {
102 return (Boolean) getStateHelper().eval(PropertyKeys.autoSubmit, false);
103 }
104
105 public void setAutoSubmit(final boolean autoSubmit) {
106 getStateHelper().put(PropertyKeys.autoSubmit, autoSubmit);
107 }
108
109 public boolean isOpenExtended() {
110 return (Boolean) getStateHelper().eval(PropertyKeys.openExtended, false);
111 }
112
113 public void setOpenExtended(final boolean openExtended) {
114 getStateHelper().put(PropertyKeys.openExtended, openExtended);
115 }
116
117 public String getButtonBarPosition() {
118 return (String) getStateHelper().eval(PropertyKeys.buttonBarPosition, "bottom");
119 }
120
121 public void setButtonBarPosition(final String buttonBarPosition) {
122 getStateHelper().put(PropertyKeys.buttonBarPosition, buttonBarPosition);
123 }
124
125 public void setStyle(final String style) {
126 getStateHelper().put(PropertyKeys.style, style);
127 }
128
129 public String getStyle() {
130 return (String) getStateHelper().eval(PropertyKeys.style, null);
131 }
132
133 public void setStyleClass(final String styleClass) {
134 getStateHelper().put(PropertyKeys.styleClass, styleClass);
135 }
136
137 public String getStyleClass() {
138 return (String) getStateHelper().eval(PropertyKeys.styleClass, null);
139 }
140
141 public void setColumnClasses(java.lang.String columnClasses) {
142 getStateHelper().put(PropertyKeys.columnClasses, columnClasses);
143 }
144
145 public java.lang.String getColumnClasses() {
146 return (java.lang.String) getStateHelper().eval(PropertyKeys.columnClasses, null);
147 }
148
149 public UIDynaFormControl getControlCell(final String type) {
150 final UIDynaFormControl cell = getControlCells().get(type);
151
152 if (cell == null) {
153 throw new FacesException("UIDynaFormControl to type " + type + " was not found");
154 }
155 else {
156 return cell;
157 }
158 }
159
160 protected Map<String, UIDynaFormControl> getControlCells() {
161 if (cells == null) {
162 cells = new HashMap<>();
163 for (final UIComponent child : getChildren()) {
164 if (child instanceof UIDynaFormControl) {
165 final UIDynaFormControl dynaFormCell = (UIDynaFormControl) child;
166 cells.put(dynaFormCell.getType(), dynaFormCell);
167 }
168 }
169 }
170
171 return cells;
172 }
173
174 protected static void checkModelInstance(Object value) {
175 if (!(value instanceof DynaFormModel)) {
176 throw new FacesException("Value in DynaForm must be of type DynaFormModel");
177 }
178 }
179
180 @Override
181 protected KeyData findData(final String key) {
182 final Object value = getValue();
183 if (value == null) {
184 return null;
185 }
186
187 checkModelInstance(value);
188
189 final List<DynaFormControl> dynaFormControls = ((DynaFormModel) value).getControls();
190 for (final DynaFormControl dynaFormControl : dynaFormControls) {
191 if (key.equals(dynaFormControl.getKey())) {
192 return dynaFormControl;
193 }
194 }
195
196 return null;
197 }
198
199 @Override
200 protected void processChildren(final FacesContext context, final PhaseId phaseId) {
201 final Object value = getValue();
202 if (value != null) {
203 checkModelInstance(value);
204
205 final List<DynaFormControl> dynaFormControls = ((DynaFormModel) value).getControls();
206 for (final DynaFormControl dynaFormControl : dynaFormControls) {
207 processDynaFormCells(context, phaseId, dynaFormControl);
208 }
209 }
210
211 resetData();
212 }
213
214 @Override
215 protected boolean visitChildren(final VisitContext context, final VisitCallback callback) {
216 final Object value = getValue();
217 if (value == null) {
218 return false;
219 }
220
221 checkModelInstance(value);
222
223 final List<DynaFormControl> dynaFormControls = ((DynaFormModel) value).getControls();
224 for (final DynaFormControl dynaFormControl : dynaFormControls) {
225 if (visitDynaFormCells(context, callback, dynaFormControl)) {
226 return true;
227 }
228 }
229
230 resetData();
231
232 return false;
233 }
234
235 @Override
236 protected boolean invokeOnChildren(final FacesContext context, final String clientId, final ContextCallback callback) {
237 final Object value = getValue();
238 if (value == null) {
239 return false;
240 }
241
242 checkModelInstance(value);
243
244 if (getChildCount() > 0) {
245
246
247 String key = clientId.substring(getClientId().length() + 1);
248 key = key.substring(0, key.indexOf(UINamingContainer.getSeparatorChar(context)));
249
250 final List<DynaFormControl> dynaFormControls = ((DynaFormModel) value).getControls();
251 for (final DynaFormControl dynaFormControl : dynaFormControls) {
252
253
254 if (dynaFormControl.getKey().equals(key)) {
255
256
257 final UIDynaFormControl uiDynaFormControl = getControlCell(dynaFormControl.getType());
258
259 try {
260
261 setData(dynaFormControl);
262
263
264 if (uiDynaFormControl.invokeOnComponent(context, clientId, callback)) {
265 return true;
266 }
267 }
268 finally {
269 resetData();
270 }
271
272 break;
273 }
274 }
275 }
276
277 return false;
278 }
279
280 private void processDynaFormCells(final FacesContext context, final PhaseId phaseId, final DynaFormControl dynaFormControl) {
281 for (int i = 0; i < getChildCount(); i++) {
282 final UIComponent kid = getChildren().get(i);
283 if (!(kid instanceof UIDynaFormControl) || !kid.isRendered()
284 || !((UIDynaFormControl) kid).getType().equals(dynaFormControl.getType())) {
285 continue;
286 }
287
288 setData(dynaFormControl);
289 if (getData() == null) {
290 return;
291 }
292
293 for (int j = 0; j < kid.getChildCount(); j++) {
294 final UIComponent grandkid = kid.getChildren().get(j);
295 processGrandkid(context, phaseId, grandkid);
296 }
297 }
298 }
299
300 private static void processGrandkid(final FacesContext context, final PhaseId phaseId, final UIComponent grandkid) {
301 if (!grandkid.isRendered()) {
302 return;
303 }
304
305 if (phaseId == PhaseId.APPLY_REQUEST_VALUES) {
306 grandkid.processDecodes(context);
307 }
308 else if (phaseId == PhaseId.PROCESS_VALIDATIONS) {
309 grandkid.processValidators(context);
310 }
311 else if (phaseId == PhaseId.UPDATE_MODEL_VALUES) {
312 grandkid.processUpdates(context);
313 }
314 else {
315 throw new IllegalArgumentException();
316 }
317 }
318
319 private boolean visitDynaFormCells(final VisitContext context, final VisitCallback callback, final DynaFormControl dynaFormControl) {
320 if (getChildCount() > 0) {
321 for (final UIComponent child : getChildren()) {
322 if (child instanceof UIDynaFormControl
323 && ((UIDynaFormControl) child).getType().equals(dynaFormControl.getType())) {
324 setData(dynaFormControl);
325 if (getData() == null) {
326 return false;
327 }
328
329 if (child.visitTree(context, callback)) {
330 return true;
331 }
332 }
333 }
334 }
335
336 return false;
337 }
338
339 @Override
340 public Object saveState(FacesContext context) {
341
342 cells = null;
343
344 return super.saveState(context);
345 }
346 }