2009/05/20 - Apache Shale has been retired.
For more information, please explore the Attic.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shale.view;
19
20 import org.apache.shale.view.impl.DefaultViewControllerMapper;
21
22 /***
23 * <p>{@link ViewController} is a "backing bean" interface which adds several
24 * extension points to the standard JavaServer Faces lifecycle. The extension
25 * points help Shale interact with JSF <code>UIComponent</code>s.
26 * </p>
27 * <p>
28 * A "backing bean" represents a convenient place to retrieve and store
29 * dynamic values associated with the user interface components that comprise
30 * the view, as well as to code event handlers triggered by state changes on
31 * those components. A JavaServer Faces <em>view</em> is most often a JSP page,
32 * but any JSF view rendering system can be used.
33 * </p>
34 * <p>
35 * Essentially, the ViewController is a
36 * <a href="http://java.sun.com/blueprints/corej2eepatterns/Patterns/ViewHelper.html">
37 * View Helper</a> interface for a backing bean and its associated View.
38 * </p>
39 * <p><strong>NOTE</strong> - JavaServer Faces imposes no restrictions on
40 * the inheritance hierarchy (or interface implementation) for backing beans
41 * associated with a view. Therefore, the use of this interface for your own
42 * backing beans is entirely optional. That being said, having your
43 * backing beans implement this interface (typically by extending
44 * {@link org.apache.shale.view.AbstractViewController}) will receive the
45 * benefit of the extra services described by this interface, all of which will be
46 * provided automatically.</p>
47 * <p>
48 * To be useful, the ViewController must be plugged into the application
49 * lifecycle through a custom JSF ViewHandler, like the
50 * {@link org.apache.shale.view.faces.ViewViewHandler ViewViewHandler}.
51 * </p>
52 *
53 * <h3>Registering a ViewController backing bean</h3>
54 *
55 * <p>For each JSF view that you wish to associate with a ViewController
56 * backing bean, you must do the following:</p>
57 * <ul>
58 * <li>First, as required by the JavaBeans specification, be sure to provide a public no-args
59 * constructor in your ViewController backing bean implementation class.
60 * Configuration of ViewController beans is performed using setter injection,
61 * rather than through "rich" constructors.</li>
62 * <li>In order for Shale to properly locate the {@link ViewController} for
63 * a particular JSF view, you must register your implementation class in
64 * a JSF <code><managed-bean></code> element, using a
65 * <code><managed-bean-name></code> value that can be <em>mapped</em>
66 * from the view identifier. The actual mapping is performed by an instance
67 * of {@link ViewControllerMapper} configured for your application. If no
68 * special configuration is done, {@link DefaultViewControllerMapper} is
69 * used by default. See the Javadocs for that class to see what mapping
70 * rules are applied, and examples of correct managed bean names that
71 * correspond to particular JSF view identifiers.
72 * <blockquote>
73 * <strong>WARNING</strong> - if your managed bean name does not match
74 * the required mapping rules, it will function as a standard JSF backing
75 * bean, but none of the extra {@link ViewController} event handling
76 * methods will be called.
77 * </blockquote></li>
78 * <li>Under nearly all circumstances, you will want to register this
79 * managed bean to be stored in request scope, so that its lifetime
80 * matches the corresponding view.</li>
81 * <li>Optionally, you may use <code><managed-property></code>
82 * elements within the <code><managed-bean></code> element
83 * to configure the behavior of your ViewController bean.</li>
84 * </ul>
85 *
86 * <p>Since the ViewController is a backing bean, you have the option of
87 * establishing other links with the UIComponents, such as:</p>
88 * <ul>
89 * <li>You may use the <code>binding</code> property of any JSF
90 * <code>UIComponent</code> to establish a linkage between a component
91 * instance in the component tree representing this view, and a propery
92 * (of type <code>UIComponent</code> or an appropriate subclass) in your
93 * backing bean. This technique is useful if you need to programmatically
94 * manipulate properties of the corresponding component in an event
95 * handler in the backing bean.</li>
96 * <li>You may use the <code>value</code> property of any JSF
97 * component that implements <code>ValueHolder</code> (for example, any
98 * component based on <code>UIInput</code> or <code>UIOutput</code>) to
99 * establish a linkage between the dynamic value to be rendered or stored,
100 * and a property (of some appropriate type relevant to the model tier
101 * of your application) in your backing bean. This technique is convenient
102 * if you are primarily interested in manipulating the <em>values</em> to
103 * be rendered or stored, and/or you wish to leverage JSF's support for
104 * implicit registration of a <code>Converter</code>.</li>
105 * </ul>
106 *
107 * <h3>ViewController Lifecycle</h3>
108 *
109 * <p>Once you have configured the use of a {@link ViewController} backing bean
110 * associated with a JSF view, Shale will provide the following services:</p>
111 * <ul>
112 * <li>Whenever a JSF view with the appropriate <code>view identifier</code>
113 * is created or restored, an appropriate instance of the corresponding
114 * {@link ViewController} class will be created via the managed beans
115 * facility (if such a bean does not already exist), using a key derived
116 * from the {@link ViewControllerMapper} for this application. As a
117 * side effect, property setters wil be called for any
118 * <code><managed-property></code> configuration you have
119 * specified.</li>
120 * <li>Prior to any other method calls, the following additional property
121 * setters will be called:
122 * <ul>
123 * <li><code>setPostBack()</code> will be called with a flag indicating
124 * whether this backing bean was created as result of a "post back"
125 * (i.e. to handle an HTTP request submitted by the client) or as a
126 * result of navigating to a different page.</li>
127 * </ul></li>
128 * <li>The <code>init()</code> method will be called, allowing the backing bean
129 * to acquire data from the model tier as needed to prepare for execution
130 * of the JSF request processing lifecycle for this view.</li>
131 * <li>For a restored view (i.e. where the <code>postBack</code> property
132 * was set to <code>true</code>, the <code>preprocess()</code> method will
133 * be called after the component tree has been restored by the
134 * <em>Restore View</em> phase. This method will <strong>not</strong>
135 * be called for a view that will only be rendered.</li>
136 * <li>For a restored view, standard JSF processing and event handling occurs
137 * for the <em>Apply Request Values</em> through <em>Invoke Application</em>
138 * phases of the request processing lifecycle. As a side effect, it is
139 * possible that navigation to a different view will have occurred. In
140 * this case, the corresponding <code>ViewController</code> for the new
141 * view will have been instantiated, and its <code>init()</code> method
142 * will have been called, as described above.</li>
143 * <li>For the <code>ViewController</code> whose view will be rendered, the
144 * <code>prerender()</code> method will be called. If your
145 * <code>ViewController</code> performed navigation to a different view,
146 * this method will <strong>NOT</strong> be called on the original view;
147 * however, it will be called on the <code>ViewController</code> instance
148 * for the page that was navigated to.</li>
149 * <li>The <code>destroy()</code> method will be called, allowing the backing
150 * bean to clean up any resources that it has allocated before processing
151 * for this HTTP request is completed. In the case where navigation has
152 * occurred, this call will take place on both <code>ViewController</code>
153 * instances that have been initialized.</li>
154 * </ul>
155 *
156 * $Id: ViewController.java 464373 2006-10-16 04:21:54Z rahul $
157 */
158
159 public interface ViewController {
160
161
162
163
164
165 /***
166 * <p>Return a flag indicating whether this request is a "post back" (that
167 * is, the view was restored in order to respond to a submit from the
168 * client), or a newly created view. This method must return any value
169 * passed to the <code>setPostBack()</code> method.</p>
170 */
171 public boolean isPostBack();
172
173
174 /***
175 * <p>Set a flag indicating whether this request is a "post back" (that is,
176 * the view was restored in order to respond to a submit from the client),
177 * or a newly created view.</p>
178 *
179 * @param postBack <code>true</code> for a post back request, or
180 * <code>false</code> for a newly created request
181 */
182 public void setPostBack(boolean postBack);
183
184
185
186
187
188 /***
189 * <p>Called after the JSF request processing lifecycle has been completed
190 * for the current request. This allows a {@link ViewController} to clean
191 * up any resources it has allocated (perhaps during earlier execution of
192 * the <code>init()</code> method).</p>
193 */
194 public void destroy();
195
196
197 /***
198 * <p>Called after this {@link ViewController} has been instantiated, and
199 * after all of the property setters specified above have been called, but
200 * before the JSF request processing lifecycle processing and events related
201 * to our corresponding view are executed. Within this method, you may
202 * consult the <code>isPostBack()</code> method to vary the initialization
203 * behavior based on whether a post back is being processed or not.</p>
204 */
205 public void init();
206
207
208 /***
209 * <p>Called after the component tree has been restored (in <em>Restore
210 * View</em> phase), if the current request is a postback. If this view
211 * is only going to be rendered (because of either direct navigation, or
212 * because this view was navigated to from a different view), this method
213 * will <strong>NOT</strong> be called. As such, this method makes a good
214 * place to acquire information from your model tier that will be required
215 * during the execution of the <em>Apply Request Values</em> through
216 * <em>Invoke Application</em> phases of the request processing lifecycle.
217 * </p>
218 */
219 public void preprocess();
220
221
222 /***
223 * <p>Called before the <em>Render Response</em> processing for this request
224 * is performed, whether or not this is a post back request. This method
225 * will be called only for the view that will actually be rendered. For
226 * example, it will not be called if you have performed navigation to a
227 * different view. As such, it makes a good place to acquire information
228 * from your model tier that is required to complete this view's
229 * presentation.</p>
230 */
231 public void prerender();
232
233
234 }