You are viewing a plain text version of this content. The canonical link for it is here.
Posted to docs@cocoon.apache.org by da...@cocoon.zones.apache.org on 2007/06/07 18:31:18 UTC

[DAISY] Created: Using Control Flow

A new document has been created.

http://cocoon.zones.apache.org/daisy/documentation/1380.html

Document ID: 1380
Branch: main
Language: default
Name: Using Control  Flow
Document Type: Cocoon Document
Created: 6/7/07 4:31:06 PM
Creator (owner): Reinhard Pötz
State: publish

Parts
=====

Content
-------
Mime type: text/xml
Size: 6504 bytes
Content:
<html>
<body>

<p class="note">The concept of Control  Flow is explained on Flowscript, one of
the available implementations.</p>

<p>The general flow of actions in an application which uses the control flow is
as described below.</p>

<p>The request is received by Cocoon and passed to the sitemap for processing.
In the sitemap, you can do two things to pass the control to the Control Flow
layer:</p>

<ul>
<li>You can invoke a JavaScript top-level function to start processing a
logically grouped sequences of pages. Each time a response page is being sent
back to the client browser from this function, the processing of the JavaScript
code stops at the point the page is sent back, and the HTTP request finishes.
Through the magic of continuations, the execution state is saved in a
continuation object. Each continuation is given a unique string id, which could
be embedded in generated page, so that you can restart the saved computation
later on.</li>
<li>To invoke a top level JavaScript function in the Control Flow, you use the
<a href="daisy:512#callFunction"><tt>&lt;map:call
function="[function-name]"/&gt;</tt></a> construction.</li>
<li>To restart the computation of a previously stopped function, you use the
<a href="daisy:512#callContinuation"><tt>&lt;map:call
continuation="..."/&gt;</tt></a> construction. This restarts the computation
saved in a continuation object identified by the string value of the
<tt>continuation</tt> attribute. This value could be extracted in the sitemap
from the requested URL, from a POST or GET parameter etc. When the computation
stored in the continuation object is restarted, it appears as if nothing
happened, all the local and global variables have exactly the same values as
they had when the computation was stopped.</li>
</ul>

<p>Once the JavaScript function in the control layer is restarted, you're
effectively inside the Control Flow. Here you have access to the request
parameters, and to the business logic objects. The controller script takes the
appropriate actions to invoke the business logic, usually written in Java,
creating objects, setting various values on them etc...</p>

<p>When the business logic is invoked, you're inside the Model. The business
logic takes whatever actions are needed, accessing a database, making a SOAP
request to a Web service etc. When this logic finishes, the program control goes
back to the Control Flow.</p>

<p>Once here, the Control Flow has to decide which page needs to be sent back to
the client browser. To do this, the script can invoke one of the
<a href="daisy:518#sendPageAndWait"><tt>cocoon.sendPageAndWait()</tt></a> or
<a href="daisy:518#sendPage"><tt>cocoon.sendPage()</tt></a> functions. These
functions take two parameters, the relative URL of the page to be sent back to
the client, and a context object which can be accessed inside this page to
extract various values and place them in the generated page.</p>

<p>The second argument to <tt>cocoon.sendPageAndWait()</tt> and
<tt>cocoon.sendPage()</tt> is a context object, which can be a simple dictionary
with values that need to be displayed by the View. More generally any Java or
JavaScript object can be passed here, as long as the necessary get methods for
the important values are provided.</p>

<p>The page specified by the URL is processed by the sitemap, using the normal
sitemap rules. The simplest case is a <a href="daisy:519">generator</a>
followed by an XSLT transformation and a serializer. This page generation is
part of the View layer. To process a page you can make use of several Cocoon
<a href="daisy:519">generators</a> to retrieve values from the context objects
passed by the Control Flow.</p>

<p>Going back to the <tt>cocoon.sendPageAndWait()</tt> and <tt>sendPage()</tt>
functions, there is a big difference between them. The first function will send
the response back to the client browser, and will stop the processing of the
JavaScript script by saving it into a continuation object. The other function,
<tt>cocoon.sendPage()</tt> will send the response, but it will not stop the
computation. This is useful for example when you need to exit a top-level
JavaScript function invoked with <tt>&lt;map:call function="..."/&gt;</tt>.</p>

<p>The above explains how MVC could be really achieved in Cocoon with the
control flow layer. Note that there is no direct communication between Model and
View, everything is directed by the Control Flow by passing to View a context
object constructed from Model data.</p>

<h2>Basic usage</h2>

<p>As hinted in the previous section, an application using Cocoon's MVC approach
is composed of three layers:</p>

<ul>
<li>A JavaScript controller which implements the interaction with the client
</li>
<li>The business logic model which implements your application</li>
<li>The <a href="daisy:519">page templates</a>, which describe the content of
the pages, and XSLT stylesheets which describe the look of the content.</li>
</ul>

<p>In more complex applications, the flow of pages can be thought of smaller
sequences of pages which are composed together. The natural analogy is to
describe these sequences in separate JavaScript functions, which can then be
called either from the sitemap, can call each other freely.</p>

<p>An example of such an application is the user login and preferences sample
</p>

<p>This application is composed of four top-level JavaScript functions:</p>

<ul>
<li><tt>login</tt>,</li>
<li><tt>registerUser</tt>,</li>
<li><tt>edit</tt> and</li>
<li><tt>logout</tt>.</li>
</ul>

<p>The entry level point in the application can be any of these functions, but
in order for a user to use the application, (s)he must login first. Once the
user logs in, we want to maintain the Java User object which represents the user
between top-level function invocations.</p>

<p>Even if you don't need complex control flow in your application, you may
still choose to use the MVC pattern described above. You can have top- level
JavaScript functions which obtain the request parameters, invoke the business
logic and then call <tt>cocoon.sendPage()</tt> to generate a response page and
return from the computation. Since there's no continuation object being created
by this function, and no global scope being saved, there's no memory resource
being eaten. The approach provides a clean way of separating logic and content,
and makes things easy to follow, since you have to look at a single script to
understand what's going on.</p>

</body>
</html>

Collections
===========
The document belongs to the following collections: cdocs-core