A document has been updated:
http://cocoon.zones.apache.org/daisy/documentation/498.html
Document ID: 498
Branch: main
Language: default
Name: Java API (previously Cocoon Forms: Java API)
Document Type: Cocoon Document (unchanged)
Updated on: 11/6/05 10:21:38 AM
Updated by: guest
A new version has been created, state: draft
Parts
=====
Content
-------
This part has been updated.
Mime type: text/xml (unchanged)
File name: (unchanged)
Size: 12225 bytes (previous version: 71 bytes)
Content diff:
<html>
<body>
--- <h1>To be done</h1>
+++ <h1>Intro</h1>
--- <p>To be done.</p>
+++ <p>CForms is implemented in Java so the natural way to access it is through
its
+++ Java API. In this section we will show you how to get started. The two
primary
+++ flow-solutions of Cocoon (Flowscript and Javaflow) each have an additional
Forms
+++ integration part. However, here we want to show how the core Forms APIs
should
+++ be used independent of specific flow solutions, and therefore we will use
the
+++ very basic "Apples" flow.</p>
+++ <p class="note">The Apples flow solution (contained in the "apples" block)
is
+++ not officially supported by the Cocoon community. We use it here only for
+++ demonstrative purposes to illustrate the use of the Forms API.</p>
+++
+++ <h1>Apples flow</h1>
+++
+++ <p>If you are familiar with Apples, you can skip this section. What follows
is a
+++ super-super short summary of how Apples works.</p>
+++
+++ <p>An Apple flow-controller is a Java class implementing the following
+++ interface:</p>
+++
+++ <pre>package org.apache.cocoon.components.flow.apples;
+++
+++ public interface AppleController {
+++ void process(AppleRequest req, AppleResponse res) throws Exception;
+++ }</pre>
+++
+++ <p>In the sitemap, a flow-interaction is started using map:call with the
+++ function attribute:</p>
+++
+++ <pre><map:call
function="<em>some.fully.qualified.Classname</em>"/></pre>
+++
+++ <p>This will create an instance of the specified class (which should
implement
+++ the AppleController interface), associate that class with a continuation
ID, and
+++ call the <tt>process</tt> method of the Apple (we refer to a specific Apples
+++ controller object simply as "Apple"). The Apple can then do whathever it
wants
+++ to do, but before returning the process method should have called either the
+++ <tt>sendPage</tt> or <tt>redirectTo</tt> method on the supplied
+++ <tt>appleResponse</tt> object.</p>
+++
+++ <p>To continue interacting with the same Apple instance, use map:call with
the
+++ contination attribute:</p>
+++
+++ <pre><map:call continuation="<em>some-continuation-id</em>"/></pre>
+++
+++ <p>This will look up the previously created Apple and call again its process
+++ method.</p>
+++
+++ <p>This is basically it. An Apple can maintain state in its instance
variables.
+++ You can think of an Apple object as a session specific for a certain
+++ interaction. It encapsulates both the state of the interaction and its
+++ corresponding flow logic in one object.</p>
+++
+++ <p>In contrast with the continuation-based flow solutions, the execution of
an
+++ Apple always starts at the top of the process method. To find out what you
need
+++ to do, you can simply use request information (the requested path, request
+++ parameters and the request method).</p>
+++
+++ <p>To make this overview complete, if you don't need a stateful interaction
you
+++ can let your Apple implement the interface
<tt>StatelessAppleController</tt>. In
+++ that case, no continuation ID will be associated with the Apple and it will
be
+++ discarded directly after use.</p>
+++
+++ <h1>Avalon</h1>
+++
+++ <p>An Apples controller can implement the Avalon Framework interfaces to get
+++ access to its context. If you are familiar with Avalon, you can skip this
+++ section.</p>
+++
+++ <p>Cocoon internally manages components using the contracts defined by
Avalon
+++ Framework. Avalon Framework defines a few interfaces that components can
+++ implement to let the container communicate with the component. An Apples
+++ controller is treated as such a component, thus an Apple can implement
Avalon
+++ Framework interfaces.</p>
+++
+++ <p>For working with forms, we will need to be able to access the FormManager
+++ (and possibly the BindingManager). To get access to other components, Avalon
+++ defines the ServiceManager interface, which provides the following
method:</p>
+++
+++ <pre>public void service(ServiceManager serviceManager);
+++ </pre>
+++
+++ <p>So if your component (an Apple in this case) implements the
ServiceManager,
+++ this service method will be called during the setup of the component, and
via
+++ the supplied ServiceManager object you can get access to other components
+++ running inside Cocoon. We will see below how we use this to get access to
the
+++ FormManager.</p>
+++
+++ <h1>Setting up a working environment</h1>
+++
+++ <p>To have a comfortable work/build environment, we suggest to use the
+++ <a href="http://wiki.apache.org/cocoon/YourCocoonBasedProjectAnt16">Ant
script
+++ found on the wiki</a>.</p>
+++
+++ <h1>A basic Forms usage</h1>
+++
+++ <h2>Creating a form instance</h2>
+++
+++ <p>Creating a form instance based on a form definition is done using the
+++ FormManager. Since the few lines to do this are needed each time we would
like
+++ to create a form instance, we define a helper class to do this. While at
it, it
+++ includes also a method to create a binding object using the
BindingManager.</p>
+++
+++ <pre>package my;
+++
+++ import org.apache.cocoon.forms.formmodel.Form;
+++ import org.apache.cocoon.forms.FormManager;
+++ import org.apache.cocoon.forms.binding.Binding;
+++ import org.apache.cocoon.forms.binding.BindingManager;
+++ import org.apache.avalon.framework.service.ServiceManager;
+++
+++ public class FormHelper {
+++ public static Form createForm(ServiceManager serviceManager, String
formDefinitionFileName) throws Exception {
+++ FormManager formManager = null;
+++ try {
+++ formManager =
(FormManager)serviceManager.lookup(FormManager.ROLE);
+++ return formManager.createForm(formDefinitionFileName);
+++ } finally {
+++ if (formManager != null)
+++ serviceManager.release(formManager);
+++ }
+++ }
+++
+++ public static Binding createBinding(ServiceManager serviceManager,
String bindingDefinitionFileName) throws Exception {
+++ BindingManager bindingManager = null;
+++ try {
+++ bindingManager =
(BindingManager)serviceManager.lookup(BindingManager.ROLE);
+++ return bindingManager.createBinding(bindingDefinitionFileName);
+++ } finally {
+++ if (bindingManager != null)
+++ serviceManager.release(bindingManager);
+++ }
+++ }
+++ }
+++ </pre>
+++
+++ <h2>The Apple controller</h2>
+++
+++ <p>Below is an Apple controller which is used to display a simple form
+++ containing just one field, "name". Once the name is entered correctly, it
will
+++ redirect to google to perform a search on that name.</p>
+++
+++ <pre>package my;
+++
+++ import org.apache.cocoon.components.flow.apples.AppleController;
+++ import org.apache.cocoon.components.flow.apples.AppleRequest;
+++ import org.apache.cocoon.components.flow.apples.AppleResponse;
+++ import org.apache.cocoon.forms.formmodel.Form;
+++ import org.apache.cocoon.forms.FormContext;
+++ import org.apache.cocoon.environment.Request;
+++ import org.apache.avalon.framework.service.ServiceManager;
+++ import org.apache.avalon.framework.service.Serviceable;
+++ import org.apache.avalon.framework.service.ServiceException;
+++
+++ import java.util.Map;
+++ import java.util.HashMap;
+++ import java.util.Locale;
+++ import java.net.URLEncoder;
+++
+++ public class FirstFormsApple implements AppleController, Serviceable {
+++ private ServiceManager serviceManager;
+++ private boolean init = false;
+++ private Form form;
+++ private Locale locale = Locale.US;
+++
+++ public void service(ServiceManager serviceManager) throws
ServiceException {
+++ this.serviceManager = serviceManager;
+++ }
+++
+++ public void process(AppleRequest appleRequest, AppleResponse
appleResponse) throws Exception {
+++ if (!init) {
+++ form = FormHelper.createForm(serviceManager,
"resources/form/firstform_definition.xml");
+++ init = true;
+++ }
+++
+++ Request request = appleRequest.getCocoonRequest();
+++ if (request.getMethod().equals("GET")) {
+++ showForm(appleResponse);
+++ } else if (request.getMethod().equals("POST")) {
+++ boolean finished = form.process(new FormContext(request,
locale));
+++ if (!finished) {
+++ showForm(appleResponse);
+++ } else {
+++ String name = (String)form.getChild("name").getValue();
+++ appleResponse.redirectTo("http://google.com/search?q=" +
URLEncoder.encode(name, "UTF-8"));
+++ }
+++ } else {
+++ throw new Exception("Unexpected HTTP method: " +
request.getMethod());
+++ }
+++ }
+++
+++ private void showForm(AppleResponse appleResponse) {
+++ Map viewData = new HashMap();
+++ viewData.put("CocoonFormsInstance", form);
+++ viewData.put("locale", locale);
+++ appleResponse.sendPage("FirstFormPipe", viewData);
+++ }
+++ }
+++ </pre>
+++
+++ <p>Some notes:</p>
+++
+++ <ul>
+++ <li>if this is the first time the Apple is called, the form instance is
created
+++ using the <tt>FormHelper</tt> utility class defined earlier</li>
+++ <li>if the request method is GET, we simply show the form</li>
+++ <li>if the request method is POST, the user has submitted the form so we
let the
+++ form object process the request. This returns a boolean to indicate whether
the
+++ form processing finished (finished means: all widgets validated
successfully,
+++ and the reason for the form submit was not to execute some action or event
+++ handler). If not finished, we redisplay the form, otherwise, we do whatever
it
+++ is we want to do with the collected form data. To keep this sample simple,
we
+++ redirect to google.</li>
+++ </ul>
+++
+++ <p>It is important to notice that you can make the form definition and
template
+++ much more complex (containing many & advanced widgets, with validation
+++ logic, event handlers, etc.), while the Apple can stay as simple as
this.</p>
+++
+++ <h2>Supporting files</h2>
+++
+++ <p>For reference, we list the form definition, form template and sitemap
used
+++ for this example.</p>
+++
+++ <h3>form definition</h3>
+++
+++ <pre><fd:form
xmlns:fd="http://apache.org/cocoon/forms/1.0#definition">
+++ <fd:widgets>
+++ <fd:field id="name" required="true">
+++ <fd:label>Name</fd:label>
+++ <fd:datatype base="string"/>
+++ </fd:field>
+++ </fd:widgets>
+++ </fd:form>
+++ </pre>
+++
+++ <h3>form template</h3>
+++
+++ <pre><html xmlns:ft="http://apache.org/cocoon/forms/1.0#template"
+++ xmlns:fi="http://apache.org/cocoon/forms/1.0#instance"
+++ xmlns:jx="http://apache.org/cocoon/templates/jx/1.0">
+++
+++ <jx:import
uri="resource://org/apache/cocoon/forms/generation/jx-macros.xml"/>
+++
+++ <head>
+++ <title>First form!</title>
+++ </head>
+++ <body>
+++ <ft:form-template action="#{$continuation/id}.continue"
method="POST">
+++ <ft:widget-label id="name"/>
+++ <ft:widget id="name"/>
+++ <br/>
+++ <input type="submit"/>
+++ </ft:form-template>
+++ </body>
+++ </html>
+++ </pre>
+++
+++ <h3>sitemap</h3>
+++
+++ <pre><?xml version="1.0"?>
+++ <map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+++
+++ <map:components>
+++ <map:transformers default="xslt">
+++ <map:transformer name="i18n"
+++ src="org.apache.cocoon.transformation.I18nTransformer">
+++ <catalogues default="forms">
+++ <catalogue id="forms" name="messages"
+++ location="resource://org/apache/cocoon/forms/system/i18n"/>
+++ </catalogues>
+++ <cache-at-startup>true</cache-at-startup>
+++ </map:transformer>
+++ </map:transformers>
+++ </map:components>
+++
+++ <map:views>
+++ </map:views>
+++
+++ <map:resources>
+++ </map:resources>
+++
+++ <map:flow language="apples"/>
+++
+++ <map:pipelines>
+++
+++ <map:pipeline internal="true">
+++ <map:match pattern="FirstFormPipe">
+++ <map:generate type="jx"
src="resources/form/firstform_template.xml"/>
+++ <map:transform type="i18n">
+++ <map:parameter name="locale" value="flow-attr:locale"/>
+++ </map:transform>
+++ <map:transform src="resources/xsl/forms-samples-styling.xsl"/>
+++ <map:serialize/>
+++ </map:match>
+++ </map:pipeline>
+++
+++ <map:pipeline>
+++ <map:match pattern="firstform">
+++ <map:call function="my.FirstFormsApple"/>
+++ </map:match>
+++
+++ <map:match pattern="*.continue">
+++ <map:call continuation="{1}"/>
+++ </map:match>
+++
+++ <map:match pattern="resources/*/**">
+++ <map:read
src="resource://org/apache/cocoon/{1}/resources/{2}"/>
+++ </map:match>
+++ </map:pipeline>
+++
+++ </map:pipelines>
+++
+++ </map:sitemap>
+++ </pre>
+++
+++ <h1>Next</h1>
+++
+++ <p>[TODO]</p>
+++
+++ <p>See also the javadoc of the forms package for more information on the
API.
+++ </p>
+++
</body>
</html>
Fields
======
no changes
Links
=====
no changes
Custom Fields
=============
no changes
Collections
===========
no changes