001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License version 2
011: * as published by the Free Software Foundation.
012: *
013: * Resin Open Source is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
016: * of NON-INFRINGEMENT. See the GNU General Public License for more
017: * details.
018: *
019: * You should have received a copy of the GNU General Public License
020: * along with Resin Open Source; if not, write to the
021: *
022: * Free Software Foundation, Inc.
023: * 59 Temple Place, Suite 330
024: * Boston, MA 02111-1307 USA
025: *
026: * @author Scott Ferguson
027: */
028:
029: package javax.faces.component;
030:
031: import java.util.*;
032: import java.util.logging.*;
033:
034: import javax.el.*;
035:
036: import javax.faces.*;
037: import javax.faces.application.*;
038: import javax.faces.context.*;
039: import javax.faces.event.*;
040: import javax.faces.webapp.*;
041: import javax.faces.lifecycle.*;
042:
043: public class UIViewRoot extends UIComponentBase {
044: private static final Logger log = Logger.getLogger(UIViewRoot.class
045: .getName());
046:
047: public static final String COMPONENT_FAMILY = "javax.faces.ViewRoot";
048: public static final String COMPONENT_TYPE = "javax.faces.ViewRoot";
049: public static final String UNIQUE_ID_PREFIX = "j_id";
050:
051: private String _renderKitId;
052: private ValueExpression _renderKitIdExpr;
053:
054: private String _viewId;
055: private int _unique;
056:
057: private Locale _locale;
058: private ValueExpression _localeExpr;
059:
060: private ArrayList<PhaseListener> _phaseListeners;
061:
062: private ArrayList<FacesEvent> _eventList;
063:
064: private MethodExpression _beforePhaseListener;
065: private MethodExpression _afterPhaseListener;
066:
067: private Lifecycle _lifecycle;
068:
069: public UIViewRoot() {
070: }
071:
072: public String getFamily() {
073: return COMPONENT_FAMILY;
074: }
075:
076: public void setAfterPhaseListener(MethodExpression expr) {
077: _afterPhaseListener = expr;
078: }
079:
080: public MethodExpression getAfterPhaseListener() {
081: return _afterPhaseListener;
082: }
083:
084: public void setBeforePhaseListener(MethodExpression expr) {
085: _beforePhaseListener = expr;
086: }
087:
088: public MethodExpression getBeforePhaseListener() {
089: return _beforePhaseListener;
090: }
091:
092: public String getRenderKitId() {
093: if (_renderKitId != null)
094: return _renderKitId;
095: else if (_renderKitIdExpr != null)
096: return Util.evalString(_renderKitIdExpr, getFacesContext());
097: else
098: return null;
099: }
100:
101: public void setRenderKitId(String renderKitId) {
102: _renderKitId = renderKitId;
103: }
104:
105: public String getViewId() {
106: return _viewId;
107: }
108:
109: public void setViewId(String value) {
110: _viewId = value;
111: }
112:
113: public void setLocale(Locale locale) {
114: _locale = locale;
115: }
116:
117: public Locale getLocale() {
118: if (_locale != null)
119: return _locale;
120:
121: Locale locale = null;
122: FacesContext context = getFacesContext();
123:
124: if (_localeExpr != null)
125: locale = toLocale(Util.eval(_localeExpr, context));
126:
127: if (locale == null) {
128: ViewHandler viewHandler = context.getApplication()
129: .getViewHandler();
130:
131: locale = viewHandler.calculateLocale(context);
132: }
133:
134: return locale;
135: }
136:
137: //
138: // expression map override
139: //
140:
141: /**
142: * Returns the value expression with the given name.
143: */
144: @Override
145: public ValueExpression getValueExpression(String name) {
146: if ("renderKitId".equals(name))
147: return _renderKitIdExpr;
148: else if ("locale".equals(name))
149: return _localeExpr;
150: else {
151: return super .getValueExpression(name);
152: }
153: }
154:
155: /**
156: * Sets the value expression with the given name.
157: */
158: @Override
159: public void setValueExpression(String name, ValueExpression expr) {
160: if ("renderKitId".equals(name)) {
161: if (expr != null && expr.isLiteralText()) {
162: _renderKitId = (String) expr.getValue(null);
163: return;
164: } else
165: _renderKitIdExpr = expr;
166: } else if ("locale".equals(name)) {
167: if (expr != null && expr.isLiteralText()) {
168: _locale = toLocale(expr.getValue(null));
169: return;
170: } else
171: _localeExpr = expr;
172: }
173:
174: super .setValueExpression(name, expr);
175: }
176:
177: public void addPhaseListener(PhaseListener listener) {
178: if (_phaseListeners == null)
179: _phaseListeners = new ArrayList<PhaseListener>();
180:
181: _phaseListeners.add(listener);
182: }
183:
184: public void removePhaseListener(PhaseListener listener) {
185: if (_phaseListeners != null)
186: _phaseListeners.remove(listener);
187: }
188:
189: public String createUniqueId() {
190: return UNIQUE_ID_PREFIX + _unique++;
191: }
192:
193: /**
194: * Process the application.
195: */
196: public void processApplication(FacesContext context) {
197: if (context == null)
198: throw new NullPointerException();
199:
200: if (_beforePhaseListener != null || _phaseListeners != null)
201: beforePhase(context, PhaseId.INVOKE_APPLICATION);
202:
203: broadcastEvents(PhaseId.INVOKE_APPLICATION);
204:
205: if (_afterPhaseListener != null || _phaseListeners != null)
206: afterPhase(context, PhaseId.INVOKE_APPLICATION);
207: }
208:
209: /**
210: * Process the decodes.
211: */
212: public void processDecodes(FacesContext context) {
213: if (_beforePhaseListener != null || _phaseListeners != null)
214: beforePhase(context, PhaseId.APPLY_REQUEST_VALUES);
215:
216: super .processDecodes(context);
217:
218: broadcastEvents(PhaseId.APPLY_REQUEST_VALUES);
219:
220: if (_afterPhaseListener != null || _phaseListeners != null)
221: afterPhase(context, PhaseId.APPLY_REQUEST_VALUES);
222: }
223:
224: /**
225: * Process the updates.
226: */
227: public void processUpdates(FacesContext context) {
228: if (_beforePhaseListener != null || _phaseListeners != null)
229: beforePhase(context, PhaseId.UPDATE_MODEL_VALUES);
230:
231: super .processUpdates(context);
232:
233: broadcastEvents(PhaseId.UPDATE_MODEL_VALUES);
234:
235: if (_afterPhaseListener != null || _phaseListeners != null)
236: afterPhase(context, PhaseId.UPDATE_MODEL_VALUES);
237: }
238:
239: /**
240: * Process the validators.
241: */
242: @Override
243: public void processValidators(FacesContext context) {
244: if (_beforePhaseListener != null || _phaseListeners != null)
245: beforePhase(context, PhaseId.PROCESS_VALIDATIONS);
246:
247: super .processValidators(context);
248:
249: broadcastEvents(PhaseId.PROCESS_VALIDATIONS);
250:
251: if (_afterPhaseListener != null || _phaseListeners != null)
252: afterPhase(context, PhaseId.PROCESS_VALIDATIONS);
253: }
254:
255: /**
256: * Begin rendering
257: */
258: @Override
259: public void encodeBegin(FacesContext context)
260: throws java.io.IOException {
261: if (_beforePhaseListener != null || _phaseListeners != null)
262: beforePhase(context, PhaseId.RENDER_RESPONSE);
263:
264: super .encodeBegin(context);
265: }
266:
267: /**
268: * Begin rendering
269: */
270: @Override
271: public void encodeEnd(FacesContext context)
272: throws java.io.IOException {
273: super .encodeEnd(context);
274:
275: if (_afterPhaseListener != null || _phaseListeners != null)
276: afterPhase(context, PhaseId.RENDER_RESPONSE);
277: }
278:
279: @Override
280: public void queueEvent(FacesEvent event) {
281: if (_eventList == null)
282: _eventList = new ArrayList<FacesEvent>();
283:
284: if (log.isLoggable(Level.FINE))
285: log.fine(this + " queueEvent " + event);
286:
287: _eventList.add(event);
288: }
289:
290: private void broadcastEvents(PhaseId phaseId) {
291: if (_eventList != null) {
292: for (int i = 0; i < _eventList.size(); i++) {
293: FacesEvent event = _eventList.get(i);
294: PhaseId eventPhaseId = event.getPhaseId();
295:
296: if (phaseId.equals(eventPhaseId)
297: || PhaseId.ANY_PHASE.equals(eventPhaseId)) {
298: event.getComponent().broadcast(event);
299: _eventList.remove(i);
300: i--;
301: }
302: }
303: }
304: }
305:
306: private void afterPhase(FacesContext context, PhaseId phaseId) {
307: Lifecycle lifecycle = getLifecycle(context);
308: PhaseEvent event = new PhaseEvent(context, phaseId, lifecycle);
309:
310: if (_afterPhaseListener != null) {
311: try {
312: _afterPhaseListener.invoke(context.getELContext(),
313: new Object[] { event });
314: } catch (RuntimeException e) {
315: throw e;
316: } catch (Exception e) {
317: throw new FacesException(e);
318: }
319: }
320:
321: if (_phaseListeners != null) {
322: for (int i = 0; i < _phaseListeners.size(); i++) {
323: PhaseListener listener = _phaseListeners.get(i);
324:
325: listener.afterPhase(event);
326: }
327: }
328: }
329:
330: private void beforePhase(FacesContext context, PhaseId phaseId) {
331: Lifecycle lifecycle = getLifecycle(context);
332: PhaseEvent event = new PhaseEvent(context, phaseId, lifecycle);
333:
334: if (_beforePhaseListener != null) {
335: try {
336: _beforePhaseListener.invoke(context.getELContext(),
337: new Object[] { event });
338: } catch (RuntimeException e) {
339: throw e;
340: } catch (Exception e) {
341: throw new FacesException(e);
342: }
343: }
344:
345: if (_phaseListeners != null) {
346: for (int i = 0; i < _phaseListeners.size(); i++) {
347: PhaseListener listener = _phaseListeners.get(i);
348:
349: listener.beforePhase(event);
350: }
351: }
352: }
353:
354: private Lifecycle getLifecycle(FacesContext context) {
355: if (_lifecycle == null) {
356: LifecycleFactory factory = (LifecycleFactory) FactoryFinder
357: .getFactory(FactoryFinder.LIFECYCLE_FACTORY);
358:
359: ExternalContext extContext = context.getExternalContext();
360: String id = extContext
361: .getInitParameter(FacesServlet.LIFECYCLE_ID_ATTR);
362:
363: if (id == null)
364: id = LifecycleFactory.DEFAULT_LIFECYCLE;
365:
366: _lifecycle = factory.getLifecycle(id);
367: }
368:
369: return _lifecycle;
370: }
371:
372: //
373: // state
374: //
375:
376: public Object saveState(FacesContext context) {
377: return new Object[] { super .saveState(context), _viewId,
378: _renderKitId,
379: _locale == null ? null : _locale.toString(), _unique,
380: _afterPhaseListener, _beforePhaseListener,
381: saveAttachedState(context, _phaseListeners), };
382: }
383:
384: public void restoreState(FacesContext context, Object value) {
385: Object[] state = (Object[]) value;
386:
387: super .restoreState(context, state[0]);
388:
389: _viewId = (String) state[1];
390: _renderKitId = (String) state[2];
391: _locale = toLocale((String) state[3]);
392: _unique = (Integer) state[4];
393: _afterPhaseListener = (MethodExpression) state[5];
394: _beforePhaseListener = (MethodExpression) state[6];
395: _phaseListeners = (ArrayList) restoreAttachedState(context,
396: state[7]);
397: }
398:
399: private Locale toLocale(Object value) {
400: if (value instanceof Locale)
401: return (Locale) value;
402: else if (value instanceof String) {
403: String sValue = (String) value;
404: String[] values = sValue.split("[-_]");
405:
406: if (values.length > 2)
407: return new Locale(values[0], values[1], values[2]);
408: else if (values.length > 1)
409: return new Locale(values[0], values[1]);
410: else
411: return new Locale(sValue);
412: } else if (value == null)
413: return null;
414: else
415: return (Locale) value;
416: }
417:
418: public String toString() {
419: return getClass().getSimpleName() + "[" + getViewId() + "]";
420: }
421: }
|