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.impl;
20
21 import java.io.IOException;
22 import java.net.URL;
23 import java.util.ArrayList;
24 import java.util.HashSet;
25 import java.util.Iterator;
26 import java.util.LinkedList;
27 import java.util.List;
28 import java.util.Set;
29
30 import javax.el.ELContext;
31 import javax.el.ELException;
32 import javax.el.ELResolver;
33 import javax.el.ExpressionFactory;
34 import javax.el.FunctionMapper;
35 import javax.el.ValueExpression;
36 import javax.el.VariableMapper;
37 import javax.faces.FacesException;
38 import javax.faces.application.Resource;
39 import javax.faces.component.UIComponent;
40 import javax.faces.context.FacesContext;
41 import javax.faces.view.facelets.FaceletContext;
42 import javax.faces.view.facelets.FaceletException;
43
44 import org.apache.myfaces.view.facelets.AbstractFacelet;
45 import org.apache.myfaces.view.facelets.AbstractFaceletContext;
46 import org.apache.myfaces.view.facelets.ELExpressionCacheMode;
47 import org.apache.myfaces.view.facelets.FaceletCompositionContext;
48 import org.apache.myfaces.view.facelets.PageContext;
49 import org.apache.myfaces.view.facelets.TemplateClient;
50 import org.apache.myfaces.view.facelets.TemplateContext;
51 import org.apache.myfaces.view.facelets.TemplateManager;
52 import org.apache.myfaces.view.facelets.el.DefaultVariableMapper;
53 import org.apache.myfaces.view.facelets.el.VariableMapperBase;
54 import org.apache.myfaces.view.facelets.tag.jsf.core.AjaxHandler;
55
56
57
58
59
60
61
62
63
64
65
66
67 final class DefaultFaceletContext extends AbstractFaceletContext
68 {
69 private final FacesContext _faces;
70
71 private final ELContext _ctx;
72
73 private final AbstractFacelet _facelet;
74 private final List<AbstractFacelet> _faceletHierarchy;
75
76 private VariableMapper _varMapper;
77 private final DefaultVariableMapper _defaultVarMapper;
78 private VariableMapperBase _varMapperBase;
79
80 private FunctionMapper _fnMapper;
81
82
83
84 private String _prefix;
85
86 private StringBuilder _uniqueIdBuilder;
87
88
89
90 private final FaceletCompositionContext _mctx;
91
92 private LinkedList<AjaxHandler> _ajaxHandlerStack;
93
94 private final List<TemplateContext> _isolatedTemplateContext;
95
96 private int _currentTemplateContext;
97
98 private ELExpressionCacheMode _elExpressionCacheMode;
99
100 private boolean _isCacheELExpressions;
101
102 private final List<PageContext> _isolatedPageContext;
103
104 public DefaultFaceletContext(DefaultFaceletContext ctx,
105 AbstractFacelet facelet, boolean ccWrap)
106 {
107 _ctx = ctx._ctx;
108
109
110
111 _faces = ctx._faces;
112 _fnMapper = ctx._fnMapper;
113 _varMapper = ctx._varMapper;
114 _defaultVarMapper = ctx._defaultVarMapper;
115 _varMapperBase = ctx._varMapperBase;
116 _faceletHierarchy = new ArrayList<AbstractFacelet>(ctx._faceletHierarchy
117 .size() + 1);
118 _faceletHierarchy.addAll(ctx._faceletHierarchy);
119 _faceletHierarchy.add(facelet);
120 _facelet = facelet;
121 _mctx = ctx._mctx;
122
123 if (ccWrap)
124 {
125
126
127
128 _ajaxHandlerStack = null;
129 }
130 else
131 {
132
133
134 _ajaxHandlerStack = ctx._ajaxHandlerStack;
135 }
136
137
138
139
140
141
142
143
144
145
146 _isolatedTemplateContext = ctx._isolatedTemplateContext;
147 _currentTemplateContext = ctx._currentTemplateContext;
148
149 _isolatedPageContext = ctx._isolatedPageContext;
150
151 _elExpressionCacheMode = ctx._elExpressionCacheMode;
152 _isCacheELExpressions = ctx._isCacheELExpressions;
153
154 }
155
156 public DefaultFaceletContext(FacesContext faces, AbstractFacelet facelet, FaceletCompositionContext mctx)
157 {
158 _ctx = faces.getELContext();
159
160
161
162 _faces = faces;
163 _fnMapper = _ctx.getFunctionMapper();
164 _varMapper = _ctx.getVariableMapper();
165 if (_varMapper == null)
166 {
167 _defaultVarMapper = new DefaultVariableMapper();
168 _varMapper = _defaultVarMapper;
169 _varMapperBase = _defaultVarMapper;
170 }
171 else
172 {
173 _defaultVarMapper = new DefaultVariableMapper(_varMapper);
174 _varMapper = _defaultVarMapper;
175 _varMapperBase = _defaultVarMapper;
176 }
177
178 _faceletHierarchy = new ArrayList<AbstractFacelet>(1);
179 _faceletHierarchy.add(facelet);
180 _facelet = facelet;
181 _mctx = mctx;
182
183 _isolatedTemplateContext = new ArrayList<TemplateContext>(1);
184 _isolatedTemplateContext.add(new TemplateContextImpl());
185 _currentTemplateContext = 0;
186 _defaultVarMapper.setTemplateContext(_isolatedTemplateContext.get(_currentTemplateContext));
187
188 _isolatedPageContext = new ArrayList<PageContext>(8);
189
190 _elExpressionCacheMode = mctx.getELExpressionCacheMode();
191 _isCacheELExpressions = !ELExpressionCacheMode.noCache.equals(_elExpressionCacheMode);
192 }
193
194
195
196
197 @Override
198 public FacesContext getFacesContext()
199 {
200 return _faces;
201 }
202
203
204
205
206 @Override
207 public ExpressionFactory getExpressionFactory()
208 {
209 return _facelet.getExpressionFactory();
210 }
211
212
213
214
215 @Override
216 public void setVariableMapper(VariableMapper varMapper)
217 {
218
219 _varMapper = varMapper;
220 _varMapperBase = (_varMapper instanceof VariableMapperBase) ? (VariableMapperBase) varMapper : null;
221 }
222
223
224
225
226 @Override
227 public void setFunctionMapper(FunctionMapper fnMapper)
228 {
229
230 _fnMapper = fnMapper;
231 }
232
233
234
235
236 @Override
237 public void includeFacelet(UIComponent parent, String relativePath)
238 throws IOException
239 {
240 _facelet.include(this, parent, relativePath);
241 }
242
243
244
245
246 @Override
247 public FunctionMapper getFunctionMapper()
248 {
249 return _fnMapper;
250 }
251
252
253
254
255 @Override
256 public VariableMapper getVariableMapper()
257 {
258 return _varMapper;
259 }
260
261
262
263
264 @Override
265 @SuppressWarnings("unchecked")
266 public Object getContext(Class key)
267 {
268 return _ctx.getContext(key);
269 }
270
271
272
273
274 @Override
275 @SuppressWarnings("unchecked")
276 public void putContext(Class key, Object contextObject)
277 {
278 _ctx.putContext(key, contextObject);
279 }
280
281 private void initPrefix()
282 {
283 if (_prefix == null)
284 {
285 _uniqueIdBuilder = new StringBuilder(
286 _faceletHierarchy.size() * 30);
287 for (int i = 0; i < _faceletHierarchy.size(); i++)
288 {
289 AbstractFacelet facelet = _faceletHierarchy.get(i);
290 _uniqueIdBuilder.append(facelet.getFaceletId());
291 }
292
293
294
295
296
297
298
299 _prefix = Integer.toString(Math.abs(_uniqueIdBuilder.toString().hashCode()));
300 }
301 }
302
303
304
305
306 @Override
307 public String generateUniqueId(String base)
308 {
309 initPrefix();
310
311 _uniqueIdBuilder.setLength(0);
312
313
314
315
316
317
318 String uniqueIdFromIterator = getFaceletCompositionContext().getUniqueIdFromIterator();
319 if (uniqueIdFromIterator == null)
320 {
321 getFaceletCompositionContext().generateUniqueId(_uniqueIdBuilder);
322
323
324
325
326
327
328
329
330
331 if (!getFaceletCompositionContext().isInMetadataSection())
332 {
333 _uniqueIdBuilder.append("_");
334 _uniqueIdBuilder.append(_prefix);
335 _uniqueIdBuilder.append("_");
336 _uniqueIdBuilder.append(base);
337 }
338 uniqueIdFromIterator = _uniqueIdBuilder.toString();
339 getFaceletCompositionContext().addUniqueId(uniqueIdFromIterator);
340 return uniqueIdFromIterator;
341 }
342 else
343 {
344 getFaceletCompositionContext().incrementUniqueId();
345 return uniqueIdFromIterator;
346 }
347 }
348
349 public String generateUniqueFaceletTagId(String count, String base)
350 {
351 initPrefix();
352 _uniqueIdBuilder.setLength(0);
353 _uniqueIdBuilder.append(count);
354 _uniqueIdBuilder.append("_");
355 _uniqueIdBuilder.append(_prefix);
356 _uniqueIdBuilder.append("_");
357 _uniqueIdBuilder.append(base);
358 return _uniqueIdBuilder.toString();
359 }
360
361
362
363
364 @Override
365 public Object getAttribute(String name)
366 {
367 if (_varMapper != null)
368 {
369 ValueExpression ve = _varMapper.resolveVariable(name);
370 if (ve != null)
371 {
372 return ve.getValue(this);
373 }
374 }
375 return null;
376 }
377
378
379
380
381 @Override
382 public void setAttribute(String name, Object value)
383 {
384 if (_varMapper != null)
385 {
386 if (value == null)
387 {
388 _varMapper.setVariable(name, null);
389 }
390 else
391 {
392 _varMapper.setVariable(name, _facelet.getExpressionFactory()
393 .createValueExpression(value, Object.class));
394 }
395 }
396 }
397
398
399
400
401 @Override
402 public void includeFacelet(UIComponent parent, URL absolutePath)
403 throws IOException, FacesException, ELException
404 {
405 _facelet.include(this, parent, absolutePath);
406 }
407
408
409
410
411 @Override
412 public ELResolver getELResolver()
413 {
414 return _ctx.getELResolver();
415 }
416
417
418
419 @Override
420 public TemplateManager popClient(TemplateClient client)
421 {
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436 return _isolatedTemplateContext.get(_currentTemplateContext).popClient(this);
437 }
438
439 @Override
440 public void pushClient(final TemplateClient client)
441 {
442
443
444 _isolatedTemplateContext.get(_currentTemplateContext).pushClient(this, this._facelet, client);
445 }
446
447 public TemplateManager popExtendedClient(TemplateClient client)
448 {
449
450 return _isolatedTemplateContext.get(_currentTemplateContext).popExtendedClient(this);
451 }
452
453 @Override
454 public void extendClient(final TemplateClient client)
455 {
456
457
458 _isolatedTemplateContext.get(_currentTemplateContext).extendClient(this, this._facelet, client);
459 }
460
461 @Override
462 public boolean includeDefinition(UIComponent parent, String name)
463 throws IOException, FaceletException, FacesException, ELException
464 {
465
466
467
468
469
470
471
472
473
474
475 return _isolatedTemplateContext.get(_currentTemplateContext).includeDefinition(
476 this, this._facelet, parent, name);
477 }
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
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
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595 @Override
596 public void pushCompositeComponentClient(final TemplateClient client)
597 {
598 TemplateContext itc = new TemplateContextImpl();
599 itc.setCompositeComponentClient(
600 new CompositeComponentTemplateManager(this._facelet, client, getPageContext()));
601 _isolatedTemplateContext.add(itc);
602 _currentTemplateContext++;
603 _defaultVarMapper.setTemplateContext(itc);
604 }
605
606 @Override
607 public void popCompositeComponentClient()
608 {
609 if (_currentTemplateContext > 0)
610 {
611 _isolatedTemplateContext.remove(_currentTemplateContext);
612 _currentTemplateContext--;
613 _defaultVarMapper.setTemplateContext(_isolatedTemplateContext.get(_currentTemplateContext));
614 }
615 }
616
617 @Override
618 public void pushTemplateContext(TemplateContext client)
619 {
620 _isolatedTemplateContext.add(client);
621 _currentTemplateContext++;
622 _defaultVarMapper.setTemplateContext(client);
623 }
624
625
626 @Override
627 public TemplateContext popTemplateContext()
628 {
629 if (_currentTemplateContext > 0)
630 {
631 TemplateContext itc = _isolatedTemplateContext.get(_currentTemplateContext);
632 _isolatedTemplateContext.remove(_currentTemplateContext);
633 _currentTemplateContext--;
634 _defaultVarMapper.setTemplateContext(_isolatedTemplateContext.get(_currentTemplateContext));
635 return itc;
636 }
637 return null;
638 }
639
640 @Override
641 public TemplateContext getTemplateContext()
642 {
643 return _isolatedTemplateContext.get(_currentTemplateContext);
644 }
645
646 @Override
647 public boolean includeCompositeComponentDefinition(UIComponent parent, String name)
648 throws IOException, FaceletException, FacesException, ELException
649 {
650
651
652
653
654
655
656
657
658
659
660
661
662 TemplateClient ccClient = _isolatedTemplateContext.get(_currentTemplateContext).getCompositeComponentClient();
663 if (ccClient != null)
664 {
665 return ccClient.apply(this, parent, name);
666 }
667 return false;
668 }
669
670 private final static class CompositeComponentTemplateManager extends TemplateManager implements TemplateClient
671 {
672 private final AbstractFacelet _owner;
673
674 protected final TemplateClient _target;
675
676 private final Set<String> _names = new HashSet<String>();
677
678 private final PageContext _pageContext;
679
680 public CompositeComponentTemplateManager(AbstractFacelet owner, TemplateClient target, PageContext pageContext)
681 {
682 this._owner = owner;
683 this._target = target;
684 this._pageContext = pageContext;
685 }
686
687 public boolean apply(FaceletContext ctx, UIComponent parent, String name)
688 throws IOException, FacesException, FaceletException,
689 ELException
690 {
691 String testName = (name != null) ? name : "facelets._NULL_DEF_";
692 if (this._names.contains(testName))
693 {
694 return false;
695 }
696 else
697 {
698 this._names.add(testName);
699 boolean found = false;
700 AbstractFaceletContext actx = new DefaultFaceletContext(
701 (DefaultFaceletContext) ctx, this._owner, false);
702 ctx.getFacesContext().getAttributes().put(FaceletContext.FACELET_CONTEXT_KEY, actx);
703 try
704 {
705 actx.pushPageContext(this._pageContext);
706 found = this._target
707 .apply(actx,
708 parent, name);
709 }
710 finally
711 {
712 actx.popPageContext();
713 }
714 ctx.getFacesContext().getAttributes().put(FaceletContext.FACELET_CONTEXT_KEY, ctx);
715 this._names.remove(testName);
716 return found;
717 }
718 }
719
720 public boolean equals(Object o)
721 {
722
723
724 return this._owner == o || this._target == o;
725 }
726
727 @Override
728 public int hashCode()
729 {
730 int result = _owner != null ? _owner.hashCode() : 0;
731 result = 31 * result + (_target != null ? _target.hashCode() : 0);
732 return result;
733 }
734 }
735
736 @Override
737 public void pushPageContext(PageContext client)
738 {
739 _isolatedPageContext.add(client);
740 _defaultVarMapper.setPageContext(client);
741 }
742
743 @Override
744 public PageContext popPageContext()
745 {
746 if (!_isolatedPageContext.isEmpty())
747 {
748 int currentPageContext = _isolatedPageContext.size()-1;
749 PageContext itc = _isolatedPageContext.get(currentPageContext);
750 _isolatedPageContext.remove(currentPageContext);
751 if (!_isolatedPageContext.isEmpty())
752 {
753 _defaultVarMapper.setPageContext(getPageContext());
754 }
755 else
756 {
757 _defaultVarMapper.setPageContext(null);
758 }
759 return itc;
760 }
761 return null;
762 }
763
764 @Override
765 public PageContext getPageContext()
766 {
767 return _isolatedPageContext.get(_isolatedPageContext.size()-1);
768 }
769
770
771
772
773
774
775 @Override
776 public boolean isPropertyResolved()
777 {
778 return _ctx.isPropertyResolved();
779 }
780
781
782
783
784 @Override
785 public void setPropertyResolved(boolean resolved)
786 {
787 _ctx.setPropertyResolved(resolved);
788 }
789
790 @Override
791 public void applyCompositeComponent(UIComponent parent, Resource resource)
792 throws IOException, FaceletException, FacesException, ELException
793 {
794 _facelet.applyCompositeComponent(this, parent, resource);
795 }
796
797 @Override
798 public Iterator<AjaxHandler> getAjaxHandlers()
799 {
800 if (_ajaxHandlerStack != null && !_ajaxHandlerStack.isEmpty())
801 {
802 return _ajaxHandlerStack.iterator();
803 }
804 return null;
805 }
806
807 @Override
808 public void popAjaxHandlerToStack()
809 {
810 if (_ajaxHandlerStack != null && !_ajaxHandlerStack.isEmpty())
811 {
812 _ajaxHandlerStack.removeFirst();
813 }
814 }
815
816 @Override
817 public void pushAjaxHandlerToStack(
818 AjaxHandler parent)
819 {
820 if (_ajaxHandlerStack == null)
821 {
822 _ajaxHandlerStack = new LinkedList<AjaxHandler>();
823 }
824
825 _ajaxHandlerStack.addFirst(parent);
826 }
827
828 @Override
829 public boolean isBuildingCompositeComponentMetadata()
830 {
831 return _facelet.isBuildingCompositeComponentMetadata();
832 }
833
834 public FaceletCompositionContext getFaceletCompositionContext()
835 {
836 return _mctx;
837 }
838
839 public boolean isAnyFaceletsVariableResolved()
840 {
841
842 if (_varMapperBase != null)
843 {
844 return _varMapperBase.isAnyFaceletsVariableResolved();
845 }
846 return true;
847 }
848
849 public boolean isAllowCacheELExpressions()
850 {
851 return _isCacheELExpressions && getTemplateContext().isAllowCacheELExpressions()
852 && getPageContext().isAllowCacheELExpressions();
853 }
854
855 public void beforeConstructELExpression()
856 {
857
858 if (_varMapperBase != null)
859 {
860 _varMapperBase.beforeConstructELExpression();
861 }
862 }
863
864 public void afterConstructELExpression()
865 {
866
867 if (_varMapperBase != null)
868 {
869 _varMapperBase.afterConstructELExpression();
870 }
871 }
872
873 public ELExpressionCacheMode getELExpressionCacheMode()
874 {
875 return _elExpressionCacheMode;
876 }
877
878 }