ovidiu 02/05/19 12:23:29
Modified: src/webapp/WEB-INF cocoon.xconf logkit.xconf
Added: src/webapp/samples/flow sitemap.xmap
src/webapp/samples/flow/docs .cvsignore book.xml
continuations.xml how-does-it-work.xml index.xml
samples.xml
src/webapp/samples/flow/examples/calc calc.js
displayResult.xsp getNumberA.xsp getNumberB.xsp
getOperator.xsp sitemap.xmap
src/webapp/samples/flow/stylesheets
extended-document2html.xsl
Log:
Added the continuations based control flow layer from scratchpad/schecoon/.
Revision Changes Path
1.21 +7 -0 xml-cocoon2/src/webapp/WEB-INF/cocoon.xconf
Index: cocoon.xconf
===================================================================
RCS file: /home/cvs/xml-cocoon2/src/webapp/WEB-INF/cocoon.xconf,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- cocoon.xconf 8 May 2002 07:03:59 -0000 1.20
+++ cocoon.xconf 19 May 2002 19:23:28 -0000 1.21
@@ -355,6 +355,13 @@
<parameter name="uri" value="http://apache.org/xsp/soap/3.0"/>
<parameter name="href"
value="resource://org/apache/cocoon/components/language/markup/xsp/java/soap.xsl"/>
</builtin-logicsheet>
+
+ <builtin-logicsheet>
+ <parameter name="prefix" value="jpath"/>
+ <parameter name="uri" value="http://apache.org/xsp/jpath/1.0"/>
+ <parameter name="href"
value="resource://org/apache/cocoon/components/language/markup/xsp/java/jpath.xsl"/>
+ </builtin-logicsheet>
+
</target-language>
</xsp-language>
1.9 +14 -0 xml-cocoon2/src/webapp/WEB-INF/logkit.xconf
Index: logkit.xconf
===================================================================
RCS file: /home/cvs/xml-cocoon2/src/webapp/WEB-INF/logkit.xconf,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- logkit.xconf 27 Apr 2002 17:30:43 -0000 1.8
+++ logkit.xconf 19 May 2002 19:23:28 -0000 1.9
@@ -49,6 +49,15 @@
<append>false</append>
</cocoon>
+ <!-- The logger for the flow layer -->
+ <cocoon id="flow">
+ <filename>${context-root}/WEB-INF/logs/flow.log</filename>
+ <format type="cocoon">
+ %7.7{priority} %{time} [%{category}] (%{uri}) %{thread}/%{class:short}:
%{message}\n%{throwable}
+ </format>
+ <append>false</append>
+ </cocoon>
+
<!--
This log file gets only messages with log level ERROR and below.
-->
@@ -111,5 +120,10 @@
<log-target id-ref="access"/>
<log-target id-ref="error"/>
</category>
+
+ <category name="flow" log-level="DEBUG">
+ <log-target id-ref="flow"/>
+ <log-target id-ref="error"/>
+ </category>
</categories>
</logkit>
1.1 xml-cocoon2/src/webapp/samples/flow/sitemap.xmap
Index: sitemap.xmap
===================================================================
<?xml version="1.0"?>
<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
<map:components>
<map:generators default="file"/>
<map:transformers default="xslt">
<map:transformer name="augment"
src="org.apache.cocoon.transformation.AugmentTransformer"
mime-type="text/xml"
logger="sitemap.transformer.augment"/>
</map:transformers>
<map:readers default="resource"/>
<map:serializers default="html"/>
<map:matchers default="wildcard"/>
<map:flow-interpreters default="JavaScript"/>
</map:components>
<map:resources>
<map:resource name="show-page">
<map:aggregate element="site">
<map:part src="cocoon:/book-{full-filename}.xml"/>
<map:part src="cocoon:/body-{full-filename}.xml"/>
</map:aggregate>
<map:transform src="../../../documentation/stylesheets/site2xhtml.xsl">
<map:parameter name="use-request-parameters" value="true"/>
<map:parameter name="header" value="graphics/{filename}-header.jpg"/>
</map:transform>
<map:serialize/>
</map:resource>
</map:resources>
<map:pipelines>
<!-- Schecoon documentation pipeline -->
<map:pipeline>
<map:match pattern="">
<map:redirect-to uri="index.html"/>
</map:match>
<map:match pattern="**book-**.xml">
<map:generate src="docs/{1}book.xml"/>
<map:transform type="augment">
<map:parameter name="mount" value="samples/flow/"/>
</map:transform>
<map:transform src="../../../documentation/stylesheets/book2menu.xsl">
<map:parameter name="use-request-parameters" value="true"/>
<map:parameter name="resource" value="{2}.html"/>
</map:transform>
<map:serialize type="xml"/>
</map:match>
<map:match pattern="body-examples/**.xml">
<map:generate src="examples/{1}.xsp" type="serverpages"/>
<map:transform src="stylesheets/extended-document2html.xsl"/>
<map:serialize type="xml"/>
</map:match>
<map:match pattern="body-**.xml">
<map:generate src="docs/{1}.xml"/>
<map:transform src="../../../documentation/stylesheets/document2html.xsl"/>
<map:serialize/>
</map:match>
<map:match pattern="*.html">
<map:call resource="show-page">
<map:parameter name="filename" value="{1}"/>
<map:parameter name="full-filename" value="{1}"/>
</map:call>
</map:match>
<map:match pattern="**/*.html">
<map:call resource="show-page">
<map:parameter name="filename" value="{2}"/>
<map:parameter name="full-filename" value="{1}/{2}"/>
</map:call>
</map:match>
<map:match pattern="**resources/script.js">
<map:read src="../../../documentation/stylesheets/script-cli.js"
mime-type="application/javascript"/>
</map:match>
<map:match pattern="**resources/**.js">
<map:read src="../../../documentation/stylesheets/{2}.js"
mime-type="application/javascript"/>
</map:match>
<map:match pattern="**.css">
<map:read src="../../../documentation/{1}.css" mime-type="text/css"/>
</map:match>
<map:match pattern="**images/*.png">
<map:read src="../../tutorial/resources/images/{2}.png" mime-type="image/png"/>
</map:match>
<map:match pattern="**images/*.jpg">
<map:read src="../../tutorial/resources/images/{2}.jpg" mime-type="image/jpeg"/>
</map:match>
<map:match pattern="**images/*.gif">
<map:read src="../../tutorial/resources/images/{2}.gif" mime-type="image/gif"/>
</map:match>
<map:match pattern="**graphics/**-*.jpg">
<map:generate src="svg/{3}.xml"/>
<map:transform src="svg/addlabel.xsl">
<map:parameter name="use-request-parameters" value="true"/>
<map:parameter name="label" value="{2}"/>
</map:transform>
<map:serialize type="svg2jpeg"/>
</map:match>
</map:pipeline>
<!-- All examples are located under the examples/ directory, and
are standalone samples, with their own sitemap. The following
generic mount operation loads them on demand. -->
<map:pipeline>
<map:match pattern="examples/*/**">
<map:mount uri-prefix="examples/{1}"
src="examples/{1}/sitemap.xmap"
check-reload="yes"/>
</map:match>
</map:pipeline>
</map:pipelines>
</map:sitemap>
1.1 xml-cocoon2/src/webapp/samples/flow/docs/.cvsignore
Index: .cvsignore
===================================================================
dtd
1.1 xml-cocoon2/src/webapp/samples/flow/docs/book.xml
Index: book.xml
===================================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//APACHE//DTD Cocoon Documentation Book V1.0//EN"
"../../../resources/entities/book-cocoon-v10.dtd">
<book software="Apache Cocoon"
title="Apache Schecoon Documentation"
copyright="1999-2002 The Apache Software Foundation"
xmlns:xlink="http://www.w3.org/1999/xlink">
<menu label="Documentation">
<menu-item label="Back" href=".."/>
<menu-item label="Introduction" href="index.html"/>
<menu-item label="Continuations" href="continuations.html"/>
<menu-item label="How does it work?" href="how-does-it-work.html"/>
<menu-item label="Examples" href="samples.html"/>
</menu>
</book>
1.1 xml-cocoon2/src/webapp/samples/flow/docs/continuations.xml
Index: continuations.xml
===================================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.0//EN"
"../../../resources/entities/document-v10.dtd">
<document>
<header>
<title>Advanced Control Flow</title>
<authors>
<person name="Ovidiu Predescu" email="[EMAIL PROTECTED]"/>
</authors>
</header>
<body>
<s1 title="A different approach">
<p>Web applications are essentially event-driven
applications. Such applications have to react to events
generated from the client browser, and they respond to these
perhaps by changing their internal state and generating a
response.</p>
<p>The result is that even a simple application that needs to
collect some information from the user using more than one page,
has to somehow maintain the input accumulated so far from the
user. This input is a characteristic of the application
state. Another characteristic of the application state is where
the program processing is.</p>
<p>Let's look at an example. Suppose we want to write a very
simple calculator, which collects the numbers to be added, as
well as the operator, each in a separate page. It would be very
nice if we could write something like this:</p>
<source><![CDATA[
function calculator()
{
var a, b, operator;
sendPage("getA.html");
a = request.getParameter("a");
sendPage("getB.html");
b = request.getParameter("b");
sendPage("getOperator.html");
operator = request.getParameter("op");
try {
if (operator == "plus")
sendPage("result.html", a + b);
else if (operator == "minus")
sendPage("result.html", a - b);
else if (operator == "multiply")
sendPage("result.html", a * b);
else if (operator == "divide")
sendPage("result.html", a / b);
else
sendResult("invalidOperator.html");
}
catch (Exception ex) {
sendResult("error.html", "Operation failed: " + ex.toString();
}
}
]]></source>
<p>In this example, the <code>calculator</code> function is
called to start the calculator application. We'd like the
<code>sendPage</code> function to be a special function, that
takes as arguments an HTML file to be sent as response, and some
optional data that needs to be placed dynamically in it. We
would like <code>sendPage</code> to send the response page and
then block the executing thread, until the user clicks on a link
in the response page, which sends a request back to the
server. This request resumes the processing at the point it was
left, right after the call to <code>sendPage</code>.</p>
<p>This approach looks very powerful, since the flow of pages
within the application can be described as a normal
program. Using this approach you no longer have to think of your
Web application as a finite state machine, which transitions
from one state to another, and in the process generates response
pages.</p>
<p>A big disadvantage of the approach above is that we need to
maintain a thread alive until the user hits the link on the
response page. This is clearly very expensive!</p>
<p>It would be very nice if we can capture the state of the
application, its stack of function calls, which includes local
variables, the global variables and the program counter, and
save them into an object. If this object would give us the
ability to restart the processing from the point stored in it,
this would be what we need!</p>
<s2 title="What are continuations?">
<p>A continuation is exactly the type of object that we need.
Think of a continuation as an object that, for a given point
in your program, contains a snapshot of the stack trace,
including all the local variables, and the program
counter. You can not only store these things in the
continuation object, but also restore the execution of the
program from a continuation object. This means that the stack
trace and the program counter of the running program become
the ones stored in a continuation.</p>
<p>Continuations are powerful concepts from the world of
functional languages, like <link
href="http://www.schemers.org/">Scheme</link>, but they are
becoming popular in other languages as well.</p>
</s2>
</s1>
</body>
</document>
1.1 xml-cocoon2/src/webapp/samples/flow/docs/how-does-it-work.xml
Index: how-does-it-work.xml
===================================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.0//EN"
"../../../resources/entities/document-v10.dtd">
<document>
<header>
<title>Advanced Control Flow</title>
<authors>
<person name="Ovidiu Predescu" email="[EMAIL PROTECTED]"/>
</authors>
</header>
<body>
<s1 title="Cocoon and continuations">
<p>With continuations in the language, you can essentially
store the continuation of <code>sendPage</code> (think of all
the stack trace, and the program counter), put it in a global
hash table associated with an id. The id is then encoded in
the <code>response.xml</code> page as an URL. When the user
clicks on that URL, on the server side the associated
continuation is resumed. Resuming the processing happens as if
nothing was stopped, you get all the stack trace back, and all
the local variables.</p>
<p>So instead of using beans to store things in session, you
use normal variables in a program. Since each user has its own
version of the program, all the local variables in the program
are separate between users.</p>
<p>With this approach clicking the <em>Back</em> button in the
browser is no longer a hassle to deal with for you as a
server-side programmer. They will simply refer to past
continuations objects, which have their own state of the local
variables.</p>
<p>Since continuations are objects, you can also store them in
a database, for really long-lived session, just like you do
with session beans.</p>
</s1>
</body>
</document>
1.1 xml-cocoon2/src/webapp/samples/flow/docs/index.xml
Index: index.xml
===================================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.0//EN"
"../../../resources/entities/document-v10.dtd">
<document>
<header>
<title>Apache Cocoon - Control Flow</title>
<authors>
<person name="Ovidiu Predescu" email="[EMAIL PROTECTED]"/>
</authors>
</header>
<body>
<s1 title="Control flow">
<p>Cocoon has advanced control flow, the ability to describe the
order of Web pages that have to be sent to the client, at any
given point in time in an application.</p>
<p>Traditional Web applications try to model the control flow of
a Web application by modeling the application as a finite state
machine (FSM). In this model, the Web application is composed of
multiple states, but the application can be only in one state at
a time. Any request received by the application transitions it
in a different state. During such a transition, the application
may perform various side-effects, such as updating objects
either in memory or in a database. Another important side-effect
of such a transition is that a Web page is sent back to the
client browser.</p>
<p>For simple Web applications, this model works fine. However,
as the application grows, the number of states and transitions
between them grows as well, and it becomes hard to visualize
what's happening in the application.</p>
<p>Moreover, the interactions in some applications are more
complex than a simple finite state machine. In such cases it's
much easier to think and implement the application as a program,
rather than a FSM.</p>
<p>By using a high level programming concept called
<em>continuations</em>, Cocoon tries to solve this problem, and
promises to allow the control flow in Web applications to be
modeled as a normal program.</p>
</s1>
</body>
</document>
1.1 xml-cocoon2/src/webapp/samples/flow/docs/samples.xml
Index: samples.xml
===================================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.0//EN"
"../../../resources/entities/document-v10.dtd">
<document>
<header>
<title>Apache Cocoon - Examples</title>
<authors>
<person name="Ovidiu Predescu" email="[EMAIL PROTECTED]"/>
</authors>
</header>
<body>
<s1 title="Examples">
<p>This page contains shows some examples built using the
control flow layer available in Cocoon.</p>
<p>Some of these examples use continuations in their
implementation to manage the flow from one page to the other,
while other pass a continuation identifier in the generated
page.</p>
<ul>
<li><link href="examples/calc/">Calculator</link> - a simple
example using continuations to maintain the state between
requests.</li>
</ul>
</s1>
</body>
</document>
1.1 xml-cocoon2/src/webapp/samples/flow/examples/calc/calc.js
Index: calc.js
===================================================================
var prefix;
function calculator(uriPrefix)
{
prefix = uriPrefix;
var a = getNumber("a");
var b = getNumber("b", a);
var op = getOperator(a, b);
if (op == "plus")
sendResult(a, b, op, a + b);
else if (op == "minus")
sendResult(a, b, op, a - b);
else if (op == "multiply")
sendResult(a, b, op, a * b);
else if (op == "divide")
sendResult(a, b, op, a / b);
else
sendResult("Error: Unkown operator!");
}
function getNumber(name, a, b)
{
var uri = prefix + "getNumber" + name.toUpperCase() + ".html";
sendPage(uri, { "a" : a, "b" : b });
return parseFloat(cocoon.request.getParameter(name));
}
function getOperator(a, b)
{
var uri = prefix + "getOperator.html";
sendPage(uri, { "a" : a, "b" : b });
return cocoon.request.getParameter("operator");
}
function sendResult(a, b, op, result)
{
sendPage(prefix + "displayResult.html",
{ "a" : a, "b" : b, "operator" : op, "result" : result });
}
1.1
xml-cocoon2/src/webapp/samples/flow/examples/calc/displayResult.xsp
Index: displayResult.xsp
===================================================================
<?xml version="1.0"?>
<!--
Author: Ovidiu Predescu "[EMAIL PROTECTED]"
Date: March 23, 2002
-->
<xsp:page
language="java"
xmlns:xsp="http://apache.org/xsp"
xmlns:jpath="http://apache.org/xsp/jpath/1.0"
>
<document>
<header>
<title>Calculator example</title>
<authors>
<person name="Ovidiu Predescu" email="[EMAIL PROTECTED]"/>
</authors>
</header>
<body>
<s1 title="Calculator">
<form action="../../calc/">
<p>a = <strong><jpath:value-of select="a"/></strong></p>
<p>b = <strong><jpath:value-of select="b"/></strong></p>
<p>Operator = <strong><jpath:value-of select="operator"/></strong></p>
<p>Result = <strong><jpath:value-of select="result"/></strong></p>
<input type="submit" name="submit" value="Start over"/>
</form>
</s1>
</body>
</document>
</xsp:page>
1.1 xml-cocoon2/src/webapp/samples/flow/examples/calc/getNumberA.xsp
Index: getNumberA.xsp
===================================================================
<?xml version="1.0"?>
<!--
Author: Ovidiu Predescu "[EMAIL PROTECTED]"
Date: March 23, 2002
-->
<xsp:page
language="java"
xmlns:xsp="http://apache.org/xsp"
xmlns:jpath="http://apache.org/xsp/jpath/1.0"
>
<document>
<header>
<title>Calculator example</title>
<authors>
<person name="Ovidiu Predescu" email="[EMAIL PROTECTED]"/>
</authors>
</header>
<body>
<s1 title="Calculator">
<form><xsp:attribute name="action"><xsp:expr>"kont/" +
<jpath:continuation/></xsp:expr></xsp:attribute>
<p>Enter value of <strong>a</strong>: <input type="text" name="a"/></p>
<input type="submit" name="submit" value="Enter"/>
</form>
</s1>
</body>
</document>
</xsp:page>
1.1 xml-cocoon2/src/webapp/samples/flow/examples/calc/getNumberB.xsp
Index: getNumberB.xsp
===================================================================
<?xml version="1.0"?>
<!--
Author: Ovidiu Predescu "[EMAIL PROTECTED]"
Date: March 23, 2002
-->
<xsp:page
language="java"
xmlns:xsp="http://apache.org/xsp"
xmlns:jpath="http://apache.org/xsp/jpath/1.0"
>
<document>
<header>
<title>Calculator example</title>
<authors>
<person name="Ovidiu Predescu" email="[EMAIL PROTECTED]"/>
</authors>
</header>
<body>
<s1 title="Calculator">
<form><xsp:attribute
name="action"><xsp:expr><jpath:continuation/></xsp:expr></xsp:attribute>
<p>a = <strong><jpath:value-of select="a"/></strong></p>
<p>Enter value of <strong>b</strong>: <input type="text" name="b"/></p>
<input type="submit" name="submit" value="Enter"/>
</form>
</s1>
</body>
</document>
</xsp:page>
1.1
xml-cocoon2/src/webapp/samples/flow/examples/calc/getOperator.xsp
Index: getOperator.xsp
===================================================================
<?xml version="1.0"?>
<!--
Author: Ovidiu Predescu "[EMAIL PROTECTED]"
Date: March 23, 2002
-->
<xsp:page
language="java"
xmlns:xsp="http://apache.org/xsp"
xmlns:jpath="http://apache.org/xsp/jpath/1.0"
>
<document>
<header>
<title>Calculator example</title>
<authors>
<person name="Ovidiu Predescu" email="[EMAIL PROTECTED]"/>
</authors>
</header>
<body>
<s1 title="Calculator">
<form><xsp:attribute
name="action"><xsp:expr><jpath:continuation/></xsp:expr></xsp:attribute>
<p>a = <strong><jpath:value-of select="a"/></strong></p>
<p>b = <strong><jpath:value-of select="b"/></strong></p>
<p>Enter operator
<select name="operator">
<option>plus</option>
<option>minus</option>
<option>multiply</option>
<option>divide</option>
</select>
</p>
<input type="submit" name="submit" value="Do it!"/>
</form>
</s1>
</body>
</document>
</xsp:page>
1.1 xml-cocoon2/src/webapp/samples/flow/examples/calc/sitemap.xmap
Index: sitemap.xmap
===================================================================
<?xml version="1.0"?>
<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
<map:components>
<map:generators default="file"/>
<map:transformers default="xslt"/>
<map:readers default="resource"/>
<map:serializers default="html"/>
<map:matchers default="wildcard"/>
<map:flow-interpreters default="JavaScript"/>
</map:components>
<map:resources>
<map:resource name="flow">
<map:script src="calc.js"/>
</map:resource>
</map:resources>
<map:pipelines>
<map:pipeline>
<map:match pattern="kont/*">
<map:continue with="{1}"/>
</map:match>
<map:match pattern="">
<map:call function="calculator">
<!-- Don't forget to modify the value of the parameter if
mounted at a different URI -->
<map:parameter name="prefix" value="/samples/flow/examples/calc/"/>
</map:call>
</map:match>
<map:match pattern="*.html">
<map:generate src="{1}.xsp" type="serverpages"/>
<map:serialize/>
</map:match>
</map:pipeline>
</map:pipelines>
</map:sitemap>
1.1
xml-cocoon2/src/webapp/samples/flow/stylesheets/extended-document2html.xsl
Index: extended-document2html.xsl
===================================================================
<?xml version="1.0" encoding="utf-8"?>
<!-- An extension to the document DTD, which allows for HTML forms to
be embedded within the document.
-->
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:include href="../../../documentation/stylesheets/document2html.xsl"/>
<xsl:template match="form | input | select | option | textarea | keygen | isindex">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
----------------------------------------------------------------------
In case of troubles, e-mail: [EMAIL PROTECTED]
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]