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