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 2005/02/15 22:10:32 UTC
svn commit: r153960 [1/3] - in struts/flow: ./ branches/ tags/ trunk/
trunk/src/ trunk/src/guess-example/ trunk/src/guess-example/WEB-INF/
trunk/src/java/ trunk/src/java/org/ trunk/src/java/org/apache/
trunk/src/java/org/apache/struts/ trunk/src/java/org/apache/struts/flow/
trunk/src/java/org/apache/struts/flow/core/ trunk/src/wizard-example/
trunk/src/wizard-example/WEB-INF/
Author: mrdon
Date: Tue Feb 15 13:09:29 2005
New Revision: 153960
URL: http://svn.apache.org/viewcvs?view=rev&rev=153960
Log:
Initial import of struts-flow
Added:
struts/flow/
struts/flow/branches/
struts/flow/tags/
struts/flow/trunk/
struts/flow/trunk/build.xml (with props)
struts/flow/trunk/project.xml
struts/flow/trunk/src/
struts/flow/trunk/src/guess-example/
struts/flow/trunk/src/guess-example/WEB-INF/
struts/flow/trunk/src/guess-example/WEB-INF/numberguess.js (with props)
struts/flow/trunk/src/guess-example/WEB-INF/struts-config.xml (with props)
struts/flow/trunk/src/guess-example/WEB-INF/web.xml (with props)
struts/flow/trunk/src/guess-example/guess.jsp (with props)
struts/flow/trunk/src/guess-example/index.html
struts/flow/trunk/src/guess-example/success.jsp (with props)
struts/flow/trunk/src/java/
struts/flow/trunk/src/java/org/
struts/flow/trunk/src/java/org/apache/
struts/flow/trunk/src/java/org/apache/struts/
struts/flow/trunk/src/java/org/apache/struts/flow/
struts/flow/trunk/src/java/org/apache/struts/flow/CommonsLogger.java (with props)
struts/flow/trunk/src/java/org/apache/struts/flow/Constants.java (with props)
struts/flow/trunk/src/java/org/apache/struts/flow/FlowAction.java (with props)
struts/flow/trunk/src/java/org/apache/struts/flow/FlowMapping.java (with props)
struts/flow/trunk/src/java/org/apache/struts/flow/FlowPlugIn.java (with props)
struts/flow/trunk/src/java/org/apache/struts/flow/core/
struts/flow/trunk/src/java/org/apache/struts/flow/core/Argument.java (with props)
struts/flow/trunk/src/java/org/apache/struts/flow/core/CompilingInterpreter.java (with props)
struts/flow/trunk/src/java/org/apache/struts/flow/core/ContinuationsDisposer.java (with props)
struts/flow/trunk/src/java/org/apache/struts/flow/core/ContinuationsManager.java (with props)
struts/flow/trunk/src/java/org/apache/struts/flow/core/ContinuationsManagerImpl.java (with props)
struts/flow/trunk/src/java/org/apache/struts/flow/core/Factory.java (with props)
struts/flow/trunk/src/java/org/apache/struts/flow/core/FlowException.java (with props)
struts/flow/trunk/src/java/org/apache/struts/flow/core/InvalidContinuationException.java (with props)
struts/flow/trunk/src/java/org/apache/struts/flow/core/JSContext.java
struts/flow/trunk/src/java/org/apache/struts/flow/core/JSErrorReporter.java (with props)
struts/flow/trunk/src/java/org/apache/struts/flow/core/JSGlobal.java (with props)
struts/flow/trunk/src/java/org/apache/struts/flow/core/JSLog.java (with props)
struts/flow/trunk/src/java/org/apache/struts/flow/core/JSWebContinuation.java (with props)
struts/flow/trunk/src/java/org/apache/struts/flow/core/JavaScriptInterpreter.java (with props)
struts/flow/trunk/src/java/org/apache/struts/flow/core/Logger.java (with props)
struts/flow/trunk/src/java/org/apache/struts/flow/core/ScriptableMap.java (with props)
struts/flow/trunk/src/java/org/apache/struts/flow/core/WebContinuation.java (with props)
struts/flow/trunk/src/java/org/apache/struts/flow/core/package.html (with props)
struts/flow/trunk/src/java/org/apache/struts/flow/package.html (with props)
struts/flow/trunk/src/java/struts.js (with props)
struts/flow/trunk/src/java/system.js (with props)
struts/flow/trunk/src/wizard-example/
struts/flow/trunk/src/wizard-example/WEB-INF/
struts/flow/trunk/src/wizard-example/WEB-INF/struts-config.xml (with props)
struts/flow/trunk/src/wizard-example/WEB-INF/web.xml (with props)
struts/flow/trunk/src/wizard-example/WEB-INF/wizard-flow.js (with props)
struts/flow/trunk/src/wizard-example/WEB-INF/wizard.js (with props)
struts/flow/trunk/src/wizard-example/hobbies-form.jsp (with props)
struts/flow/trunk/src/wizard-example/index.html
struts/flow/trunk/src/wizard-example/name-form.jsp (with props)
struts/flow/trunk/src/wizard-example/summary-form.jsp (with props)
Added: struts/flow/trunk/build.xml
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/build.xml?view=auto&rev=153960
==============================================================================
--- struts/flow/trunk/build.xml (added)
+++ struts/flow/trunk/build.xml Tue Feb 15 13:09:29 2005
@@ -0,0 +1,269 @@
+<project name="struts-flow" default="jar" basedir=".">
+
+ <!-- ========== Initialization Properties ================================= -->
+ <!--
+ These property values may optionally be overridden with property
+ settings from an "ant" command line, the "antrc" properties file
+ in your home directory, or from settings in a superior build.xml
+ script.
+ -->
+
+ <!-- Java compilation options -->
+ <property name="compile.debug" value="true" />
+ <property name="compile.deprecation" value="true" />
+ <property name="compile.optimize" value="false" />
+
+ <!-- Doc directory and packages that go in there -->
+ <property name="doc.dir" value="./doc"/>
+
+ <!-- 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.build" value="${lib.dir}/build" />
+
+ <!-- application information -->
+ <property name="app.name" value="struts-flow" />
+ <property name="app.version" value="0.3-dev" />
+
+ <!-- The base directory for distribution targets -->
+ <property name="dist.dir" value="./dist" />
+
+ <property name="src.dir" value="src" />
+ <property name="src.java" value="${src.dir}/java" />
+ <property name="src.guess.example" value="${src.dir}/guess-example" />
+ <property name="src.wizard.example" value="${src.dir}/wizard-example" />
+
+ <property name="build.dir" value="build" />
+ <property name="build.guess.example" value="${build.dir}/guess-example" />
+ <property name="build.wizard.example" value="${build.dir}/wizard-example" />
+ <property name="build.target" value="${build.dir}/target" />
+
+ <property name="javadoc.packages" value="org.apache.struts.flow.*" />
+
+
+ <!-- ========== Derived Properties ======================================== -->
+ <!--
+ These property values are derived from values defined above, and
+ generally should NOT be overridden by command line settings
+ -->
+
+ <!-- The name of the web application archive file to be produced -->
+ <property name="app.jar" value="${app.name}-${app.version}.jar" />
+ <property name="release.zip" value="${app.name}-${app.version}.zip" />
+
+ <path id="base.classpath">
+ <fileset dir="lib">
+ <include name="**/*.jar"/>
+ </fileset>
+ <pathelement location="${build.target}"/>
+ <pathelement location="${build.test}" />
+ </path>
+
+ <!-- ========== Executable Targets ======================================== -->
+ <!--
+ The "init" target evaluates "available" expressions as necessary
+ to modify the behavior of this script.
+ -->
+
+ <target name="init">
+ <echo message="Processing build.target init ${app.name}"/>
+ <available file="${src.java}" property="src.java.present"/>
+ <available file="${lib.dir}" property="lib.dir.present"/>
+ </target>
+
+ <target name="download-dependencies" unless="lib.dir.present">
+ <mkdir dir="${lib.build}" />
+
+ <get dest="${lib.build}/servletapi-2.3.jar" usetimestamp="true"
+ ignoreerrors="true"
+ src="http://www.ibiblio.org/maven/servletapi/jars/servletapi-2.3.jar"/>
+
+ <mkdir dir="${lib.core}" />
+ <get dest="${lib.core}/struts-1.1.jar" usetimestamp="true"
+ ignoreerrors="true"
+ src="http://www.ibiblio.org/maven/struts/jars/struts-1.1.jar"/>
+
+ <get dest="${lib.core}/js-1.6R1.jar" usetimestamp="true"
+ ignoreerrors="true"
+ src="http://www.ibiblio.org/maven/rhino/jars/js-1.6R1.jar"/>
+
+ <get dest="${lib.core}/commons-chain-1.0.jar" usetimestamp="true"
+ ignoreerrors="true"
+ src="http://www.ibiblio.org/maven/commons-chain/jars/commons-chain-1.0.jar"/>
+
+ <get dest="${lib.core}/jakarta-oro-2.0.7.jar" usetimestamp="true"
+ ignoreerrors="true"
+ src="http://www.ibiblio.org/maven/oro/jars/oro-2.0.7.jar"/>
+
+ <get dest="${lib.core}/commons-logging.jar" usetimestamp="true"
+ ignoreerrors="true"
+ src="http://www.ibiblio.org/maven/commons-logging/jars/commons-logging-1.0.3.jar"/>
+
+ <get dest="${lib.core}/commons-beanutils.jar" usetimestamp="true"
+ ignoreerrors="true"
+ src="http://www.ibiblio.org/maven/commons-beanutils/jars/commons-beanutils-1.7.0.jar"/>
+
+ <get dest="${lib.core}/commons-validator.jar" usetimestamp="true"
+ ignoreerrors="true"
+ src="http://www.ibiblio.org/maven/commons-validator/jars/commons-validator-1.1.3.jar"/>
+ <get dest="${lib.core}/commons-digester.jar" usetimestamp="true"
+ ignoreerrors="true"
+ src="http://www.ibiblio.org/maven/commons-digester/jars/commons-digester-1.6.jar"/>
+ </target>
+
+
+ <!--
+ The "clean" task deletes any created directories that have resulted
+ from running any of the other targets in this script.
+ -->
+
+ <target name="clean"
+ description="Clean build and distribution directories">
+ <echo message="Processing build.target clean ${app.name}"/>
+ <delete dir="${build.dir}" />
+ <delete dir="${dist.dir}" />
+ <delete dir="${doc.dir}" />
+ </target>
+
+ <!--
+ The "prepare" target creates a directory structure in the build target
+ area for the unpacked files associated with this web application
+ -->
+ <target name="prepare" depends="init, download-dependencies"
+ description="Prepare target directory">
+ <echo message="Processing app ${app.name}"/>
+ <mkdir dir="${build.dir}" />
+ <mkdir dir="${build.target}" />
+ <mkdir dir="${dist.dir}" />
+ </target>
+
+ <target name="release" depends="clean, jar, guess-example, wizard-example,javadoc"
+ description="Creates a release">
+ <echo message="Creating ${app.version} release" />
+
+ <zip destfile="${release.zip}"
+ compress="true">
+ <zipfileset dir="${src.dir}" prefix="src" />
+ <zipfileset dir="${doc.dir}" prefix="doc" />
+ <zipfileset dir="${lib.dir}" prefix="lib" />
+ <zipfileset dir="${dist.dir}" prefix="dist" />
+ <fileset dir="." includes="build.xml" />
+ </zip>
+ </target>
+
+
+ <!--
+ The "compile" target compiles the Java source code of your web
+ application, if and only if the specified source directory
+ actually exists.
+ -->
+ <target name="compile" depends="prepare" description="Compile Java sources">
+ <echo message="Processing app ${app.name}"/>
+
+ <echo message="Source ${src.java}"/>
+ <echo message="Target ${build.target}"/>
+ <javac srcdir="${src.java}"
+ destdir="${build.target}"
+ debug="${compile.debug}"
+ deprecation="${compile.deprecation}"
+ optimize="${compile.optimize}">
+ <classpath refid="base.classpath" />
+ </javac>
+ <copy todir="${build.target}">
+ <fileset dir="${src.java}">
+ <exclude name="**/*.java"/>
+ <exclude name="**/!dirinfo.txt"/>
+ </fileset>
+ </copy>
+ </target>
+
+<!--
+ <target name="run-tests" depends="compile">
+ <javac srcdir="${test.src}" destdir="${test.build}"
+ debug="on" optimize="off" deprecation="off" >
+ <classpath refid="base.classpath" />
+ </javac>
+ <junit printsummary="on" fork="on">
+ <formatter type="xml" />
+ <classpath refid="base.classpath" />
+
+ <batchtest todir="${test.results}">
+ <fileset dir="${test.src}">
+ <include name="**/*Test.java" />
+ </fileset>
+ </batchtest>
+ </junit>
+ </target>
+ -->
+ <!--
+ The 'javadoc' target creates the API documentation.
+ All javadoc is created in the ${doc.dir}/javadoc directory.
+ -->
+ <target name="javadoc" depends="init">
+ <mkdir dir="${doc.dir}/api"/>
+ <delete includeEmptyDirs="true" >
+ <fileset dir="${doc.dir}/api"/>
+ </delete>
+ <mkdir dir="${doc.dir}/api"/>
+ <javadoc packagenames="${javadoc.packages}"
+ sourcepath="${src.java}"
+ destdir="${doc.dir}/api"
+ author="true"
+ version="true"
+ private="false"
+ doctitle="${app.name} Version ${app.version}">
+ <classpath refid="base.classpath" />
+ </javadoc>
+ </target>
+ <!--
+ The "dist" target creates a web application archive containing
+ your completed web application, suitable for deployment on any
+ compatible servlet container.
+ -->
+ <target name="jar" depends="compile"
+ description="Create jar">
+ <echo message="Processing jarfile ${app.name}"/>
+ <jar jarfile="${dist.dir}/${app.jar}"
+ basedir="${build.target}"
+ excludes="**/example/*.*"/>
+ </target>
+
+ <target name="guess-example" depends="jar"
+ description="Create guess example">
+ <echo message="Creating guess example"/>
+ <mkdir dir="${build.guess.example}" />
+ <mkdir dir="${build.guess.example}/WEB-INF/lib" />
+ <copy todir="${build.guess.example}">
+ <fileset dir="${src.guess.example}" excludes="WEB-INF/web.xml" />
+ </copy>
+ <copy todir="${build.guess.example}/WEB-INF/lib">
+ <fileset dir="${lib.core}" />
+ </copy>
+ <copy todir="${build.guess.example}/WEB-INF/lib" file="${dist.dir}/${app.jar}" />
+
+ <war destfile="${dist.dir}/guess-example.war"
+ basedir="${build.guess.example}"
+ webxml="${src.guess.example}/WEB-INF/web.xml"/>
+ </target>
+
+ <target name="wizard-example" depends="jar"
+ description="Create wizard example">
+ <echo message="Creating wizard example"/>
+ <mkdir dir="${build.wizard.example}" />
+ <mkdir dir="${build.wizard.example}/WEB-INF/lib" />
+ <copy todir="${build.wizard.example}">
+ <fileset dir="${src.wizard.example}" excludes="WEB-INF/web.xml" />
+ </copy>
+ <copy todir="${build.wizard.example}/WEB-INF/lib">
+ <fileset dir="${lib.core}" />
+ </copy>
+ <copy todir="${build.wizard.example}/WEB-INF/lib" file="${dist.dir}/${app.jar}" />
+
+ <war destfile="${dist.dir}/wizard-example.war"
+ basedir="${build.wizard.example}"
+ webxml="${src.wizard.example}/WEB-INF/web.xml"/>
+ </target>
+
+
+
+</project>
Propchange: struts/flow/trunk/build.xml
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/project.xml
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/project.xml?view=auto&rev=153960
==============================================================================
--- struts/flow/trunk/project.xml (added)
+++ struts/flow/trunk/project.xml Tue Feb 15 13:09:29 2005
@@ -0,0 +1,175 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+ <pomVersion>3</pomVersion>
+ <id>struts-flow</id>
+ <name>Struts Flow</name>
+ <currentVersion>0.3-SNAPSHOT</currentVersion>
+
+ <organization>
+ <name />
+ <url>http://struts.apache.org/flow/</url>
+ <logo />
+ </organization>
+ <logo>http://struts.apache.org/struts/images/struts.gif</logo>
+ <inceptionYear>2003</inceptionYear>
+ <package>org.apache.struts.flow</package>
+ <packageGroups>
+ <packageGroup>
+ <title>Struts Flow</title>
+ <packages>org.apache.struts.flow</packages>
+ </packageGroup>
+ </packageGroups>
+
+ <shortDescription>Struts Flow</shortDescription>
+
+ <!--
+ <gumpRepositoryId></gumpRepositoryId>
+ -->
+
+ <description>
+ Struts Flow is a port of Cocoon's Control Flow to Struts to allow complex workflow, like multi-form wizards, to be easily implemented using continuations-capable JavaScript. It provides 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.
+ </description>
+
+ <url>http://struts.apache.org/flow</url>
+ <repository>
+ <connection>scm|svn|http|//svn.apache.org/repos/asf/struts/flow/trunk</connection>
+ <developerConnection>scm|svn|https|//svn.apache.org/repos/asf/struts/flow/trunk</developerConnection>
+ <url>http://svn.apache.org/repos/asf/struts/flow/trunk</url>
+ </repository>
+ <versions>
+ <version>
+ <id>rel_0_3</id>
+ <name>rel_0_3</name>
+ <tag>rel_0_3</tag>
+ </version>
+ </versions>
+<!--
+ <branches>
+ <branch>
+ <tag></tag>
+ </branch>
+ </branches>
+-->
+ <mailingLists>
+ <mailingList>
+ <name>Struts User List</name>
+ <subscribe>user-subscribe@struts.apache.org</subscribe>
+ <unsubscribe>user-unsubscribe@struts.apache.org</unsubscribe>
+ <archive>http://mail-archives.apache.org/eyebrowse/SummarizeList?listId=42</archive>
+ </mailingList>
+ <mailingList>
+ <name>Struts Developer List</name>
+ <subscribe>dev-subscribe@struts.apache.org</subscribe>
+ <unsubscribe>dev-unsubscribe@struts.apache.org</unsubscribe>
+ <archive>http://mail-archives.apache.org/eyebrowse/SummarizeList?listId=41</archive>
+ </mailingList>
+ </mailingLists>
+ <developers>
+ <developer>
+ <name>Don Brown</name>
+ <id>mrdon</id>
+ <email>mrdon at apache.org</email>
+ <organization/>
+ </developer>
+</developers>
+
+<!-- <contributors /> -->
+ <dependencies>
+ <dependency>
+ <id>servletapi</id>
+ <version>2.3</version>
+ </dependency>
+ <dependency>
+ <id>struts</id>
+ <version>1.1</version>
+ </dependency>
+ <dependency>
+ <id>rhino</id>
+ <artifactId>js</artifactId>
+ <version>1.6R1</version>
+ </dependency>
+ <dependency>
+ <id>commons-chain</id>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <id>commons-logging</id>
+ <version>1.0.3</version>
+ </dependency>
+ <dependency>
+ <id>commons-beanutils</id>
+ <version>1.7.0</version>
+ </dependency>
+ <dependency>
+ <id>commons-digester</id>
+ <version>1.6</version>
+ </dependency>
+ <dependency>
+ <id>commons-validator</id>
+ <version>1.1.3</version>
+ </dependency>
+ <dependency>
+ <id>oro</id>
+ <version>2.0.7</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <nagEmailAddress/>
+ <sourceDirectory>src/java</sourceDirectory>
+<!--
+ <unitTestSourceDirectory/>
+ <integrationUnitTestSourceDirectory/>
+ <aspectSourceDirectory/>
+
+ <resources>
+ <resource>
+ <directory></directory>
+ <includes>
+ <include></include>
+ </includes>
+ </resource>
+ </resources>
+
+ <unitTest>
+ <includes>
+ <include>**/Test*.java</include>
+ </includes>
+ <resources>
+ <resource>
+ <directory>src/test</directory>
+ <includes>
+ <include>**/*.jelly</include>
+ <include>**/*.xml</include>
+ <include>**/*.xsl</include>
+ <include>**/*.rng</include>
+ <include>**/*.dtd</include>
+ <include>**/*.properties</include>
+ <include>**/*.html</include>
+ </includes>
+ </resource>
+ </resources>
+ </unitTest>
+
+ <integrationUnitTestPatterns></integrationUnitTestPatterns>
+-->
+
+ </build>
+
+ <reports>
+ <report>maven-javadoc-plugin</report>
+ <report>maven-junit-report-plugin</report>
+ <report>maven-jdepend-plugin</report>
+ <report>maven-checkstyle-plugin</report>
+ <report>maven-jxr-plugin</report>
+ <report>maven-linkcheck-plugin</report>
+ <report>maven-tasklist-plugin </report>
+ <report>maven-changes-plugin</report>
+ <report>maven-file-activity-plugin</report>
+<!--
+ <report>maven-changelog-plugin</report>
+ <report>maven-developer-activity-plugin</report>
+ <report>maven-license-plugin</report>
+-->
+ </reports>
+</project>
Added: struts/flow/trunk/src/guess-example/WEB-INF/numberguess.js
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/guess-example/WEB-INF/numberguess.js?view=auto&rev=153960
==============================================================================
--- struts/flow/trunk/src/guess-example/WEB-INF/numberguess.js (added)
+++ struts/flow/trunk/src/guess-example/WEB-INF/numberguess.js Tue Feb 15 13:09:29 2005
@@ -0,0 +1,37 @@
+function main() {
+
+ var random = Math.round( Math.random() * 9 ) + 1;
+ var hint = "No hint for you!"
+ var guesses = 0;
+
+ while (true) {
+
+ // send guess page to user and wait for response
+ forwardAndWait("failure",
+ { "random" : random,
+ "hint" : hint,
+ "guesses" : guesses} );
+
+ // process user's guess
+ var guess = parseInt( getRequestParams().guess );
+ guesses++;
+ if (guess) {
+ if (guess > random) {
+ hint = "Nope, lower!"
+ }
+ else if (guess < random) {
+ hint = "Nope, higher!"
+ }
+ else {
+ // correct guess
+ break;
+ }
+ }
+ }
+
+ // send success page to user
+ forwardAndWait("success",
+ {"random" : random,
+ "guess" : guess,
+ "guesses" : guesses} );
+}
Propchange: struts/flow/trunk/src/guess-example/WEB-INF/numberguess.js
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/src/guess-example/WEB-INF/struts-config.xml
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/guess-example/WEB-INF/struts-config.xml?view=auto&rev=153960
==============================================================================
--- struts/flow/trunk/src/guess-example/WEB-INF/struts-config.xml (added)
+++ struts/flow/trunk/src/guess-example/WEB-INF/struts-config.xml Tue Feb 15 13:09:29 2005
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+
+<!DOCTYPE struts-config PUBLIC
+ "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
+ "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
+
+<struts-config>
+
+
+ <!-- ========== Action Mapping Definitions ============================== -->
+ <action-mappings>
+
+ <action path="/guess"
+ type="net.sf.struts.flow.FlowAction"
+ className="net.sf.struts.flow.FlowMapping">
+
+ <set-property property="function" value="main" />
+
+ <forward name="failure" path="/guess.jsp"/>
+ <forward name="success" path="/success.jsp"/>
+ </action>
+ </action-mappings>
+
+
+ <plug-in className="net.sf.struts.flow.FlowPlugIn">
+ <set-property property="scripts" value="/WEB-INF/numberguess.js" />
+ <set-property property="debugger" value="false" />
+ <set-property property="timeToLive" value="600000" />
+ </plug-in>
+
+
+</struts-config>
Propchange: struts/flow/trunk/src/guess-example/WEB-INF/struts-config.xml
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/src/guess-example/WEB-INF/web.xml
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/guess-example/WEB-INF/web.xml?view=auto&rev=153960
==============================================================================
--- struts/flow/trunk/src/guess-example/WEB-INF/web.xml (added)
+++ struts/flow/trunk/src/guess-example/WEB-INF/web.xml Tue Feb 15 13:09:29 2005
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
+<web-app>
+ <!-- Action Servlet Configuration -->
+ <servlet>
+ <servlet-name>action</servlet-name>
+ <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
+ <init-param>
+ <param-name>config</param-name>
+ <param-value>/WEB-INF/struts-config.xml</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+
+
+ <!-- Action Servlet Mapping -->
+ <servlet-mapping>
+ <servlet-name>action</servlet-name>
+ <url-pattern>*.do</url-pattern>
+ </servlet-mapping>
+</web-app>
Propchange: struts/flow/trunk/src/guess-example/WEB-INF/web.xml
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/src/guess-example/guess.jsp
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/guess-example/guess.jsp?view=auto&rev=153960
==============================================================================
--- struts/flow/trunk/src/guess-example/guess.jsp (added)
+++ struts/flow/trunk/src/guess-example/guess.jsp Tue Feb 15 13:09:29 2005
@@ -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="guess.do">
+ <input type="hidden" name="contid" value='<%= request.getAttribute("contid") %>' />
+ <input type="text" name="guess"/>
+ <input type="submit"/>
+ </form>
+
+</body>
+</html>
\ No newline at end of file
Propchange: struts/flow/trunk/src/guess-example/guess.jsp
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/src/guess-example/index.html
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/guess-example/index.html?view=auto&rev=153960
==============================================================================
--- struts/flow/trunk/src/guess-example/index.html (added)
+++ struts/flow/trunk/src/guess-example/index.html Tue Feb 15 13:09:29 2005
@@ -0,0 +1,9 @@
+<html>
+<head>
+ <META HTTP-EQUIV="Refresh" CONTENT="0;URL=./guess.do">
+</head>
+<body>
+ <p>Should be redirected to <a href="guess.do">guess.do</a>
+ </p>
+</body>
+</html>
Added: struts/flow/trunk/src/guess-example/success.jsp
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/guess-example/success.jsp?view=auto&rev=153960
==============================================================================
--- struts/flow/trunk/src/guess-example/success.jsp (added)
+++ struts/flow/trunk/src/guess-example/success.jsp Tue Feb 15 13:09:29 2005
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+<html>
+<head>
+ <title>cocoon 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="guess.do">Play again</a></p>
+
+</body>
+</html>
\ No newline at end of file
Propchange: struts/flow/trunk/src/guess-example/success.jsp
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/src/java/org/apache/struts/flow/CommonsLogger.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/CommonsLogger.java?view=auto&rev=153960
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/CommonsLogger.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/CommonsLogger.java Tue Feb 15 13:09:29 2005
@@ -0,0 +1,84 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts.flow;
+
+import org.apache.commons.logging.*;
+
+/** Logger extension that hooks into commons-logging */
+public class CommonsLogger extends org.apache.struts.flow.core.Logger {
+
+ private final static Log log = LogFactory.getLog(CommonsLogger.class);
+
+
+ /**
+ * Logs an error message
+ *
+ *@param msg The message
+ */
+ public void error(String msg) {
+ log.error(msg);
+ }
+
+
+ /**
+ * Logs a warning message
+ *
+ *@param msg The message
+ */
+ public void warn(String msg) {
+ log.warn(msg);
+ }
+
+
+ /**
+ * Logs an info message
+ *
+ *@param msg The message
+ */
+ public void info(String msg) {
+ log.info(msg);
+ }
+
+
+ /**
+ * Logs a debug message
+ *
+ *@param msg The message
+ */
+ public void debug(String msg) {
+ log.debug(msg);
+ }
+
+
+ /**
+ * Gets whether debugging is enabled
+ *
+ *@return True if enabled
+ */
+ public boolean isDebugEnabled() {
+ return log.isDebugEnabled();
+ }
+
+
+ /**
+ * Prints an exception
+ *
+ *@param e The exception
+ */
+ public void error(Exception e) {
+ log.error(e);
+ }
+}
Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/CommonsLogger.java
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/src/java/org/apache/struts/flow/Constants.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/Constants.java?view=auto&rev=153960
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/Constants.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/Constants.java Tue Feb 15 13:09:29 2005
@@ -0,0 +1,95 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts.flow;
+
+/**
+ * <p>
+ *
+ * Global constants for the Chain of Responsibility Library.</p>
+ */
+public final class Constants {
+
+ // -------------------------------------------------- Context Attribute Keys
+
+ /**
+ * <p>
+ *
+ * The default context attribute under which the forward name for
+ * the current request will be stored.</p>
+ */
+ public final static String FORWARD_NAME_KEY = "forward";
+
+ /**
+ * <p>
+ *
+ * The default context attribute under which the continuation id for
+ * the current request will be stored.</p>
+ */
+ public final static String CONTINUATION_ID_KEY = "contId";
+
+ /**
+ * <p>
+ *
+ * The default context attribute under which the business data for
+ * the current request will be stored.</p>
+ */
+ public final static String BIZ_DATA_KEY = "bizData";
+
+
+ // ----------------------- Context Attribute Keys borrowed from Struts-Chain
+
+ /**
+ * <p>
+ *
+ * The default context attribute under which the <code>Action</code> for
+ * the current request will be stored.</p>
+ */
+ public final static String ACTION_KEY = "action";
+
+ /**
+ * <p>
+ *
+ * The default context attribute under which the <code>ActionConfig</code>
+ * for the current request will be stored.</p>
+ */
+ public final static String ACTION_CONFIG_KEY = "actionConfig";
+
+ /**
+ * <p>
+ *
+ * The default context attribute under which the <code>ActionForm</code>
+ * for the current request will be stored.</p>
+ */
+ public final static String ACTION_FORM_KEY = "actionForm";
+
+ /**
+ * <p>
+ *
+ * The default context attribute under which the <code>ActionServet</code>
+ * for the current application will be stored.</p>
+ */
+ public final static String ACTION_SERVLET_KEY = "actionServlet";
+
+ /**
+ * <p>
+ *
+ * The default context attribute under which the <code>MessageResources</code>
+ * for the current request will be stored.</p>
+ */
+ public final static String MESSAGE_RESOURCES_KEY = "messageResources";
+
+}
+
Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/Constants.java
------------------------------------------------------------------------------
svn:executable = *
Added: 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?view=auto&rev=153960
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/FlowAction.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/FlowAction.java Tue Feb 15 13:09:29 2005
@@ -0,0 +1,271 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts.flow;
+
+import org.apache.struts.flow.core.Argument;
+import org.apache.struts.flow.core.JSContext;
+import org.apache.struts.flow.core.JavaScriptInterpreter;
+
+import java.io.IOException;
+import java.util.*;
+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.apache.struts.action.*;
+
+import org.mozilla.javascript.Scriptable;
+import org.apache.commons.chain.web.servlet.ServletWebContext;
+
+/** Executes scripts and continuations */
+public class FlowAction extends Action {
+
+ /**
+ * Gets the interpreter when no script is specified
+ *
+ *@return The interpreter value
+ */
+ protected JavaScriptInterpreter getInterpreter() {
+ return (JavaScriptInterpreter) servlet.getServletContext().getAttribute(FlowPlugIn.INTERPRETER_KEY);
+ }
+
+ /**
+ * Gets the interpreter for the requested script
+ *
+ *@param script The script to load the interpeter for
+ *@return The interpreter value
+ */
+ protected JavaScriptInterpreter getInterpreter(String script) {
+ Map map = (Map)servlet.getServletContext().getAttribute(FlowPlugIn.INTERPRETERS_KEY);
+ return (JavaScriptInterpreter) map.get(script);
+ }
+
+
+ /**
+ * Handle by either starting a new Control Flow or continuing an existing
+ * one. The logic is:<br />
+ * - If request contains contid, then continue existing flow.<br />
+ * - Else if the action mapping parameter attribute has the contid, then
+ * continue the existing flow.<br />
+ * - Else start a new flow.<br />
+ * The name of the function to execute for a new flow should be specified
+ * in the <code>function</code> property of the custom action mapping
+ * class, <code>FlowMapping</code>
+ *
+ *@param request the request send by the client to the server
+ *@param response the response send by the server to the client
+ *@param mapping the action mapping
+ *@param form the action form
+ *@return the action forward
+ *@exception Exception If something goes wrong
+ */
+ public ActionForward execute(ActionMapping mapping,
+ ActionForm form,
+ HttpServletRequest request,
+ HttpServletResponse response)
+ throws Exception {
+
+ FlowMapping flowMapping = null;
+ if (mapping instanceof FlowMapping) {
+ flowMapping = (FlowMapping) mapping;
+ } else {
+ throw new ServletException("FlowMapping implementation of ActionMapping required");
+ }
+ // Create and populate a Context for this request
+ ServletWebContext context = new ServletWebContext();
+ context.initialize(servlet.getServletContext(), request, response);
+ context.put(Constants.ACTION_SERVLET_KEY,
+ this.servlet);
+ context.put(Constants.ACTION_CONFIG_KEY,
+ mapping);
+ context.put(Constants.ACTION_FORM_KEY,
+ form);
+ context.put(Constants.MESSAGE_RESOURCES_KEY,
+ getResources(request));
+ context.put(Constants.ACTION_KEY, this);
+
+ String contid = request.getParameter("contid");
+
+ JavaScriptInterpreter interp = null;
+ if (flowMapping.getScript() == null) {
+ interp = getInterpreter();
+ } else {
+ interp = getInterpreter(flowMapping.getScript());
+ }
+
+ String func = flowMapping.getFunction();
+ if (func == null || func.length() == 0) {
+ func = mapping.getParameter();
+ }
+
+ if (contid == null || contid.length() == 0) {
+
+ // --- start a new flow
+
+ List args = new LinkedList();
+
+ if (func == null || func.length() == 0) {
+ throw new ServletException("You must specify a function name to call");
+ } else {
+ // call control script function
+ interp.callFunction(func, args, context);
+
+ // retrieve page, continuation ID, and attributes from chain context
+ String page = (String) JSContext.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 = JSContext.jsobjectToMap(bizdata);
+ }
+ return dispatchToPage(request, response, mapping, page, contid, atts);
+ }
+ } else {
+ // --- continue an existing flow
+
+ // kick off continuation
+ context.put("id", "5");
+ interp.handleContinuation(
+ request.getParameter("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 = JSContext.jsobjectToMap(bizdata);
+ }
+ return dispatchToPage(request, response, mapping, page, contid, atts);
+ }
+ }
+
+
+ /**
+ * Add continuation ID and attributes to request scope, dispatch to page.
+ *
+ *@param request The request
+ *@param response The response
+ *@param page The action forward name
+ *@param contid Continuation ID to be set in request.
+ *@param atts Attributes to be set in request.
+ *@param mapping The action mapping
+ *@return
+ *@throws ServletException
+ *@throws IOException
+ */
+ private ActionForward dispatchToPage(
+ HttpServletRequest request, HttpServletResponse response, ActionMapping mapping,
+ String page, String contid, Map atts)
+ throws ServletException, 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, JSContext.jsobjectToObject(atts.get(attkey)));
+ }
+ }
+
+ ActionForward af = mapping.findForward(page);
+ if (af == null) {
+ af = new ActionForward(page);
+ }
+ return af;
+ }
+ return null;
+ }
+
+
+ // These methods seem necessary as some scripting engines are not able to
+ // access Action's protected methods.
+
+ /**
+ * Saves a token
+ *
+ *@param req The request object
+ */
+ public void saveToken(HttpServletRequest req) {
+ super.saveToken(req);
+ }
+
+
+ /**
+ * Checks to see if the request is cancelled
+ *
+ *@param req The request object
+ *@return True if cancelled
+ */
+ public boolean isCancelled(HttpServletRequest req) {
+ return super.isCancelled(req);
+ }
+
+
+ /**
+ * Checks to see if the token is valid
+ *
+ *@param req The request object
+ *@return True if valid
+ */
+ public boolean isTokenValid(HttpServletRequest req) {
+ return super.isTokenValid(req);
+ }
+
+
+ /**
+ * Resets the token
+ *
+ *@param req The request object
+ */
+ public void resetToken(HttpServletRequest req) {
+ super.resetToken(req);
+ }
+
+
+ /**
+ * Saves the messages to the request
+ *
+ *@param req The request object
+ *@param mes The action messages
+ */
+ public void saveMessages(HttpServletRequest req, ActionMessages mes) {
+ super.saveMessages(req, mes);
+ }
+
+
+ /**
+ * Saves the errors to the request
+ *
+ *@param req The request object
+ *@param errs The action errors
+ */
+ public void saveErrors(HttpServletRequest req, ActionErrors errs) {
+ super.saveErrors(req, errs);
+ }
+
+}
+
Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/FlowAction.java
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/src/java/org/apache/struts/flow/FlowMapping.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/FlowMapping.java?view=auto&rev=153960
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/FlowMapping.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/FlowMapping.java Tue Feb 15 13:09:29 2005
@@ -0,0 +1,74 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts.flow;
+
+import org.apache.struts.action.ActionMapping;
+
+/**
+ * <p>
+ *
+ * The extension of a Struts action mapping adds support for the <code>function</code>
+ * property which contains the JavaScript Flow function to execute.</p>
+ *
+ *@version $Revision: 1.3 $ $Date: 2004/06/14 18:46:34 $
+ */
+
+public class FlowMapping extends ActionMapping {
+
+ private String func;
+ private String script;
+
+
+ /**
+ * Returns the value of script.
+ *
+ *@return The script value
+ */
+ public String getScript() {
+ return script;
+ }
+
+
+ /**
+ * Sets the value of script.
+ *
+ *@param script The value to assign script.
+ */
+ public void setScript(String script) {
+ this.script = script;
+ }
+
+
+ /**
+ * Sets the function attribute of the FlowMapping object
+ *
+ *@param f The new function value
+ */
+ public void setFunction(String f) {
+ this.func = f;
+ }
+
+
+ /**
+ * Gets the function attribute of the FlowMapping object
+ *
+ *@return The function value
+ */
+ public String getFunction() {
+ return func;
+ }
+}
+
Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/FlowMapping.java
------------------------------------------------------------------------------
svn:executable = *
Added: 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?view=auto&rev=153960
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/FlowPlugIn.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/FlowPlugIn.java Tue Feb 15 13:09:29 2005
@@ -0,0 +1,243 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts.flow;
+
+import org.apache.struts.flow.core.JavaScriptInterpreter;
+import org.apache.struts.flow.core.Factory;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.*;
+import java.util.ArrayList;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts.action.ActionServlet;
+import org.apache.struts.action.PlugIn;
+import org.apache.struts.config.ModuleConfig;
+
+/**
+ * Initializes the Flow interpreter and loads system and user scripts. There
+ * are two mutually exclusive ways to specify scripts:
+ * <ol>
+ * <li> <code>scripts</code> - A comma-delimited list of scripts to load. All
+ * loaded scripts share the same script scope.</li>
+ * <li> <code>scriptBase</code> - The base path to use when resolving
+ * scripts. Each action mapping then needs to set the <code>script</code>
+ * property for the name of the actual script. The scripts will be looked up
+ * by concatinating the script base with the script name. Each script gets
+ * its own scope.</li>
+ * </ol>
+ * <p>
+ *
+ * Scripts can be located either in the webapp directory, as an absolute path
+ * on the filesystem, or in the classpath like in a jar file. </p> <p>
+ *
+ * The following optional properties can be specified:</p>
+ * <ul>
+ * <li> <code>debugger</code> - Whether to enable the Swing debugger</li>
+ *
+ * <li> <code>reloadScripts</code> - Whether to enable the reloading of
+ * scripts if their contents have been modified. The check for modification
+ * occurs every <code>checkTime</code> interval</li>
+ * <li> <code>checkTime</code> - The interval time in milliseconds between
+ * checking for script modifications, if enabled</li>
+ * <li> <code>timeToLive</code> - The length in milliseconds continuations
+ * will live from when they were last accessed</li>
+ * </ul>
+ *
+ */
+public final class FlowPlugIn implements PlugIn {
+
+ /** Servlet context key flow interpreter is stored under */
+ public final static String INTERPRETER_KEY = "interpreter";
+
+ /** Servlet context key flow interpreters are stored under */
+ public final static String INTERPRETERS_KEY = "interpreters";
+
+ /** Commons Logging instance. */
+ private static Log log = LogFactory.getLog(FlowPlugIn.class);
+
+ private ServletContext context;
+ private String scripts = null;
+ private String scriptBase = null;
+
+ private boolean debugger = false;
+ private boolean reloadScripts;
+ private long checkTime;
+
+ private int ttl;
+
+
+ /**
+ * Gets a comma delimitted list of user scripts.
+ *
+ *@return comma delimited list of user script path names
+ */
+ public String getScripts() {
+ return scripts;
+ }
+
+
+ /**
+ * Sets a comma delimitted list of user scripts.
+ *
+ *@param scripts delimited list of user script path names
+ */
+ public void setScripts(String scripts) {
+ this.scripts = scripts;
+ }
+
+
+ /**
+ * Sets the base path to resolve scripts against
+ *
+ *@param scriptBase The base path
+ */
+ public void setScriptBase(String scriptBase) {
+ this.scriptBase = scriptBase;
+ }
+
+
+ /**
+ * Sets the value of reloadScripts.
+ *
+ *@param reloadScripts The value to assign reloadScripts.
+ */
+ public void setReloadScripts(boolean reloadScripts) {
+ this.reloadScripts = reloadScripts;
+ }
+
+
+ /**
+ * Sets the value of checkTime.
+ *
+ *@param checkTime The value to assign checkTime.
+ */
+ public void setCheckTime(long checkTime) {
+ this.checkTime = checkTime;
+ }
+
+
+ /**
+ * Sets the debugger attribute of the FlowPlugIn object
+ *
+ *@param val The new debugger value
+ */
+ public void setDebugger(boolean val) {
+ debugger = val;
+ }
+
+
+ /**
+ * Sets the timeToLive attribute of the FlowPlugIn object
+ *
+ *@param ttl The new timeToLive value
+ */
+ public void setTimeToLive(int ttl) {
+ this.ttl = ttl;
+ }
+
+
+ /**
+ * Initialize the flow interpreter
+ *
+ *@param servlet The ActionServlet for this web application
+ *@param config The ModuleConfig for our owning module
+ *@exception ServletException if we cannot configure ourselves correctly
+ */
+ public void init(ActionServlet servlet, ModuleConfig config)
+ throws ServletException {
+
+ if ((scripts == null || scripts.length() == 0) && scriptBase == null) {
+ throw new ServletException("No scripts or script base defined");
+ }
+ context = servlet.getServletContext();
+ Factory.setLogger(new CommonsLogger());
+ Factory.getContinuationsManager().setDefaultTimeToLive(ttl);
+
+ if (scripts != null && scripts.length() > 0) {
+ StringTokenizer st = new StringTokenizer(scripts, ",");
+ List streamList = new ArrayList();
+ try {
+ JavaScriptInterpreter interp = createInterpreter();
+ context.setAttribute(INTERPRETER_KEY, interp);
+ while (st.hasMoreTokens()) {
+ String scriptPath = st.nextToken().trim();
+ if (log.isInfoEnabled()) {
+ log.info("Registering script '" + scriptPath + "'");
+ }
+ interp.register(scriptPath);
+ }
+ } catch (Exception ex) {
+ throw new ServletException("Unable to create global JavaScript interpreter", ex);
+ }
+ } else {
+ Map map =
+ new HashMap() {
+ public Object get(Object key) {
+ JavaScriptInterpreter interp = (JavaScriptInterpreter) super.get(key);
+ if (interp == null) {
+ if (log.isDebugEnabled()) {
+ log.debug("Creating interpreter for " + key);
+ }
+ interp = createInterpreter();
+ interp.register(scriptBase + key);
+ put(key, interp);
+ }
+ return interp;
+ }
+ };
+ context.setAttribute(INTERPRETERS_KEY, map);
+ }
+ }
+
+
+ private JavaScriptInterpreter createInterpreter() {
+ JavaScriptInterpreter interp = new JavaScriptInterpreter();
+ interp.setDebugger(debugger);
+ interp.setCheckTime(checkTime);
+ interp.setReloadScripts(reloadScripts);
+ interp.initialize();
+ interp.register("/system.js");
+ interp.register("/struts.js");
+ return interp;
+ }
+
+
+ /**
+ * Release any resources that were allocated at initialization, including
+ * any continuations.
+ */
+ public void destroy() {
+
+ log.info("Finalizing flow plug in");
+ Factory.getContinuationsManager().destroy();
+
+ context.removeAttribute(INTERPRETER_KEY);
+ context.removeAttribute(INTERPRETERS_KEY);
+ scriptBase = null;
+ context = null;
+ scripts = null;
+ }
+
+}
+
Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/FlowPlugIn.java
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/Argument.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/Argument.java?view=auto&rev=153960
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/Argument.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/Argument.java Tue Feb 15 13:09:29 2005
@@ -0,0 +1,65 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts.flow.core;
+
+/** Stores an argument to be passed into the method called for flow execution */
+public class Argument {
+ private String name;
+ private Object value;
+
+
+ /**
+ * Constructor for the Argument object
+ *
+ *@param name The argument name
+ *@param value The argument value
+ */
+ public Argument(String name, Object value) {
+ this.name = name;
+ this.value = value;
+ }
+
+
+ /**
+ * Returns the value of name.
+ *
+ *@return The name value
+ */
+ public String getName() {
+ return name;
+ }
+
+
+ /**
+ * Returns the value of value.
+ *
+ *@return The value value
+ */
+ public Object getValue() {
+ return value;
+ }
+
+
+ /**
+ * Prints the string value of the state
+ *
+ *@return The string state
+ */
+ public String toString() {
+ return name + ": " + value;
+ }
+
+}
Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/Argument.java
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/CompilingInterpreter.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/CompilingInterpreter.java?view=auto&rev=153960
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/CompilingInterpreter.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/CompilingInterpreter.java Tue Feb 15 13:09:29 2005
@@ -0,0 +1,137 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts.flow.core;
+
+import java.io.*;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.Script;
+import org.mozilla.javascript.Scriptable;
+
+/**
+ * This is a base class for all interpreters compiling the scripts
+ *
+ *@author <a href="mailto:ovidiu@apache.org">Ovidiu Predescu</a>
+ *@author <a href="mailto:crafterm@apache.org">Marcus Crafter</a>
+ *@author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
+ *@version CVS $Id: CompilingInterpreter.java,v 1.2 2004/06/02 21:56:54 mrdon
+ * Exp $
+ */
+public abstract class CompilingInterpreter {
+
+ /**
+ * Mapping of String objects (absolute script paths) to ScriptSourceEntry's
+ */
+ protected Map compiledScripts = new HashMap();
+
+
+ /**
+ * TODO - This is a little bit strange, the interpreter calls get Script on
+ * the ScriptSourceEntry which in turn calls reallyCompileScript on the
+ * interpreter. I think we need more refactoring here.
+ *
+ *@param context The script context
+ *@param source The script file
+ *@return A compiled script object
+ *@exception IOException If anything goes wrong
+ */
+ protected abstract Script compileScript(Context context,
+ File source) throws IOException;
+
+
+ /**
+ * Compiles the script
+ *
+ *@param context The script context
+ *@param source The script file
+ *@return The compiled script object
+ *@exception IOException If anything goes wrong
+ */
+ protected abstract Script reallyCompileScript(Context context,
+ File source) throws IOException;
+
+
+ /**
+ * An association between the script source and the compiled Script. This
+ * class also calles the parent class to perform compilation lazily
+ */
+ protected class ScriptSourceEntry {
+ private final File source;
+ private Script script;
+ private long compileTime;
+
+
+ /**
+ * Constructor for the ScriptSourceEntry object
+ *
+ *@param source Script source file
+ */
+ public ScriptSourceEntry(File source) {
+ this.source = source;
+ }
+
+
+ /**
+ * Constructor for the ScriptSourceEntry object
+ *
+ *@param source Script source file
+ *@param script Compiled script
+ *@param t Compile time in milliseconds
+ */
+ public ScriptSourceEntry(File source, Script script, long t) {
+ this.source = source;
+ this.script = script;
+ this.compileTime = t;
+ }
+
+
+ /**
+ * Gets the script source
+ *
+ *@return The source value
+ */
+ public File getSource() {
+ return source;
+ }
+
+
+ /**
+ * Gets the compiled script. The source is compiled if it hasn't been
+ * already.
+ *
+ *@param context The script context
+ *@param scope The script scope
+ *@param refresh Whether to check to see if script needs to be
+ * reloaded by looking at the lastModified property
+ *@param interpreter The compiling interpreter
+ *@return The script value
+ *@exception IOException If anything goes wrong
+ */
+ public Script getScript(Context context, Scriptable scope,
+ boolean refresh, CompilingInterpreter interpreter)
+ throws IOException {
+ if (script == null || (compileTime < source.lastModified() && refresh)) {
+ script = interpreter.reallyCompileScript(context, source);
+ compileTime = source.lastModified();
+ }
+ return script;
+ }
+ }
+
+}
+
Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/CompilingInterpreter.java
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/ContinuationsDisposer.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/ContinuationsDisposer.java?view=auto&rev=153960
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/ContinuationsDisposer.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/ContinuationsDisposer.java Tue Feb 15 13:09:29 2005
@@ -0,0 +1,39 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts.flow.core;
+
+/**
+ * ContinuationsDisposer declares the contract for the clean-up of specfic
+ * continuations.
+ * <p>
+ * Typically an Interpreter implementation that produces continuation
+ * objects which require proper clean up will implement this interface to get
+ * a call-back in the event of the ContinuationsManager deciding to invalidate
+ * a WebContinuation.
+ */
+public interface ContinuationsDisposer {
+ /**
+ * Disposes the passed continuation object.
+ * <p>
+ * This method is called from the ContinuationsManager in the event of
+ * the invalidation of a continuation upon the {@link ContinuationsDisposer}
+ * object passed during the creation of the WebContinuation.
+ *
+ * @param webContinuation the {@link WebContinuation} value representing the
+ * continuation object.
+ */
+ public void disposeContinuation(WebContinuation webContinuation);
+}
Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/ContinuationsDisposer.java
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/ContinuationsManager.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/ContinuationsManager.java?view=auto&rev=153960
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/ContinuationsManager.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/ContinuationsManager.java Tue Feb 15 13:09:29 2005
@@ -0,0 +1,96 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts.flow.core;
+
+/**
+ * The interface of the Continuations manager. The continuation manager
+ * maintains a forrest of {@link WebContinuation} trees. Each tree defines the
+ * flow of control for a user within the application. A <code>WebContinuation</code>
+ * is created for a continuation object from the scripting language used. A
+ * continuation object in the implementation of the scripting language is an
+ * opaque object here. It is only stored inside the <code>WebContinuation</code>
+ * , without being interpreted in any way.
+ *
+ *@author <a href="mailto:ovidiu@cup.hp.com">Ovidiu Predescu</a>
+ *@since March 19, 2002
+ *@see WebContinuation
+ *@version CVS $Id: ContinuationsManager.java,v 1.3 2004/06/02 21:56:54 mrdon
+ * Exp $
+ */
+public interface ContinuationsManager {
+
+ /**
+ * Create a <code>WebContinuation</code> object given a native continuation
+ * object and its parent. If the parent continuation is null, the <code>WebContinuation</code>
+ * returned becomes the root of a tree in the forrest.
+ *
+ *@param kont an <code>Object</code> value
+ *@param parentKont a <code>WebContinuation</code> value
+ *@param timeToLive an <code>int</code> value indicating how long in
+ * seconds this continuation will live in the server if not accessed
+ *@param disposer a <code>ContinuationsDisposer</code> instance to
+ * called when the continuation gets cleaned up.
+ *@return a <code>WebContinuation</code> value
+ *@see WebContinuation
+ */
+ public WebContinuation createWebContinuation(Object kont,
+ WebContinuation parentKont,
+ int timeToLive,
+ ContinuationsDisposer disposer);
+
+
+ /**
+ * Invalidates a <code>WebContinuation</code>. This effectively means that
+ * the continuation object associated with it will no longer be accessible
+ * from Web pages. Invalidating a <code>WebContinuation</code> invalidates
+ * all the <code>WebContinuation</code>s which are children of it.
+ *
+ *@param k a <code>WebContinuation</code> value
+ */
+ public void invalidateWebContinuation(WebContinuation k);
+
+
+ /**
+ * Given a <code>WebContinuation</code> id, retrieve the associated <code>WebContinuation</code>
+ * object.
+ *
+ *@param id a <code>String</code> value
+ *@return a <code>WebContinuation</code> object, or null if no such
+ * <code>WebContinuation</code> could be found.
+ */
+ public WebContinuation lookupWebContinuation(String id);
+
+
+ /**
+ * Prints debug information about all web continuations into the log file.
+ *
+ *@see WebContinuation#display()
+ */
+ public void displayAllContinuations();
+
+
+ /**
+ * Set the default time to live value
+ *
+ *@param ttl The time-to-live in milliseconds
+ */
+ public void setDefaultTimeToLive(int ttl);
+
+
+ /** Destroys all continuations and any other resident objects */
+ public void destroy();
+}
+
Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/ContinuationsManager.java
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/ContinuationsManagerImpl.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/ContinuationsManagerImpl.java?view=auto&rev=153960
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/ContinuationsManagerImpl.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/ContinuationsManagerImpl.java Tue Feb 15 13:09:29 2005
@@ -0,0 +1,407 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts.flow.core;
+
+import java.security.SecureRandom;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/**
+ * The default implementation of {@link ContinuationsManager}.
+ *
+ *@author <a href="mailto:ovidiu@cup.hp.com">Ovidiu Predescu</a>
+ *@author <a href="mailto:Michael.Melhem@managesoft.com">Michael Melhem</a>
+ *@since March 19, 2002
+ *@see ContinuationsManager
+ *@version CVS $Id: ContinuationsManagerImpl.java,v 1.3 2004/06/02 21:56:54
+ * mrdon Exp $
+ */
+public class ContinuationsManagerImpl
+ implements ContinuationsManager {
+
+ private final static int CONTINUATION_ID_LENGTH = 20;
+
+ /** Random object for creating continuation ids */
+ protected SecureRandom random = null;
+
+ /**
+ * How long a continuation exists in memory since the last access. The
+ * time is in miliseconds, and the default is 1 hour.
+ */
+ protected int defaultTimeToLive = 1 * 60 * 60 * 1000;
+
+ /** Maintains the forrest of <code>WebContinuation</code> trees. */
+ protected Set forrest = Collections.synchronizedSet(new HashSet());
+
+ /**
+ * Association between <code>WebContinuation</code> ids and the
+ * corresponding <code>WebContinuation</code> object.
+ */
+ protected Map idToWebCont = Collections.synchronizedMap(new HashMap());
+
+ /**
+ * Sorted set of <code>WebContinuation</code> instances, based on their
+ * expiration time. This is used by the background thread to invalidate
+ * continuations.
+ */
+ protected SortedSet expirations = Collections.synchronizedSortedSet(new TreeSet());
+
+ private Thread expireThread;
+
+ /**
+ * Gets the logger
+ *
+ *@return The logger value
+ */
+ public Logger getLogger() {
+ return Factory.getLogger();
+ }
+
+
+ /**
+ * Constructor for the ContinuationsManagerImpl object. Initializes the random
+ * seed for continuation ids and starts the expiration thread.
+ *
+ *@exception Exception If anything goes wrong
+ */
+ public ContinuationsManagerImpl() throws Exception {
+ try {
+ random = SecureRandom.getInstance("SHA1PRNG");
+ } catch (java.security.NoSuchAlgorithmException nsae) {
+ // maybe we are on IBM's SDK
+ random = SecureRandom.getInstance("IBMSecureRandom");
+ }
+ random.setSeed(System.currentTimeMillis());
+ expireThread = new Thread(
+ new Runnable() {
+ public void run() {
+ boolean shouldKeepRunning = true;
+ while (shouldKeepRunning) {
+ try {
+ Thread.sleep(60 * 1000);
+ } catch (InterruptedException ex) {
+ getLogger().debug("Continuation expiration thread interrupted");
+ shouldKeepRunning = false;
+ }
+ if (shouldKeepRunning) {
+ expireContinuations();
+ }
+ }
+ }
+ });
+
+ getLogger().debug("Starting continuation expiration thread");
+ expireThread.setName("Flow continuations expiration thread");
+ expireThread.setPriority(Thread.MIN_PRIORITY);
+ expireThread.start();
+ }
+
+
+ /**
+ * Set the default time to live value
+ *
+ *@param ttl The time-to-live in milliseconds
+ */
+ public void setDefaultTimeToLive(int ttl) {
+ this.defaultTimeToLive = ttl;
+ }
+
+
+ /**
+ * Create a <code>WebContinuation</code> object given a native continuation
+ * object and its parent. If the parent continuation is null, the <code>WebContinuation</code>
+ * returned becomes the root of a tree in the forrest.
+ *
+ *@param kont an <code>Object</code> value
+ *@param parent a <code>WebContinuation</code> value
+ *@param timeToLive an <code>int</code> value indicating how long in
+ * seconds this continuation will live in the server if not accessed
+ *@param disposer a <code>ContinuationsDisposer</code> instance to
+ * called when the continuation gets cleaned up.
+ *@return a <code>WebContinuation</code> value
+ *@see WebContinuation
+ */
+ public WebContinuation createWebContinuation(Object kont,
+ WebContinuation parent,
+ int timeToLive,
+ ContinuationsDisposer disposer) {
+ int ttl = (timeToLive == 0 ? defaultTimeToLive : timeToLive);
+
+ WebContinuation wk = generateContinuation(kont, parent, ttl, disposer);
+
+ if (parent == null) {
+ forrest.add(wk);
+ }
+
+ // REVISIT: This Places only the "leaf" nodes in the expirations Sorted Set.
+ // do we really want to do this?
+ if (parent != null) {
+ if (wk.getParentContinuation().getChildren().size() < 2) {
+ expirations.remove(wk.getParentContinuation());
+ }
+ }
+
+ expirations.add(wk);
+
+ // No need to add the WebContinuation in idToWebCont as it was
+ // already done during its construction.
+
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("WK: Just Created New Continuation " + wk.getId());
+ }
+
+ return wk;
+ }
+
+
+ /**
+ * Invalidates a <code>WebContinuation</code>. This effectively means that
+ * the continuation object associated with it will no longer be accessible
+ * from Web pages. Invalidating a <code>WebContinuation</code> invalidates
+ * all the <code>WebContinuation</code>s which are children of it.
+ *
+ *@param wk a <code>WebContinuation</code> value
+ */
+ public void invalidateWebContinuation(WebContinuation wk) {
+ WebContinuation parent = wk.getParentContinuation();
+ if (parent == null) {
+ forrest.remove(wk);
+ } else {
+ List parentKids = parent.getChildren();
+ parentKids.remove(wk);
+ }
+
+ _invalidate(wk);
+ }
+
+
+ private void _invalidate(WebContinuation wk) {
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("WK: Manual Expire of Continuation " + wk.getId());
+ }
+ disposeContinuation(wk);
+ expirations.remove(wk);
+
+ // Invalidate all the children continuations as well
+ List children = wk.getChildren();
+ int size = children.size();
+ for (int i = 0; i < size; i++) {
+ _invalidate((WebContinuation) children.get(i));
+ }
+ }
+
+
+ /**
+ * Makes the continuation inaccessible for lookup, and triggers possible
+ * needed cleanup code through the ContinuationsDisposer interface.
+ *
+ *@param wk the continuation to dispose.
+ */
+ private void disposeContinuation(WebContinuation wk) {
+ idToWebCont.remove(wk.getId());
+
+ // Call specific possible implementation-specific clean-up on this continuation.
+ ContinuationsDisposer disposer = wk.getDisposer();
+ if (disposer != null) {
+ disposer.disposeContinuation(wk);
+ }
+ }
+
+
+ /**
+ * Given a <code>WebContinuation</code> id, retrieve the associated <code>WebContinuation</code>
+ * object.
+ *
+ *@param id a <code>String</code> value
+ *@return a <code>WebContinuation</code> object, or null if no such
+ * <code>WebContinuation</code> could be found.
+ */
+ public WebContinuation lookupWebContinuation(String id) {
+ // REVISIT: Is the folliwing check needed to avoid threading issues:
+ // return wk only if !(wk.hasExpired) ?
+ return (WebContinuation) idToWebCont.get(id);
+ }
+
+
+ /**
+ * Create <code>WebContinuation</code> and generate unique identifier for
+ * it. The identifier is generated using a cryptographically strong
+ * algorithm to prevent people to generate their own identifiers. <p>
+ *
+ * It has the side effect of interning the continuation object in the
+ * <code>idToWebCont</code> hash table.
+ *
+ *@param kont an <code>Object</code> value representing continuation
+ *@param parent value representing parent <code>WebContinuation</code>
+ *@param ttl <code>WebContinuation</code> time to live
+ *@param disposer <code>ContinuationsDisposer</code> instance to use for
+ * cleanup of the continuation.
+ *@return the generated <code>WebContinuation</code> with unique
+ * identifier
+ */
+ private WebContinuation generateContinuation(Object kont,
+ WebContinuation parent,
+ int ttl,
+ ContinuationsDisposer disposer) {
+
+ byte[] bytes = new byte[CONTINUATION_ID_LENGTH];
+ char[] result = new char[bytes.length * 2];
+ WebContinuation wk = null;
+
+ while (true) {
+ random.nextBytes(bytes);
+
+ for (int i = 0; i < CONTINUATION_ID_LENGTH; i++) {
+ byte ch = bytes[i];
+ result[2 * i] = Character.forDigit(Math.abs(ch >> 4), 16);
+ result[2 * i + 1] = Character.forDigit(Math.abs(ch & 0x0f), 16);
+ }
+
+ String id = new String(result);
+ synchronized (idToWebCont) {
+ if (!idToWebCont.containsKey(id)) {
+ wk = new WebContinuation(id, kont, parent, ttl, disposer);
+ idToWebCont.put(id, wk);
+ break;
+ }
+ }
+ }
+
+ return wk;
+ }
+
+
+ /**
+ * Removes an expired leaf <code>WebContinuation</code> node from its
+ * continuation tree, and recursively removes its parent(s) if it they have
+ * expired and have no (other) children.
+ *
+ *@param wk <code>WebContinuation</code> node
+ */
+ private void removeContinuation(WebContinuation wk) {
+ if (wk.getChildren().size() != 0) {
+ return;
+ }
+
+ // remove access to this contination
+ disposeContinuation(wk);
+
+ WebContinuation parent = wk.getParentContinuation();
+ if (parent == null) {
+ forrest.remove(wk);
+ } else {
+ List parentKids = parent.getChildren();
+ parentKids.remove(wk);
+ }
+
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("WK: deleted this WK: " + wk.getId());
+ }
+
+ // now check if parent needs to be removed.
+ if (null != parent && parent.hasExpired()) {
+ removeContinuation(parent);
+ }
+ }
+
+
+ /**
+ * Dump to Log file the current contents of the expirations <code>SortedSet</code>
+ */
+ private void displayExpireSet() {
+ Iterator iter = expirations.iterator();
+ StringBuffer wkSet = new StringBuffer("\nWK; Expire Set Size: " + expirations.size());
+ while (iter.hasNext()) {
+ final WebContinuation wk = (WebContinuation) iter.next();
+ final long lat = wk.getLastAccessTime() + wk.getTimeToLive();
+ wkSet.append("\nWK: ")
+ .append(wk.getId())
+ .append(" ExpireTime [");
+
+ if (lat < System.currentTimeMillis()) {
+ wkSet.append("Expired");
+ } else {
+ wkSet.append(lat);
+ }
+ wkSet.append("]");
+ }
+
+ getLogger().debug(wkSet.toString());
+ }
+
+
+ /**
+ * Dump to Log file all <code>WebContinuation</code>s in the system
+ */
+ public void displayAllContinuations() {
+ Iterator iter = forrest.iterator();
+ while (iter.hasNext()) {
+ ((WebContinuation) iter.next()).display();
+ }
+ }
+
+
+ /** Destroys all continuations and any other resident objects */
+ public void destroy() {
+ expirations.clear();
+ Set clone = new HashSet(forrest);
+ for (Iterator i = clone.iterator(); i.hasNext(); ) {
+ removeContinuation((WebContinuation) i.next());
+ }
+
+ if (expireThread != null && expireThread.isAlive()) {
+ expireThread.interrupt();
+ }
+ }
+
+
+ /** Remove all continuations which have already expired */
+ private void expireContinuations() {
+ // log state before continuations clean up
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("WK: Forrest size: " + forrest.size());
+ displayAllContinuations();
+ displayExpireSet();
+ }
+
+ // clean up
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("WK CurrentSystemTime[" + System.currentTimeMillis() +
+ "]: Cleaning up expired Continuations....");
+ }
+ WebContinuation wk;
+ Iterator iter = expirations.iterator();
+ while (iter.hasNext() && ((wk = (WebContinuation) iter.next()).hasExpired())) {
+ iter.remove();
+ this.removeContinuation(wk);
+ }
+
+ // log state after continuations clean up
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("WK: Forrest size: " + forrest.size());
+ displayAllContinuations();
+ displayExpireSet();
+ }
+ }
+}
+
Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/ContinuationsManagerImpl.java
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/Factory.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/Factory.java?view=auto&rev=153960
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/Factory.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/Factory.java Tue Feb 15 13:09:29 2005
@@ -0,0 +1,65 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts.flow.core;
+
+/**
+ * Simple static factory for getting interface implementations. Should be
+ * replaced later by something more pluggable.
+ *
+ *@author <a href="mailto:davjon@sas.com">David M Johnson</a>
+ */
+public class Factory {
+
+ private static Logger logger = new Logger();
+ private static ContinuationsManager continuationsManager = null;
+
+ /**
+ * Sets the logger
+ *
+ *@param log The new logger value
+ */
+ public static void setLogger(Logger log) {
+ logger = log;
+ }
+
+
+ /**
+ * Gets the logger
+ *
+ *@return The logger value
+ */
+ public static Logger getLogger() {
+ return logger;
+ }
+
+
+ /**
+ * Gets the continuationsManager
+ *
+ *@return The continuationsManager value
+ */
+ public static ContinuationsManager getContinuationsManager() {
+ if (continuationsManager == null) {
+ try {
+ continuationsManager = new ContinuationsManagerImpl();
+ } catch (Exception e) {
+ throw new RuntimeException("ERROR initializing ContinationsManager", e);
+ }
+ }
+ return continuationsManager;
+ }
+}
+
Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/Factory.java
------------------------------------------------------------------------------
svn:executable = *
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org