OPS User Guide
- Getting Started
- Tutorial
- Core Technologies Reference
- XForms
- Page Flow
- XML Pipelines (XPL)
- OPS Technologies Reference
- Processors Reference
- API Reference
- Integration
- Obsolete
|
XForms Reference
1. Scope
Web applications use forms to collect data from users. Orbeon PresentationServer
(OPS)'s form handling capabilities are based on XForms, namely the XForms 1.0 W3C Recommendation. This section
provides an introduction to XForms concepts and explains how to use XForms in your
OPS application.
Warning
This page is a work in progress.
2. Getting Started
2.1. The XForms Sandbox
The easiest way to get started with simple examples is to use the OPS XForms
Sandbox. This tool allows you to upload example XForms files from your web browser
and to see the results directly. You can access the XForms sandbox:
-
Online: visit this link
to access the online public XForms Sandbox.
-
Locally: if this documentation is produced by your local installation
of OPS, visit this link.
After submitting an XHTML + XForms file, the result, or errors, should display. Use
your browser's "Back" button to return to the main XForms Sandbox page, or use a
bookmark.
2.2. Integrating XForms in OPS
TODO: past the sandbox, how to integrate XForms with OPS: single static page,
dynamic page, PFC and MVC, submissions, services, proxy mode, etc.
3. Programming With XForms 1.0
3.2. Repeating with xforms:repeat
3.2.1. Basics
A very common requirement of user interfaces consists in repeating visual, such
as rows in a table, entries in a list, etc. Those repeated sections usually have
an homogeneous aspect: they all have the same or a very similar structure. For
example, multiple table rows will differ only in the particular content they
display in their cells. An example of this is an invoice made of lines with each
a description, unit price, and quantity.
XForms provides a very powerful mechanism to implement such repeated structures:
the xforms:repeat element. You use xforms:repeat
around XHTML elements or XForms controls. For example, to repeat a table row,
you write:
<xforms:repeat> <xhtml:tr>... </xhtml:tr> </xforms:repeat>
This is not enough to be functional code: you need to indicate to the
xforms:repeat element how many repetitions must be performed. This
is done not by supplying a simple count value, but by binding the the element to
a node-set with the node-set attribute. Consider the following
XForms instance:
<xforms:instance id="employees-instance" xmlns:xforms="http://www.w3.org/2002/xforms"> <employees> <employee> <first-name>Alice</first-name> </employee> <employee> <first-name>Bob</first-name> </employee> <employee> <first-name>Marie</first-name> </employee> </employees> </xforms:instance>
Assuming you want to produce one table row per employee, add the following
nodeset attribute:
<xforms:repeat nodeset="instance('employees-instance')/employee"> <xhtml:tr>... </xhtml:tr> </xforms:repeat>
This produces automatically three xhtml:tr rows. Note that we
explicitly use the XForms instance() function, but you may not have
to do so if that instance is already in scope. Then you display in each row the
content of the first-name element for each employee:
<xforms:repeat nodeset="instance('employees-instance')/employee"> <xhtml:tr> <xhtml:td> <xforms:output ref="first-name"/> </xhtml:td> </xhtml:tr> </xforms:repeat>
This works because for each iteration, the context node for the
ref attribute changes: during the first iteration, the context node
is the first employee element of the XForms instance; during the
second iteration, the second employee element, and so on.
Note
The nodeset attribute of xforms:repeat must point
to a so-called homogeneous collection. Such a collection must consist
of contiguous XML elements with same name and same namespace. XForms does
not predict what happens if the node-set is not homogenous.
3.2.3. Deleting Rows with the xforms:delete Action
xforms:repeat may be used purely for display purposes, but it
can also be used for interactively editing repeated data. This includes
allowing the user to delete and insert rows. Two XForms actions are used
for this purpose: xforms:delete and xforms:insert .
xforms:delete is provided with a nodeset attribute
pointing to the homogenous collection into which the insertion must take
place. It also has an at attribute, which contains an XPath
expression returning the index of the element to delete. The following
deletes the last element of the collection:
<!-- This deletes the last element of the collection --> <xforms:delete nodeset="employees" at="last()"/> <!-- This deletes the first element of the collection --> <xforms:delete nodeset="employees" at="1"/> <!-- This deletes the currently selected element of the collection (assuming the repeat id 'employee-repeat') --> <xforms:delete nodeset="employees" at="index('employee-repeat')"/>
3.2.4. Inserting Rows with the xforms:insert Action
xforms:insert is provided with a nodeset attribute
pointing to the homogenous collection into which the insertion must take
place. xforms:insert then considers the last element of
that collection (and all its content if any) as a template for the
new element to insert: it duplicates it and inserts it into the homogenous
collection at a position you specify. The last element of an homogeneous
collection therefore always acts as a template for insertions:
<!-- This inserts a copy of the template before the last element of the collection --> <xforms:insert nodeset="employees" at="last()" position="before"/> <!-- This inserts a copy of the template after the last element of the collection --> <xforms:insert nodeset="employees" at="last()" position="after"/> <!-- This inserts a copy of the template before the first element of the collection --> <xforms:insert nodeset="employees" at="1" position="before"/> <!-- This inserts a copy of the template after the first element of the collection --> <xforms:insert nodeset="employees" at="1" position="after"/> <xforms:insert nodeset="employees" at="last()" position="after"/> <!-- This inserts a copy of the template before the currently selected element of the collection --> <xforms:insert nodeset="employees" at="index('employee-repeat')" position="before"/> <!-- This inserts a copy of the template after the currently selected element of the collection --> <xforms:insert nodeset="employees" at="index('employee-repeat')" position="after"/>
The at attribute contains an XPath expression returning the
index of the element before or after which the insertion must be performed.
The position element contains either after or
before , and specifies whether the insertion is performed before
or after the element specified by the at attribute.
It is important to note that while it is possible to delete the last element
of an homogeneous collection, it becomes them impossible to insert a new
element into that collection with XForms 1.0, since there is no longer a
template element available in this case (save for using an XML submission
with replace="instance" ). This means that in general you design
your collections so that there always at least one element in it.
In case you want the user interface to visually appear empty empty when
there is "no more" elements in the collection, you can use the tip provided
below, which can be used in most situations. The idea is to consider that
the last element of the collection is never displayed, but always used as a
template for xforms:insert :
<xforms:instance id="employees-instance" xmlns:xforms="http://www.w3.org/2002/xforms"> <employees> <employee> <first-name>Alice</first-name> </employee> <employee> <first-name>Bob</first-name> </employee> <employee> <first-name>Marie</first-name> </employee> <!-- This is a template used by xforms:insert --> <employee> <first-name/> </employee> </employees> </xforms:instance>
You do not want to display that template, however. Therefore you use an
xforms:repeat element of the form:
<xforms:repeat nodeset="instance('employees-instance')/employee[position() < last()]">... </xforms:repeat>
The position() < last() condition tells
xforms:repeat to consider all the elements of the collection
except the last one. This causes the repetition to display zero iteration
when there is one element in the collection, one iteration when there are
two, etc. The xforms:insert action, on the other hand, operates
on the entire collection including the last element, so that that element
can be duplicated:
<xforms:insert nodeset="employees" at="..." position="..."/>
Another solution involves using an xforms:bind element which
makes the last element of the collection non-relevant. This achieves the
same result, but requires extra code, so the tip above is usually
preferred.
Upon submission, some care must be taken with repeat template. For example,
if the first-name element above is required, and the template
contains an empty value as above, submission will fail.
xforsm:bind statements must then also exclude the last element
of the collection:
<xforms:bind nodeset="employee[position() < last()]/first-name" required="true()"/>
Note
If you are dealing with an XML document format which requires
removing the last element of a collection, you have to post-process
your XForms instance to remove such extra elements, and pre-process
it to add such elements when initializing your XForms instance.
3.2.5. Setting the Current Index with the xforms:setindex Action
3.2.6. Using xforms:trigger to Execute Actions
Insertions and deletions are typically performed when the user of the
application presses a button, with the effect of adding a new repeated
element before or after the currently selected element, or of deleting the
currently selected element. You use an xforms:trigger control
and the XPath index() function for that purpose:
<xforms:trigger> <xforms:label>Add</xforms:label> <xforms:action ev:event="DOMActivate"> <xforms:insert nodeset="employees" at="index('employee-repeat')" position="after"/> </xforms:action> </xforms:trigger>
<xforms:trigger> <xforms:label>Delete</xforms:label> <xforms:action ev:event="DOMActivate"> <xforms:delete nodeset="employees" at="index('employee-repeat')"/> </xforms:action> </xforms:trigger>
Note that we use xforms:action as a container for
xforms:insert and xforms:delete . Since there is
only one action to execute, xforms:action is not necessary, but
it may increase the legibility of the code. It is also possible to write:
<xforms:trigger> <xforms:label>Add</xforms:label> <xforms:insert ev:event="DOMActivate" nodeset="employees" at="index('employee-repeat')" position="after"/> </xforms:trigger>
<xforms:trigger> <xforms:label>Delete</xforms:label> <xforms:delete ev:event="DOMActivate" nodeset="employees" at="index('employee-repeat')"/> </xforms:trigger>
Notice in that case how ev:event="DOMActivate" has been moved
from the enclosing xforms:action to the
xforms:insert and xforms:delete elements.
3.2.8. Heterogeneous-Looking Repeated Section
TODO: use of relevant, switch.
3.2.9. Nested Repeats
It is often desirable to nest repeat sections. Consider the following
XForms instance representing a company containing departments, each
containing a number of employees:
<xforms:instance id="departments"> <departments> <department> <name>Research and Development</name> <employees> <employee> <first-name>John</first-name> </employee> <employee> <first-name>Mary</first-name> </employee> </employees> </department> <department> <name>Support</name> <employees> <employee> <first-name>Anne</first-name> </employee> <employee> <first-name>Mark</first-name> </employee> <employee> <first-name>Sophie</first-name> </employee> </employees> </department> </departments> </xforms:instance>
This document clearly contains two nested sections subject to repetition:
-
Departments: a node-set containing all the
department elements can be referred to with the
following XPath expression:
instance('departments')/department .
-
Employees: a node-set containing all the
employee elements can be referred to with the following
XPath expression:
instance('departments')/department/employees/employee .
However, if the context node of the XPath expression points
to a particular department element, then the following
relative XPath expression refers to all the
employee elements under that department
element: employees/employee .
Following the example above, here is how departments and employees can be
represented in nested tables with XForms:
<xhtml:table> <xforms:repeat nodeset="instance('departments')/department"> <xhtml:tr> <xhtml:td> <xforms:output ref="name"/> </xhtml:td> <xhtml:td> <xhtml:table> <xforms:repeat nodeset="employees/employee"> <xhtml:tr> <xhtml:td> <xforms:output ref="first-name"/> </xhtml:td> </xhtml:tr> </xforms:repeat> </xhtml:table> </xhtml:td> </xhtml:tr> </xforms:repeat> </xhtml:table>
In the code above, the second xforms:repeat 's nodeset
expression is interpreted relatively to the department element of
the parent xforms:repeat for each iteration of the parent's
repetition. During the first iteration of the parent, the "Research and
Development" department is in scope, and employees/employee refers
to the two employees of that department, John and Mary. During the second
iteration of the parent, the "Support" department is in scope, and
employees/employee refers to the three employees of that
department, Anne, Mark and Sophie.
3.3. Submission
Two properties control some aspects of XForms submission in OPS:
<property as="xs:boolean" name="oxf.xforms.optimize-post-all" value="true"/>
If set to true (the default), OPS optimizes submissions with
replace="all" by sending the response of the submission directly to
the web browser. This however means that submission errors cannot be caught by
XForms event handlers after OPS has started connecting to the submission URL,
as should be the case following XForms 1.0. If set to false , OPS
buffers the reply so that errors can be handled as per XForms 1.0. However, this
solution is less efficient.
<property as="xs:boolean" name="oxf.xforms.optimize-local-submission" value="true"/>
If set to true (the default), OPS optimizes "local" HTTP and HTTPS
submissions, i.e. submissions performed to a URL controlled by OPS itself, by
directly submitting using the Java Servlet API instead of actually using the
HTTP protocol for the submission. If set to false , OPS always
always uses the HTTP or HTTPS protocol, which is less efficient. If set to
false , it is possible to specify the xxforms:post
method instead of the post method on the
xforms:submission element to force an optimized local submission.
4. Formatting
4.1. Rationale
It is usually recommended to use native XML types within XForms instances, as
this guarantees interoperability and maintainability. For example, a date of
January 10, 2005 is stored in ISO format as: 2005-10-01 . However it
is often necessary to format such values on screen in a user-readable format,
like "January 10, 2005", "10 janvier 2005", or "10. Januar 2005".
OPS provides an extension attribute, xxforms:format , for that
purpose. xxforms:format must contain an XPath 2.0 expression, and
also supports the following XSLT 2.0 functions:
The XPath expression is evaluated by the XForms engine whenever the value bound
to the xforms:input control changes and needs to be updated on
screen. It is evaluated in the context of the instance node bound to the
control. This means that the current value of the control can be accessed with
". ". Often the value must be converted, for example to a date, in
which case the conversion can be done with XPath 2.0 type casts such as
xs:date(.) .
4.2. xforms:input
When using xforms:input and a bound xs:date type, you
can control the formatting of the date using the xxforms:format
extension attribute on the xforms:input control. For example:
<xforms:input ref="date" xxforms:format="format-date(xs:date(.), '[MNn] [D], [Y]', 'en', (), ())"/>
4.3. xforms:output
When using xforms:output , you can control the formatting of the
date using the xxforms:format extension attribute on the
xforms:input control.
<xforms:output ref="date" xxforms:format="format-date(xs:date(.), '[MNn] [D], [Y]', 'en', (), ())"/> <xforms:output ref="size" xxforms:format="format-number(., '###,##0')"/>
4.4. Default Formatting
For both xforms:input and xforms:output , if the bound
node is of type xs:date , xs:dateTime or
xs:time , and if no xxforms:format attribute is present
on the control, formatting is based on properties. If the properties are missing, a
built-in default formatting is used. The default properties, as well as the
built-in defaults, are as follows:
<property as="xs:string" name="oxf.xforms.format.date" value="if (. castable as xs:date) then format-date(xs:date(.), '[FNn] [MNn] [D], [Y]', 'en', (), ()) else ."/> <property as="xs:string" name="oxf.xforms.format.dateTime" value="if (. castable as xs:dateTime) then format-dateTime(xs:dateTime(.), '[FNn] [MNn] [D], [Y] [H01]:[m01]:[s01] UTC', 'en', (),
()) else ."/> <property as="xs:string" name="oxf.xforms.format.time" value="if (. castable as xs:time) then format-time(xs:time(.), '[H01]:[m01]:[s01] UTC', 'en', (), ()) else ."/>
They produce results as follows:
-
2004-01-07 is displayed as Wednesday January 7, 2004
-
2004-01-07T04:38:35.123 is displayed as Wednesday January 7, 2004 04:38:35 UTC
-
04:38:35.123 is displayed as 04:38:35 UTC
Note that with the condition in the XPath expressions, a value which cannot be
converted to the appropriate type is simply displayed as is.
5. XForms Instance Initialization
5.1. Rationale
An XForms page often needs to contain initial data when first loaded. The data
may come from a database, a form submitted on a previous page, etc. There are
several ways to achieve this with OPS.
5.2. Page Flow Definitions
Within your page flow, you define a page model and either a static page view:
<page id="..." path-info="..." model="my-page-model.xpl" view="my-page-view.xhtml"/>
Or a dynamic XSLT page view:
<page id="..." path-info="..." model="my-page-model.xpl" view="my-page-view.xsl"/>
The page model is in charge of producing an XML document which is then going to
be used by the page view to initialize the XForms instance. As always with OPS,
the page model produces this document on its data output, and the
page view can access this document on its data input, as shown in
the following sections. This mechanism is described in details in the PFC documentation.
5.3. Using XInclude
Following the MVC architecture, the PFC page model generates an XML document
which contains an XForms instance. A static PFC page view then includes this
instance using xi:include , as follows:
<html> <head> <title>Summary</title> <xforms:model> <xforms:instance id="document-infos-instance"> <!-- This is where the XML document produced by the page model is included --> <xi:include href="input:data"/> </xforms:instance>... </xforms:model> </head> <body>... </body> </html>
The use of the URI input:data instructs XInclude processing to
dynamically include the data output of the page view, which is
produced on the data output of the page model. Note that it is
possible to use the instance input, which then refers to the
current XML submission.
5.4. Using XSLT
It is also possible to use a dynamic XSLT page view to perform the inclusion of
the instance. XSLT is more flexible than XInclude, but less efficient at
runtime. This is an example:
<html xsl:version="2.0"> <head> <title>Summary</title> <xforms:model> <xforms:instance id="document-infos-instance"> <!-- This is where the XML document produced by the page model is included --> <xsl:copy-of select="doc('input:data')/*"/> </xforms:instance>... </xforms:model> </head> <body>... </body> </html>
Note the use of xsl:version="2.0" on the root element of the
document, which instructs the PFC to process the page view as an XSLT
stylesheet.
The use of the XPath doc() function with a URI
input:data instructs XSLT processing to dynamically include the
data output of the page view, which is produced on the
data output of the page model.
Note
It is possible to use XInclude instructions in a dynamic XSLT page view as well.
In this case, it is important to note that XInclude instructions are processed
before XSLT instructions, i.e. the result of XInclude instructions is an XSLT
stylesheet, which is then executed. [TODO: Figure showing XInclude -> XSLT
processing.]
Note
Using XSLT for page views has an impact for debugging, as the output of XSLT
transformations do not contain valuable location information. For performance
and ease of debugging reasons, we recommend using static XHTML views with
XInclude whenever possible.
6. XSLT or XForms?
There are some similarities between XSLT and XForms. XSLT can be used to extract
data from an XML document, format it, and output it with xsl:value-of .
XForms can do the same using xforms:output .
7. Relative Paths
7.1. Rationale
XForms documents can refer to external resources using URIs in the following
circumstances:
-
External Instances. The xforms:instance element can
have an src attribute linking to an external instance
definition.
-
Submission. The xforms:submission element must refer
to an action URI.
-
Load Action. The xforms:load action must refer to an
URI that must be loaded upon execution.
-
Image Mediatype. The xforms:output control may refer
to an image URI.
-
Message, Label, Help, Hint, and Alert.
xforms:label , xforms:help ,
xforms:hint , and xforms:alert may use an
src attribute to refer to external content.
Note
The XForms 1.1 draft of November 15, 2004 removes linking attributes
from actions and metadata elements and "the src attribute
is not available to XForms 1.1 message , label ,
help , hint , alert elements."
URIs are resolved relatively to a base URI. The base URI is, by default,
the external URL used to display the XForms page, with special handling of the
servlet context, if necessary. It is also possible to override this behavior by
adding xml:base attributes on xforms:load or any of
its ancestor elements.
7.2. External Instances
This is done with the src attribute on the
xforms:instance element, for example:
<xforms:instance src="my-instance.xml"/>
With a client-side implementation of XForms, it makes sense for the
src attribute to be relative to the base URI of the XForms page,
which is usually an http: URI.
With a server-side implementation, it may make more sense in general to
interpret the URI relative to the location of the source XForms page, which is
usually an oxf: URI.
7.3. Load Action
The xforms:load action can refer to a resource to load either
through the resource attribute or using a single-node binding
retrieving the URI from an XForms instance. In both cases, the value of the URI
is resolved relatively to the base URI.
The following assumes that OPS runs in the /ops servlet context:
Base URI (External URL or xml:base attributes)
|
Initial URI (resource or Single-Node Binding)
|
show |
Resolved URI |
Comment |
The following URI is loaded in a servlet:
http://example.org/ops/my-page
|
http://orbeon.com/software/ |
replace |
http://orbeon.com/software/ |
An absolute URL is left untouched. The new page replaces the existing
page.
|
new |
An absolute URL is left untouched. A new window or tab opens for the new
page.
|
/my-new-page |
replace |
http://example.org/ops/my-new-page |
Absolute paths resolve against the current servlet context. The new page
replaces the existing page.
|
new |
Absolute paths resolve against the current servlet context. A new window
or tab opens for the new page.
|
admin/main-page |
replace |
http://example.org/ops/admin/main-page |
The new page replaces the existing page.
|
new |
A new window or tab opens for the new page.
|
The following path is loaded in a portlet:
/my-example/my-page
|
http://orbeon.com/software/ |
replace |
http://orbeon.com/software/ |
This causes the application to load a page outside of the portlet,
replacing the entire portal.
|
new |
This causes the application to load a page in a new window outside of
the portlet.
|
/my-new-page |
replace |
/my-new-page |
The resulting path is loaded within the portlet.
|
new |
admin/main-page |
replace |
/my-example/admin/main-page |
The resulting path is loaded within the portlet.
|
new |
7.4. Image Mediatype for xforms:output
When an xforms:output control refers to an image URI, as documented
below, the resulting value is resolved
relatively to the base URI.
8. Labels, Hints, Alerts, Help Messages
TODO: explain purpose, styling, content allowed (xforms:output), and when e.g.
labels should not be used.
9. XForms and Services
9.1. Introduction
XForms 1.0 allows an XForms page to perform submissions of XForms instances and
to handle a response. In most cases, both the submitted XForms instance and the
response are XML documents.
Note
It is possible to submit an XForms instance with the HTTP GET method. In that
case, some information contained in the XML document is lost, as the structure
of the instance, attributes, and namespace prefixes among others, are not passed
to the submission.
The XForms submission featuer practically allows forms to call XML services.
Those services are accessible through an XML API, which means that a request is
performed by sending an XML document to the service, and a response consists of
an XML document as well.
9.4. Implementing Services with OPS
9.5. Page Flow Controller (PFC) Best Practices
10. Extensions
10.1. Media Type for xforms:output
In XForms 1.0, xforms:output is used to display text. However,
based on a proposal in a draft version of XForms 1.1, OPS supports a
mediatype attribute on that element.
10.1.1. Image Types
When the following conditions are met for an xforms:output
control:
-
The control has an optional mediatype attribute
referring to an image, such as image/* or
image/jpeg .
-
The value is provided to the xforms:output control with
the value attribute, or with a single-node binding to a
node without type or with an xs:anyURI type.
The resulting value is interpreted as URI pointing to an image. The image is
loaded where the xforms:output is located. When a single-node
binding is used, it is possible to dynamically change the image pointed to.
For example:
<xforms:output mediatype="image/*" value="'/images/moon.jpg'"/>
<xforms:model> <xforms:instance> <image-uri/> </xforms:instance> <xforms:bind nodeset="image-uri" type="xs:anyURI"/> </xforms:model>... <xforms:output mediatype="image/*" ref="image-uri"/>
Note
It is not yet possible to directly embed image data in an XForms instance
using the xs:base64Binary type.
10.1.2. HTML Type
When an xforms:output control has an optional
mediatype attribute with value text/html , the
value of the node to which the control is bound is interpreted as HTML
content.
Consider the following XForms instance:
<xforms:instance id="my-instance"> <form> <html-content>This is in <b>bold</b>! </html-content> </form> </xforms:instance>
You bind an xforms:output control to the
html-content node as follows:
<xforms:output ref="instance('my-instance')/html-content" mediatype="text/html"/>
This will display the result as HTML, as expected: "This is in in
bold!". If the mediatype is not specified, the result
would be instead: "This is in in <b>bold</b>!".
In the XForms instance, the HTML content must be escaped as text. On the
other hand, the following content will not work as expected:
<xforms:instance> <form> <html-content>This is in in<b>bold</b>! </html-content> </form> </xforms:instance>
10.2. XPath Extension Functions
OPS implements some extension functions which can be used from XPath expressions
in XForms documents.
10.2.1. XSLT 2.0 Extensions
When using XPath 2.0, the following functions from XSLT 2.0 are also available:
10.2.2. OPS Extensions
The following functions are implemented:
10.2.3. eXForms Extensions
eXForms is a suggested set of
extensions to XForms 1.0, grouped into different modules. OPS supports the
exf:mip module,
which includes the following functions:
-
exf:relevant()
-
exf:readonly()
-
exf:required()
eXForms functions live in the http://www.exforms.org/exf/1-0
namespace, usually bound to the prefix exf .
11. State Handling
11.1. Rationale
The OPS XForms engine requires keeping processing state while operating on an
XForms page. Such state includes the current values of XForms instances,
selected repeated elements, and more. With OPS, XForms state information can be
handled in one of two ways:
-
Client-side: in this case, static initial state information is
sent along with the initial HTML page, and dynamic state is exchanged
over the wire between the client browser and the OPS XForms server when
necessary.
Benefits of the approach:
-
The OPS server is entirely stateless. It only requires memory
while processing a client request. It can be restarted without
consequence for the XForms engine.
-
State information does not expire as long as the user keeps the
application page open in the web browser.
Drawbacks of the approach:
-
Resulting HTML pages are larger. In particular, the size of
state data grows when XForms instances grow, regardless of
whether many XForms controls are bound to instance data.
-
More data circulates between the client browser and the OPS
XForms server.
Note
OPS compresses and encrypts XForms state information sent to the
client.
-
Server-side: in this case, state information is stored on the
server, in association with an application session. Only very little
state information circulates between client and server.
Benefits of the approach:
-
Resulting HTML page are smaller. HTML pages increase in size as
more XForms controls are used, but they don't increase in size
proportionally to the size of XForms instances. This means that
very large XForms instances can be processed without impacting
client-server performance.
-
Small amounts of data circulate between the client browser and
the OPS XForms server.
Drawbacks of the approach:
-
The OPS server is stateful. It requires server memory to store
state information in a session even when no request is being
processed. The server must be configured to determine how much
state information is kept in a session, how long session take to
expire, etc.
-
State information can expire if the server is restarted (in case
session information is not restored), or when sessions expire,
even if the client browser is still displaying the page.
Expired state information causes an XForms page to no longer
function until it is reloaded.
Note
With most servlet containers, it is possible to configure
session handling to passivate sessions out of the application
server memory to a persistent store. It is this way possible to
partially alleviate the drawback above by making sure that a
very large number of active but idle sessions can be kept, with
a minimum impact on application server memory. It is this way
also possible to make sure that sessions survive a servlet
container restart.
Note
OPS ensures that it is possible to open multiple client browser windows
showing the same page within the same session.
11.2. Configuring State Handling
State handling can be configured globally for all pages, or locally for each
individual page served. Global configuration is performed in
properties.xml with the oxf.xforms.state-handling
property. When missing or set to client , state is stored
client-side. When set to session , state is stored server-side in a
session. For example:
<!-- Store state in the session --> <property as="xs:string" name="oxf.xforms.state-handling" value="session"/>
The global configuration can be overridden for each page by setting the
xxforms:state-handling attribute in the page. This attribute can be
set for example on the root element of the XHTML page, or on the first
xforms:model element. Only the first such attribute encountered by
the XForms engine is used:
<xforms:model xxforms:state-handling="client">...</xforms:model>
When storing state in a session, the maximum size of the data to be stored for
each user can be selected using the oxf.xforms.cache.session.size
property. The size is specified in bytes:
<!-- Allow a maximum of 500 KB of state information for each user --> <property as="xs:integer" name="oxf.xforms.cache.session.size" value="500000"/>
Whether state information is kept client-side or server-side, a property
controls whether the XForms engine should try to optimize state reconstruction
by using a cache. This property should usually be set to true :
<!-- This should usually be set to "true" --> <property as="xs:boolean" name="oxf.xforms.cache.document" value="true"/>
11.3. Handling the Browser's Back Button
TODO: Explain what OPS does and how different browsers behave.
11.4. Configuring Session Handling
This section is relevant when XForm state is stored into a session.
TODO: Configuration tips: expiration (web.xml), passivation? (Tomcat).
Session passivation can be tightly controlled with Tomcat 5.5. Please refer to
the relevant
Tomcat documentation for more information. Other servlet containers may have
similar relevant documentation.
12. Javascript Integration
TODO: Describe how you can use your own Javascript to set values to XForms controls.
|