cocoon-docs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From da...@cocoon.zones.apache.org
Subject [DAISY] Updated: Java API
Date Sun, 06 Nov 2005 10:21:46 GMT
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>&lt;map:call function="<em>some.fully.qualified.Classname</em>"/&gt;</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>&lt;map:call continuation="<em>some-continuation-id</em>"/&gt;</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 &amp; 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>&lt;fd:form xmlns:fd="http://apache.org/cocoon/forms/1.0#definition"&gt;
+++   &lt;fd:widgets&gt;
+++     &lt;fd:field id="name" required="true"&gt;
+++       &lt;fd:label&gt;Name&lt;/fd:label&gt;
+++       &lt;fd:datatype base="string"/&gt;
+++     &lt;/fd:field&gt;
+++   &lt;/fd:widgets&gt;
+++ &lt;/fd:form&gt;
+++ </pre>
+++ 
+++ <h3>form template</h3>
+++ 
+++ <pre>&lt;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"&gt;
+++ 
+++   &lt;jx:import uri="resource://org/apache/cocoon/forms/generation/jx-macros.xml"/&gt;
+++ 
+++   &lt;head&gt;
+++     &lt;title&gt;First form!&lt;/title&gt;
+++   &lt;/head&gt;
+++   &lt;body&gt;
+++     &lt;ft:form-template action="#{$continuation/id}.continue" method="POST"&gt;
+++       &lt;ft:widget-label id="name"/&gt;
+++       &lt;ft:widget id="name"/&gt;
+++       &lt;br/&gt;
+++       &lt;input type="submit"/&gt;
+++     &lt;/ft:form-template&gt;
+++   &lt;/body&gt;
+++ &lt;/html&gt;
+++ </pre>
+++ 
+++ <h3>sitemap</h3>
+++ 
+++ <pre>&lt;?xml version="1.0"?&gt;
+++ &lt;map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0"&gt;
+++ 
+++   &lt;map:components&gt;
+++     &lt;map:transformers default="xslt"&gt;
+++       &lt;map:transformer name="i18n"
+++         src="org.apache.cocoon.transformation.I18nTransformer"&gt;
+++         &lt;catalogues default="forms"&gt;
+++           &lt;catalogue id="forms" name="messages"
+++             location="resource://org/apache/cocoon/forms/system/i18n"/&gt;
+++         &lt;/catalogues&gt;
+++         &lt;cache-at-startup&gt;true&lt;/cache-at-startup&gt;
+++       &lt;/map:transformer&gt;
+++     &lt;/map:transformers&gt;
+++   &lt;/map:components&gt;
+++ 
+++   &lt;map:views&gt;
+++   &lt;/map:views&gt;
+++ 
+++   &lt;map:resources&gt;
+++   &lt;/map:resources&gt;
+++ 
+++   &lt;map:flow language="apples"/&gt;
+++ 
+++   &lt;map:pipelines&gt;
+++ 
+++     &lt;map:pipeline internal="true"&gt;
+++       &lt;map:match pattern="FirstFormPipe"&gt;
+++         &lt;map:generate type="jx" src="resources/form/firstform_template.xml"/&gt;
+++         &lt;map:transform type="i18n"&gt;
+++           &lt;map:parameter name="locale" value="flow-attr:locale"/&gt;
+++         &lt;/map:transform&gt;
+++         &lt;map:transform src="resources/xsl/forms-samples-styling.xsl"/&gt;
+++         &lt;map:serialize/&gt;
+++       &lt;/map:match&gt;
+++     &lt;/map:pipeline&gt;
+++ 
+++     &lt;map:pipeline&gt;
+++       &lt;map:match pattern="firstform"&gt;
+++         &lt;map:call function="my.FirstFormsApple"/&gt;
+++       &lt;/map:match&gt;
+++ 
+++       &lt;map:match pattern="*.continue"&gt;
+++         &lt;map:call continuation="{1}"/&gt;
+++       &lt;/map:match&gt;
+++ 
+++       &lt;map:match pattern="resources/*/**"&gt;
+++         &lt;map:read src="resource://org/apache/cocoon/{1}/resources/{2}"/&gt;
+++       &lt;/map:match&gt;
+++     &lt;/map:pipeline&gt;
+++ 
+++   &lt;/map:pipelines&gt;
+++ 
+++ &lt;/map:sitemap&gt;
+++ </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

Mime
View raw message