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 ctx.getFacesContext().getAttributes().put(
157 FaceletContext.FACELET_CONTEXT_KEY, this);
158 }
159
160 public DefaultFaceletContext(FacesContext faces, AbstractFacelet facelet, FaceletCompositionContext mctx)
161 {
162 _ctx = faces.getELContext();
163
164
165
166 _faces = faces;
167 _fnMapper = _ctx.getFunctionMapper();
168 _varMapper = _ctx.getVariableMapper();
169 if (_varMapper == null)
170 {
171 _defaultVarMapper = new DefaultVariableMapper();
172 _varMapper = _defaultVarMapper;
173 _varMapperBase = _defaultVarMapper;
174 }
175 else
176 {
177 _defaultVarMapper = new DefaultVariableMapper(_varMapper);
178 _varMapper = _defaultVarMapper;
179 _varMapperBase = _defaultVarMapper;
180 }
181
182 _faceletHierarchy = new ArrayList<AbstractFacelet>(1);
183 _faceletHierarchy.add(facelet);
184 _facelet = facelet;
185 _mctx = mctx;
186
187 _isolatedTemplateContext = new ArrayList<TemplateContext>(1);
188 _isolatedTemplateContext.add(new TemplateContextImpl());
189 _currentTemplateContext = 0;
190 _defaultVarMapper.setTemplateContext(_isolatedTemplateContext.get(_currentTemplateContext));
191
192 _isolatedPageContext = new ArrayList<PageContext>(8);
193
194 _elExpressionCacheMode = mctx.getELExpressionCacheMode();
195 _isCacheELExpressions = !ELExpressionCacheMode.noCache.equals(_elExpressionCacheMode);
196 }
197
198
199
200
201 @Override
202 public FacesContext getFacesContext()
203 {
204 return _faces;
205 }
206
207
208
209
210 @Override
211 public ExpressionFactory getExpressionFactory()
212 {
213 return _facelet.getExpressionFactory();
214 }
215
216
217
218
219 @Override
220 public void setVariableMapper(VariableMapper varMapper)
221 {
222
223 _varMapper = varMapper;
224 _varMapperBase = (_varMapper instanceof VariableMapperBase) ? (VariableMapperBase) varMapper : null;
225 }
226
227
228
229
230 @Override
231 public void setFunctionMapper(FunctionMapper fnMapper)
232 {
233
234 _fnMapper = fnMapper;
235 }
236
237
238
239
240 @Override
241 public void includeFacelet(UIComponent parent, String relativePath)
242 throws IOException
243 {
244 _facelet.include(this, parent, relativePath);
245 }
246
247
248
249
250 @Override
251 public FunctionMapper getFunctionMapper()
252 {
253 return _fnMapper;
254 }
255
256
257
258
259 @Override
260 public VariableMapper getVariableMapper()
261 {
262 return _varMapper;
263 }
264
265
266
267
268 @Override
269 @SuppressWarnings("unchecked")
270 public Object getContext(Class key)
271 {
272 return _ctx.getContext(key);
273 }
274
275
276
277
278 @Override
279 @SuppressWarnings("unchecked")
280 public void putContext(Class key, Object contextObject)
281 {
282 _ctx.putContext(key, contextObject);
283 }
284
285
286
287
288 @Override
289 public String generateUniqueId(String base)
290 {
291 if (_prefix == null)
292 {
293 _uniqueIdBuilder = new StringBuilder(
294 _faceletHierarchy.size() * 30);
295 for (int i = 0; i < _faceletHierarchy.size(); i++)
296 {
297 AbstractFacelet facelet = _faceletHierarchy.get(i);
298 _uniqueIdBuilder.append(facelet.getFaceletId());
299 }
300
301
302
303
304
305
306
307 Integer prefixInt = new Integer(Math.abs(_uniqueIdBuilder.toString().hashCode()));
308 _prefix = prefixInt.toString();
309 }
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 _uniqueIdBuilder.append("_");
323 _uniqueIdBuilder.append(_prefix);
324
325
326
327
328
329
330 if (!getFaceletCompositionContext().isInMetadataSection())
331 {
332 _uniqueIdBuilder.append("_");
333 _uniqueIdBuilder.append(base);
334 }
335 uniqueIdFromIterator = _uniqueIdBuilder.toString();
336 getFaceletCompositionContext().addUniqueId(uniqueIdFromIterator);
337 return uniqueIdFromIterator;
338 }
339 else
340 {
341 getFaceletCompositionContext().incrementUniqueId();
342 return uniqueIdFromIterator;
343 }
344 }
345
346
347
348
349 @Override
350 public Object getAttribute(String name)
351 {
352 if (_varMapper != null)
353 {
354 ValueExpression ve = _varMapper.resolveVariable(name);
355 if (ve != null)
356 {
357 return ve.getValue(this);
358 }
359 }
360 return null;
361 }
362
363
364
365
366 @Override
367 public void setAttribute(String name, Object value)
368 {
369 if (_varMapper != null)
370 {
371 if (value == null)
372 {
373 _varMapper.setVariable(name, null);
374 }
375 else
376 {
377 _varMapper.setVariable(name, _facelet.getExpressionFactory()
378 .createValueExpression(value, Object.class));
379 }
380 }
381 }
382
383
384
385
386 @Override
387 public void includeFacelet(UIComponent parent, URL absolutePath)
388 throws IOException, FacesException, ELException
389 {
390 _facelet.include(this, parent, absolutePath);
391 }
392
393
394
395
396 @Override
397 public ELResolver getELResolver()
398 {
399 return _ctx.getELResolver();
400 }
401
402
403
404 @Override
405 public TemplateManager popClient(TemplateClient client)
406 {
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421 return _isolatedTemplateContext.get(_currentTemplateContext).popClient(this);
422 }
423
424 @Override
425 public void pushClient(final TemplateClient client)
426 {
427
428
429 _isolatedTemplateContext.get(_currentTemplateContext).pushClient(this, this._facelet, client);
430 }
431
432 public TemplateManager popExtendedClient(TemplateClient client)
433 {
434
435 return _isolatedTemplateContext.get(_currentTemplateContext).popExtendedClient(this);
436 }
437
438 @Override
439 public void extendClient(final TemplateClient client)
440 {
441
442
443 _isolatedTemplateContext.get(_currentTemplateContext).extendClient(this, this._facelet, client);
444 }
445
446 @Override
447 public boolean includeDefinition(UIComponent parent, String name)
448 throws IOException, FaceletException, FacesException, ELException
449 {
450
451
452
453
454
455
456
457
458
459
460 return _isolatedTemplateContext.get(_currentTemplateContext).includeDefinition(
461 this, this._facelet, parent, name);
462 }
463
464
465
466
467
468
469
470
471
472
473
474
475
476
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 @Override
581 public void pushCompositeComponentClient(final TemplateClient client)
582 {
583 TemplateContext itc = new TemplateContextImpl();
584 itc.setCompositeComponentClient(
585 new CompositeComponentTemplateManager(this._facelet, client, getPageContext()));
586 _isolatedTemplateContext.add(itc);
587 _currentTemplateContext++;
588 _defaultVarMapper.setTemplateContext(itc);
589 }
590
591 @Override
592 public void popCompositeComponentClient()
593 {
594 if (_currentTemplateContext > 0)
595 {
596 _isolatedTemplateContext.remove(_currentTemplateContext);
597 _currentTemplateContext--;
598 _defaultVarMapper.setTemplateContext(_isolatedTemplateContext.get(_currentTemplateContext));
599 }
600 }
601
602 @Override
603 public void pushTemplateContext(TemplateContext client)
604 {
605 _isolatedTemplateContext.add(client);
606 _currentTemplateContext++;
607 _defaultVarMapper.setTemplateContext(client);
608 }
609
610
611 @Override
612 public TemplateContext popTemplateContext()
613 {
614 if (_currentTemplateContext > 0)
615 {
616 TemplateContext itc = _isolatedTemplateContext.get(_currentTemplateContext);
617 _isolatedTemplateContext.remove(_currentTemplateContext);
618 _currentTemplateContext--;
619 _defaultVarMapper.setTemplateContext(_isolatedTemplateContext.get(_currentTemplateContext));
620 return itc;
621 }
622 return null;
623 }
624
625 @Override
626 public TemplateContext getTemplateContext()
627 {
628 return _isolatedTemplateContext.get(_currentTemplateContext);
629 }
630
631 @Override
632 public boolean includeCompositeComponentDefinition(UIComponent parent, String name)
633 throws IOException, FaceletException, FacesException, ELException
634 {
635
636
637
638
639
640
641
642
643
644
645
646
647 TemplateClient ccClient = _isolatedTemplateContext.get(_currentTemplateContext).getCompositeComponentClient();
648 if (ccClient != null)
649 {
650 return ccClient.apply(this, parent, name);
651 }
652 return false;
653 }
654
655 private final static class CompositeComponentTemplateManager extends TemplateManager implements TemplateClient
656 {
657 private final AbstractFacelet _owner;
658
659 protected final TemplateClient _target;
660
661 private final Set<String> _names = new HashSet<String>();
662
663 private final PageContext _pageContext;
664
665 public CompositeComponentTemplateManager(AbstractFacelet owner, TemplateClient target, PageContext pageContext)
666 {
667 this._owner = owner;
668 this._target = target;
669 this._pageContext = pageContext;
670 }
671
672 public boolean apply(FaceletContext ctx, UIComponent parent, String name)
673 throws IOException, FacesException, FaceletException,
674 ELException
675 {
676 String testName = (name != null) ? name : "facelets._NULL_DEF_";
677 if (this._names.contains(testName))
678 {
679 return false;
680 }
681 else
682 {
683 this._names.add(testName);
684 boolean found = false;
685 AbstractFaceletContext actx = new DefaultFaceletContext(
686 (DefaultFaceletContext) ctx, this._owner, false);
687 ctx.getFacesContext().getAttributes().put(FaceletContext.FACELET_CONTEXT_KEY, actx);
688 try
689 {
690 actx.pushPageContext(this._pageContext);
691 found = this._target
692 .apply(actx,
693 parent, name);
694 }
695 finally
696 {
697 actx.popPageContext();
698 }
699 ctx.getFacesContext().getAttributes().put(FaceletContext.FACELET_CONTEXT_KEY, ctx);
700 this._names.remove(testName);
701 return found;
702 }
703 }
704
705 public boolean equals(Object o)
706 {
707
708
709 return this._owner == o || this._target == o;
710 }
711
712 @Override
713 public int hashCode()
714 {
715 int result = _owner != null ? _owner.hashCode() : 0;
716 result = 31 * result + (_target != null ? _target.hashCode() : 0);
717 return result;
718 }
719 }
720
721 @Override
722 public void pushPageContext(PageContext client)
723 {
724 _isolatedPageContext.add(client);
725 _defaultVarMapper.setPageContext(client);
726 }
727
728 @Override
729 public PageContext popPageContext()
730 {
731 if (!_isolatedPageContext.isEmpty())
732 {
733 int currentPageContext = _isolatedPageContext.size()-1;
734 PageContext itc = _isolatedPageContext.get(currentPageContext);
735 _isolatedPageContext.remove(currentPageContext);
736 if (!_isolatedPageContext.isEmpty())
737 {
738 _defaultVarMapper.setPageContext(getPageContext());
739 }
740 else
741 {
742 _defaultVarMapper.setPageContext(null);
743 }
744 return itc;
745 }
746 return null;
747 }
748
749 @Override
750 public PageContext getPageContext()
751 {
752 return _isolatedPageContext.get(_isolatedPageContext.size()-1);
753 }
754
755
756
757
758
759
760 @Override
761 public boolean isPropertyResolved()
762 {
763 return _ctx.isPropertyResolved();
764 }
765
766
767
768
769 @Override
770 public void setPropertyResolved(boolean resolved)
771 {
772 _ctx.setPropertyResolved(resolved);
773 }
774
775 @Override
776 public void applyCompositeComponent(UIComponent parent, Resource resource)
777 throws IOException, FaceletException, FacesException, ELException
778 {
779 _facelet.applyCompositeComponent(this, parent, resource);
780 }
781
782 @Override
783 public Iterator<AjaxHandler> getAjaxHandlers()
784 {
785 if (_ajaxHandlerStack != null && !_ajaxHandlerStack.isEmpty())
786 {
787 return _ajaxHandlerStack.iterator();
788 }
789 return null;
790 }
791
792 @Override
793 public void popAjaxHandlerToStack()
794 {
795 if (_ajaxHandlerStack != null && !_ajaxHandlerStack.isEmpty())
796 {
797 _ajaxHandlerStack.removeFirst();
798 }
799 }
800
801 @Override
802 public void pushAjaxHandlerToStack(
803 AjaxHandler parent)
804 {
805 if (_ajaxHandlerStack == null)
806 {
807 _ajaxHandlerStack = new LinkedList<AjaxHandler>();
808 }
809
810 _ajaxHandlerStack.addFirst(parent);
811 }
812
813 @Override
814 public boolean isBuildingCompositeComponentMetadata()
815 {
816 return _facelet.isBuildingCompositeComponentMetadata();
817 }
818
819 public FaceletCompositionContext getFaceletCompositionContext()
820 {
821 return _mctx;
822 }
823
824 public boolean isAnyFaceletsVariableResolved()
825 {
826
827 if (_varMapperBase != null)
828 {
829 return _varMapperBase.isAnyFaceletsVariableResolved();
830 }
831 return true;
832 }
833
834 public boolean isAllowCacheELExpressions()
835 {
836 return _isCacheELExpressions && getTemplateContext().isAllowCacheELExpressions()
837 && getPageContext().isAllowCacheELExpressions();
838 }
839
840 public void beforeConstructELExpression()
841 {
842
843 if (_varMapperBase != null)
844 {
845 _varMapperBase.beforeConstructELExpression();
846 }
847 }
848
849 public void afterConstructELExpression()
850 {
851
852 if (_varMapperBase != null)
853 {
854 _varMapperBase.afterConstructELExpression();
855 }
856 }
857
858 public ELExpressionCacheMode getELExpressionCacheMode()
859 {
860 return _elExpressionCacheMode;
861 }
862
863 }