/*
* Created on Mar 20, 2004
*/
package jspflow;
import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.mozilla.javascript.Scriptable;
import flow.Argument;
import flow.JSWebapp;
import flow.JavaScriptInterpreter;
/**
* Controls flow of JSP application using Cocoon's Control Flow engine.
* @author David M Johnson
*/
public class FlowServlet extends HttpServlet {
/**
* Initialize JavaScript interpreter with system and user scripts, store
* interpreter ServletContext.
*/
public void init() throws ServletException {
try {
JavaScriptInterpreter interp = new JavaScriptInterpreter();
interp.initialize();
interp.register("C:\\allfiles\\scratch\\JspFlow\\src\\flow\\system.js");
interp.register("C:\\allfiles\\scratch\\JspFlow\\web\\WEB-INF\\numberguess.js");
getServletContext().setAttribute("controlFlow", interp);
}
catch (Exception e) {
throw new ServletException("ERROR initializing Control Flow", e);
}
}
public JavaScriptInterpreter getControlFlow() {
return (JavaScriptInterpreter)getServletContext().getAttribute("controlFlow");
}
/**
* Handle by either starting a new Control Flow or continuing an existing
* one. The logic is:
* - If request contains contid, then continue existing flow.
* - Else start a new flow.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
if (request.getParameter("contid") == null) {
// --- start a new flow
// flow will return values in tray
List args = new LinkedList();
List tray = new LinkedList();
args.add(new Argument("tray", tray));
try {
// call control script function
getControlFlow().callFunction("main", args, request, response);
// retrieve page, continuation ID, and attributes from tray
String page = (String)tray.get(0);
String contid = (String)tray.get(1);
Map atts = JSWebapp.jsobjectToMap((Scriptable)tray.get(2));
dispatchToPage(request, response, page, contid, atts);
}
catch (Exception e) {
throw new ServletException(
"ERROR starting execution of Control Flow: "+e.getMessage(), e);
}
}
else {
// --- continue an existing flow
// flow will return values in tray
try {
// kick off continuation
List tray = getControlFlow().handleContinuation(
request.getParameter("contid"), new LinkedList(), request, response);
// retrieve page, continuation ID, and attributes from tray
String page = (String)tray.get(0);
String contid = (String)tray.get(1);
Map atts = JSWebapp.jsobjectToMap((Scriptable)tray.get(2));
dispatchToPage(request, response, page, contid, atts);
}
catch (Exception e) {
e.printStackTrace();
throw new ServletException("ERROR starting execution of Control Flow", e);
}
}
}
/**
* Add continuation ID and attributes to request scope, dispatch to page.
* @param request
* @param response
* @param page JSP page name to which to dispath.
* @param contid Continuation ID to be set in request.
* @param atts Attributes to be set in request.
* @throws ServletException
* @throws IOException
*/
private void dispatchToPage(
HttpServletRequest request, HttpServletResponse response,
String page, String contid, Map atts)
throws ServletException, IOException {
request.setAttribute("contid", contid);
Iterator attkeys = atts.keySet().iterator();
while (attkeys.hasNext())
{
String attkey = (String)attkeys.next();
request.setAttribute(attkey, JSWebapp.jsobjectToObject(atts.get(attkey)));
}
RequestDispatcher dispatcher = request.getRequestDispatcher(page);
dispatcher.forward(request, response);
}
/**
* Calls doGet().
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}