001: /**********************************************************************************
002: *
003: * $Id: FlowState.java 9278 2006-05-10 23:29:21Z ray@media.berkeley.edu $
004: *
005: ***********************************************************************************
006: *
007: *
008: * Licensed under the Educational Community License, Version 1.0 (the "License");
009: * you may not use this file except in compliance with the License.
010: * You may obtain a copy of the License at
011: *
012: * http://www.opensource.org/licenses/ecl1.php
013: *
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: *
020: **********************************************************************************/package org.sakaiproject.jsf.component;
021:
022: import java.io.IOException;
023:
024: import javax.faces.component.UIComponentBase;
025: import javax.faces.context.FacesContext;
026: import javax.faces.el.ValueBinding;
027:
028: import org.apache.commons.logging.Log;
029: import org.apache.commons.logging.LogFactory;
030: import org.sakaiproject.jsf.model.PhaseAware;
031:
032: /**
033: * This JSF UI component lets backing beans track the request life cycle and
034: * save their state within the component tree itself. (These two aspects could
035: * be separated with a "saveState" Boolean attribute if we ever need to let
036: * a session-scoped bean track the request life cycle.)
037: *
038: * Like the MyFaces x:saveState tag, this passes the bean's state from request
039: * to request without use of session scope. That in turn enables request-thread
040: * functionality such as "what if?" scenarios and multiple active
041: * application views from a single session.
042: *
043: * <p>
044: * Usage:
045: *
046: * <sakaix:flowState bean="#{phaseAwareBean}" />
047: *
048: * should be placed in the JSP file before any other bean references are made.
049: *
050: * <p>
051: * The bean must implement the PhaseAware interface and be serializable.
052: * Any non-transient fields in the bean will be saved and restored from this component.
053: */
054: public class FlowState extends UIComponentBase {
055: private static final Log logger = LogFactory
056: .getLog(FlowState.class);
057:
058: public static final String COMPONENT_TYPE = "org.sakaiproject.jsf.FlowState";
059:
060: private PhaseAware _bean;
061:
062: public FlowState() {
063: }
064:
065: public void setBean(PhaseAware bean) {
066: if (logger.isDebugEnabled())
067: logger.debug("setBean " + bean);
068: _bean = bean;
069: }
070:
071: public PhaseAware getBean() {
072: if (logger.isDebugEnabled())
073: logger.debug("getBean " + _bean);
074: if (_bean != null)
075: return _bean;
076:
077: PhaseAware returnObject = null;
078: ValueBinding vb = getValueBinding("bean");
079: if (vb != null) {
080: returnObject = (PhaseAware) vb.getValue(getFacesContext());
081: }
082: if (logger.isDebugEnabled())
083: logger.debug(" returning " + returnObject);
084: return returnObject;
085: }
086:
087: public Object saveState(FacesContext context) {
088: if (logger.isDebugEnabled())
089: logger.debug("saveState " + _bean);
090: Object values[] = new Object[2];
091: values[0] = super .saveState(context);
092: values[1] = getBean();
093: return ((Object) values);
094: }
095:
096: public void restoreState(FacesContext context, Object state) {
097: if (logger.isDebugEnabled())
098: logger.debug("restoreState " + state);
099: Object values[] = (Object[]) state;
100: super .restoreState(context, values[0]);
101: _bean = (PhaseAware) values[1];
102: ValueBinding vb = getValueBinding("bean");
103: if (vb != null) {
104: vb.setValue(context, _bean);
105: }
106: }
107:
108: public void processRestoreState(FacesContext context, Object state) {
109: if (logger.isDebugEnabled())
110: logger.debug("processRestoreState " + _bean);
111: super .processRestoreState(context, state);
112: }
113:
114: public void processDecodes(FacesContext context) {
115: if (logger.isDebugEnabled())
116: logger.debug("processDecodes " + _bean);
117: super .processDecodes(context);
118: }
119:
120: public void processValidators(FacesContext context) {
121: if (logger.isDebugEnabled())
122: logger.debug("processValidators " + _bean);
123: super .processValidators(context);
124: if (_bean != null) {
125: _bean.endProcessValidators();
126: }
127: }
128:
129: public void processUpdates(FacesContext context) {
130: if (logger.isDebugEnabled())
131: logger.debug("processUpdates " + _bean);
132: super .processUpdates(context);
133: if (_bean != null) {
134: _bean.endProcessUpdates();
135: }
136: }
137:
138: public void encodeBegin(FacesContext context) throws IOException {
139: PhaseAware bean = getBean();
140: if (logger.isDebugEnabled())
141: logger.debug(" getBean=" + bean);
142: if (bean != null) {
143: bean.startRenderResponse();
144: }
145: super .encodeBegin(context);
146: }
147:
148: public String getFamily() {
149: if (logger.isDebugEnabled())
150: logger.debug("getFamily " + _bean);
151: return "javax.faces.Data";
152: }
153:
154: }
|