1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.orchestra.dynaForm.jsf.component;
20
21 import org.apache.myfaces.orchestra.dynaForm.jsf.guiBuilder.Slipstream;
22 import org.apache.myfaces.orchestra.dynaForm.jsf.guiBuilder.impl.jsf.JsfGuiBuilder;
23 import org.apache.myfaces.orchestra.dynaForm.jsf.guiBuilder.impl.jsf.JsfGuiBuilderFactory;
24 import org.apache.myfaces.orchestra.dynaForm.jsf.guiBuilder.impl.jsf.NewComponentListener;
25 import org.apache.myfaces.orchestra.dynaForm.lib.ViewType;
26 import org.apache.myfaces.orchestra.dynaForm.lib._FacesUtils;
27 import org.apache.myfaces.orchestra.dynaForm.metadata.Extractor;
28 import org.apache.myfaces.orchestra.dynaForm.metadata.MetaData;
29 import org.apache.myfaces.orchestra.dynaForm.metadata.MetaField;
30 import org.apache.myfaces.orchestra.dynaForm.metadata.impl.MetaDataImpl;
31 import org.apache.myfaces.orchestra.dynaForm.metadata.impl.jsf.JsfExclusiveExtractor;
32 import org.apache.myfaces.orchestra.dynaForm.metadata.impl.jsf.JsfExtractor;
33 import org.apache.myfaces.orchestra.dynaForm.metadata.impl.jsf.JsfRequestFieldExtractor;
34 import org.apache.myfaces.orchestra.dynaForm.uri.FacesUriResolver;
35 import org.apache.myfaces.orchestra.dynaForm.uri.UriResolver;
36
37 import javax.el.ELContext;
38 import javax.faces.component.UIColumn;
39 import javax.faces.component.UIComponent;
40 import javax.faces.component.UIComponentBase;
41 import javax.faces.component.UIData;
42 import javax.faces.context.FacesContext;
43 import javax.faces.el.ValueBinding;
44 import javax.persistence.Transient;
45 import java.util.Iterator;
46 import java.util.List;
47 import java.util.Map;
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81 public class DynaForm extends UIComponentBase
82 {
83 public static final String COMPONENT_TYPE = "org.apache.myfaces.orchestra.dynaForm.DynaForm";
84 public static final String DEFAULT_RENDERER_TYPE = "org.apache.myfaces.orchestra.dynaForm.DynaForm";
85 public static final String COMPONENT_FAMILY = "org.apache.myfaces.orchestra.dynaForm.DynaForm";
86
87 public static final String DYNA_FORM_CREATED = "org.apache.myfaces.dynaForm.CREATED";
88 public static final String DYNA_FORM_URI = "org.apache.myfaces.dynaForm.URI";
89
90 private String uri;
91 private String bundle;
92 private String valueBindingPrefix;
93 private Boolean displayOnly;
94 private Boolean exclusiveFields;
95 private Boolean idAsDisplayOnly;
96 private NewComponentListener newComponentListener;
97
98
99 @Transient
100 private transient UriResolver.Configuration configuration = null;
101 @Transient
102 private transient DynaConfigs formConfigs = null;
103 @Transient
104 private transient ELContext elcontext;
105
106
107
108
109
110
111
112
113
114
115
116
117 protected static class AddComponentToTable implements NewComponentListener
118 {
119
120 @SuppressWarnings("unchecked")
121 public void newComponent(UIComponent destCmp,
122 MetaField field, String fieldName,
123 UIComponent label, UIComponent component)
124 {
125 UIColumn column = new UIColumn();
126 if (component.getId() != null)
127 {
128 column.setId("col" + component.getId());
129 }
130 column.getChildren().add(component);
131 column.setHeader(label);
132 column.getAttributes().put(DynaForm.DYNA_FORM_CREATED, Boolean.TRUE);
133
134 _FacesUtils.copyRendered(component, column);
135
136 destCmp.getChildren().add(column);
137 }
138
139 public boolean containsComponent(UIComponent destCmp, String id)
140 {
141 return destCmp.findComponent(id) != null;
142 }
143 }
144
145
146
147
148
149
150
151
152 protected static class AddComponentSimple implements NewComponentListener
153 {
154 @SuppressWarnings("unchecked")
155 public void newComponent(UIComponent destCmp,
156 MetaField field, String fieldName,
157 UIComponent label, UIComponent component)
158 {
159 _FacesUtils.copyRendered(component, label);
160
161 destCmp.getChildren().add(label);
162 destCmp.getChildren().add(component);
163 }
164
165 public boolean containsComponent(UIComponent destCmp, String id)
166 {
167 return destCmp.findComponent(id) != null;
168 }
169 }
170
171 public DynaForm()
172 {
173 super();
174 }
175
176 @Override
177 public String getFamily()
178 {
179 return COMPONENT_FAMILY;
180 }
181
182
183
184
185 public NewComponentListener getNewComponentListener()
186 {
187 if (newComponentListener != null)
188 {
189 return newComponentListener;
190 }
191
192 ValueBinding vb = getValueBinding("newComponentListener");
193 return vb != null ? (NewComponentListener) vb.getValue(getFacesContext()) : null;
194 }
195
196
197
198
199
200 public void setNewComponentListener(NewComponentListener newComponentListener)
201 {
202 this.newComponentListener = newComponentListener;
203 }
204
205
206
207
208 public String getUri()
209 {
210 if (uri != null)
211 {
212 return uri;
213 }
214 ValueBinding vb = getValueBinding("uri");
215 return vb != null ? (String) vb.getValue(getFacesContext()) : null;
216 }
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236 public void setUri(String uri)
237 {
238 this.uri = uri;
239 }
240
241
242
243
244 public String getValueBindingPrefix()
245 {
246 if (valueBindingPrefix != null)
247 {
248 return valueBindingPrefix;
249 }
250 ValueBinding vb = getValueBinding("valueBindingPrefix");
251 return vb != null ? (String) vb.getValue(getFacesContext()) : null;
252 }
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274 public void setValueBindingPrefix(String valueBindingPrefix)
275 {
276 this.valueBindingPrefix = valueBindingPrefix;
277 }
278
279
280
281
282 public String getBundle()
283 {
284 if (bundle != null)
285 {
286 return bundle;
287 }
288 ValueBinding vb = getValueBinding("bundle");
289 return vb != null ? (String) vb.getValue(getFacesContext()) : null;
290 }
291
292
293
294
295
296
297
298
299
300
301 public void setBundle(String bundle)
302 {
303 this.bundle = bundle;
304 }
305
306
307
308
309
310 public void setDisplayOnly(boolean displayOnly)
311 {
312 this.displayOnly = displayOnly;
313 }
314
315
316
317
318 public boolean isDisplayOnly()
319 {
320 if (displayOnly != null)
321 {
322 return displayOnly.booleanValue();
323 }
324 ValueBinding vb = getValueBinding("displayOnly");
325 if (vb != null)
326 {
327 Boolean ret = (Boolean) vb.getValue(getFacesContext());
328 if (ret != null)
329 {
330 return ret.booleanValue();
331 }
332 }
333
334 return false;
335 }
336
337
338
339
340
341
342
343
344
345
346
347
348 public void setIdAsDisplayOnly(boolean idAsDisplayOnly)
349 {
350 this.idAsDisplayOnly = idAsDisplayOnly;
351 }
352
353
354
355
356 public boolean isIdAsDisplayOnly()
357 {
358 if (idAsDisplayOnly != null)
359 {
360 return idAsDisplayOnly.booleanValue();
361 }
362 ValueBinding vb = getValueBinding("idAsDisplayOnly");
363 if (vb != null)
364 {
365 Boolean ret = (Boolean) vb.getValue(getFacesContext());
366 if (ret != null)
367 {
368 return ret.booleanValue();
369 }
370 }
371
372 return false;
373 }
374
375
376
377
378
379
380 public void setExclusiveFields(boolean exclusiveFields)
381 {
382 this.exclusiveFields = exclusiveFields;
383 }
384
385
386
387
388 public boolean isExclusiveFields()
389 {
390 if (exclusiveFields != null)
391 {
392 return exclusiveFields.booleanValue();
393 }
394 ValueBinding vb = getValueBinding("exclusiveFields");
395 if (vb != null)
396 {
397 Boolean ret = (Boolean) vb.getValue(getFacesContext());
398 if (ret != null)
399 {
400 return ret.booleanValue();
401 }
402 }
403
404 return false;
405 }
406
407 @Override
408 public void restoreState(FacesContext context, Object stateArray)
409 {
410 Object[] states = (Object[]) stateArray;
411 super.restoreState(context, states[0]);
412 uri = (String) states[1];
413
414 displayOnly = (Boolean) states[2];
415 bundle = (String) states[3];
416 valueBindingPrefix = (String) states[4];
417 idAsDisplayOnly = (Boolean) states[5];
418 exclusiveFields = (Boolean) states[6];
419 newComponentListener = (NewComponentListener) restoreAttachedState(context, states[7]);
420 }
421
422 @Override
423 public Object saveState(FacesContext context)
424 {
425 return new Object[]
426 {
427 super.saveState(context),
428 uri,
429
430 displayOnly,
431 bundle,
432 valueBindingPrefix,
433 idAsDisplayOnly,
434 exclusiveFields,
435 saveAttachedState(context, newComponentListener)
436 };
437 }
438
439
440
441
442
443
444
445
446
447
448 protected UriResolver.Configuration getConfiguration()
449 {
450 if (configuration == null)
451 {
452 configuration = new FacesUriResolver().resolveUri(getUri());
453 }
454 return configuration;
455 }
456
457 public Extractor getExtractor()
458 {
459 return getConfiguration().getExtractor();
460 }
461
462
463
464
465 protected DynaForm findParentDynaForm(DynaForm start)
466 {
467 UIComponent component = start.getParent();
468 while (component != null)
469 {
470 if (component instanceof DynaForm)
471 {
472 return (DynaForm) component;
473 }
474 component = component.getParent();
475 }
476
477 return null;
478 }
479
480
481
482
483 public static DynaForm getDynaForm(UIComponent component)
484 {
485 if (component == null)
486 {
487 throw new IllegalArgumentException("component==null not allowed");
488 }
489
490 UIComponent dynaFormComponent = component;
491 while (dynaFormComponent != null && (!(dynaFormComponent instanceof DynaForm)))
492 {
493 dynaFormComponent = dynaFormComponent.getParent();
494 }
495 if (dynaFormComponent == null)
496 {
497 throw new IllegalArgumentException(
498 "component with id '" + component.getId() + "' not contained in an dynaForm");
499 }
500
501 return (DynaForm) dynaFormComponent;
502 }
503
504
505
506
507 public DynaConfigs getFormConfigs()
508 {
509 if (formConfigs != null)
510 {
511 return formConfigs;
512 }
513
514 for (Object obj : getChildren())
515 {
516 if (obj instanceof DynaConfigs)
517 {
518 formConfigs = (DynaConfigs) obj;
519 return formConfigs;
520 }
521 }
522
523 return null;
524 }
525
526
527
528
529
530
531
532
533
534 public ELContext getELContext()
535 {
536 return elcontext;
537 }
538
539 public void setELContext(ELContext elcontext)
540 {
541 this.elcontext = elcontext;
542 }
543
544 @Override
545 public boolean isRendered()
546 {
547
548 return false;
549 }
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574 @SuppressWarnings("unchecked")
575 public void initView(FacesContext context)
576 {
577 UIComponent layoutComponent = getParent();
578 ViewType viewType = getViewType(layoutComponent);
579
580
581
582 String previousUri = (String) getAttributes().get(DynaForm.DYNA_FORM_URI);
583 if (previousUri != null && !previousUri.equals(getUri()))
584 {
585 removeDynaFormCreatedComponents(layoutComponent);
586 }
587
588
589
590
591 {
592 getAttributes().put(DynaForm.DYNA_FORM_URI, getUri());
593 addComponents(context, this, layoutComponent, viewType);
594 }
595 }
596
597 public void removeDynaFormCreatedComponents(UIComponent base)
598 {
599 @SuppressWarnings("unchecked")
600 List<UIComponent> children = base.getChildren();
601 if (children == null || children.size() < 1 )
602 {
603 return;
604 }
605
606 Iterator<UIComponent> iterChildren = children.iterator();
607 while (iterChildren.hasNext())
608 {
609 UIComponent component = (UIComponent) iterChildren.next();
610
611 if (Boolean.TRUE.equals(component.getAttributes().get(DynaForm.DYNA_FORM_CREATED)))
612 {
613 iterChildren.remove();
614 }
615 else
616 {
617 removeDynaFormCreatedComponents(component);
618 }
619 }
620 }
621
622
623
624
625
626
627
628
629 protected ViewType getViewType(UIComponent startComponent)
630 {
631 UIComponent component = startComponent;
632 while (component != null && !(component instanceof DynaForm))
633 {
634 if (isTable(component))
635 {
636 return ViewType.LIST;
637 }
638
639 component = component.getParent();
640 }
641
642 return ViewType.FORM;
643 }
644
645
646
647
648
649
650
651 protected void addComponents(final FacesContext context,
652 final DynaForm dynaForm, final UIComponent layoutComponent,
653 final ViewType viewType)
654 {
655 MetaData metaData = extractMetaData(dynaForm);
656
657 Slipstream slipstream = new Slipstream();
658 slipstream.setDynaForm(this);
659 slipstream.setModelMetaData(metaData);
660
661 if (dynaForm.getBundle() != null)
662 {
663
664 ValueBinding vb = context.getApplication().createValueBinding("#{" + dynaForm.getBundle() + "}");
665 @SuppressWarnings("unchecked")
666 Map<String, String> bundleMap = (Map<String, String>) vb.getValue(context);
667 slipstream.setLabelBundle(bundleMap);
668 }
669
670 JsfGuiBuilder guiBuilder = createGuiBuilder(context);
671
672 guiBuilder.setDestCmp(layoutComponent);
673 guiBuilder.setELContext(dynaForm.getELContext());
674 guiBuilder.setContext(context);
675
676 if (dynaForm.getNewComponentListener() != null)
677 {
678 guiBuilder.setNewComponentListener(dynaForm.getNewComponentListener());
679 }
680 else if (isTable(layoutComponent))
681 {
682 guiBuilder.setNewComponentListener(new AddComponentToTable());
683 }
684 else
685 {
686 guiBuilder.setNewComponentListener(new AddComponentSimple());
687 }
688
689 String valueBindingPrefix = getValueBindingPrefix(dynaForm, layoutComponent);
690 if (valueBindingPrefix == null)
691 {
692 throw new UnsupportedOperationException("can't determine the value binding prefix");
693 }
694 guiBuilder.setBackingEntityPrefix(valueBindingPrefix);
695
696 slipstream.setGuiBuilder(guiBuilder);
697 slipstream.process();
698 }
699
700 private boolean isTable(UIComponent layoutComponent)
701 {
702 return layoutComponent instanceof UIData || UIData.COMPONENT_FAMILY.equals(layoutComponent.getFamily());
703 }
704
705 protected String getValueBindingPrefix(DynaForm dynaForm, UIComponent layoutComponent)
706 {
707 String valueBindingPrefix = dynaForm.getValueBindingPrefix();
708 if (valueBindingPrefix == null)
709 {
710 valueBindingPrefix = (String) layoutComponent.getAttributes().get("var");
711 }
712
713 return valueBindingPrefix;
714 }
715
716 private MetaData extractMetaData(final DynaForm dynaForm)
717 {
718 MetaDataImpl metaData = new MetaDataImpl();
719
720 try
721 {
722
723 new JsfRequestFieldExtractor().getMetaData(metaData, dynaForm);
724
725 if (dynaForm.isExclusiveFields())
726 {
727
728 new JsfExclusiveExtractor().getMetaData(metaData, dynaForm);
729 metaData.setLockFields(true);
730 }
731
732
733 dynaForm.getExtractor().getMetaData(metaData, dynaForm.getConfiguration().getEntity());
734
735
736 new JsfExtractor().getMetaData(metaData, dynaForm);
737
738 }
739 finally
740 {
741 metaData.setLockFields(false);
742 }
743
744 return metaData;
745 }
746
747 protected JsfGuiBuilder createGuiBuilder(final FacesContext facesContext)
748 {
749 return JsfGuiBuilderFactory.create(facesContext);
750 }
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766 protected boolean processPreviouslyAdded(FacesContext context,
767 UIComponent root)
768 {
769 @SuppressWarnings("unchecked")
770 List<UIComponent> rootComponentChildren = root.getChildren();
771 if (rootComponentChildren != null)
772 {
773 for (Object component : rootComponentChildren)
774 {
775 UIComponent child = (UIComponent) component;
776 if (Boolean.TRUE.equals(child.getAttributes().get(
777 DynaForm.DYNA_FORM_CREATED)))
778 {
779 return false;
780 }
781
782 if (!processPreviouslyAdded(context, child))
783 {
784 return false;
785 }
786 }
787 }
788
789 return true;
790 }
791 }