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.util.Collection;
23 import java.util.Iterator;
24 import java.util.Locale;
25 import java.util.Map;
26
27 import javax.faces.FacesException;
28 import javax.faces.component.NamingContainer;
29 import javax.faces.component.UIComponent;
30 import javax.faces.component.UINamingContainer;
31 import javax.faces.component.UIPanel;
32 import javax.faces.component.UIViewRoot;
33 import javax.faces.component.UniqueIdVendor;
34 import javax.faces.context.FacesContext;
35 import javax.faces.view.facelets.FaceletContext;
36 import javax.faces.view.facelets.TagAttribute;
37 import javax.faces.view.facelets.TagAttributeException;
38
39 import org.apache.myfaces.shared.config.MyfacesConfig;
40 import org.apache.myfaces.view.facelets.ComponentState;
41 import org.apache.myfaces.view.facelets.DefaultFaceletsStateManagementStrategy;
42 import org.apache.myfaces.view.facelets.FaceletCompositionContext;
43 import org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage;
44
45
46
47
48
49
50 public final class ComponentSupport
51 {
52
53 private final static String MARK_DELETED = "oam.vf.MARK_DELETED";
54 public final static String MARK_CREATED = "oam.vf.MARK_ID";
55
56
57
58
59
60
61 public final static String FACET_CREATED_UIPANEL_MARKER = "oam.vf.createdUIPanel";
62
63
64
65
66
67
68 public final static String COMPONENT_ADDED_BY_HANDLER_MARKER = "oam.vf.addedByHandler";
69
70
71
72
73 public final static String FACELET_STATE_INSTANCE = "oam.FACELET_STATE_INSTANCE";
74
75
76
77
78
79
80
81
82 @Deprecated
83 public static void finalizeForDeletion(UIComponent component)
84 {
85
86 component.getAttributes().remove(MARK_DELETED);
87
88
89 if (component.getChildCount() > 0)
90 {
91 for (Iterator<UIComponent> iter = component.getChildren().iterator(); iter.hasNext();)
92 {
93 UIComponent child = iter.next();
94 if (child.getAttributes().containsKey(MARK_DELETED))
95 {
96 iter.remove();
97 }
98 }
99 }
100
101
102 Map<String, UIComponent> facets = component.getFacets();
103 if (!facets.isEmpty())
104 {
105 Collection<UIComponent> col = facets.values();
106 for (Iterator<UIComponent> itr = col.iterator(); itr.hasNext();)
107 {
108 UIComponent fc = itr.next();
109 if (fc.getAttributes().containsKey(MARK_DELETED))
110 {
111 itr.remove();
112 }
113 }
114 }
115 }
116
117
118
119
120
121
122
123
124
125
126 public static UIComponent findChild(UIComponent parent, String id)
127 {
128 int childCount = parent.getChildCount();
129 if (childCount > 0)
130 {
131 for (int i = 0; i < childCount; i++)
132 {
133 UIComponent child = parent.getChildren().get(i);
134 if (id.equals(child.getId()))
135 {
136 return child;
137 }
138 }
139 }
140
141 return null;
142 }
143
144
145
146
147
148
149
150
151 public static UIComponent findChildByTagId(UIComponent parent, String id)
152 {
153 Iterator<UIComponent> itr = null;
154 if (parent.getChildCount() > 0)
155 {
156 for (int i = 0, childCount = parent.getChildCount(); i < childCount; i ++)
157 {
158 UIComponent child = parent.getChildren().get(i);
159 if (id.equals(child.getAttributes().get(MARK_CREATED)))
160 {
161 return child;
162 }
163 }
164 }
165 if (parent.getFacetCount() > 0)
166 {
167 itr = parent.getFacets().values().iterator();
168 while (itr.hasNext())
169 {
170 UIComponent facet = itr.next();
171
172 if (Boolean.TRUE.equals(facet.getAttributes()
173 .get(FACET_CREATED_UIPANEL_MARKER)))
174 {
175
176 if (facet.getChildCount() > 0)
177 {
178 for (int i = 0, childCount = facet.getChildCount(); i < childCount; i ++)
179 {
180 UIComponent child = facet.getChildren().get(i);
181 if (id.equals(child.getAttributes().get(MARK_CREATED)))
182 {
183 return child;
184 }
185 }
186 }
187 if (facet.getFacetCount() > 0)
188 {
189 Iterator<UIComponent> itr2 = facet.getFacets().values().iterator();
190 while (itr2.hasNext())
191 {
192 UIComponent child = itr2.next();
193 if (id.equals(child.getAttributes().get(MARK_CREATED)))
194 {
195 return child;
196 }
197 }
198 }
199 }
200 else if (id.equals(facet.getAttributes().get(MARK_CREATED)))
201 {
202 return facet;
203 }
204 }
205 }
206
207 return null;
208 }
209
210
211
212
213
214
215
216
217
218
219
220
221
222 public static Locale getLocale(FaceletContext ctx, TagAttribute attr) throws TagAttributeException
223 {
224 Object obj = attr.getObject(ctx);
225 if (obj instanceof Locale)
226 {
227 return (Locale) obj;
228 }
229 if (obj instanceof String)
230 {
231 String s = (String) obj;
232 if (s.length() == 2)
233 {
234 return new Locale(s);
235 }
236
237 if (s.length() == 5)
238 {
239 return new Locale(s.substring(0, 2), s.substring(3, 5).toUpperCase());
240 }
241
242 if (s.length() >= 7)
243 {
244 return new Locale(s.substring(0, 2), s.substring(3, 5).toUpperCase(), s.substring(6, s.length()));
245 }
246
247 throw new TagAttributeException(attr, "Invalid Locale Specified: " + s);
248 }
249 else
250 {
251 throw new TagAttributeException(attr, "Attribute did not evaluate to a String or Locale: " + obj);
252 }
253 }
254
255
256
257
258
259
260
261
262
263
264
265 public static UIViewRoot getViewRoot(FaceletContext ctx, UIComponent parent)
266 {
267 UIComponent c = parent;
268 do
269 {
270 if (c instanceof UIViewRoot)
271 {
272 return (UIViewRoot) c;
273 }
274 else
275 {
276 c = c.getParent();
277 }
278 } while (c != null);
279
280 return ctx.getFacesContext().getViewRoot();
281 }
282
283
284
285
286
287
288
289
290
291 @Deprecated
292 public static void markForDeletion(UIComponent component)
293 {
294
295 component.getAttributes().put(MARK_DELETED, Boolean.TRUE);
296
297 Iterator<UIComponent> iter = component.getFacetsAndChildren();
298 while (iter.hasNext())
299 {
300 UIComponent child = iter.next();
301 if (child.getAttributes().containsKey(MARK_CREATED))
302 {
303 child.getAttributes().put(MARK_DELETED, Boolean.TRUE);
304 }
305 }
306 }
307
308 public static void encodeRecursive(FacesContext context, UIComponent toRender) throws IOException, FacesException
309 {
310 if (toRender.isRendered())
311 {
312 toRender.encodeBegin(context);
313
314 if (toRender.getRendersChildren())
315 {
316 toRender.encodeChildren(context);
317 }
318 else if (toRender.getChildCount() > 0)
319 {
320 for (int i = 0, childCount = toRender.getChildCount(); i < childCount; i++)
321 {
322 UIComponent child = toRender.getChildren().get(i);
323 encodeRecursive(context, child);
324 }
325 }
326
327 toRender.encodeEnd(context);
328 }
329 }
330
331 public static void removeTransient(UIComponent component)
332 {
333 if (component.getChildCount() > 0)
334 {
335 for (Iterator<UIComponent> itr = component.getChildren().iterator(); itr.hasNext();)
336 {
337 UIComponent child = itr.next();
338 if (child.isTransient())
339 {
340 itr.remove();
341 }
342 else
343 {
344 removeTransient(child);
345 }
346 }
347 }
348
349 Map<String, UIComponent> facets = component.getFacets();
350 if (!facets.isEmpty())
351 {
352 for (Iterator<UIComponent> itr = facets.values().iterator(); itr.hasNext();)
353 {
354 UIComponent facet = itr.next();
355 if (facet.isTransient())
356 {
357 itr.remove();
358 }
359 else
360 {
361 removeTransient(facet);
362 }
363 }
364 }
365 }
366
367
368
369
370
371
372
373
374
375
376 @Deprecated
377 public static boolean isNew(UIComponent component)
378 {
379 return component != null && component.getParent() == null;
380 }
381
382
383
384
385
386
387
388
389 private static UIComponent createFacetUIPanel(FaceletContext ctx, UIComponent parent, String facetName)
390 {
391 FacesContext facesContext = ctx.getFacesContext();
392 UIComponent panel = facesContext.getApplication().createComponent(facesContext, UIPanel.COMPONENT_TYPE, null);
393
394
395
396
397
398
399
400
401
402
403
404
405 FaceletCompositionContext mctx = FaceletCompositionContext.getCurrentInstance(ctx);
406 UniqueIdVendor uniqueIdVendor = mctx.getUniqueIdVendorFromStack();
407 if (uniqueIdVendor == null)
408 {
409 uniqueIdVendor = ComponentSupport.getViewRoot(ctx, parent);
410 }
411 if (uniqueIdVendor != null)
412 {
413
414
415 int index = facetName.indexOf('.');
416 String cleanFacetName = facetName;
417 if (index >= 0)
418 {
419 cleanFacetName = facetName.replace('.', '_');
420 }
421 panel.setId(uniqueIdVendor.createUniqueId(facesContext,
422 mctx.getSharedStringBuilder()
423 .append(parent.getId())
424 .append("__f_")
425 .append(cleanFacetName).toString()));
426 }
427 panel.getAttributes().put(FACET_CREATED_UIPANEL_MARKER, Boolean.TRUE);
428 panel.getAttributes().put(ComponentSupport.COMPONENT_ADDED_BY_HANDLER_MARKER, Boolean.TRUE);
429 return panel;
430 }
431
432 public static void addFacet(FaceletContext ctx, UIComponent parent, UIComponent c, String facetName)
433 {
434
435
436 UIComponent facet = parent.getFacets().get(facetName);
437 if (facet == null)
438 {
439
440 parent.getFacets().put(facetName, c);
441 }
442 else if (!(facet instanceof UIPanel))
443 {
444
445 UIComponent child = facet;
446 facet = createFacetUIPanel(ctx, parent, facetName);
447 facet.getChildren().add(child);
448 facet.getChildren().add(c);
449 parent.getFacets().put(facetName, facet);
450 }
451 else
452 {
453
454
455 if (Boolean.TRUE.equals(facet.getAttributes().get(FACET_CREATED_UIPANEL_MARKER)))
456 {
457 facet.getChildren().add(c);
458 }
459 else
460 {
461
462
463 UIComponent oldPanel = facet;
464 facet = createFacetUIPanel(ctx, parent, facetName);
465 facet.getChildren().add(oldPanel);
466 facet.getChildren().add(c);
467 parent.getFacets().put(facetName, facet);
468 }
469 }
470 }
471
472 public static void removeFacet(FaceletContext ctx, UIComponent parent, UIComponent c, String facetName)
473 {
474 UIComponent facet = parent.getFacet(facetName);
475 if (Boolean.TRUE.equals(facet.getAttributes().get(FACET_CREATED_UIPANEL_MARKER)))
476 {
477 facet.getChildren().remove(c);
478 }
479 else
480 {
481 parent.getFacets().remove(facetName);
482 }
483 }
484
485 public static void markComponentToRestoreFully(FacesContext context, UIComponent component)
486 {
487 if (MyfacesConfig.getCurrentInstance(context.getExternalContext()).isRefreshTransientBuildOnPSSPreserveState())
488 {
489 component.getAttributes().put(DefaultFaceletsStateManagementStrategy.COMPONENT_ADDED_AFTER_BUILD_VIEW,
490 ComponentState.REMOVE_ADD);
491 }
492
493 if (FaceletViewDeclarationLanguage.isRefreshTransientBuildOnPSSAuto(context))
494 {
495 FaceletViewDeclarationLanguage.cleanTransientBuildOnRestore(context);
496 }
497 }
498
499 public static UIComponent findComponentChildOrFacetFrom(FacesContext facesContext, UIComponent parent, String expr)
500 {
501 final char separatorChar = UINamingContainer.getSeparatorChar(facesContext);
502 int separator = expr.indexOf(separatorChar);
503 if (separator == -1)
504 {
505 return ComponentSupport.findComponentChildOrFacetFrom(
506 parent, expr, null);
507 }
508 else
509 {
510 return ComponentSupport.findComponentChildOrFacetFrom(
511 parent, expr.substring(0,separator), expr);
512 }
513 }
514
515 public static UIComponent findComponentChildOrFacetFrom(UIComponent parent, String id, String innerExpr)
516 {
517 if (parent.getFacetCount() > 0)
518 {
519 for (UIComponent facet : parent.getFacets().values())
520 {
521 if (id.equals(facet.getId()))
522 {
523 if (innerExpr == null)
524 {
525 return facet;
526 }
527 else if (facet instanceof NamingContainer)
528 {
529 UIComponent find = facet.findComponent(innerExpr);
530 if (find != null)
531 {
532 return find;
533 }
534 }
535 }
536 else if (!(facet instanceof NamingContainer))
537 {
538 UIComponent find = findComponentChildOrFacetFrom(facet, id, innerExpr);
539 if (find != null)
540 {
541 return find;
542 }
543 }
544 }
545 }
546 if (parent.getChildCount() > 0)
547 {
548 for (int i = 0, childCount = parent.getChildCount(); i < childCount; i++)
549 {
550 UIComponent child = parent.getChildren().get(i);
551 if (id.equals(child.getId()))
552 {
553 if (innerExpr == null)
554 {
555 return child;
556 }
557 else if (child instanceof NamingContainer)
558 {
559 UIComponent find = child.findComponent(innerExpr);
560 if (find != null)
561 {
562 return find;
563 }
564 }
565 }
566 else if (!(child instanceof NamingContainer))
567 {
568 UIComponent find = findComponentChildOrFacetFrom(child, id, innerExpr);
569 if (find != null)
570 {
571 return find;
572 }
573 }
574 }
575 }
576 return null;
577 }
578
579 public static String getFindComponentExpression(FacesContext facesContext, UIComponent component)
580 {
581 char separatorChar = UINamingContainer.getSeparatorChar(facesContext);
582 UIComponent parent = component.getParent();
583 StringBuilder sb = new StringBuilder();
584 sb.append(component.getId());
585 while (parent != null)
586 {
587 if (parent instanceof NamingContainer)
588 {
589 sb.insert(0, separatorChar);
590 sb.insert(0, parent.getId());
591 }
592 parent = parent.getParent();
593 }
594 return sb.toString();
595 }
596
597 public static Object restoreInitialTagState(FaceletContext ctx, FaceletCompositionContext fcc,
598 UIComponent parent, String uniqueId)
599 {
600 Object value = null;
601
602
603
604
605 if (fcc.isUsingPSSOnThisView() && !fcc.isRefreshTransientBuildOnPSSPreserveState())
606 {
607 UIViewRoot root = getViewRoot(ctx, parent);
608 FaceletState map = (FaceletState) root.getAttributes().get(FACELET_STATE_INSTANCE);
609 if (map == null)
610 {
611 value = null;
612 }
613 else
614 {
615 value = map.getState(uniqueId);
616 }
617 }
618 return value;
619 }
620
621 public static void saveInitialTagState(FaceletContext ctx, FaceletCompositionContext fcc,
622 UIComponent parent, String uniqueId, Object value)
623 {
624
625
626
627
628
629
630
631
632
633
634 if (fcc.isUsingPSSOnThisView() && !fcc.isRefreshTransientBuildOnPSSPreserveState())
635 {
636 UIViewRoot root = getViewRoot(ctx, parent);
637 FaceletState map = (FaceletState) root.getAttributes().get(FACELET_STATE_INSTANCE);
638 if (map == null)
639 {
640 map = new FaceletState();
641 root.getAttributes().put(FACELET_STATE_INSTANCE, map);
642 }
643 map.putState(uniqueId, value);
644 }
645 }
646
647 }