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.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>&lt;managed-bean&gt;</code> element, using a
65   *     <code>&lt;managed-bean-name&gt;</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>&lt;managed-property&gt;</code>
82   *     elements within the <code>&lt;managed-bean&gt;</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>&lt;managed-property&gt;</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     // -------------------------------------------------------------- Properties
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     // ---------------------------------------------------------- Public Methods
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 }