1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package javax.faces.component;
20
21 import java.util.ArrayList;
22 import java.util.ConcurrentModificationException;
23 import java.util.List;
24 import java.util.ListIterator;
25 import java.util.Locale;
26 import java.util.logging.Level;
27 import java.util.logging.Logger;
28
29 import javax.el.MethodExpression;
30 import javax.el.ValueExpression;
31 import javax.faces.FactoryFinder;
32 import javax.faces.context.ExternalContext;
33 import javax.faces.context.FacesContext;
34 import javax.faces.event.AbortProcessingException;
35 import javax.faces.event.FacesEvent;
36 import javax.faces.event.PhaseEvent;
37 import javax.faces.event.PhaseId;
38 import javax.faces.event.PhaseListener;
39 import javax.faces.lifecycle.Lifecycle;
40 import javax.faces.lifecycle.LifecycleFactory;
41 import javax.faces.webapp.FacesServlet;
42
43 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFComponent;
44 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFJspProperty;
45 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFProperty;
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 @JSFComponent(name="f:view", bodyContent="JSP", tagClass="org.apache.myfaces.taglib.core.ViewTag")
61 @JSFJspProperty(name="binding", returnType="java.lang.String", tagExcluded=true)
62 public class UIViewRoot extends UIComponentBase
63 {
64 public static final String COMPONENT_TYPE = "javax.faces.ViewRoot";
65 public static final String COMPONENT_FAMILY = "javax.faces.ViewRoot";
66
67 public static final String UNIQUE_ID_PREFIX = "j_id";
68 private static final int ANY_PHASE_ORDINAL = PhaseId.ANY_PHASE.getOrdinal();
69
70 private final Logger logger = Logger.getLogger(UIViewRoot.class.getName());
71
72
73
74
75
76 private long _uniqueIdCounter = 0;
77
78 private Locale _locale;
79 private String _renderKitId;
80 private String _viewId;
81
82
83 private List<FacesEvent> _events;
84 private List<PhaseListener> _phaseListeners;
85
86 private MethodExpression _beforePhaseListener;
87 private MethodExpression _afterPhaseListener;
88
89 private transient Lifecycle _lifecycle = null;
90
91 private interface Processor
92 {
93 void process();
94 }
95
96
97
98
99 public UIViewRoot()
100 {
101 setRendererType(null);
102 }
103
104 public void queueEvent(FacesEvent event)
105 {
106 checkNull(event, "event");
107 if (_events == null)
108 {
109 _events = new ArrayList<FacesEvent>();
110 }
111 _events.add(event);
112 }
113
114 public void processDecodes(final FacesContext context)
115 {
116 checkNull(context, "context");
117 process(context, PhaseId.APPLY_REQUEST_VALUES, new Processor()
118 {
119 public void process()
120 {
121 UIViewRoot.super.processDecodes(context);
122 }
123 }, true);
124 }
125
126 public void processValidators(final FacesContext context)
127 {
128 checkNull(context, "context");
129 process(context, PhaseId.PROCESS_VALIDATIONS, new Processor()
130 {
131 public void process()
132 {
133 UIViewRoot.super.processValidators(context);
134 }
135 }, true);
136 }
137
138 public void processUpdates(final FacesContext context)
139 {
140 checkNull(context, "context");
141 process(context, PhaseId.UPDATE_MODEL_VALUES, new Processor()
142 {
143 public void process()
144 {
145 UIViewRoot.super.processUpdates(context);
146 }
147 }, true);
148 }
149
150 public void processApplication(final FacesContext context)
151 {
152 checkNull(context, "context");
153 process(context, PhaseId.INVOKE_APPLICATION, null, true);
154 }
155
156 public void encodeBegin(FacesContext context) throws java.io.IOException
157 {
158 checkNull(context, "context");
159
160 boolean skipPhase = false;
161
162 try
163 {
164 skipPhase = notifyListeners(context, PhaseId.RENDER_RESPONSE,
165 getBeforePhaseListener(), true);
166 }
167 catch (Exception e)
168 {
169
170 logger.log(Level.SEVERE,
171 "Exception while processing phase listener: "
172 + e.getMessage(), e);
173 }
174
175 if (!skipPhase)
176 {
177 super.encodeBegin(context);
178 }
179 }
180
181 public void encodeEnd(FacesContext context) throws java.io.IOException
182 {
183 checkNull(context, "context");
184 super.encodeEnd(context);
185 try
186 {
187 notifyListeners(context, PhaseId.RENDER_RESPONSE,
188 getAfterPhaseListener(), false);
189 }
190 catch (Exception e)
191 {
192
193 logger.log(Level.SEVERE,
194 "Exception while processing phase listener: "
195 + e.getMessage(), e);
196 }
197 }
198
199
200
201
202 public String createUniqueId()
203 {
204 StringBuilder bld = __getSharedStringBuilder();
205 return bld.append(UNIQUE_ID_PREFIX).append(
206 _uniqueIdCounter++).toString();
207 }
208
209
210
211
212
213
214
215 @JSFProperty
216 public Locale getLocale()
217 {
218 if (_locale != null)
219 {
220 return _locale;
221 }
222 ValueExpression expression = getValueExpression("locale");
223 if (expression != null)
224 {
225 return (Locale) expression.getValue(getFacesContext()
226 .getELContext());
227 }
228 else
229 {
230 Object locale = getFacesContext().getApplication().getViewHandler()
231 .calculateLocale(getFacesContext());
232
233 if (locale instanceof Locale)
234 {
235 return (Locale) locale;
236 }
237 else if (locale instanceof String)
238 {
239 return stringToLocale((String) locale);
240 }
241 }
242
243 return getFacesContext().getApplication().getViewHandler()
244 .calculateLocale(getFacesContext());
245 }
246
247 public void setLocale(Locale locale)
248 {
249 this._locale = locale;
250 }
251
252 private boolean process(FacesContext context, PhaseId phaseId,
253 Processor processor, boolean broadcast)
254 {
255 if (!notifyListeners(context, phaseId, getBeforePhaseListener(), true))
256 {
257 if (processor != null)
258 processor.process();
259
260 if (broadcast)
261 {
262 _broadcastForPhase(phaseId);
263 }
264 }
265 if (context.getRenderResponse() || context.getResponseComplete())
266 {
267 clearEvents();
268 }
269 return notifyListeners(context, phaseId, getAfterPhaseListener(), false);
270 }
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286 private boolean notifyListeners(FacesContext context, PhaseId phaseId,
287 MethodExpression listener, boolean beforePhase)
288 {
289 boolean skipPhase = false;
290
291 if (listener != null
292 || (_phaseListeners != null && !_phaseListeners.isEmpty()))
293 {
294 PhaseEvent event = createEvent(context, phaseId);
295
296 if (listener != null)
297 {
298 listener.invoke(context.getELContext(), new Object[]
299 { event });
300 skipPhase = context.getResponseComplete()
301 || context.getRenderResponse();
302 }
303
304 if (_phaseListeners != null && !_phaseListeners.isEmpty())
305 {
306 for (PhaseListener phaseListener : _phaseListeners)
307 {
308 PhaseId listenerPhaseId = phaseListener.getPhaseId();
309 if (phaseId.equals(listenerPhaseId)
310 || PhaseId.ANY_PHASE.equals(listenerPhaseId))
311 {
312 if (beforePhase)
313 {
314 phaseListener.beforePhase(event);
315 }
316 else
317 {
318 phaseListener.afterPhase(event);
319 }
320 skipPhase = context.getResponseComplete()
321 || context.getRenderResponse();
322 }
323 }
324 }
325 }
326
327 return skipPhase;
328 }
329
330 private PhaseEvent createEvent(FacesContext context, PhaseId phaseId)
331 {
332 if (_lifecycle == null)
333 {
334 LifecycleFactory factory = (LifecycleFactory) FactoryFinder
335 .getFactory(FactoryFinder.LIFECYCLE_FACTORY);
336 String id = context.getExternalContext().getInitParameter(
337 FacesServlet.LIFECYCLE_ID_ATTR);
338 if (id == null)
339 {
340 id = LifecycleFactory.DEFAULT_LIFECYCLE;
341 }
342 _lifecycle = factory.getLifecycle(id);
343 }
344 return new PhaseEvent(context, phaseId, _lifecycle);
345 }
346
347 private void _broadcastForPhase(PhaseId phaseId)
348 {
349 if (_events == null)
350 {
351 return;
352 }
353
354 boolean abort = false;
355
356 int phaseIdOrdinal = phaseId.getOrdinal();
357 for (ListIterator<FacesEvent> listiterator = _events.listIterator(); listiterator
358 .hasNext();)
359 {
360 FacesEvent event = listiterator.next();
361 int ordinal = event.getPhaseId().getOrdinal();
362 if (ordinal == ANY_PHASE_ORDINAL || ordinal == phaseIdOrdinal)
363 {
364 UIComponent source = event.getComponent();
365 try
366 {
367 source.broadcast(event);
368 }
369 catch (AbortProcessingException e)
370 {
371
372
373
374
375
376 abort = true;
377 break;
378 }
379 finally
380 {
381 try
382 {
383 listiterator.remove();
384 }
385 catch (ConcurrentModificationException cme)
386 {
387 int eventIndex = listiterator.previousIndex();
388 _events.remove(eventIndex);
389 listiterator = _events.listIterator();
390 }
391 }
392 }
393 }
394
395 if (abort)
396 {
397
398
399 clearEvents();
400 }
401 }
402
403 private void clearEvents()
404 {
405 _events = null;
406 }
407
408 private void checkNull(Object value, String valueLabel)
409 {
410 if (value == null)
411 {
412 throw new NullPointerException(valueLabel + " is null");
413 }
414 }
415
416 private Locale stringToLocale(String localeStr)
417 {
418
419
420 if (localeStr.contains("_") || localeStr.contains("-"))
421 {
422 if (localeStr.length() == 2)
423 {
424
425 return new Locale(localeStr);
426 }
427 }
428 else
429 {
430 if (localeStr.length() == 5)
431 {
432 String lang = localeStr.substring(0, 1);
433 String country = localeStr.substring(3, 4);
434 return new Locale(lang, country);
435 }
436 }
437
438 return Locale.getDefault();
439 }
440
441
442
443
444 @JSFProperty
445 public String getRenderKitId()
446 {
447 if (_renderKitId != null)
448 {
449 return _renderKitId;
450 }
451 ValueExpression expression = getValueExpression("renderKitId");
452 if (expression != null)
453 {
454 return (String) expression.getValue(getFacesContext()
455 .getELContext());
456 }
457 return null;
458 }
459
460 public void setRenderKitId(String renderKitId)
461 {
462 this._renderKitId = renderKitId;
463 }
464
465
466
467
468
469
470
471
472
473 @Override
474 @JSFProperty(tagExcluded=true)
475 public void setRendered(boolean state)
476 {
477
478 super.setRendered(state);
479
480 }
481
482 @Override
483 public boolean isRendered()
484 {
485
486 return super.isRendered();
487 }
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505 public void setId(String id)
506 {
507
508
509
510
511 super.setId(id);
512 }
513
514 public String getId()
515 {
516
517 return super.getId();
518 }
519
520
521
522
523
524
525 public String getClientId(FacesContext context)
526 {
527 return super.getClientId(context);
528
529
530 }
531
532
533
534
535
536
537
538 @JSFProperty(tagExcluded = true)
539 public String getViewId()
540 {
541 return _viewId;
542 }
543
544 public void setViewId(String viewId)
545 {
546
547
548
549 this._viewId = viewId;
550 }
551
552
553
554
555 public void addPhaseListener(PhaseListener phaseListener)
556 {
557 if (phaseListener == null)
558 throw new NullPointerException("phaseListener");
559 if (_phaseListeners == null)
560 _phaseListeners = new ArrayList<PhaseListener>();
561
562 _phaseListeners.add(phaseListener);
563 }
564
565
566
567
568 public void removePhaseListener(PhaseListener phaseListener)
569 {
570 if (phaseListener == null || _phaseListeners == null)
571 return;
572
573 _phaseListeners.remove(phaseListener);
574 }
575
576
577
578
579
580
581
582
583 @JSFProperty(stateHolder = true, returnSignature = "void", methodSignature = "javax.faces.event.PhaseEvent", jspName = "beforePhase")
584 public MethodExpression getBeforePhaseListener()
585 {
586 if (_beforePhaseListener != null)
587 {
588 return _beforePhaseListener;
589 }
590 ValueExpression expression = getValueExpression("beforePhaseListener");
591 if (expression != null)
592 {
593 return (MethodExpression) expression.getValue(getFacesContext()
594 .getELContext());
595 }
596 return null;
597 }
598
599
600
601
602
603
604
605 public void setBeforePhaseListener(MethodExpression beforePhaseListener)
606 {
607 this._beforePhaseListener = beforePhaseListener;
608 }
609
610
611
612
613
614
615
616
617 @JSFProperty(stateHolder = true, returnSignature = "void", methodSignature = "javax.faces.event.PhaseEvent", jspName = "afterPhase")
618 public MethodExpression getAfterPhaseListener()
619 {
620 if (_afterPhaseListener != null)
621 {
622 return _afterPhaseListener;
623 }
624 ValueExpression expression = getValueExpression("afterPhaseListener");
625 if (expression != null)
626 {
627 return (MethodExpression) expression.getValue(getFacesContext()
628 .getELContext());
629 }
630 return null;
631 }
632
633
634
635
636
637
638
639 public void setAfterPhaseListener(MethodExpression afterPhaseListener)
640 {
641 this._afterPhaseListener = afterPhaseListener;
642 }
643
644 @Override
645 public Object saveState(FacesContext facesContext)
646 {
647 Object[] values = new Object[8];
648 values[0] = super.saveState(facesContext);
649 values[1] = _locale;
650 values[2] = _renderKitId;
651 values[3] = _viewId;
652 values[4] = _uniqueIdCounter;
653 values[5] = saveAttachedState(facesContext, _phaseListeners);
654 values[6] = saveAttachedState(facesContext, _beforePhaseListener);
655 values[7] = saveAttachedState(facesContext, _afterPhaseListener);
656
657 return values;
658 }
659
660 @Override
661 public void restoreState(FacesContext facesContext, Object state)
662 {
663 Object[] values = (Object[]) state;
664 super.restoreState(facesContext, values[0]);
665 _locale = (Locale) values[1];
666 _renderKitId = (String) values[2];
667 _viewId = (String) values[3];
668 _uniqueIdCounter = (Long) values[4];
669 _phaseListeners = (List) restoreAttachedState(facesContext, values[5]);
670 _beforePhaseListener = (MethodExpression) restoreAttachedState(
671 facesContext, values[6]);
672 _afterPhaseListener = (MethodExpression) restoreAttachedState(
673 facesContext, values[7]);
674 }
675
676 @Override
677 public String getFamily()
678 {
679 return COMPONENT_FAMILY;
680 }
681 }