Author: mrdon Date: Fri Nov 4 18:12:42 2005 New Revision: 330961 URL: http://svn.apache.org/viewcvs?rev=330961&view=rev Log: Adding new experimental Portlet support. Basically, instead of coming through a Struts Action, the flow is entered through the Portlet. Currently, only the most simple portlets are possible, but more to come. The server-side Javascript, especially paired with Javascript Templates for the rendering, works as a great, quick integration approach, especially potent for front-ending web services due to Rhino's E4X support.
Added: struts/flow/trunk/src/java/org/apache/struts/flow/portlet/ struts/flow/trunk/src/java/org/apache/struts/flow/portlet/FlowPortlet.java Modified: struts/flow/trunk/build.xml struts/flow/trunk/project.xml struts/flow/trunk/src/java/org/apache/struts/flow/core/JavaScriptInterpreter.java Modified: struts/flow/trunk/build.xml URL: http://svn.apache.org/viewcvs/struts/flow/trunk/build.xml?rev=330961&r1=330960&r2=330961&view=diff ============================================================================== --- struts/flow/trunk/build.xml (original) +++ struts/flow/trunk/build.xml Fri Nov 4 18:12:42 2005 @@ -19,6 +19,7 @@ <!-- where all the library files are kept, plus what to include/exclude when building --> <property name="lib.dir" value="./lib" /> <property name="lib.core" value="${lib.dir}/core" /> + <property name="lib.examples" value="${lib.dir}/examples" /> <property name="lib.build" value="${lib.dir}/build" /> <!-- application information --> @@ -131,7 +132,17 @@ <get dest="${lib.core}/commons-digester.jar" usetimestamp="true" ignoreerrors="true" src="http://www.ibiblio.org/maven/commons-digester/jars/commons-digester-1.7.jar"/> - </target> + + <get dest="${lib.core}/portlet-api-1.0.jar" usetimestamp="true" + ignoreerrors="true" + src="http://www.ibiblio.org/maven/portlet-api/jars/portlet-api-1.0.jar"/> + + <mkdir dir="${lib.examples}" /> + <get dest="${lib.examples}/hsqldb.jar" usetimestamp="true" + ignoreerrors="true" + src="http://www.ibiblio.org/maven/hsqldb/jars/hsqldb-1.8.0.1.jar"/> + +</target> <!-- @@ -326,6 +337,7 @@ </copy> <copy todir="${build.examples}/WEB-INF/lib"> <fileset dir="${lib.core}" /> + <fileset dir="${lib.examples}" /> </copy> <copy todir="${build.examples}/WEB-INF/lib" file="${dist.dir}/${app.jar}" /> Modified: struts/flow/trunk/project.xml URL: http://svn.apache.org/viewcvs/struts/flow/trunk/project.xml?rev=330961&r1=330960&r2=330961&view=diff ============================================================================== --- struts/flow/trunk/project.xml (original) +++ struts/flow/trunk/project.xml Fri Nov 4 18:12:42 2005 @@ -61,12 +61,18 @@ <url>http://struts.apache.org/</url> </dependency> - <dependency> + <dependency> <groupId>servletapi</groupId> <artifactId>servletapi</artifactId> <version>2.3</version> <url>http://java.sun.com/products/servlet/</url> - </dependency> + </dependency> + + <dependency> + <groupId>portlet-api</groupId> + <artifactId>portlet-api</artifactId> + <version>1.0</version> + </dependency> <dependency> <groupId>rhino</groupId> Modified: struts/flow/trunk/src/java/org/apache/struts/flow/core/JavaScriptInterpreter.java URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/JavaScriptInterpreter.java?rev=330961&r1=330960&r2=330961&view=diff ============================================================================== --- struts/flow/trunk/src/java/org/apache/struts/flow/core/JavaScriptInterpreter.java (original) +++ struts/flow/trunk/src/java/org/apache/struts/flow/core/JavaScriptInterpreter.java Fri Nov 4 18:12:42 2005 @@ -23,6 +23,9 @@ import org.apache.commons.chain.web.servlet.ServletWebContext; import javax.servlet.ServletContext; +import org.apache.commons.chain.web.portlet.PortletWebContext; +import javax.portlet.PortletContext; + import org.mozilla.javascript.Context; import org.mozilla.javascript.EcmaError; @@ -786,8 +789,23 @@ // Try to locate the file in the servlet context is = context.getResourceAsStream(pathname); - } else { + } else if (ctx instanceof PortletWebContext) { + PortletContext context = ((PortletWebContext) ctx).getContext(); + // Can we access the file in the portlet directory? + String path = context.getRealPath(pathname); + if (path != null) { + File file = new File(path); + if (file.exists()) { + return (path); + } + } + + // Try to locate the file in the servlet context + is = context.getResourceAsStream(pathname); + } + + if (tmpdir == null) { // Set the temp directory tmpdir = new File(System.getProperty("java.io.tmpdir")); } Added: struts/flow/trunk/src/java/org/apache/struts/flow/portlet/FlowPortlet.java URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/portlet/FlowPortlet.java?rev=330961&view=auto ============================================================================== --- struts/flow/trunk/src/java/org/apache/struts/flow/portlet/FlowPortlet.java (added) +++ struts/flow/trunk/src/java/org/apache/struts/flow/portlet/FlowPortlet.java Fri Nov 4 18:12:42 2005 @@ -0,0 +1,149 @@ +package org.apache.struts.flow.portlet; + +import java.io.PrintWriter; +import java.io.IOException; + +import javax.portlet.GenericPortlet; +import javax.portlet.RenderRequest; +import javax.portlet.*; +import javax.portlet.PortletException; + +import org.apache.struts.flow.*; +import org.apache.struts.flow.core.*; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.struts.flow.core.Factory; +import org.apache.struts.flow.core.JavaScriptInterpreter; +import org.apache.struts.flow.core.DefaultCallVariableRegistrar; +import org.apache.struts.flow.sugar.SugarWrapFactory; +import org.apache.commons.chain.*; +import org.apache.commons.chain.web.portlet.*; +import java.util.*; +import java.io.*; +import org.mozilla.javascript.Scriptable; + +/** Description of the Class */ +public class FlowPortlet extends GenericPortlet { + + private JavaScriptInterpreter interp; + + public void init() { + + Factory.setLogger(new CommonsLogger()); + Factory.getContinuationsManager().setDefaultTimeToLive(10 * 60 * 1000); + interp = createInterpreter(); + interp.register(getInitParameter("path")); + } + + private JavaScriptInterpreter createInterpreter() { + JavaScriptInterpreter interp = new JavaScriptInterpreter(); + interp.setDebugger(false); + interp.setCheckTime(0); + interp.setReloadScripts(true); + interp.setWrapFactory(new SugarWrapFactory()); + interp.initialize(); + interp.register("/system.js"); + //interp.addVariableRegistrar(new DefaultCallVariableRegistrar(Struts.class, "struts")); + //interp.addVariableRegistrar(new DefaultCallVariableRegistrar(SqlMap.class, "sqlMap")); + return interp; + } + + /** + * The portlet's main view prints "Hello, World" + * + [EMAIL PROTECTED] request Description of the Parameter + [EMAIL PROTECTED] response Description of the Parameter + [EMAIL PROTECTED] PortletException If anything goes wrong + [EMAIL PROTECTED] IOException If anything goes wrong + */ + public void doView(RenderRequest request, RenderResponse response) + throws PortletException, IOException { + + // Create and populate a Context for this request + PortletWebContext context = new PortletWebContext(); + context.initialize(getPortletContext(), request, response); + + String view = request.getParameter("view"); + String contid = request.getParameter("contid"); + + String func = "doView"; + if (view != null) { + func = view + "View"; + } + + if (contid == null || contid.length() == 0) { + + // --- start a new flow + + List args = new LinkedList(); + + // call control script function + interp.callFunction(func, args, context); + + // retrieve page, continuation ID, and attributes from chain context + String page = (String) JSFlow.jsobjectToObject(context.get(Constants.FORWARD_NAME_KEY)); + contid = (String) context.get(Constants.CONTINUATION_ID_KEY); + Scriptable bizdata = (Scriptable) context.get(Constants.BIZ_DATA_KEY); + Map atts = null; + if (bizdata != null) { + atts = JSFlow.jsobjectToMap(bizdata); + } + dispatchToPage(request, response, page, contid, atts); + } else { + // --- continue an existing flow + + // kick off continuation + context.put("id", "5"); + + interp.handleContinuation(contid, new LinkedList(), context); + + // retrieve page, continuation ID, and attributes from chain context + String page = (String) context.get(Constants.FORWARD_NAME_KEY); + contid = (String) context.get(Constants.CONTINUATION_ID_KEY); + Scriptable bizdata = (Scriptable) context.get(Constants.BIZ_DATA_KEY); + Map atts = null; + if (bizdata != null) { + atts = JSFlow.jsobjectToMap(bizdata); + } + + dispatchToPage(request, response, page, contid, atts); + } + } + + /** + * Add continuation ID and attributes to request scope, dispatch to page. + * + [EMAIL PROTECTED] request The request + [EMAIL PROTECTED] response The response + [EMAIL PROTECTED] page The action forward name + [EMAIL PROTECTED] contid Continuation ID to be set in request. + [EMAIL PROTECTED] atts Attributes to be set in request. + [EMAIL PROTECTED] mapping The action mapping + [EMAIL PROTECTED] + [EMAIL PROTECTED] ServletException + [EMAIL PROTECTED] IOException + */ + private void dispatchToPage(RenderRequest request, RenderResponse response, + String page, String contid, Map atts) + throws PortletException, IOException { + + // Probably only need to process if the response hasn't already been committed. This + // should let flow code be able to completely handle a request if desired. + if (!response.isCommitted()) { + request.setAttribute("contid", contid); + + if (atts != null) { + Iterator attkeys = atts.keySet().iterator(); + while (attkeys.hasNext()) { + String attkey = (String) attkeys.next(); + request.setAttribute(attkey, JSFlow.jsobjectToObject(atts.get(attkey))); + } + } + + PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher(page); + rd.include(request,response); + } + } +} + --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]