2009/05/20 - Apache Shale has been retired.

For more information, please explore the Attic.

View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to you under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.shale.dialog.base;
19  
20  import java.io.Serializable;
21  import javax.faces.application.Application;
22  import javax.faces.context.FacesContext;
23  import javax.faces.el.ValueBinding;
24  import org.apache.shale.dialog.DialogContext;
25  import org.apache.shale.dialog.DialogContextListener;
26  
27  /***
28   * <p>Convenience {@link DialogContextListener} implementation that supports
29   * saving and restoring pre-request state information that is accessed via
30   * a configurable set of value binding expressions.  Whenever the associated
31   * {@link DialogContext} is passivated (such as at the end of a request), the
32   * <code>getValue()</code> method will be called on each value binding, to
33   * save away the retrieved information internally to this instance.  Later,
34   * when a POST causes our {@link DialogContext} instance to be activated again,
35   * <code>setValue()</code> will be called on each value binding, to restore the
36   * saved data to its original location.</p>
37   *
38   * <p>The most common use case for this class will be as the base class for
39   * a class that is registered as the <code>data</code> class for a particular
40   * dialog.  When used in this manner:</p>
41   * <ul>
42   * <li>Whenever a new {@link DialogContext} instance is created, a new instance
43   *     of the registered class will also be instantiated, and assigned to the
44   *     <code>data</code> property of the {@link DialogContext} instance.</li>
45   * <li>Because this class implements {@link DialogContextListener}, it will
46   *     automatically be registered as a listener on the {@link DialogContext}
47   *     instance, causing our <code>onActivate()</code> and <code>onPassivate</code>
48   *     methods to be called at the appropriate times.</li>
49   * <li>The default implementation of these event handlers will save and restore
50   *     state infomation specified by the value binding expressions set on the
51   *     <code>expressions</code> property, as described above.</li>
52   * </ul>
53   *
54   * <p>So, if you wish to use this mechanism to save and restore the
55   * <code>foo</code> and <code>bar</code> request scoped variables, create a
56   * subclass like this:</p>
57   * <pre>
58   *   public class MyStateSavingListener extends StateSavingListener {
59   *
60   *     public MyStateSavingListener() {
61   *       setExpressions(new String[] { "#{foo}", "#{bar}" });
62   *     }
63   *
64   *   }
65   * </pre>
66   *
67   * <p>Next, cause this class to be registered as the standard <code>data</code>
68   * class in the configuraiton for this dialog.  The details will vary depending
69   * on which dialog implementation you are using.  Now, the specified state
70   * information will be saved and restored for you.</p>
71   *
72   * <p><strong>IMPLEMENTATION NOTE</strong> - Because this instance will
73   * be stored in session scope, all of the data saved via the configured
74   * value binding expressions is expected to be serializable.</p>
75   *
76   * @since 1.1.0
77   */
78  public class StateSavingListener extends AbstractDialogContextListener
79    implements Serializable {
80  
81  
82      //--------------------------------------------------------------- Properties
83  
84  
85      /***
86       * <p>Array of value binding expression strings that identify the state
87       * information we need to save and restore.</p>
88       */
89      private String[] expressions = new String[0];
90  
91  
92      /***
93       * <p>The saved values corresponding to the specified expressions.</p>
94       */
95      private Object[] values = new Object[0];
96  
97  
98      /***
99       * <p>Return an array of value binding expressions that identify state
100      * information to be saved and restored.</p>
101      */
102     public String[] getExpressions() {
103 
104         return this.expressions;
105 
106     }
107 
108 
109     /***
110      * <p>Set the array of value binding expressions that identify state
111      * information to be saved and restored.</p>
112      *
113      * @param expressions The new expressions
114      */
115     public void setExpressions(String[] expressions) {
116 
117         if (expressions == null) {
118             expressions = new String[0];
119         }
120         this.expressions = expressions;
121         this.values = new Object[this.expressions.length];
122 
123     }
124 
125 
126     //-------------------------------------------- DialogContextListener Methods
127 
128 
129     /***
130      * <p>Restore the values specified by our configured expressions.</p>
131      */
132     public void onActivate() {
133 
134         if (expressions.length < 1) {
135             return;
136         }
137         FacesContext context = FacesContext.getCurrentInstance();
138         Application application = context.getApplication();
139         ValueBinding vb = null;
140         for (int i = 0; i < expressions.length; i++) {
141             vb = application.createValueBinding(expressions[i]);
142             vb.setValue(context, values[i]);
143             values[i] = null;
144         }
145 
146     }
147 
148 
149     /***
150      * <p>Save the values specified by our configured expressions.</p>
151      */
152     public void onPassivate() {
153 
154         if (expressions.length < 1) {
155             return;
156         }
157         FacesContext context = FacesContext.getCurrentInstance();
158         Application application = context.getApplication();
159         ValueBinding vb = null;
160         for (int i = 0; i < expressions.length; i++) {
161             vb = application.createValueBinding(expressions[i]);
162             values[i] = vb.getValue(context);
163         }
164 
165     }
166 
167 
168 }