1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.view.facelets.tag.jsf;
20
21 import java.io.IOException;
22 import java.lang.reflect.InvocationTargetException;
23 import java.lang.reflect.Method;
24 import java.util.Collection;
25 import java.util.Iterator;
26 import java.util.Locale;
27 import java.util.Map;
28
29 import javax.faces.FacesException;
30 import javax.faces.component.NamingContainer;
31 import javax.faces.component.UIComponent;
32 import javax.faces.component.UIPanel;
33 import javax.faces.component.UIViewRoot;
34 import javax.faces.component.UniqueIdVendor;
35 import javax.faces.context.FacesContext;
36 import javax.faces.view.facelets.FaceletContext;
37 import javax.faces.view.facelets.TagAttribute;
38 import javax.faces.view.facelets.TagAttributeException;
39
40 import org.apache.myfaces.shared.config.MyfacesConfig;
41 import org.apache.myfaces.view.facelets.ComponentState;
42 import org.apache.myfaces.view.facelets.DefaultFaceletsStateManagementStrategy;
43 import org.apache.myfaces.view.facelets.FaceletCompositionContext;
44 import org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage;
45 import org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguageBase;
46
47
48
49
50
51
52 public final class ComponentSupport
53 {
54 private static final Method SET_CACHED_FACES_CONTEXT;
55
56 static
57 {
58 Method method = null;
59 try
60 {
61
62
63
64
65 method = UIComponent.class.getDeclaredMethod("setCachedFacesContext", FacesContext.class);
66 method.setAccessible(true);
67 }
68 catch (NoSuchMethodException ex)
69 {
70 method = null;
71 }
72 catch (SecurityException ex)
73 {
74 method = null;
75 }
76 SET_CACHED_FACES_CONTEXT = method;
77 }
78
79 private final static String MARK_DELETED = "oam.vf.MARK_DELETED";
80 public final static String MARK_CREATED = "oam.vf.MARK_ID";
81
82
83
84
85
86
87 public final static String FACET_CREATED_UIPANEL_MARKER = "oam.vf.createdUIPanel";
88
89
90
91
92
93
94 public final static String COMPONENT_ADDED_BY_HANDLER_MARKER = "oam.vf.addedByHandler";
95
96
97
98
99 public final static String FACELET_STATE_INSTANCE = "oam.FACELET_STATE_INSTANCE";
100
101
102
103
104
105
106
107
108 @Deprecated
109 public static void finalizeForDeletion(UIComponent component)
110 {
111
112 component.getAttributes().remove(MARK_DELETED);
113
114
115 if (component.getChildCount() > 0)
116 {
117 for (Iterator<UIComponent> iter = component.getChildren().iterator(); iter.hasNext();)
118 {
119 UIComponent child = iter.next();
120 if (child.getAttributes().containsKey(MARK_DELETED))
121 {
122 iter.remove();
123 }
124 }
125 }
126
127
128 if (component.getFacetCount() > 0)
129 {
130 Map<String, UIComponent> facets = component.getFacets();
131 Collection<UIComponent> col = facets.values();
132 for (Iterator<UIComponent> itr = col.iterator(); itr.hasNext();)
133 {
134 UIComponent fc = itr.next();
135 if (fc.getAttributes().containsKey(MARK_DELETED))
136 {
137 itr.remove();
138 }
139 }
140 }
141 }
142
143
144
145
146
147
148
149
150
151
152 public static UIComponent findChild(UIComponent parent, String id)
153 {
154 int childCount = parent.getChildCount();
155 if (childCount > 0)
156 {
157 for (int i = 0; i < childCount; i++)
158 {
159 UIComponent child = parent.getChildren().get(i);
160 if (id.equals(child.getId()))
161 {
162 return child;
163 }
164 }
165 }
166 return null;
167 }
168
169 public static String findFacetNameByComponentInstance(
170 UIComponent parent, UIComponent instance)
171 {
172 if (parent.getFacetCount() > 0)
173 {
174 for (Map.Entry<String, UIComponent> entry : parent.getFacets().entrySet())
175 {
176 UIComponent facet = entry.getValue();
177
178 if (Boolean.TRUE.equals(facet.getAttributes()
179 .get(FACET_CREATED_UIPANEL_MARKER)))
180 {
181
182 if (facet.getChildCount() > 0)
183 {
184 for (int i = 0, childCount = facet.getChildCount(); i < childCount; i ++)
185 {
186 UIComponent child = facet.getChildren().get(i);
187 if (instance.equals(child))
188 {
189 return entry.getKey();
190 }
191 }
192 }
193 if (facet.getFacetCount() > 0)
194 {
195 Iterator<UIComponent> itr2 = facet.getFacets().values().iterator();
196 while (itr2.hasNext())
197 {
198 UIComponent child = itr2.next();
199 if (instance.equals(child))
200 {
201 return entry.getKey();
202 }
203 }
204 }
205 }
206 else if (instance.equals(facet))
207 {
208 return entry.getKey();
209 }
210 }
211 return null;
212 }
213 return null;
214 }
215
216 public static UIComponent findChildInFacetByTagId(
217 UIComponent parent, String id, String facetName)
218 {
219 if (parent.getFacetCount() > 0)
220 {
221 UIComponent facet = parent.getFacet(facetName);
222 if (facet != null)
223 {
224
225 if (Boolean.TRUE.equals(facet.getAttributes()
226 .get(FACET_CREATED_UIPANEL_MARKER)))
227 {
228
229 if (facet.getChildCount() > 0)
230 {
231 for (int i = 0, childCount = facet.getChildCount(); i < childCount; i ++)
232 {
233 UIComponent child = facet.getChildren().get(i);
234 if (id.equals(child.getAttributes().get(MARK_CREATED)))
235 {
236 return child;
237 }
238 }
239 }
240 if (facet.getFacetCount() > 0)
241 {
242 Iterator<UIComponent> itr2 = facet.getFacets().values().iterator();
243 while (itr2.hasNext())
244 {
245 UIComponent child = itr2.next();
246 if (id.equals(child.getAttributes().get(MARK_CREATED)))
247 {
248 return child;
249 }
250 }
251 }
252 }
253 else if (id.equals(facet.getAttributes().get(MARK_CREATED)))
254 {
255 return facet;
256 }
257 }
258 }
259 return null;
260 }
261
262 public static UIComponent findChildInChildrenByTagId(
263 UIComponent parent, String id)
264 {
265 if (parent.getChildCount() > 0)
266 {
267 for (int i = 0, childCount = parent.getChildCount(); i < childCount; i ++)
268 {
269 UIComponent child = parent.getChildren().get(i);
270 if (id.equals(child.getAttributes().get(MARK_CREATED)))
271 {
272 return child;
273 }
274 }
275 }
276 return null;
277 }
278
279
280
281
282
283
284
285
286 public static UIComponent findChildByTagId(UIComponent parent, String id)
287 {
288 Iterator<UIComponent> itr = null;
289 if (parent.getChildCount() > 0)
290 {
291 for (int i = 0, childCount = parent.getChildCount(); i < childCount; i ++)
292 {
293 UIComponent child = parent.getChildren().get(i);
294 if (id.equals(child.getAttributes().get(MARK_CREATED)))
295 {
296 return child;
297 }
298 }
299 }
300 if (parent.getFacetCount() > 0)
301 {
302 itr = parent.getFacets().values().iterator();
303 while (itr.hasNext())
304 {
305 UIComponent facet = itr.next();
306
307 if (Boolean.TRUE.equals(facet.getAttributes()
308 .get(FACET_CREATED_UIPANEL_MARKER)))
309 {
310
311 if (facet.getChildCount() > 0)
312 {
313 for (int i = 0, childCount = facet.getChildCount(); i < childCount; i ++)
314 {
315 UIComponent child = facet.getChildren().get(i);
316 if (id.equals(child.getAttributes().get(MARK_CREATED)))
317 {
318 return child;
319 }
320 }
321 }
322 if (facet.getFacetCount() > 0)
323 {
324 Iterator<UIComponent> itr2 = facet.getFacets().values().iterator();
325 while (itr2.hasNext())
326 {
327 UIComponent child = itr2.next();
328 if (id.equals(child.getAttributes().get(MARK_CREATED)))
329 {
330 return child;
331 }
332 }
333 }
334 }
335 else if (id.equals(facet.getAttributes().get(MARK_CREATED)))
336 {
337 return facet;
338 }
339 }
340 }
341
342 return null;
343 }
344
345 public static String findChildInFacetsByTagId(UIComponent parent, String id)
346 {
347 Iterator<Map.Entry<String, UIComponent>> itr = null;
348 if (parent.getFacetCount() > 0)
349 {
350 itr = parent.getFacets().entrySet().iterator();
351 while (itr.hasNext())
352 {
353 Map.Entry<String, UIComponent> entry = itr.next();
354 UIComponent facet = entry.getValue();
355
356 if (Boolean.TRUE.equals(facet.getAttributes()
357 .get(FACET_CREATED_UIPANEL_MARKER)))
358 {
359
360 if (facet.getChildCount() > 0)
361 {
362 for (int i = 0, childCount = facet.getChildCount(); i < childCount; i ++)
363 {
364 UIComponent child = facet.getChildren().get(i);
365 if (id.equals(child.getAttributes().get(MARK_CREATED)))
366 {
367 return entry.getKey();
368 }
369 }
370 }
371 if (facet.getFacetCount() > 0)
372 {
373 Iterator<UIComponent> itr2 = facet.getFacets().values().iterator();
374 while (itr2.hasNext())
375 {
376 UIComponent child = itr2.next();
377 if (id.equals(child.getAttributes().get(MARK_CREATED)))
378 {
379 return entry.getKey();
380 }
381 }
382 }
383 }
384 else if (id.equals(facet.getAttributes().get(MARK_CREATED)))
385 {
386 return entry.getKey();
387 }
388 }
389 }
390 return null;
391 }
392
393
394
395
396
397
398
399
400
401
402
403
404
405 public static Locale getLocale(FaceletContext ctx, TagAttribute attr) throws TagAttributeException
406 {
407 Object obj = attr.getObject(ctx);
408 if (obj instanceof Locale)
409 {
410 return (Locale) obj;
411 }
412 if (obj instanceof String)
413 {
414 String s = (String) obj;
415 if (s.length() == 2)
416 {
417 return new Locale(s);
418 }
419
420 if (s.length() == 5)
421 {
422 return new Locale(s.substring(0, 2), s.substring(3, 5).toUpperCase());
423 }
424
425 if (s.length() >= 7)
426 {
427 return new Locale(s.substring(0, 2), s.substring(3, 5).toUpperCase(), s.substring(6, s.length()));
428 }
429
430 throw new TagAttributeException(attr, "Invalid Locale Specified: " + s);
431 }
432 else
433 {
434 throw new TagAttributeException(attr, "Attribute did not evaluate to a String or Locale: " + obj);
435 }
436 }
437
438
439
440
441
442
443
444
445
446
447
448 public static UIViewRoot getViewRoot(FaceletContext ctx, UIComponent parent)
449 {
450 UIComponent c = parent;
451 do
452 {
453 if (c instanceof UIViewRoot)
454 {
455 return (UIViewRoot) c;
456 }
457 else
458 {
459 c = c.getParent();
460 }
461 } while (c != null);
462
463 UIViewRoot root = ctx.getFacesContext().getViewRoot();
464 if (root == null)
465 {
466 root = FaceletCompositionContext.getCurrentInstance(ctx).getViewRoot(ctx.getFacesContext());
467 }
468 return root;
469 }
470
471
472
473
474
475
476
477
478
479 @Deprecated
480 public static void markForDeletion(UIComponent component)
481 {
482
483 component.getAttributes().put(MARK_DELETED, Boolean.TRUE);
484
485 Iterator<UIComponent> iter = component.getFacetsAndChildren();
486 while (iter.hasNext())
487 {
488 UIComponent child = iter.next();
489 if (child.getAttributes().containsKey(MARK_CREATED))
490 {
491 child.getAttributes().put(MARK_DELETED, Boolean.TRUE);
492 }
493 }
494 }
495
496 public static void encodeRecursive(FacesContext context, UIComponent toRender) throws IOException, FacesException
497 {
498 if (toRender.isRendered())
499 {
500 toRender.encodeBegin(context);
501
502 if (toRender.getRendersChildren())
503 {
504 toRender.encodeChildren(context);
505 }
506 else if (toRender.getChildCount() > 0)
507 {
508 for (int i = 0, childCount = toRender.getChildCount(); i < childCount; i++)
509 {
510 UIComponent child = toRender.getChildren().get(i);
511 encodeRecursive(context, child);
512 }
513 }
514
515 toRender.encodeEnd(context);
516 }
517 }
518
519 public static void removeTransient(UIComponent component)
520 {
521 if (component.getChildCount() > 0)
522 {
523 for (Iterator<UIComponent> itr = component.getChildren().iterator(); itr.hasNext();)
524 {
525 UIComponent child = itr.next();
526 if (child.isTransient())
527 {
528 itr.remove();
529 }
530 else
531 {
532 removeTransient(child);
533 }
534 }
535 }
536
537 if (component.getFacetCount() > 0)
538 {
539 Map<String, UIComponent> facets = component.getFacets();
540 for (Iterator<UIComponent> itr = facets.values().iterator(); itr.hasNext();)
541 {
542 UIComponent facet = itr.next();
543 if (facet.isTransient())
544 {
545 itr.remove();
546 }
547 else
548 {
549 removeTransient(facet);
550 }
551 }
552 }
553 }
554
555
556
557
558
559
560
561
562
563
564 @Deprecated
565 public static boolean isNew(UIComponent component)
566 {
567 return component != null && component.getParent() == null;
568 }
569
570
571
572
573
574
575
576
577 private static UIComponent createFacetUIPanel(FaceletContext ctx, UIComponent parent, String facetName)
578 {
579 FacesContext facesContext = ctx.getFacesContext();
580 UIComponent panel = facesContext.getApplication().createComponent(facesContext, UIPanel.COMPONENT_TYPE, null);
581
582
583
584
585
586
587
588
589
590
591
592
593 FaceletCompositionContext mctx = FaceletCompositionContext.getCurrentInstance(ctx);
594 UniqueIdVendor uniqueIdVendor = mctx.getUniqueIdVendorFromStack();
595 if (uniqueIdVendor == null)
596 {
597 uniqueIdVendor = ComponentSupport.getViewRoot(ctx, parent);
598 }
599 if (uniqueIdVendor != null)
600 {
601
602
603 int index = facetName.indexOf('.');
604 String cleanFacetName = facetName;
605 if (index >= 0)
606 {
607 cleanFacetName = facetName.replace('.', '_');
608 }
609 panel.setId(uniqueIdVendor.createUniqueId(facesContext,
610 mctx.getSharedStringBuilder()
611 .append(parent.getId())
612 .append("__f_")
613 .append(cleanFacetName).toString()));
614 }
615 panel.getAttributes().put(FACET_CREATED_UIPANEL_MARKER, Boolean.TRUE);
616 panel.getAttributes().put(ComponentSupport.COMPONENT_ADDED_BY_HANDLER_MARKER, Boolean.TRUE);
617 return panel;
618 }
619
620 public static void addFacet(FaceletContext ctx, UIComponent parent, UIComponent c, String facetName)
621 {
622
623
624 UIComponent facet = parent.getFacets().get(facetName);
625 if (facet == null)
626 {
627
628 parent.getFacets().put(facetName, c);
629 }
630 else if (!(facet instanceof UIPanel))
631 {
632
633 UIComponent child = facet;
634 facet = createFacetUIPanel(ctx, parent, facetName);
635 facet.getChildren().add(child);
636 facet.getChildren().add(c);
637 parent.getFacets().put(facetName, facet);
638 }
639 else
640 {
641
642
643 if (Boolean.TRUE.equals(facet.getAttributes().get(FACET_CREATED_UIPANEL_MARKER)))
644 {
645 facet.getChildren().add(c);
646 }
647 else
648 {
649
650
651 UIComponent oldPanel = facet;
652 facet = createFacetUIPanel(ctx, parent, facetName);
653 facet.getChildren().add(oldPanel);
654 facet.getChildren().add(c);
655 parent.getFacets().put(facetName, facet);
656 }
657 }
658 }
659
660 public static void removeFacet(FaceletContext ctx, UIComponent parent, UIComponent c, String facetName)
661 {
662 UIComponent facet = parent.getFacet(facetName);
663 if (Boolean.TRUE.equals(facet.getAttributes().get(FACET_CREATED_UIPANEL_MARKER)))
664 {
665 facet.getChildren().remove(c);
666 }
667 else
668 {
669 parent.getFacets().remove(facetName);
670 }
671 }
672
673 public static void markComponentToRestoreFully(FacesContext context, UIComponent component)
674 {
675 if (MyfacesConfig.getCurrentInstance(context.getExternalContext()).isRefreshTransientBuildOnPSSPreserveState())
676 {
677 component.getAttributes().put(DefaultFaceletsStateManagementStrategy.COMPONENT_ADDED_AFTER_BUILD_VIEW,
678 ComponentState.REMOVE_ADD);
679 }
680
681 if (FaceletViewDeclarationLanguage.isRefreshTransientBuildOnPSSAuto(context))
682 {
683 FaceletViewDeclarationLanguage.cleanTransientBuildOnRestore(context);
684 }
685 }
686
687 public static void markComponentToRefreshDynamically(FacesContext context, UIComponent component)
688 {
689 FaceletViewDeclarationLanguageBase.dynamicComponentNeedsRefresh(context);
690 }
691
692 public static UIComponent findComponentChildOrFacetFrom(FacesContext facesContext, UIComponent parent, String expr)
693 {
694 final char separatorChar = facesContext.getNamingContainerSeparatorChar();
695 int separator = expr.indexOf(separatorChar);
696 if (separator == -1)
697 {
698 return ComponentSupport.findComponentChildOrFacetFrom(
699 parent, expr, null);
700 }
701 else
702 {
703 return ComponentSupport.findComponentChildOrFacetFrom(
704 parent, expr.substring(0,separator), expr);
705 }
706 }
707
708 public static UIComponent findComponentChildOrFacetFrom(UIComponent parent, String id, String innerExpr)
709 {
710 if (parent.getFacetCount() > 0)
711 {
712 for (UIComponent facet : parent.getFacets().values())
713 {
714 if (id.equals(facet.getId()))
715 {
716 if (innerExpr == null)
717 {
718 return facet;
719 }
720 else if (facet instanceof NamingContainer)
721 {
722 UIComponent find = facet.findComponent(innerExpr);
723 if (find != null)
724 {
725 return find;
726 }
727 }
728 }
729 else if (!(facet instanceof NamingContainer))
730 {
731 UIComponent find = findComponentChildOrFacetFrom(facet, id, innerExpr);
732 if (find != null)
733 {
734 return find;
735 }
736 }
737 }
738 }
739 if (parent.getChildCount() > 0)
740 {
741 for (int i = 0, childCount = parent.getChildCount(); i < childCount; i++)
742 {
743 UIComponent child = parent.getChildren().get(i);
744 if (id.equals(child.getId()))
745 {
746 if (innerExpr == null)
747 {
748 return child;
749 }
750 else if (child instanceof NamingContainer)
751 {
752 UIComponent find = child.findComponent(innerExpr);
753 if (find != null)
754 {
755 return find;
756 }
757 }
758 }
759 else if (!(child instanceof NamingContainer))
760 {
761 UIComponent find = findComponentChildOrFacetFrom(child, id, innerExpr);
762 if (find != null)
763 {
764 return find;
765 }
766 }
767 }
768 }
769 return null;
770 }
771
772 public static String getFindComponentExpression(FacesContext facesContext, UIComponent component)
773 {
774 char separatorChar = facesContext.getNamingContainerSeparatorChar();
775 UIComponent parent = component.getParent();
776 StringBuilder sb = new StringBuilder();
777 sb.append(component.getId());
778 while (parent != null)
779 {
780 if (parent instanceof NamingContainer)
781 {
782 sb.insert(0, separatorChar);
783 sb.insert(0, parent.getId());
784 }
785 parent = parent.getParent();
786 }
787 return sb.toString();
788 }
789
790 public static Object restoreInitialTagState(FaceletContext ctx, FaceletCompositionContext fcc,
791 UIComponent parent, String uniqueId)
792 {
793 Object value = null;
794
795
796
797
798 if (fcc.isUsingPSSOnThisView() && !fcc.isRefreshTransientBuildOnPSSPreserveState())
799 {
800 UIViewRoot root = getViewRoot(ctx, parent);
801 FaceletState map = (FaceletState) root.getAttributes().get(FACELET_STATE_INSTANCE);
802 if (map == null)
803 {
804 value = null;
805 }
806 else
807 {
808 value = map.getState(uniqueId);
809 }
810 }
811 return value;
812 }
813
814 public static void saveInitialTagState(FaceletContext ctx, FaceletCompositionContext fcc,
815 UIComponent parent, String uniqueId, Object value)
816 {
817
818
819
820
821
822
823
824
825
826
827 if (fcc.isUsingPSSOnThisView() && !fcc.isRefreshTransientBuildOnPSSPreserveState())
828 {
829 UIViewRoot root = getViewRoot(ctx, parent);
830 FaceletState map = (FaceletState) root.getAttributes().get(FACELET_STATE_INSTANCE);
831 if (map == null)
832 {
833 map = new FaceletState();
834 root.getAttributes().put(FACELET_STATE_INSTANCE, map);
835 }
836 map.putState(uniqueId, value);
837 }
838 }
839
840 public static FaceletState getFaceletState(FaceletContext ctx, UIComponent parent, boolean create)
841 {
842 UIViewRoot root = getViewRoot(ctx, parent);
843 FaceletState map = (FaceletState) root.getAttributes().get(FACELET_STATE_INSTANCE);
844 if (map == null && create)
845 {
846 map = new FaceletState();
847 root.getAttributes().put(FACELET_STATE_INSTANCE, map);
848 }
849 return map;
850 }
851
852 public static void setCachedFacesContext(UIComponent component,
853 FacesContext context)
854 {
855 if (SET_CACHED_FACES_CONTEXT != null)
856 {
857 try
858 {
859 SET_CACHED_FACES_CONTEXT.invoke(component, context);
860 }
861 catch (IllegalAccessException ex)
862 {
863 }
864 catch (IllegalArgumentException ex)
865 {
866 }
867 catch (InvocationTargetException ex)
868 {
869 }
870 }
871 }
872 }