View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.custom.savestate;
20  
21  import javax.el.ValueExpression;
22  import javax.faces.component.StateHolder;
23  import javax.faces.component.UIParameter;
24  import javax.faces.context.FacesContext;
25  
26  import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFComponent;
27  
28  /**
29   * Provides the ability to store a model value inside the view's component tree.
30   * <p>
31   * JSF provides three scopes for managed beans and therefore all the model
32   * objects that the managed beans reference:  request, session, application.
33   * However a common requirement is a way for a model object to have a scope
34   * that is tied to the duration of the current view; that is longer than the
35   * request scope but shorter than session scope.
36   * </p> 
37   * <p>
38   * This component simply holds a reference to an arbitrary object (specified
39   * by the value property). Because this object is an ordinary component whose
40   * scope is the current view, the reference to the model automatically has that
41   * same scope.
42   * </p> 
43   * <p>
44   * When the value is an EL expression, then after the view is restored the
45   * recreated target object is stored at the specified location.
46   * </p>
47   * <p>
48   * The object being saved must either:
49   * </p>
50   * <ul>
51   * <li>implement java.io.Serializable, or</li>
52   * <li>implement javax.faces.component.StateHolder and have a default
53   *   constructor.</li>
54   * </ul>
55   * <p>
56   * Note that the saved object can be "chained" from view to view
57   * in order to extend its lifetime from a single view to a sequence
58   * of views if desired. A UISaveState component with an EL expression
59   * such as "#{someBean}" will save the object state after render, and
60   * restore it on postback. If navigation occurs to some other view
61   * and that view has a UISaveState component with the same EL expression
62   * then the object will simply be saved into the new view, thus extending
63   * its lifetime.
64   * </p>
65   * 
66   * @JSFJspProperty name = "name" returnType = "java.lang.String" tagExcluded = "true"
67   * @author Manfred Geiler (latest modification by $Author: skitching $)
68   * @version $Revision: 705343 $ $Date: 2008-10-16 15:05:11 -0500 (Thu, 16 Oct 2008) $
69   */
70  @JSFComponent(
71      name = "t:saveState",
72      tagClass = "org.apache.myfaces.custom.savestate.SaveStateTag")
73  public class UISaveState extends UIParameter
74  {
75  
76    static public final String COMPONENT_FAMILY =
77      "javax.faces.Parameter";
78    static public final String COMPONENT_TYPE =
79      "org.apache.myfaces.SaveState";
80  
81    /**
82     * Construct an instance of the UISaveState.
83     */
84    public UISaveState()
85    {
86      setRendererType(null);
87    }
88        
89      public Object saveState(FacesContext context)
90      {
91          Object values[] = new Object[3];
92          values[0] = super.saveState(context);
93          Object objectToSave = getValue();
94          if (objectToSave instanceof StateHolder)
95          {
96              values[1] = Boolean.TRUE;
97              values[2] = saveAttachedState(context, objectToSave);
98          }
99          else
100         {
101             values[1] = Boolean.FALSE;
102             values[2] = objectToSave;
103         }
104         return values;
105     }
106 
107     public void restoreState(FacesContext context, Object state)
108     {
109         Object values[] = (Object[])state;
110         super.restoreState(context, values[0]);
111         
112         Object savedObject;
113         Boolean storedObjectIsAStateHolder = (Boolean) values[1];
114         if ( Boolean.TRUE.equals( storedObjectIsAStateHolder ) )
115         {
116             savedObject = restoreAttachedState(context,values[2]);
117         }
118         else
119         {
120             savedObject = values[2];
121         }
122         ValueExpression vb = getValueExpression("value");
123         if (vb != null)
124         {
125             vb.setValue(context.getELContext(), savedObject);
126         }
127     }
128 
129   @Override
130   public String getFamily()
131   {
132     return COMPONENT_FAMILY;
133   }
134 }