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]