Author: ekoneil
Date: Thu Aug 25 12:56:16 2005
New Revision: 240125
URL: http://svn.apache.org/viewcvs?rev=240125&view=rev
Log:
Complete the rewrite of the data binding document.
BB: self
DRT: build.release pass
Modified:
beehive/trunk/docs/forrest/release/src/documentation/content/xdocs/pageflow/databinding.xml
Modified:
beehive/trunk/docs/forrest/release/src/documentation/content/xdocs/pageflow/databinding.xml
URL:
http://svn.apache.org/viewcvs/beehive/trunk/docs/forrest/release/src/documentation/content/xdocs/pageflow/databinding.xml?rev=240125&r1=240124&r2=240125&view=diff
==============================================================================
---
beehive/trunk/docs/forrest/release/src/documentation/content/xdocs/pageflow/databinding.xml
(original)
+++
beehive/trunk/docs/forrest/release/src/documentation/content/xdocs/pageflow/databinding.xml
Thu Aug 25 12:56:16 2005
@@ -139,9 +139,15 @@
<a
href="../apidocs/classref_pageflows/org/apache/beehive/netui/tags/databinding/datagrid/DataGrid.html">
<code><netui-data:dataGrid</code></a>,
<a
href="../apidocs/classref_pageflows/org/apache/beehive/netui/tags/databinding/repeater/Repeater.html">
- <code><netui-data:repeater</code></a>, and
+ <code><netui-data:repeater</code></a>,
<a
href="../apidocs/classref_pageflows/org/apache/beehive/netui/tags/databinding/cellrepeater/CellRepeater.html">
- <code><netui-data:cellRepeater</code></a>.
+ <code><netui-data:cellRepeater</code></a>,
+ <a
href="../apidocs/classref_pageflows/org/apache/beehive/netui/tags/html/Select.html">
+ <code><netui:select</code></a>,
+ <a
href="../apidocs/classref_pageflows/org/apache/beehive/netui/tags/html/CheckBoxGroup.html">
+ <code><netui:checkBoxGroup</code></a>, and
+ <a
href="../apidocs/classref_pageflows/org/apache/beehive/netui/tags/html/RadioButtonGroup.html">
+ <code><netui:radioButtonGroup</code></a>,
</td>
<td>Provides access to the JavaBean properties exposed by the
<a
href="../apidocs/classref_pageflows/org/apache/beehive/netui/script/common/IDataAccessProvider.html">
@@ -193,446 +199,410 @@
<section id="implicit-objects-netui-actionForm">
<title>actionForm</title>
<p>
+ The <code>actionForm</code> implicit object is a convenient way to
explicitly reference a JavaBean used for authoring
+ HTML forms. This implicit object is available only inside of
<code><netui:form</code> tags with <code>action</code>
+ attributes that reference Page Flow actions accepting a JavaBean.
The <code>actionForm</code> implicit object allows
+ data binding to JavaBean properties, Map attributes, Lists, and
arrays as with any other implicit object. This example
+ shows a JSP that contains a form which POSTs to a Page Flow action
that accepts a JavaBean <code>NameForm</code>.
+ </p>
+ <p>The JavaBean:</p>
+ <source>
+ public class NameForm {
+ private String _name;
+ public String getName() {
+ return _name;
+ }
+
+ public void setName(String name) {
+ _name = name;
+ }
+ }
+ </source>
+ <p>
+ The JSP:
+ </p>
+ <source><![CDATA[
+ <netui:form action="submitNameform">
+ <netui:textBox dataSource="actionForm.name"/><br/>
+ <netui:button value="Submit"/>
+ </netui:form>
+ ]]></source>
+ <p>
+ The Page Flow action <code>submitNameForm</code>:
+ </p>
+ <source>
+ @Jpf.Action()
+ public Forward submitNameForm(NameForm form) {
+ ...
+ }
+ </source>
+ <p>
+ Here, the <code>dataSource</code>'s <code>actionForm.name</code>
expression refers to the value of the
+ <code>NameForm</code>'s <code>name</code> property. The result is
data bound to the <code>textBox</code>.
+ When the form is submitted to the server, the request parameter
<code>{actionForm.name}</code> is applied
+ to the action form which is then passed to the
<code>submitNameForm</code> action.
</p>
</section>
<section id="implicit-objects-netui-bundle">
<title>bundle</title>
<p>
+ The <code>bundle</code> implicit object is useful for binding UI
to localized message strings. The <code>bundle</code>
+ implicit object is available in one of two situations:
</p>
- </section>
- <section id="implicit-objects-netui-container">
- <title>container</title>
+ <ul>
+ <li>when declaring a resource bundle accessible to a JSP page
via the
+ <a
href="../apidocs/classref_pageflows/org/apache/beehive/netui/tags/databinding/bundle/DeclareBundle.html">
+ <code><netui-data:declareBundle></code></a> tag.</li>
+ <li>when a Page Flow with which the JSP is associated exposes
resource bundles via the <code>@Jpf.MessageBundle</code>
+ annotation.</li>
+ </ul>
<p>
+ The <code>declareBundle</code> JSP tag is used to make a specific
resource bundle avaialble to a JSP. For example,
+ given the following resource bundle and JSP, a page can data bind
to messages in the resource bundle using the
+ JSP 2.0 EL.
</p>
- </section>
- <section id="implicit-objects-netui-pageFlow">
- <title>pageFlow</title>
<p>
+ The resource bundle, which is located in
<code>WEB-INF/classes/org/foo/messages.properties</code>:
</p>
- </section>
- <section id="implicit-objects-netui-pageInput">
- <title>pageInput</title>
+ <source><![CDATA[
+ message1=This is the first message
+ message2=Another message
+ ]]></source>
<p>
+ The JSP can declare this resource bundle to be available to the
page using this JSP snippet:
</p>
- </section>
- <section id="implicit-objects-netui-sharedFlow">
- <title>sharedFlow</title>
+ <source><![CDATA[
+ <%@ taglib
uri="http://beehive.apache.org/netui/tags-databinding-1.0"
prefix="netui-data"%>
+
+ <netui-data:declareBundle name="fooMessages"
bundlePath="org/foo/messages"/>
+ ]]></source>
+ <p>
+ Finally, messages in the JSP can be data bound with JSP literal
text and tags:
+ </p>
+ <source><![CDATA[
+ <netui:span value="${bundle.fooMessages.message1}"/>
+
+ ${bundle.fooMessages.message2}
+ ]]></source>
+ <p>
+ The expressions above contain a reference to the
<code>bundle</code> implicit object. Then, the specific
+ bundle name is referred to with <code>fooMessages</code>; this
name must match the value of a <code>name</code>
+ attribute of a <code>declareBundle</code> tag or the name of a
bundle declared in a Page Flow. Finally, the
+ expressions use <code>message1</code> and <code>message2</code> to
refer to message keys in the
+ <code>messages.properties</code> file.
+ </p>
+ <p>
+ Resource bundles can also be registered with the
<code>bundle</code> implicit object by using the <code>@Jpf.MessageBundle</code>
+ class-level annotation. This allows a Page Flow to also integrate
with the implicit message resources object which is
+ available via a Struts module. These resource bundles will be
available to all JSPs that are part of a Page Flow without having
+ to use the <code>declareBundle</code> JSP tag. Because a default
resource bundle can be associated with a Struts module, the
+ bundle name <code>default</code> is reserved for referencing this
bundle. For example, the following Page Flow declares
+ the resource bundle above as the default Page Flow bundle:
+ </p>
+ <source>
+ @Jpf.Controller(
+ forwards = {...}
+ messageBundles = {
+ @Jpf.MessageBundle(bundlePath="org.foo.messages")
+ }
+ )
+ public class Controller
+ extends PageFlowController {
+ ...
+ }
+ </source>
<p>
+ Message strings from this bundle can be referred to in JSP pages
with an expression like:
+ </p>
+ <source><![CDATA[
+ ${bundle.default.message1}
+ ]]></source>
+ <p>
+ A resource bundle can also be registered with a specific name by
adding an annotation like:
+ </p>
+ <source>
+ @Jpf.Controller(
+ forwards = {...}
+ messageBundles = {
+ @Jpf.MessageBundle(bundleName="jpfBundle",
bundlePath="org.foo.messages")
+ }
+ )
+ public class Controller
+ extends PageFlowController {
+ ...
+ }
+ </source>
+ <p>
+ Then, the same message strings from the previous two examples are
available with an expression like
+ </p>
+ <source>
+ ${bundle.jpfBundle.message1}
+ </source>
+ <p>
+ Each of these three ways to register a resource bundle (JSP tag,
implicit Page Flow bundle, and explicit Page Flow bundle)
+ can be used together in a single Page Flow.
</p>
</section>
- </section>
- <section>
- <title></title>
- <p>The one-way, read-only contexts are: requestScope, param,
sessionScope, container, pageScope, bundle, pageInput, applicationScope</p>
- <p>The two-way, read-write contexts are: pageFlow, sharedFlow,
actionForm</p>
- </section>
- <section id="implicit-objects">
- <title>Summary of NetUI Implict Objects</title>
+ <section id="implicit-objects-netui-container">
+ <title>container</title>
+ <p>
+ The <code>container</code> implicit object is available to a JSP
when inside of several NetUI tags that <em>repeat</em> over
+ a Map, List, array, or various other kinds of data sets.
Generally, JSP tags that can be bound to data sets iterate through them
+ from start to end as in a Java <code>for</code> loop. Such JSP
tags include:
+ </p>
+ <ul>
+ <li>
+ <a
href="../apidocs/classref_pageflows/org/apache/beehive/netui/tags/databinding/datagrid/DataGrid.html">
+ <code><netui-data:dataGrid</code></a>
+ </li>
+ <li>
+ <a
href="../apidocs/classref_pageflows/org/apache/beehive/netui/tags/databinding/repeater/Repeater.html">
+ <code><netui-data:repeater</code></a>
+ </li>
+ <li>
+ <a
href="../apidocs/classref_pageflows/org/apache/beehive/netui/tags/databinding/cellrepeater/CellRepeater.html">
+ <code><netui-data:cellRepeater</code></a>
+ </li>
+ <li>
+ <a
href="../apidocs/classref_pageflows/org/apache/beehive/netui/tags/html/Select.html">
+ <code><netui:select</code></a>
+ </li>
+ <li>
+ <a
href="../apidocs/classref_pageflows/org/apache/beehive/netui/tags/html/CheckBoxGroup.html">
+ <code><netui:checkBoxGroup</code></a>
+ </li>
+ <li>
+ <a
href="../apidocs/classref_pageflows/org/apache/beehive/netui/tags/html/RadioButtonGroup.html">
+ <code><netui:radioButtonGroup</code></a>.
+ </li>
+ </ul>
+ <p>
+ The <code>container</code> implicit object provide access to the
current item in the data set and to metadata about the current
+ iteration. This access is based on the properties available on
the <code>IDataAccessProvider</code> interface and includes:
+ </p>
<table>
<tr>
- <th>Context Name</th><th>Object the Context
References</th><th>Description</th>
+ <th>Property Name</th>
+ <th>Description</th>
</tr>
- <tr>
- <td>
- <code>actionForm</code>
- </td>
- <td>
- The current form bean (the form bean named in the
current <code><netui:form></code> tag)
+ <tr><td><code>item</code></td>
+ <td>Refers to the current data item. In an array of
<code>Widget</code> beans, the JavaBean propeties of widget can
+ be accessed with an expression like
<code>${container.item.density}</code></td></tr>
+ <tr><td><code>index</code></td>
+ <td>Refers to the current index of iteration. Tags are
free to define their own rules for the the value of the
+ <code>index</code> property, but in general, this is a
zero-based index that increments each time the
+ JSP tag renders its body / iterates to the next data
item.
</td>
- <td>
- Individual fields defined in the form bean can be
referenced. Values are read-write.
- </td>
- </tr>
- <tr>
- <td>
- <code>bundle</code>
- </td>
- <td>Properties defined in a message resource file</td>
- <td>On a JSP page, declare the message resource file using
the <code><netui-data:declareBundle></code> tag.
- <source><netui-data:declareBundle name="myBundle"
bundlePath="properties.bundle1"/></source> Reference individual
- properties in the file using the <code>bundle</code>
databinding context. <source><netui:span
value="${bundle.myBundle.message1}"/></source></td>
</tr>
- <tr>
- <td>
- <code>container</code>
- </td>
- <td>The data set referenced in the current
<netui-data:dataGrid> or <netui-data:repeater>
- tag</td>
- <td>In the example below, the <code>container</code>
context refers to the object named in the
- <code><netui-data:dataGrid></code>'s
<code>dataSource</code> <source><![CDATA[
-<netui-data:dataGrid <strong>dataSource="pageScope.stocks"</strong>
name="portfolio">
- <netui-data:rows>
- <netui-data:spanCell
value="${<strong>container.item.symbol</strong>}"/>
- <netui-data:spanCell value="${<strong>container.item.price</strong>}"/>
- </netui-data:rows>
-</netui-data:dataGrid>
-]]></source> See below for detailed information on <code>container</code>'s
sub-contexts.</td>
- </tr>
- <tr>
- <td>
- <code>pageFlow</code>
+ <tr><td><code>container</code></td>
+ <td>Refers to an outer container repeating container.
This value is used when two repeating containers are
+ nested and the inner container needs to access about
the current item in the outer container. For example,
+ this might be used when rendering hierarchical data
sets.
</td>
- <td>The current Controller class</td>
- <td>Public members of the current Controller class can be
referenced and written to. Assume that the
- Controller class contains the following member String
and associated get and set methods.
- <source>
-public String someText = "This is some text"
-
-public String getSomeText(){
- return someText;
-}
-public void setSomeText(String newText){
- someText = newText;
-}
-</source>
- Then that member can be referenced from any JSP page
in the page flow. <source><netui:span
value="${pageFlow.someText}"/></source></td>
</tr>
- <tr>
- <td>
- <code>pageInput</code>
- </td>
- <td>an attribute map on the current Forward object</td>
- <td>Page input data can be added to the Forward object
using the <code>addActionOutput(String, Object)
- method.</code>.
-<source>
-Forward forward = new Forward("success");forward.addActionOutput("name",
someNameData);
-</source>
- The data can be retrieved on the JSP page using the
<code>pageInput</code> databinding context.
-<source>
- <netui:span value="${pageInput.name}"/>
-</source>
- </td>
- </tr>
- <tr>
- <td>
- <code>sharedFlow</code>
- </td>
- <td>Attribute map of all of the shared flows in the web
application</td>
- <td>Provided that the shared flow is declared in the
Controller file
- <source>
[EMAIL PROTECTED](
- sharedFlowRefs={
- @Jpf.SharedFlowRef(name="mySharedFlow",
type=sharedFlows.SharedFlow.class)
- }
-)
-public class Controller
- extends PageFlowController
-</source>
- You can access the members of the shared flow through the
<code>sharedFlow</code> context.
-<source><![CDATA[
-<netui:span value="${sharedFlow.mySharedFlow.someProperty}"/>
-]]></source>
- </td>
- </tr>
</table>
- </section>
- <section id="individual_binding_contexts">
- <title>Individual Binding Contexts</title>
- <section id="actionForm">
- <title>
- <code>actionForm</code>
- </title>
- <p>To bind to data in a form bean, you use the
<code>actionForm</code>
- context.
- In the following example a JSP's form fields are
pre-populated
- by binding to the fields of a form bean.
- Assume that you navigate to the JSP page via the following
action method.
- Notice that the <code>Forward</code> object is constructed
with
- two parameters: the first parameter is the string
"update", the second
- parameter is a form bean (DatabaseForm). By constructing
the
- Forward object in this way, the <code>actionForm</code>
context
- is automatically filled with the form bean values, values
which can
- be retrieved by the navigated-to JSP page.
- </p>
- <source>
[EMAIL PROTECTED](
- forwards={
- @Jpf.Forward( name="update", path="updateItems.jsp" )
- }
-)
-public Forward updateItems(DatabaseForm form) {
- ...
- // Read from the database
- // and apply the values to the form bean.
- form.applyValuesToForm(getCurrentRow());
-
- // Construct a Forward object using the form bean.
- return new Forward("update", form);
-}
-</source>
- <p>The action method above reads a record from a database
using a
- Database control (the control code is omitted in the
example) and populates the fields in the form bean with the
- record data before navigating to the JSP
<code>updateItems.jsp</code>.
- The values are retrieved by the JSP page, using the
<code>actionForm</code> context:</p>
- <source><![CDATA[
-<netui:form action="submitUpdate">
- <netui:content value="${actionForm.itemnumber}"/>
- <netui:textBox dataSource="actionForm.itemname"/>
- ...
-</netui:form>
-]]></source>
- <p>When the <netui:form> is submitted
(<code>submitUpdate</code>), you can then write the updated values back to the
database:</p>
- <source>
[EMAIL PROTECTED](
- forwards={
- @Jpf.Forward( name="updated", path="getItems.jsp" )
- }
-)
-public Forward submitUpdate(DatabaseForm aDatabaseForm) {
- // code that calls the database control and updates the database
- return new Forward("updated");
-}
-</source>
- </section>
- <section id="applicationScope">
- <title>
- <code>applicationScope</code>
- </title>
- </section>
- <section id="bundle">
- <title>
- <code>bundle</code>
- </title>
- </section>
- <section id="container">
- <title>
- <code>container</code>
- </title>
- <p>The <code>container</code> refers to the data set passed
into a
- <netui-data> or <netui-data:repeater> tag. The
<code>container</code>
- allows access to the individual rows and cells of the data
set.</p>
- <p>The <code>container</code> context has the following
properties.</p>
- <table>
- <tr>
- <td><strong>Property Name</strong></td>
- <td><strong>Description</strong></td>
- </tr>
- <tr>
- <td><code>container.item</code></td>
- <td>Refers to the current row of the data set.</td>
- </tr>
- <tr>
- <td><code>container.item.[field_name]</code></td>
- <td>Refers to an individual field of the current
row.</td>
- </tr>
- <tr>
- <td><code>container.index</code></td>
- <td>Refers to the integer index of the current
row.</td>
- </tr>
+ <p>
+ The following example uses the NetUI
<code><netui-data:repeater></code> to iterate over an array of
<code>Widget</code>
+ beans displaying each Bean's name and density properties and their
index in the array.
+ </p>
+ <source><![CDATA[
+ <%@ taglib
uri="http://beehive.apache.org/netui/tags-databinding-1.0"
prefix="netui-data"%>
+
+ <table>
+ <tr><th>Index</th><th>Name</th><th>Name</th></tr>
+ <netui-data:repeater dataSource="requestScope.widgetBeanArray">
+
<tr><td>${container.index}</td><td>${container.item.name}</td><td>${container.item.name}</td></tr>
+ </netui-data:repeater>
</table>
- <p>The following example shows how to access the name, type breed,
and weight properties
- in a data set passed to a data grid.</p>
- <p>The context <code>container</code> refers to the data set
<code>pageInput.petList</code>.</p>
-<source><![CDATA[
-<netui-data:dataGrid dataSource="<strong>pageInput.petList</strong>"
name="petGrid">
- <netui-data:rows>
- <netui-data:spanCell value="${<strong>container.item.name</strong>}"/>
- <netui-data:spanCell value="${<strong>container.item.type</strong>}"/>
- <netui-data:spanCell value="${<strong>container.item.breed</strong>}"/>
- <netui-data:spanCell
value="${<strong>container.item.weight</strong>}""/>
- </netui-data:rows>
-</netui-data:dataGrid>
-]]></source>
- </section>
- <section id="pageFlow">
- <title>
- <code>pageFlow</code>
- </title>
- <p>When you define a variable in your controller class, you
can access this
- variable from any JSP page that is part of that page flow
by providing
- access with a getter and setter method. For example, if
the JPF file
- contains this code:</p>
-
-<source> private String firstName;
-
- public String getFirstName() {
- return firstName;
- }
-
- public void setFirstName(String aStr) {
- firstName = aStr;
- }</source>
-
-<p>You can access this variable on a JSP, for instance, you can bind the value
to a netui:label as is shown next:</p>
-
-<source><![CDATA[
- <netui:label value="${pageFlow.firstName}"/>
-]]></source>
-
-
-<p>In the example the method getFirstName is used to provide read access to
the variable.
- The variable is read-write and can be changed, for instance in the
controller's action method as is shown in the next example:</p>
-
-<source>
[EMAIL PROTECTED](
- forwards={
- @Jpf.Forward( name="success", path="nextPage.jsp" )
- }
-)
-public Forward labelAction(NameActionForm form) {
- ...
- firstName = "Default Name";
- return new Forward( "success");
-}
-</source>
-
-<p>It can also be changed in a JSP by using a form, as is shown next:</p>
-
-<source><![CDATA[
-<netui:form action="submitAction">
- <netui:textBox dataSource="pageFlow.firstName"/>
- ...
- <netui:button value="submit"/>
- </netui:form>
-]]></source>
-
-<p>You can also define and access variables that are part of an object created
in the
- controller class. You can provide this access by again using getter and
setter
- methods. For instance, if the JPF file contains the code:</p>
-
-<source>
-public class dataFlowController
- extends PageFlowController {
- ...
- public Names myNames = new Names();
- ...
- public class Names implements Serializable {
- public String firstName;
- public String lastName;
-
- public String getFirstName(){
- return firstName;
- }
- public String getLastName(){
- return lastName;
- }
- }
- ...
-</source>
-
-<p>You can access the firstName property in a JSP like this:</p>
-
-<source><![CDATA[
-<netui:label value="${pageFlow.myNames.firstName}" />
-]]></source>
-
-<p>The comments in this section regarding access of page flow properties also
apply to
- properties defined to the <a
href="#sharedFlow"><code>sharedFlow</code></a> context.</p>
- </section>
- <section id="pageInput">
- <title>
- <code>pageInput</code>
- </title>
- <p>The <code>pageInput</code> context is filled with data by
an action output
- in the Controller class.</p>
- <source>Forward f = new Forward("next_page");
-f.addActionOutput("message", sMessage);</source>
- <p>The data can be retrieved on the JSP page as follows:</p>
- <source><![CDATA[
-<netui:span value="${pageInput.message}"/>
- ]]></source>
- </section>
- <section id="request">
- <title>
- <code>requestScope</code>
- </title>
+ ]]></source>
+ <p>
+ Notice in this example how the <code>repeater</code> tag has a
<code>dataSource</code> attribute that references
+ the data set to iterate through. The <code>dataSource</code>
attribute requires the use of the NetUI Expression
+ Language because the <code>repeater</code> can be used to render
editing UI for data sets. For example, in the case
+ of rendering a shopping cart, the repeater can be used to render
each item in the cart with a <code><netui:textBox></code>
+ for editing the quantity of each item. An example of this can be
found in the Beehive sample webapp called
+ <code>netui-samples</code> under the
<code>ui/repeaterediting/</code> directory.
+ </p>
</section>
- <section id="session">
- <title>
- <code>sessionScope</code>
- </title>
-<p>You can use the <code>sessionScope</code> context to read data from the
- session object (an implicit JSP object). Assuming that the session object
contains
- some data in its attribute map:</p>
-
-<source>
- getSession().setAttribute("myAttributeKey", myObject);
-</source>
-
-<p>then, you can read the data onto a JSP page as follows:</p>
-
-<source><![CDATA[
- <netui:content
value="${sessionScope.myAttributeKey.someProperty}"></netui:content>
-]]></source>
+ <section id="implicit-objects-netui-pageFlow">
+ <title>pageFlow</title>
+ <p>
+ The <code>pageFlow</code> implicit object is used to refer to the
current Page Flow as a JavaBean. If there is no Page Flow
+ present, the <code>pageFlow</code> implicit object will not be
available for data binding. For example, if a Page Flow
+ exposes a <code>username</code> property as:
+ </p>
+ <source>
+ @Jpf.Controller(
+ [EMAIL PROTECTED](name="index", path="index.jsp")}
+ )
+ public class Controller {
+ private String _username = null;
+
+ public String getUsername() {
+ return _username;
+ }
+
+ @Jpf.Action()
+ public Forward begin() {
+ _username = "Foo Bar";
+ return new Forward("index");
+ }
+ }
+ </source>
+ <p>
+ The <code>username</code> property can be data bound in
<code>index.jsp</code> as:
+ </p>
+ <source><![CDATA[
+ ${pageFlow.username}
+ ]]></source>
+ <note label="Best Practice">
+ Because mutable JavaBean properties can be updated via an HTML
form POST, JavaBean properties exposed by a Page Flow should usually
+ be read-only unless the Page Flow itself is being used as a form
bean.
+ </note>
</section>
- <section id="sharedFlow">
- <title>
- <code>sharedFlow</code>
- </title>
-<p>If you need an attribute to be available across all the page flows in a web
application's
- user (browser) session, such as a user's unique session key, you can use
shared flow.
- By convention, shared flows are located in WEB-INF/src/shared. (For
details on creating
- a shared flow, see <a href="site:pageflow_sharedFlow">Shared Flow</a>.)
In addition to
- session-wide attributes, you can also use the shared flow to define
fallback action methods
- and exception handlers. </p>
-
-<p>If you define a variable in the shared flow class:</p>
-
-<source>
-public class SharedFlow
- extends SharedFlowController {
- public String defaultText = "Please Define";
-
- public String getDefaultText(){
- return defaultText;
- }
- ...
-}
-</source>
-
-<p>and your controller file references the shared flow:</p>
-
-<source>
[EMAIL PROTECTED](
- sharedFlowsRefs = {
- @Jpf.SharedFlowRef(name = "specificSharedFlow", type =
"SharedFlow.class")
- }
-)
-public class SomeController
- extends Controller {
-...
-}
-</source>
-
-<p>you can use the databinding context <code>sharedFlow</code> in a JSP
file:</p>
-
-<source><![CDATA[
-<netui:textBox dataSource="actionForm.firstName"
defaultValue="${sharedFlow.specificSharedFlow.defaultText}"/>
-]]></source>
-
-<p>Notice that the <netui:textBox> tag in the example binds to a form bean
to post data and binds to sharedFlow's defaultText to receive its default
value.</p>
+ <section id="implicit-objects-netui-pageInput">
+ <title>pageInput</title>
+ <p>
+ The <code>pageInput</code> implicit object is used to refer to a
<code>Map</code> of objects that are passed via a
+ <code>Forward</code> from a Page Flow action to a JSP. Use of
Page Inputs consists of two parts -- the first are called
+ <em>action outputs</em> and the second are called <em>page
inputs</em>. Action outputs are passed from Page Flow actions
+ to pages via the action's <code>Forward</code> object. Page Flow
actions use Java annotations to declare a validatable
+ data contract that ensures that an action passes the correct data
via a <code>Forward</code>. At the page, this data
+ is called a <em>page input</em> and can again be checked to ensure
that the page receives the data necessary to render
+ successfully.
+ </p>
+ <p>
+ This example shows a Page Flow action that passes an action output
of type <code>Widget</code> to a JSP which
+ data binds to the <code>density</code> property on the
<code>Widget</code>.
+ </p>
+ <p>
+ The Page Flow:
+ </p>
+ <source>
+ @Jpf.Controller()
+ public class Controller
+ extends PageFlowController {
+
+ @Jpf.Action(
+ [EMAIL PROTECTED](name="success",
+ path="index.jsp",
+ [EMAIL PROTECTED](name="theWidget",
type=Widget.class, required=true)}
+ )
+ }
+ )
+ protected Forward begin() {
+ Widget widget = new Widget();
+ widget.setDensity(3.14);
+ Forward f = new Forward("success");
+ f.addActionOutput("theWidget", widget);
+ return f;
+ }
+ }
+ </source>
+ <p>
+ Notice here that the action has added an action output to the
<code>Forward</code> via the <code>addActionOutput</code>
+ method call. The Page Flow runtime will then validate the data
contract declared in the annotations against the
+ returned forward object. If validation fails, a runtime error
will be displayed in the browser.
+ </p>
+ <p>
+ The JSP:
+ </p>
+ <source><![CDATA[
+ <%@ taglib
uri="http://beehive.apache.org/netui/tags-databinding-1.0"
prefix="netui-data"%>
-<p>SharedFlow properties can be accessed from a JSP using the scope
sharedFlow, for example,</p>
+ <netui-data:declarePageInput name="theWidget"
type="org.foo.Widget"/>
-<source>
- dataSource="sharedFlow.specificSharedFlow.someProperty"
-</source>
-
-<p>Actions declared in a SharedFlow are accessed by specifying a fully
qualified action</p>
-
- <source>
-action="specificSharedFlow.someAction"
-</source>
- <p>where specificSharedFlow was the name given to the sharedFlow in
the JPF annotation <code>Jpf.SharedFlowRef</code>.</p>
+ ${pageInput.theWidget.density}
+ ]]></source>
+ <p>
+ Notice here that the page has used a <code>declarePageInput</code>
tag to ensure that the <code>Widget</code>
+ entering the page is both present in the set of page inputs and is
non-null. Given this information, the JSP
+ then refers to properties on the <code>Widget</code> via the
expression language.
+ </p>
+ <p>
+ Action outputs and page inputs can be used with or without
validation; to disable action output validation, simply remove
+ any action output annotations from a Page Flow action. To disable
page input validation in a JSP, remove any
+ <code>declarePageInput</code> tags from the JSP. The APIs to add
action outputs to <code>Forward</code> objects
+ and to refer to them via the <code>pageInput</code> implicit
object will continue to work without any data contract
+ validation.
+ </p>
+ <ul>
+ <li>An action exposes data specified in its annotations.</li>
+ <li>A JSP receives the data that it expects.An action exposes
data specified in its annotations.</li>
+ </ul>
</section>
- <section id="param">
- <title>
- <code>param</code>
- </title>
+ <section id="implicit-objects-netui-sharedFlow">
+ <title>sharedFlow</title>
+ <p>
+ The <code>sharedFlow</code> implicit object is used to refer to
properties of Shared Flow objects that are associated with
+ the current Page Flow. If there is no Page Flow present, the
<code>sharedFlow</code> implicit object will not be available
+ for data binding. In order for a Shared Flow to be available for
data binding, it must be registered with a Page Flow by
+ type; additionally, it is registered with a name that will
uniquely identify it in the set of Shared Flows associated with a
+ Page Flow. More information on Shared Flows can be found <a
href="site:pageflow_sharedFlow">here</a>.
+ </p>
+ <p>
+ The following example shows a Shared Flow, a Page Flow that uses
that Shared Flow, and a JSP that uses the JSP 2.0 EL
+ to data bind to a JavaBean propety of the Shared Flow.
+ </p>
+ <p>
+ The Shared Flow:
+ </p>
+ <source>
+ package org.foo;
+
+ import org.apache.beehive.netui.pageflow.SharedFlowController;
+
+ @Jpf.Controller()
+ public class SharedFlow
+ extends SharedFlowController {
+
+ private String _sharedMessage = null;
+
+ public String getSharedMessage() {
+ return _sharedMessage;
+ }
+ }
+
+ </source>
+ <p>
+ The Page Flow:
+ </p>
+ <source>
+ @Jpf.Controller(
+ [EMAIL PROTECTED](name="aSharedFlow",
type=org.foo.SharedFlow.class)}
+ )
+ public class Controller
+ extends PageFlowController {
+
+ ...
+ }
+ </source>
+ <p>
+ Above, the Page Flow adds an explicit reference to the Shared Flow
Controller <code>org.foo.SharedFlow</code> defined above.
+ </p>
+ <p>
+ The JSP:
+ </p>
+ <source><![CDATA[
+ ${sharedFlow.aSharedFlow.sharedMessage}
+ ]]></source>
+ <p>
+ In a JSP whose current Page Flow Controller is the
<code>Controller</code> class defined above, the JSP has access to
+ all of the Shared Flows associated to the Page Flow via its
<code>@Jpf.SharedFlowRef</code> annotation. The Shared
+ Flow can then be referenced by the <code>name</code> attribute of
the <code>SharedFlowRef</code> annotation. In this case,
+ the name <code>aSharedFlow</code> is used in the JSP 2.0
expression to refer to the <code>SharedFlow</code>'s
+ <code>sharedMessage</code> property.
+ </p>
</section>
</section>
- <section id="related">
- <title>Related Topics</title>
- <p>For more information on the JSP 2.0 Expression Language, see
- <a
href="http://www.onjava.com/pub/a/onjava/2003/11/05/jsp.html" class="fork">JSP
2.0: The New Deal, Part 1</a>
- </p>
- </section>
<section id="el-details">
<title>Expression Language Details</title>
<p>
Due to limitations in the JSP 2.0 Expression Language
specification, expressions can not be used to reference
read-write data because the JSP tag itself can never obtain both
the expression text and the value of the
- expression
+ expression. In NetUI, both the value and expression text are
required to bind to editable data because the
+ expression text is written into the JSP as the HTML
<code>name</code> attribute of HTML form <code>input</code>
+ fields.
</p>
</section>
</body>