You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by mr...@apache.org on 2006/01/21 23:00:35 UTC

svn commit: r371121 - in /struts/flow/trunk/src: examples/ examples/WEB-INF/ examples/WEB-INF/classes/ examples/WEB-INF/guess/ examples/WEB-INF/guess/flow/ examples/WEB-INF/guess/jsp/ examples/WEB-INF/rails/ examples/WEB-INF/remote/ examples/WEB-INF/re...

Author: mrdon
Date: Sat Jan 21 14:00:28 2006
New Revision: 371121

URL: http://svn.apache.org/viewcvs?rev=371121&view=rev
Log:
Reorganized examples to use new Ruby on Rails-style controllers, fixed
redirects to be true redirects, changed remote flow calls to use
continuations to access controller methods and values


Added:
    struts/flow/trunk/src/examples/WEB-INF/classes/
    struts/flow/trunk/src/examples/WEB-INF/classes/commons-logging.properties
    struts/flow/trunk/src/examples/WEB-INF/classes/simplelog.properties
    struts/flow/trunk/src/examples/WEB-INF/guess/flow/
    struts/flow/trunk/src/examples/WEB-INF/guess/flow/NumberGuess.js   (with props)
    struts/flow/trunk/src/examples/WEB-INF/guess/jsp/
    struts/flow/trunk/src/examples/WEB-INF/guess/jsp/endGame.jsp   (with props)
    struts/flow/trunk/src/examples/WEB-INF/guess/jsp/play.jsp   (with props)
    struts/flow/trunk/src/examples/WEB-INF/remote/flow/
    struts/flow/trunk/src/examples/WEB-INF/remote/flow/NumberGuess.js   (with props)
    struts/flow/trunk/src/examples/WEB-INF/remote/jsp/
    struts/flow/trunk/src/examples/WEB-INF/remote/jsp/endGame.jsp   (with props)
    struts/flow/trunk/src/examples/WEB-INF/remote/jsp/play.jsp   (with props)
    struts/flow/trunk/src/examples/WEB-INF/templates/flow/
    struts/flow/trunk/src/examples/WEB-INF/templates/flow/NumberGuess.js   (with props)
    struts/flow/trunk/src/examples/WEB-INF/templates/jt/
    struts/flow/trunk/src/examples/WEB-INF/templates/jt/endGame.jt   (with props)
    struts/flow/trunk/src/examples/WEB-INF/templates/jt/play.jt   (with props)
    struts/flow/trunk/src/examples/WEB-INF/wizard/flow/
    struts/flow/trunk/src/examples/WEB-INF/wizard/flow/Registration.js   (with props)
    struts/flow/trunk/src/examples/WEB-INF/wizard/flow/wizard.js   (with props)
    struts/flow/trunk/src/examples/WEB-INF/wizard/jsp/
    struts/flow/trunk/src/examples/WEB-INF/wizard/jsp/hobbies-form.jsp   (with props)
    struts/flow/trunk/src/examples/WEB-INF/wizard/jsp/name-form.jsp   (with props)
    struts/flow/trunk/src/examples/WEB-INF/wizard/jsp/summary-form.jsp   (with props)
    struts/flow/trunk/src/java/org/apache/struts/flow/core/javascript/fom/template.js
      - copied unchanged from r360243, struts/flow/trunk/src/examples/templates/template.js
Removed:
    struts/flow/trunk/src/examples/WEB-INF/guess/guess.jsp
    struts/flow/trunk/src/examples/WEB-INF/guess/numberguess.js
    struts/flow/trunk/src/examples/WEB-INF/guess/struts-config.xml
    struts/flow/trunk/src/examples/WEB-INF/guess/success.jsp
    struts/flow/trunk/src/examples/WEB-INF/rails/
    struts/flow/trunk/src/examples/WEB-INF/remote/guess.jsp
    struts/flow/trunk/src/examples/WEB-INF/remote/numberguess.js
    struts/flow/trunk/src/examples/WEB-INF/remote/struts-config.xml
    struts/flow/trunk/src/examples/WEB-INF/remote/success.jsp
    struts/flow/trunk/src/examples/WEB-INF/struts-config.xml
    struts/flow/trunk/src/examples/WEB-INF/templates/guess.jt
    struts/flow/trunk/src/examples/WEB-INF/templates/numberguess.js
    struts/flow/trunk/src/examples/WEB-INF/templates/struts-config.xml
    struts/flow/trunk/src/examples/WEB-INF/templates/success.jt
    struts/flow/trunk/src/examples/WEB-INF/wizard/hobbies-form.jsp
    struts/flow/trunk/src/examples/WEB-INF/wizard/name-form.jsp
    struts/flow/trunk/src/examples/WEB-INF/wizard/struts-config.xml
    struts/flow/trunk/src/examples/WEB-INF/wizard/summary-form.jsp
    struts/flow/trunk/src/examples/WEB-INF/wizard/wizard-flow.js
    struts/flow/trunk/src/examples/WEB-INF/wizard/wizard.js
Modified:
    struts/flow/trunk/src/examples/index.html
    struts/flow/trunk/src/java/org/apache/struts/flow/FlowAction.java
    struts/flow/trunk/src/java/org/apache/struts/flow/FlowPlugIn.java
    struts/flow/trunk/src/java/org/apache/struts/flow/Forward.java
    struts/flow/trunk/src/java/org/apache/struts/flow/core/Interpreter.java
    struts/flow/trunk/src/java/org/apache/struts/flow/core/javascript/fom/FOM_Flow.java
    struts/flow/trunk/src/java/org/apache/struts/flow/core/javascript/fom/FOM_JavaScriptInterpreter.java
    struts/flow/trunk/src/java/org/apache/struts/flow/core/javascript/fom/fom_system.js

Added: struts/flow/trunk/src/examples/WEB-INF/classes/commons-logging.properties
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/examples/WEB-INF/classes/commons-logging.properties?rev=371121&view=auto
==============================================================================
--- struts/flow/trunk/src/examples/WEB-INF/classes/commons-logging.properties (added)
+++ struts/flow/trunk/src/examples/WEB-INF/classes/commons-logging.properties Sat Jan 21 14:00:28 2006
@@ -0,0 +1,2 @@
+org.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog
+org.apache.commons.logging.simplelog.defaultlog=debug

Added: struts/flow/trunk/src/examples/WEB-INF/classes/simplelog.properties
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/examples/WEB-INF/classes/simplelog.properties?rev=371121&view=auto
==============================================================================
--- struts/flow/trunk/src/examples/WEB-INF/classes/simplelog.properties (added)
+++ struts/flow/trunk/src/examples/WEB-INF/classes/simplelog.properties Sat Jan 21 14:00:28 2006
@@ -0,0 +1 @@
+org.apache.commons.logging.simplelog.defaultlog=debug

Added: struts/flow/trunk/src/examples/WEB-INF/guess/flow/NumberGuess.js
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/examples/WEB-INF/guess/flow/NumberGuess.js?rev=371121&view=auto
==============================================================================
--- struts/flow/trunk/src/examples/WEB-INF/guess/flow/NumberGuess.js (added)
+++ struts/flow/trunk/src/examples/WEB-INF/guess/flow/NumberGuess.js Sat Jan 21 14:00:28 2006
@@ -0,0 +1,39 @@
+NumberGuess = function() {
+    
+    this.play = function() {
+    
+      this.random =  Math.round( Math.random() * 9 ) + 1;
+      this.hint = "No hint for you!"
+      this.guesses = 0;
+    
+      while (true) {
+    
+        // send guess page to user and wait for response
+        flow.wait();
+    
+        // process user's guess
+        this.guess = parseInt( params.guess );
+        this.guesses++;
+        if (this.guess) {
+          if (this.guess > this.random) {
+            this.hint = "Nope, lower!"
+          } 
+          else if (this.guess < this.random) {
+            this.hint = "Nope, higher!"
+          } 
+          else {
+            // correct guess
+            break;
+          }
+        }
+      }
+    
+      // send success page to user
+      flash.guesses = this.guesses;
+      flash.random = this.random;
+
+      flow.redirect( { "action" : "endGame" } );
+    }
+
+    this.endGame = function() {}
+}

Propchange: struts/flow/trunk/src/examples/WEB-INF/guess/flow/NumberGuess.js
------------------------------------------------------------------------------
    svn:executable = *

Added: struts/flow/trunk/src/examples/WEB-INF/guess/jsp/endGame.jsp
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/examples/WEB-INF/guess/jsp/endGame.jsp?rev=371121&view=auto
==============================================================================
--- struts/flow/trunk/src/examples/WEB-INF/guess/jsp/endGame.jsp (added)
+++ struts/flow/trunk/src/examples/WEB-INF/guess/jsp/endGame.jsp Sat Jan 21 14:00:28 2006
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<html>
+<head>
+  <title>Struts Flow number guessing game</title>
+</head>
+<body>
+
+  <h1>Success!</h1>
+   
+  <h2>The number was: <%= request.getAttribute("random") %></h2>
+  
+  <h3>It took you <%= request.getAttribute("guesses") %> tries.</h3>
+  
+  <p><a href="play.do">Play again</a></p>
+  
+  <a href="../../index.html">Return to index</a>  
+</body>
+</html>

Propchange: struts/flow/trunk/src/examples/WEB-INF/guess/jsp/endGame.jsp
------------------------------------------------------------------------------
    svn:executable = *

Added: struts/flow/trunk/src/examples/WEB-INF/guess/jsp/play.jsp
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/examples/WEB-INF/guess/jsp/play.jsp?rev=371121&view=auto
==============================================================================
--- struts/flow/trunk/src/examples/WEB-INF/guess/jsp/play.jsp (added)
+++ struts/flow/trunk/src/examples/WEB-INF/guess/jsp/play.jsp Sat Jan 21 14:00:28 2006
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<html>
+<head>
+  <title>Struts Flow number guessing game</title>
+</head>
+<body>
+
+  <h1>Guess the Number Between 1 and 10</h1>
+  
+  <h2><%= request.getAttribute("hint") %></h2>
+  
+  <h3>You've guessed <%= request.getAttribute("guesses") %> times.</h3>
+  
+  <form method="post" action="play.do">
+    <input type="hidden" name="contid" value='<%= request.getAttribute("contid") %>' />
+    <input type="text" name="guess"/>
+    <input type="submit"/>
+  </form>
+  <a href="../../index.html">Return to index</a>  
+</body>
+</html>

Propchange: struts/flow/trunk/src/examples/WEB-INF/guess/jsp/play.jsp
------------------------------------------------------------------------------
    svn:executable = *

Added: struts/flow/trunk/src/examples/WEB-INF/remote/flow/NumberGuess.js
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/examples/WEB-INF/remote/flow/NumberGuess.js?rev=371121&view=auto
==============================================================================
--- struts/flow/trunk/src/examples/WEB-INF/remote/flow/NumberGuess.js (added)
+++ struts/flow/trunk/src/examples/WEB-INF/remote/flow/NumberGuess.js Sat Jan 21 14:00:28 2006
@@ -0,0 +1,44 @@
+NumberGuess = function() {
+    
+    this.play = function() {
+    
+      this.random =  Math.round( Math.random() * 9 ) + 1;
+      this.hint = "No hint for you!"
+      this.guesses = 0;
+    
+      while (true) {
+    
+        // send guess page to user and wait for response
+        flow.wait();
+    
+        // process user's guess
+        this.guess = parseInt( params.guess );
+        this.guesses++;
+        if (this.guess) {
+          if (this.guess > this.random) {
+            this.hint = "Nope, lower!"
+          } 
+          else if (this.guess < this.random) {
+            this.hint = "Nope, higher!"
+          } 
+          else {
+            // correct guess
+            break;
+          }
+        }
+      }
+    
+      // send success page to user
+      flash.guesses = this.guesses;
+      flash.random = this.random;
+
+      flow.redirect( { "action" : "endGame" } );
+    }
+
+    this.endGame = function() {}
+
+    this.cheat = function() {
+        this.guesses += 5;
+        return {"secret":this.random, "guesses":this.guesses};
+    }    
+}

Propchange: struts/flow/trunk/src/examples/WEB-INF/remote/flow/NumberGuess.js
------------------------------------------------------------------------------
    svn:executable = *

Added: struts/flow/trunk/src/examples/WEB-INF/remote/jsp/endGame.jsp
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/examples/WEB-INF/remote/jsp/endGame.jsp?rev=371121&view=auto
==============================================================================
--- struts/flow/trunk/src/examples/WEB-INF/remote/jsp/endGame.jsp (added)
+++ struts/flow/trunk/src/examples/WEB-INF/remote/jsp/endGame.jsp Sat Jan 21 14:00:28 2006
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<html>
+<head>
+  <title>Struts Flow number guessing game - Remote edition</title>
+</head>
+<body>
+
+  <h1>Success!</h1>
+   
+  <h2>The number was: <%= request.getAttribute("random") %></h2>
+  
+  <h3>It took you <%= request.getAttribute("guesses") %> tries.</h3>
+  
+  <p><a href="play.do">Play again</a></p>
+  
+  <a href="../../index.html">Return to index</a>  
+</body>
+</html>

Propchange: struts/flow/trunk/src/examples/WEB-INF/remote/jsp/endGame.jsp
------------------------------------------------------------------------------
    svn:executable = *

Added: struts/flow/trunk/src/examples/WEB-INF/remote/jsp/play.jsp
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/examples/WEB-INF/remote/jsp/play.jsp?rev=371121&view=auto
==============================================================================
--- struts/flow/trunk/src/examples/WEB-INF/remote/jsp/play.jsp (added)
+++ struts/flow/trunk/src/examples/WEB-INF/remote/jsp/play.jsp Sat Jan 21 14:00:28 2006
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<html>
+<head>
+  <title>Struts Flow number guessing game - Remote edition</title>
+    <script type="text/javascript">
+  <!--
+function cheat() {
+    dojo.io.bind({
+        url:  'play.do?FlowCall=cheat&contid=<%= request.getAttribute("contid") %>',
+        type: "text/javascript",
+        load: function(type, data, evt) {
+            eval("data = "+data);
+            alert("The secret number is "+data.secret+". After applying a penalty, you have guessed "+data.guesses+" times");
+        }
+    });
+}
+    -->
+  </script>
+  <script type="text/javascript" src="../dojo-io.js"></script>
+</head>
+<body>
+
+  <h1>Guess the Number Between 1 and 10</h1>
+  
+  <h2><%= request.getAttribute("hint") %></h2>
+  
+  <h3>You've guessed <%= request.getAttribute("guesses") %> times.</h3>
+  
+  <form method="post" action="play.do">
+    <input type="hidden" name="contid" value='<%= request.getAttribute("contid") %>' />
+    <input type="text" name="guess"/>
+    <input type="submit"/>
+    <input type="button" onclick="cheat()" value="Cheat" />
+  </form>
+  
+  <a href="../../index.html">Return to index</a>  
+</body>
+</html>

Propchange: struts/flow/trunk/src/examples/WEB-INF/remote/jsp/play.jsp
------------------------------------------------------------------------------
    svn:executable = *

Added: struts/flow/trunk/src/examples/WEB-INF/templates/flow/NumberGuess.js
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/examples/WEB-INF/templates/flow/NumberGuess.js?rev=371121&view=auto
==============================================================================
--- struts/flow/trunk/src/examples/WEB-INF/templates/flow/NumberGuess.js (added)
+++ struts/flow/trunk/src/examples/WEB-INF/templates/flow/NumberGuess.js Sat Jan 21 14:00:28 2006
@@ -0,0 +1,71 @@
+NumberGuess = function() {
+    
+    this.play = function() {
+    
+      this.random =  Math.round( Math.random() * 9 ) + 1;
+      this.hint = "No hint for you!"
+      this.guesses = 0;
+    
+      while (true) {
+    
+        // send guess page to user and wait for response
+        flow.wait("play", this);
+    
+        // process user's guess
+        this.guess = parseInt( params.guess );
+        this.guesses++;
+        if (this.guess) {
+          if (this.guess > this.random) {
+            this.hint = "Nope, lower!"
+          } 
+          else if (this.guess < this.random) {
+            this.hint = "Nope, higher!"
+          } 
+          else {
+            // correct guess
+            break;
+          }
+        }
+      }
+    
+      // send success page to user
+      flash.guesses = this.guesses;
+      flash.random = this.random;
+
+      flow.redirect( { "action" : "endGame" } );
+    }
+
+    this.endGame = function() {
+        renderTemplate("endGame", this);
+    }
+
+    this.cheat = function() {
+        this.guesses += 5;
+        return {"secret":this.random, "guesses":this.guesses};
+    }    
+}
+
+
+// This function renders the content directly using Javascript Templates
+function renderTemplateAndWait(page, bizdata, ttl) {
+    var cont = new FOM_WebContinuation(new Continuation(), flow.continuation, ttl);
+    bizdata.contid = cont.id;
+    renderTemplate(page, bizdata);
+    flow.forward(null, bizdata, cont);
+    FOM_Flow.suicide();
+}
+
+function renderTemplate(page, bizdata) {
+    var res = flow.context.response;
+    var stream = struts.servletContext.getResourceAsStream("/WEB-INF/templates/jt/"+page+".jt");
+    if (stream != null) {
+        var text = new String(stream.getText());
+        var html = text.process(bizdata);
+        res.writer.print(html);
+        res.writer.close();
+    } else {
+        res.sendError(res.SC_INTERNAL_SERVER_ERROR, "Unable to find page "+page);
+    }
+}
+
+FOM_Flow.prototype._wait=renderTemplateAndWait;

Propchange: struts/flow/trunk/src/examples/WEB-INF/templates/flow/NumberGuess.js
------------------------------------------------------------------------------
    svn:executable = *

Added: struts/flow/trunk/src/examples/WEB-INF/templates/jt/endGame.jt
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/examples/WEB-INF/templates/jt/endGame.jt?rev=371121&view=auto
==============================================================================
--- struts/flow/trunk/src/examples/WEB-INF/templates/jt/endGame.jt (added)
+++ struts/flow/trunk/src/examples/WEB-INF/templates/jt/endGame.jt Sat Jan 21 14:00:28 2006
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<html>
+<head>
+  <title>Struts Flow number guessing game</title>
+</head>
+<body>
+
+  <h1>Success!</h1>
+   
+  <h2>The number was: ${random}</h2>
+  
+  <h3>It took you ${guesses} tries.</h3>
+  
+  <p><a href="play.do">Play again</a></p>
+  
+  <a href="../index.html">Return to index</a>  
+</body>
+</html>

Propchange: struts/flow/trunk/src/examples/WEB-INF/templates/jt/endGame.jt
------------------------------------------------------------------------------
    svn:executable = *

Added: struts/flow/trunk/src/examples/WEB-INF/templates/jt/play.jt
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/examples/WEB-INF/templates/jt/play.jt?rev=371121&view=auto
==============================================================================
--- struts/flow/trunk/src/examples/WEB-INF/templates/jt/play.jt (added)
+++ struts/flow/trunk/src/examples/WEB-INF/templates/jt/play.jt Sat Jan 21 14:00:28 2006
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+<html>
+<head>
+  <title>Struts Flow number guessing game</title>
+    <script type="text/javascript">
+  <!--
+function cheat() {
+    hint = document.getElementById("hint");
+    
+    dojo.io.bind({
+        url:  'play.do?FlowCall=cheat&contid=${contid}',
+        type: "text/javascript",
+        load: function(type, data, evt) {
+            eval("data = "+data);
+            dojo.io.bind({
+                url:  "../cheat.jt",
+                type: "text/plain",
+                load: function(type, temp, evt) {
+                    hint.innerHTML = temp.process(data);
+                }
+            });
+        }
+    });
+}
+    -->
+  </script>
+  <script type="text/javascript" src="../../remote/dojo-io.js"></script>
+  <script type="text/javascript" src="../template.js"></script>
+</head>
+<body>
+
+  <h1>Guess the Number Between 1 and 10</h1>
+  
+  <h2 id="hint">${hint}</h2>
+  
+  <h3>You've guessed ${guesses} times.</h3>
+  
+  <form method="post" action="play.do">
+    <input type="hidden" name="contid" value="${contid}" />
+    <input type="text" name="guess"/>
+    <input type="submit"/>
+    <input type="button" onclick="cheat()" value="Cheat" />
+  </form>
+  
+  <a href="../../index.html">Return to index</a>  
+  
+</body>
+</html>

Propchange: struts/flow/trunk/src/examples/WEB-INF/templates/jt/play.jt
------------------------------------------------------------------------------
    svn:executable = *

Added: struts/flow/trunk/src/examples/WEB-INF/wizard/flow/Registration.js
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/examples/WEB-INF/wizard/flow/Registration.js?rev=371121&view=auto
==============================================================================
--- struts/flow/trunk/src/examples/WEB-INF/wizard/flow/Registration.js (added)
+++ struts/flow/trunk/src/examples/WEB-INF/wizard/flow/Registration.js Sat Jan 21 14:00:28 2006
@@ -0,0 +1,39 @@
+flow.load("/WEB-INF/wizard/flow/wizard.js");
+
+Registration = function() {
+
+    this.start = function() {
+        var model = new java.util.HashMap();
+
+        var wizard = new Wizard(model);
+        wizard.populate = populate;
+        wizard.validate = validate;
+      
+        wizard.showForm( { "action" : "name-form" }, {
+                  "title" : "User Name Information"
+                  });
+        wizard.showForm( { "action" : "hobbies-form" }, {
+                  "title" : "User Hobbies"
+                  });
+        wizard.showForm( { "action" : "summary-form" } , {
+                  "title" : "User Summary"
+                  });  
+    };              
+}
+
+function populate() {
+  var m = struts.paramValues;
+  for (var i = m.keySet().iterator(); i.hasNext(); ) {
+    var key = i.next();
+    this.model.put(key, m.get(key)[0]);
+  }
+  // Bug in commons-chain prevents this
+  //this.model.putAll(struts.paramValues);
+}
+
+function validate() {
+  if (this.model.get("name").length() < 2) {
+    return "Name must be specified";
+  }
+}
+

Propchange: struts/flow/trunk/src/examples/WEB-INF/wizard/flow/Registration.js
------------------------------------------------------------------------------
    svn:executable = *

Added: struts/flow/trunk/src/examples/WEB-INF/wizard/flow/wizard.js
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/examples/WEB-INF/wizard/flow/wizard.js?rev=371121&view=auto
==============================================================================
--- struts/flow/trunk/src/examples/WEB-INF/wizard/flow/wizard.js (added)
+++ struts/flow/trunk/src/examples/WEB-INF/wizard/flow/wizard.js Sat Jan 21 14:00:28 2006
@@ -0,0 +1,180 @@
+/*
+ *  This file provides a Wizard object that can be used to easily implement
+ *  multi-page workflows, commonly called wizards.  The following features 
+ *  are built into the framework:
+ *
+ *  - Pluggable validation
+ *  - Pluggable data population and post-population processing
+ *  - Automatic forward/backward navigation handling
+ *  - Capable of handing any model (POJO, DynaBean, JDOM Element, etc)
+ *
+ *  To insert your own logic, particularly validation and population logic, 
+ *  simply the desired methods with your own.
+ */
+
+ /**
+  *  Constructor for the Wizard.
+  *
+  * @param model    The data model object to store form data
+  */
+function Wizard(model) {
+    
+    // The data model, can be anything
+    this.model = model;
+    
+    // The time to live for forms, defaults to continuation manager settings
+    this.timeToLive = 0;
+    
+    // The key the model is placed under
+    this.modelKey = "form";
+    
+    // The key the errors are placed under
+    this.errorsKey = "errors";
+    
+    // The name of the request parameter signifying the "Next" action
+    this.nextId = "next";
+}
+
+/**
+ *  Called to populate the model with the request
+ */
+Wizard.prototype.populate = function() {}
+
+/**
+ *  Called to handle any post-processing after populate has been called
+ */
+Wizard.prototype.postPopulate = function() {}
+
+/**
+ *  Called to validate the form
+ *
+ * @param frmName    The name of the form to validate
+ * @return           Any errors, null if none
+ */
+Wizard.prototype.validate = function(frmName) {}
+
+/**
+ *  Called to prepare the model right before the form is sent.
+ *
+ * @return The model to include in the business data passed to the form
+ */
+Wizard.prototype.prepareModel = function() {return this.model;}
+
+/**
+ *  Creates a continuation, saves the context, and sends the form.  Shouldn't
+ *  need to be called from outside the Wizard class.
+ *
+ * @param name         The name of the form to send
+ * @param lastWebCont  The parent web continuation
+ * @param bizdata      A map of objects to pass to the form
+ */ 
+Wizard.prototype.sendFormAndWait = function(name, lastWebCont, bizdata, ttl) {
+   flow.forward(name, bizdata, new FOM_WebContinuation(new Continuation(), lastWebCont, ttl));
+   flow.exit();
+}
+
+/**
+ * Shows the form, handling validation and navigation.  
+ *
+ * @param doValidate    Whether to validate or not (optional)
+ * @param exitIds       An array of submit button names that allow "next" behavior
+ * @return              The submit button name that was pressed
+ */
+Wizard.prototype.showForm = function(frm, bizdata, doValidate, exitIds) {
+    
+    // Default validation to true if not passed
+    var doValidate = (doValidate == null ? true : doValidate);
+
+    // Default to the next id if none passed
+    var exitIds = (exitIds == null ? new Array(this.nextId) : exitIds);
+    
+    var lastWebCont = flow.continuation;
+    // create a continuation, the invocation of which will resend
+    // the page: this is used to implement the back button
+    var wk = new FOM_WebContinuation(new Continuation(), lastWebCont);
+    flow.log.debug("saving spot "+wk.id+" before form:"+frm);
+    
+    // Loop to keep showing form until validation passes and next button 
+    // is pressed
+    var keepShowing = true;
+    var thisWebCont;
+    var tmpModel;
+    var exitId;
+    while (keepShowing) {
+        keepShowing = false;
+
+        // Wraps the model before attaching to bizdata to allow any necessary
+        // cloning or ActionForm wrapping
+        tmpModel = this.prepareModel(this.model);
+        bizdata[this.modelKey] = tmpModel;
+
+        // Send the form and wait
+        thisWebCont = this.sendFormAndWait(frm, wk, bizdata);
+
+        // Populate the model with form submission
+        this.populate();
+        this.postPopulate();
+        
+        // If validation is enabled, validate and determine if should keep 
+        // showing
+        if (doValidate) {
+            var errors = this.validate(frm);
+            if (errors == null || errors.length == 0) {
+                bizdata[this.errorsKey] = null;
+            } else {
+                bizdata[this.errorsKey] = errors;
+                keepShowing = true;
+            }
+        }
+        
+        // Determine if next button is pressed and should stop showing
+        if ((doValidate && !keepShowing) || !doValidate) {
+            keepShowing = true;
+            var params = struts.param;
+            for (var id in exitIds) {
+                if (params[exitIds[id]] != null || params[exitIds[id]+'.x'] != null) {
+                    exitId = exitIds[id];
+                    keepShowing = false;
+                    break;
+                }
+            }    
+        }
+    }
+    flow.continuationn = thisWebCont;
+    return exitId;
+}
+
+
+/**
+ *  This function is called to restart a previously saved continuation
+ *  passed as argument.  Overrides the default handleContinuation to
+ *  add support for back buttons.
+ * 
+ * @param kont The continuation to restart
+ */
+function handleContinuation(k, wk) {
+    
+    // This can be overridden by declaring a "prevId" variable outside the function
+    var prevId = (this.prevId != null ? this.prevId : "prev");
+    
+    flow.log.debug("Previous Id:"+struts.param[prevId]+" cont:"+wk.id);
+    if (struts.param[prevId]) {
+        var cont = wk;
+        for (var x=0; x<2; x++) {
+            if (cont == null) {
+                flow.log.error("can't get parent continuation, back "+x);
+                break;
+            } else {
+                cont = cont.getParent();
+            }
+        }
+        if (cont != null) {
+            cont.continuation(cont);
+        } else {
+            k(wk);
+        }
+    } else {
+        k(wk);
+    }
+}
+flow.handleContinuation = handleContinuation;

Propchange: struts/flow/trunk/src/examples/WEB-INF/wizard/flow/wizard.js
------------------------------------------------------------------------------
    svn:executable = *

Added: struts/flow/trunk/src/examples/WEB-INF/wizard/jsp/hobbies-form.jsp
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/examples/WEB-INF/wizard/jsp/hobbies-form.jsp?rev=371121&view=auto
==============================================================================
--- struts/flow/trunk/src/examples/WEB-INF/wizard/jsp/hobbies-form.jsp (added)
+++ struts/flow/trunk/src/examples/WEB-INF/wizard/jsp/hobbies-form.jsp Sat Jan 21 14:00:28 2006
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<html>
+<head>
+  <title><%=request.getAttribute("title")%></title>
+</head>
+<body>
+
+  <h1><%=request.getAttribute("title")%></h1>
+  <p>
+  Enter your hobbies:
+  </p>
+
+  <center style="color:red"><%=(request.getAttribute("errors") != null ? request.getAttribute("errors") : "")%></center>
+
+  <% java.util.Map form = (java.util.Map)request.getAttribute("form"); %>
+  <form action="registration.do" method="POST">
+  <table>
+   <tr>
+      <th>Favorite Sport</th>
+      <td><input type="text" name="sport" value="<%=(form.get("sport") != null ? form.get("sport") : "")%>"/></td>
+    </tr>
+
+   <tr>
+      <th>Favorite Book</th>
+      <td><input type="text" name="book" value="<%=(form.get("book") != null ? form.get("book") : "")%>"/></td>
+    </tr>
+
+  </table>
+
+  <input type="hidden" name="contid" value='<%= request.getAttribute("contid") %>' />
+  <input type="submit" name="prev" value="Previous" />
+  <input type="submit" name="next" value="Next" />
+  </form>
+
+  <a href="../../index.html">Return to index</a>  
+</body>
+</html>

Propchange: struts/flow/trunk/src/examples/WEB-INF/wizard/jsp/hobbies-form.jsp
------------------------------------------------------------------------------
    svn:executable = *

Added: struts/flow/trunk/src/examples/WEB-INF/wizard/jsp/name-form.jsp
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/examples/WEB-INF/wizard/jsp/name-form.jsp?rev=371121&view=auto
==============================================================================
--- struts/flow/trunk/src/examples/WEB-INF/wizard/jsp/name-form.jsp (added)
+++ struts/flow/trunk/src/examples/WEB-INF/wizard/jsp/name-form.jsp Sat Jan 21 14:00:28 2006
@@ -0,0 +1,40 @@
+<?xml version="1.0"?>
+<html>
+<head>
+  <title><%=request.getAttribute("title")%></title>
+</head>
+<body>
+
+  <h1><%=request.getAttribute("title")%></h1>
+  <p>
+  Enter your name information:
+  </p>
+
+  <center style="color:red"><%=(request.getAttribute("errors") != null ? request.getAttribute("errors") : "")%></center>
+  <form action="registration.do" method="POST">
+
+  <% java.util.Map form = (java.util.Map)request.getAttribute("form"); %>
+  <table>
+   <tr>
+      <th>First Name</th>
+      <td><input type="text" name="name" value="<%=(form.get("name") != null ? form.get("name") : "")%>"/></td>
+    </tr>
+
+   <tr>
+      <th>Last Name</th>
+      <td><input type="text" name="lastname" value="<%=(form.get("lastname") != null ? form.get("lastname") : "")%>"/></td>
+    </tr>
+
+   <tr>
+      <th>Middle Name</th>
+      <td><input type="text" name="middlename" value="<%=(form.get("middlename") != null ? form.get("middlename") : "")%>"/></td>
+    </tr>
+  </table>
+
+  <input type="hidden" name="contid" value='<%= request.getAttribute("contid") %>' />
+  <input type="submit" name="next" value="Next" />
+  </form>
+
+  <a href="../../index.html">Return to index</a>  
+</body>
+</html>

Propchange: struts/flow/trunk/src/examples/WEB-INF/wizard/jsp/name-form.jsp
------------------------------------------------------------------------------
    svn:executable = *

Added: struts/flow/trunk/src/examples/WEB-INF/wizard/jsp/summary-form.jsp
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/examples/WEB-INF/wizard/jsp/summary-form.jsp?rev=371121&view=auto
==============================================================================
--- struts/flow/trunk/src/examples/WEB-INF/wizard/jsp/summary-form.jsp (added)
+++ struts/flow/trunk/src/examples/WEB-INF/wizard/jsp/summary-form.jsp Sat Jan 21 14:00:28 2006
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+<html>
+<head>
+  <title><%=request.getAttribute("title")%></title>
+</head>
+<body>
+
+  <h1><%=request.getAttribute("title")%></h1>
+  <p>
+  Congratulations!
+  </p>
+
+  <% java.util.Map form = (java.util.Map)request.getAttribute("form"); %>
+  <table border="1">
+  <tr>
+      <th>First Name</th>
+      <td><%=form.get("name")%></td>
+    </tr>
+
+   <tr>
+      <th>Last Name</th>
+      <td><%=form.get("lastname")%></td>
+    </tr>
+
+  <tr>
+      <th>Middle Name</th>
+      <td><%=form.get("middlename")%></td>
+    </tr>
+
+  <tr>
+      <th>Favorite Sport</th>
+      <td><%=form.get("sport")%></td>
+    </tr>
+
+  <tr>
+      <th>Favorite Book</th>
+      <td><%=form.get("book")%></td>
+    </tr>
+  </table>
+
+  <form action="registration.do" method="POST">
+  <input type="hidden" name="contid" value='<%= request.getAttribute("contid") %>' />
+  <input type="submit" name="prev" value="Previous" />
+  </form>
+
+  <a href="../../index.html">Return to index</a>  
+</body>
+</html>

Propchange: struts/flow/trunk/src/examples/WEB-INF/wizard/jsp/summary-form.jsp
------------------------------------------------------------------------------
    svn:executable = *

Modified: struts/flow/trunk/src/examples/index.html
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/examples/index.html?rev=371121&r1=371120&r2=371121&view=diff
==============================================================================
--- struts/flow/trunk/src/examples/index.html (original)
+++ struts/flow/trunk/src/examples/index.html Sat Jan 21 14:00:28 2006
@@ -8,21 +8,18 @@
   in Struts Flow:
   </p>
   <ul>
-    <li><a href="guess/guess.do">Number Guess Example</a> - Shows a simple
+    <li><a href="guess/NumberGuess/play.do">Number Guess Example</a> - Shows a simple
         number guessing game to demonstrate the use of continuations.</li>
-    <li><a href="remote/guess.do">Number Guess Example - Remote Edition</a> - 
+    <li><a href="remote/NumberGuess/play.do">Number Guess Example - Remote Edition</a> - 
         Shows the above example but adding a remote rpc or (Ajax) example by
         adding a "cheat" button that retrieves the number from the server
         without reloading the page.</li>
-    <li><a href="templates/guess.do">Number Guess Example - Template Edition</a> - 
+    <li><a href="templates/NumberGuess/play.do">Number Guess Example - Template Edition</a> - 
         Shows the remote example but using <a 
         href="http://www.trimpath.com/project/wiki/JavaScriptTemplates">Javascript 
         Templates</a> to render HTML on both the server instead of JSP and client
         instead of string contatenations.</li>
-    <li><a href="rails/NumberGuess/play.do">Number Guess Example - Rails Edition</a> - Shows the 
-        game but written using <a href="http://www.rubyonrails.org">Ruby on Rails</a>-style
-        controllers with a zero-configuration layout.</li>
-    <li><a href="wizard/registration.do">Registration Wizard Example</a> - 
+    <li><a href="wizard/Registration/start.do">Registration Wizard Example</a> - 
         Shows a simple server-side wizard framework built on continuations
         with automatic back button support both from a form and browser 
         button.</li>

Modified: struts/flow/trunk/src/java/org/apache/struts/flow/FlowAction.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/FlowAction.java?rev=371121&r1=371120&r2=371121&view=diff
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/FlowAction.java (original)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/FlowAction.java Sat Jan 21 14:00:28 2006
@@ -113,13 +113,8 @@
         // A FlowCall means the request came from client-side javascript that
         // expects the return type to be JSON
         boolean isFlowCall = (request.getParameter("FlowCall") != null);
-        String func = null, controller = null;
-        if (isFlowCall) {
-            func = request.getParameter("FlowCall");
-        } else {
-            func = getProperty("function", request, mapping);
-            controller = getProperty("controller", request, mapping);
-        }
+        String func = getProperty("function", request, mapping);
+        String controller = getProperty("controller", request, mapping);
         
         if ("true".equals(FlowConfiguration.getInstance().getProperty("flow.devMode"))) {
             SqlMap.reloadConfig();
@@ -150,25 +145,6 @@
                 throw new ServletException("You must specify a function name to call");
             } else {
                 
-                // validate JSON in the body of a flowcall
-                if (isFlowCall) {
-                    StringBuffer sb = new StringBuffer();
-                    char[] buffer = new char[1024];
-                    int len = 0;
-                    BufferedReader reader = request.getReader();
-                    while ((len = reader.read(buffer)) > 0 ) {
-                        sb.append(buffer, 0, len);
-                    }
-                    String json = sb.toString();
-                    if (log.isDebugEnabled()) {
-                        log.debug("processing json:"+json);
-                    }
-                    if (isValidJSON(json)) {
-                        context.put("json", json);
-                    }
-                    
-                }
-                
                 String id = mapping.getProperty("id");
                 if (id != null) {
                     args.add(new Interpreter.Argument("id", id));
@@ -176,32 +152,47 @@
                 
                 // call control script function
                 
-                Object ret = interp.callController(controller, func, args, context);
-                
-                if (isFlowCall) {
-                    Map atts = ConversionHelper.jsobjectToMap((Scriptable) ret);
-                    String json = new JSONSerializer().serialize(atts);
-                    if (log.isDebugEnabled()) {
-                        log.debug("returning json: "+json);
-                    }
-                    response.getWriter().write(json);
-                    response.getWriter().flush();
-                    response.getWriter().close();
-                    return null;
-                }
+                interp.callController(controller, func, args, context);
                 
                 return dispatchToPage(request, response, mapping, forward);
             }
         } else {
             // --- continue an existing flow
 
-            // kick off continuation
-            context.put("id", "5");
+            // validate JSON in the body of a flowcall
+            if (isFlowCall) {
+                StringBuffer sb = new StringBuffer();
+                char[] buffer = new char[1024];
+                int len = 0;
+                BufferedReader reader = request.getReader();
+                while ((len = reader.read(buffer)) > 0 ) {
+                    sb.append(buffer, 0, len);
+                }
+                String json = sb.toString();
+                if (log.isDebugEnabled()) {
+                    log.debug("processing json:"+json);
+                }
+                if (isValidJSON(json)) {
+                    context.put("json", json);
+                }
+                
+            }
             
             interp.handleContinuation(
                     request.getParameter("contid"), new LinkedList(), context);
 
-            return dispatchToPage(request, response, mapping, forward);
+            if (isFlowCall) {
+                String json = new JSONSerializer().serialize(forward.getBizData());
+                if (log.isDebugEnabled()) {
+                    log.debug("returning json: "+json);
+                }
+                response.getWriter().write(json);
+                response.getWriter().flush();
+                response.getWriter().close();
+                return null;
+            } else {     
+                return dispatchToPage(request, response, mapping, forward);
+            }
         }
     }
 

Modified: struts/flow/trunk/src/java/org/apache/struts/flow/FlowPlugIn.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/FlowPlugIn.java?rev=371121&r1=371120&r2=371121&view=diff
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/FlowPlugIn.java (original)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/FlowPlugIn.java Sat Jan 21 14:00:28 2006
@@ -239,6 +239,7 @@
         classesToRegister.add(SqlMap.class);
         interp.initialize(classesToRegister);
         interp.register("/org/apache/struts/flow/core/javascript/fom/fom_system.js");
+        interp.register("/org/apache/struts/flow/core/javascript/fom/template.js");
         interp.addFlowVariable("struts", new DefaultFlowVariableFactory(Struts.class));
         interp.addFlowVariable("params", new DefaultFlowVariableFactory(Params.class));
         return interp;

Modified: struts/flow/trunk/src/java/org/apache/struts/flow/Forward.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/Forward.java?rev=371121&r1=371120&r2=371121&view=diff
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/Forward.java (original)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/Forward.java Sat Jan 21 14:00:28 2006
@@ -46,7 +46,7 @@
         this.action = (String) setIfNotNull(action, map.get("action"));
         this.params = (Map) setIfNotNull(params, map.get("params"));
         this.controller = (String) setIfNotNull(controller, map.get("controller"));
-        this.redirect = "true".equals(map.get("redirect"));
+        this.redirect = Boolean.TRUE.equals(map.get("redirect"));
         this.options = map;
     }
 

Modified: struts/flow/trunk/src/java/org/apache/struts/flow/core/Interpreter.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/Interpreter.java?rev=371121&r1=371120&r2=371121&view=diff
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/Interpreter.java (original)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/Interpreter.java Sat Jan 21 14:00:28 2006
@@ -222,7 +222,7 @@
      * @param redirector a <code>Redirector</code> used to call views
      * @exception Exception if an error occurs
      */
-    void handleContinuation(String continuationId, List params,
+    Object handleContinuation(String continuationId, List params,
                             WebContext chainCtx)
     throws Exception;
 }

Modified: struts/flow/trunk/src/java/org/apache/struts/flow/core/javascript/fom/FOM_Flow.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/javascript/fom/FOM_Flow.java?rev=371121&r1=371120&r2=371121&view=diff
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/javascript/fom/FOM_Flow.java (original)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/javascript/fom/FOM_Flow.java Sat Jan 21 14:00:28 2006
@@ -212,7 +212,7 @@
     }
 
     public FOM_WebContinuation jsFunction_forward(Object options,
-                                                   Object obj,
+                                                   Object bizdata,
                                                    Object wk)
         throws Exception {
             
@@ -231,14 +231,26 @@
             forward.setUri((String) options);
         } else if (options instanceof Scriptable 
                 && options != Undefined.instance) {
-            forward.populate((Map)ConversionHelper.jsobjectToMap((Scriptable)options));
+            Map vals = (Map)ConversionHelper.jsobjectToMap((Scriptable)options);
+            forward.populate(vals);
         }
         
-        if (obj != null && obj != Undefined.instance) {
-            forward.setBizData((Map)ConversionHelper.jsobjectToMap((Scriptable)obj));
+        if (bizdata != null && bizdata != Undefined.instance) {
+            forward.setBizData((Map)ConversionHelper.jsobjectToMap((Scriptable)bizdata));
         }
         ctx.put(Constants.FORWARD_KEY, forward);
         return fom_wk;
+    }
+    
+    public String jsFunction_calculateUri(Object fwd, Object options, String pattern) {
+        Forward forward = (Forward)fwd;
+        if (options instanceof String) {
+            forward.setUri((String) options);
+        } else if (options instanceof Scriptable 
+                && options != Undefined.instance) {
+            forward.populate((Map)ConversionHelper.jsobjectToMap((Scriptable)options));
+        }
+        return forward.toUri(pattern);
     }
 
     public Scriptable jsFunction_createPageLocal() {

Modified: struts/flow/trunk/src/java/org/apache/struts/flow/core/javascript/fom/FOM_JavaScriptInterpreter.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/javascript/fom/FOM_JavaScriptInterpreter.java?rev=371121&r1=371120&r2=371121&view=diff
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/javascript/fom/FOM_JavaScriptInterpreter.java (original)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/javascript/fom/FOM_JavaScriptInterpreter.java Sat Jan 21 14:00:28 2006
@@ -878,9 +878,10 @@
         return ret;
     }
 
-    public void handleContinuation(String id, List params,
+    public Object handleContinuation(String id, List params,
                                    WebContext webctx) throws Exception
     {
+        Object ret = null;
         WebContinuation wk = continuationsMgr.lookupWebContinuation(id, getInterpreterID(), webctx);
 
         if (wk == null) {
@@ -940,7 +941,7 @@
                 initFlowVariables(kScope.getFlowVariables(), webctx);
                 Object[] args = new Object[] {k, fom_wk};
                 try {
-                    ScriptableObject.callMethod(flow,
+                    ret = ScriptableObject.callMethod(flow,
                                                 "handleContinuation", args);
                 } catch (JavaScriptException ex) {
                     throw locationTracker.getException("Error calling continuation", ex);
@@ -966,6 +967,7 @@
                 Context.exit();
                 Thread.currentThread().setContextClassLoader(savedClassLoader);
             }
+            return ret;
         }
     }
 

Modified: struts/flow/trunk/src/java/org/apache/struts/flow/core/javascript/fom/fom_system.js
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/javascript/fom/fom_system.js?rev=371121&r1=371120&r2=371121&view=diff
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/javascript/fom/fom_system.js (original)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/javascript/fom/fom_system.js Sat Jan 21 14:00:28 2006
@@ -30,10 +30,37 @@
 }
 
 
-FOM_Flow.prototype.wait = function(ttl) {
-    this.forward(null, null,
+FOM_Flow.prototype.wait = function(uri, bizData, ttl, fun) {
+    this._wait(uri, bizData, ttl, fun);
+    var funcName = params.FlowCall;
+    if (funcName) {
+        var func = controller[funcName];
+        if (func) {
+            var json;
+            eval("json = "+flow.context.json);
+            var ret = func.call(controller, json);
+            this.forward(null, ret);
+            FOM_Flow.suicide();
+        } else {
+            flow.log.error("Unable to locate function "+funcName+
+                " on controller "+typeof(controller));
+        }        
+    } else {
+        flow.log.debug("Not a flow call");
+    }    
+}
+
+FOM_Flow.prototype._wait = function(uri, bizData, ttl, fun) {
+    this.forward(uri, bizData,
                   new FOM_WebContinuation(new Continuation(), 
                                           this.continuation, ttl));
+    if (fun) {
+        if (!(fun instanceof Function)) {
+            throw "Expected a function instead of: " + fun;
+        }
+        fun();
+    }
+    
     FOM_Flow.suicide();
 }
 
@@ -78,6 +105,30 @@
  */
 FOM_Flow.prototype.exit = function() {
     FOM_Flow.suicide();
+}
+
+
+// This function renders the content directly using Javascript Templates
+FOM_Flow.prototype.renderAndWait = function(page, bizdata, ttl) { 
+   var cont = new FOM_WebContinuation(new Continuation(), 
+                                          this.continuation, ttl)
+   bizdata.contid = cont.id;
+   render(page, bizdata);
+   this.forward(null, bizdata, cont);
+   FOM_Flow.suicide();
+}
+
+FOM_Flow.prototype.render = function(page, bizdata) {
+   var res = this.context.response;
+   var stream = struts.servletContext.getResourceAsStream("/WEB-INF/templates/"+page+".jt");
+   if (stream != null) {
+       var text = new String(stream.getText());
+       var html = text.process(bizdata);
+       res.writer.print(html);
+       res.writer.close();
+   } else {
+       res.sendError(res.SC_INTERNAL_SERVER_ERROR, "Unable to find page "+page);
+   }  
 }
 
 



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org