Orbeon Forms User Guide

Using the Orbeon Forms XForms Engine with Java Applications

1. Introduction

Most of the example applications shipped with Orbeon Forms use the Page Flow Controller (PFC) and are implemented using components provided by Orbeon Forms such as XML pipelines. But it is also possible to use the XForms engine without worrying about these technologies and to simply use it as an XForms engine for your Java applications.

There are two main ways of integrating the Orbeon Forms XForms engine with Java applications:

  • Separately from the Orbeon Forms WAR. With this method, your application is deployed in its own Java web archive (WAR), and Orbeon Forms in its own WAR.

  • Together with the Orbeon Forms WAR. With this method, you integrate your application directly with Orbeon Forms. This means that the Java JAR files and classes of your application and Orbeon Forms are deployed within the same WAR.

Both methods are documented below. Deploying separately is the recommended method.

2. Deployment and Configuration

The following table compares the two deployment methods:

Separate Deployment Integrated Deployment
Benefits
  • Easier upgrades of both your application and Orbeon Forms.

  • Preventing situations where different versions of JAR files could conflict.

  • Cleaner application architecture.

  • No need to create your own WAR. Just use the Orbeon Forms WAR.

  • Default web.xml configuration works out of the box for JSPs.

web.xml Configuration

In order to enable XForms in your application, you need to add the following configuration to your application's web.xml:

<!-- Declare and configure the Orbeon Forms XForms filter --><filter><filter-name>ops-xforms-filter</filter-name><filter-class>org.orbeon.oxf.servlet.OPSXFormsFilter</filter-class><init-param><param-name>oxf.xforms.renderer.context</param-name><param-value>/ops</param-value></init-param></filter><!-- Any web resource under /xforms-jsp is processed by the XForms engine --><filter-mapping><filter-name>ops-xforms-filter</filter-name><url-pattern>/xforms-jsp/*</url-pattern></filter-mapping><!-- This is necessary so that XForms engine resources can be served appropriately --><filter-mapping><filter-name>ops-xforms-filter</filter-name><url-pattern>/ops/*</url-pattern></filter-mapping>

The value of the oxf.xforms.renderer.context parameter specifies the context into which you have deployed Orbeon Forms. By default, Orbeon forms deploys to /ops so this value is usually safe. If you deploy Orbeon Forms to another context, you need to change this value accordingly.

The <url-pattern> defined under the first <filter-mapping> has the value /xforms-jsp/*. This means that all the data generated by URLs starting with /xforms-jsp/ is post-processed by Orbeon Forms. You can change this value as desired.

The <url-pattern> defined under the second <filter-mapping> has the value /ops/*. This is necessary to allow for all Orbeon Forms resources, such as JavaScript, CSS, and Ajax server, to be accessible. This /ops/* value is related to the default context into which you deploy Orbeon Forms: if you change you context, you change this value as well.

The following configuration is enabled by default in the Orbeon Forms web.xml:

<filter><filter-name>ops-xforms-filter</filter-name><filter-class>org.orbeon.oxf.servlet.OPSXFormsFilter</filter-class></filter><filter-mapping><filter-name>ops-xforms-filter</filter-name><url-pattern>/xforms-jsp/*</url-pattern></filter-mapping>

The <url-pattern> defined under the <filter-mapping> has the value /xforms-jsp/*. This means that all the data generated by URLs starting with /xforms-jsp/ is post-processed by Orbeon Forms. You can change this value as desired.

Application Server Configuration

Your WAR must be deployed in such a way that it is allowed forwarding requests to other web applications. With Tomcat, this is called a cross-context setup, and you enable it as follows with the crossContext attribute in server.xml:

<Context path="/my-app" docBase="/path/to/my-app/war" crossContext="true"/>
None particular: just deploy Orbeon Forms as usual.
Location of JSPs

With the default configuration shown above, all JSPs located in the directory called xforms-jsp in your WAR are processed by the XForms engine. However, it is likely that you will prefer another location. In that case, you just change the url-mapping configuration.

You must not deploy resources under the /ops/ directory, as that directory is reserved for Orbeon Forms resources.

With the default configuration in the Orbeon Forms web.xml, all JSPs located in the directory called xforms-jsp in your WAR are processed by the XForms engine.

Under this directory, by default you find one directory per example, for instance xforms-jsp/guess-the-number or xforms-jsp/flickr-search. You can add your own directories and JSP files as desired.

Other Java Resources

You don't have to produce XForms from JSP. You can do so directly from servlets, or other Java web application frameworks (usually based on servlets and template languages). What matters is that the filter defined in web.xml kicks in for those resources and that you produce well-formed XML as output. For this to happen, you modify the <filter-mapping> accordingly to enable the filter for the URLs handled by your framework.

Session Handling

All URLs are designed go through your web application's context, so your application and the Orbeon Forms XForms engine automatically share the same session.

All URLs access the same web application context, so your application and Orbeon Forms automatically share the same session.

Access Control

You control security for all of your application's pages, including XForms pages, in your own application's web.xml. It is not possible to access your application's XForms pages by accessing Orbeon Forms URLs directly: your application controls the generation of XForms content, not Orbeon Forms.

However by default you can still access Orbeon Forms applications through Orbeon Forms URLs. If you don't want to deploy any Orbeon Forms applications directly, you can block external accesses to the Orbeon Forms WAR by configuring the Orbeon Forms WAR's web.xml.

You control security for all pages in the single application's web.xml.

3. Separate WAR Deployment Steps

You deploy Orbeon Forms as a separate WAR with the following steps:

  1. Deploy Orbeon Forms as usual, typically in the /ops context. Follow the installation instructions and the Orbeon Forms Tutorial if needed.

  2. Deploy your own application as a separate WAR.

  3. Copy WEB-INF/lib/ops-xforms-filter.jar from the Orbeon Forms WAR into your application's WEB-INF/lib/ directory.

  4. Configure your application's web.xml as described in the previous section to setup the Orbeon Forms XForms filter.

  5. Setup your application in cross-context mode, as described in the previous section.

4. Generating XHTML and XForms

Your JSP pages or servlets must generate well-formed XML documents that contain XHTML and XForms tags. There are two methods of passing this information to Orbeon Forms, described below.

4.1. Producing XHTML and XForms as JSP or Servlet Output

With this method, your JSP or servlet simply outputs XHTML and XForms in its output as it would HTML content. For example, a basic JSP page typically looks like this:

<xhtml:html xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:head><xhtml:title>Guess The Number</xhtml:title><xforms:model><xforms:instance>...</xforms:instance></xforms:model></xhtml:head><xhtml:body><xhtml:h1>My Page</xhtml:h1><xforms:input ref="..."/>...</xhtml:body></xhtml:html>

When using JSP, you can then use JSP tags as usual to produce your XHTML and XForms page as you would a regular HTML page.

4.2. Passing XHTML and XForms as a Request Attribute

With this method, the output of your JSP or servlet is ignored by Orbeon Forms. Instead, you set an attribute into the HttpServletRequest object which is passed to servlets (and also accessible in JSP through the request variable):

request.setAttribute("oxf.xforms.renderer.document", xformsDocument);

The name of the attribute must be "oxf.xforms.renderer.document". It may contain XHTML and XForms as an XML Document Object Model (DOM), as a dom4j Document, or as a String containing XML.

5. Processing Model

What happens after your JSP or servlet produces an XHTML and XForms document?

  • If configured appropriately in web.xml, the Orbeon Forms XForms filter kicks in and intercepts the output of the JSP or servlet (whether produced the regular way or passed as a request attribute).

  • The Orbeon Forms XForms filter then forward the request to Orbeon Forms, at the location /xforms-renderer.

  • Orbeon Forms reacts to /xforms-renderer by extracting the XHTML and XForms document from the forwarded request.

  • Orbeon Forms sends the XHTML and XForms document to the standard Orbeon Forms epilogue called /config/epilogue-servlet.xpl. The epilogue performs several tasks, including transforming XHTML and XForms into HTML that the browser can understand. The default configuration of this pipeline should be fine for most use cases, which means you usually don't need to worry about it.

Note that the epilogue applies the default theme under /config/theme-plain.xsl. However, it does not perform further URL rewriting by default.

6. Implementing XForms Services with JSP

The backend of your forms is usually best implemented with "services" which can be called with <xforms:submission>. Most of the time, XML is being posted to the service and XML is returned by the service. Since services take XML as input and generate XML, XML pipelines are an ideal tool to implement services.

However, you can also implement simple services directly with JSP. To produce XML output, your JSP page has to set the appropriate content type for the response with:

response.setContentType("application/xml")

To read XML input, you can create an object that represents the input document using the dom4j API:

Document queryDocument = xmlReader.read(request.getInputStream())

You then use this object to gather data about the query sent to your service.

In XForms you reference the service with the action attribute of <xforms:submission>:

<xforms:submission id="do-query" method="post" replace="instance" ref="instance('query')" instance="photos" action="/xforms-jsp/flickr-search/service-search.jsp"/>