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