You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by ra...@apache.org on 2005/10/15 04:41:25 UTC
svn commit: r321280 - in /jakarta/commons/sandbox/scxml/trunk: ./ xdocs/
xdocs/usecases/ xdocs/usecases/shale-dialogs/
Author: rahul
Date: Fri Oct 14 19:41:20 2005
New Revision: 321280
URL: http://svn.apache.org/viewcvs?rev=321280&view=rev
Log:
The second illustrated usecase for Commons SCXML is Shale dialogs.
The content in this commit is just a port of:
http://people.apache.org/~rahul/scxml-in-shale/
*time sensitive URL*
with some changes based on comments from Craig on dev@struts.
Added:
jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/scxml-in-shale-dialogs.xml (with props)
jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/
jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/SCXMLDialogNavigationHandler.java (with props)
jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/SCXMLDialogNavigationHandler.java.txt (with props)
jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/dialog-config.xml (with props)
jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/dialogstate2view.xml (with props)
jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/edit-profile-config.xml (with props)
jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/log-on-config.xml (with props)
Modified:
jakarta/commons/sandbox/scxml/trunk/project.properties
jakarta/commons/sandbox/scxml/trunk/xdocs/navigation.xml
jakarta/commons/sandbox/scxml/trunk/xdocs/usecases.xml
Modified: jakarta/commons/sandbox/scxml/trunk/project.properties
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/scxml/trunk/project.properties?rev=321280&r1=321279&r2=321280&view=diff
==============================================================================
--- jakarta/commons/sandbox/scxml/trunk/project.properties (original)
+++ jakarta/commons/sandbox/scxml/trunk/project.properties Fri Oct 14 19:41:20 2005
@@ -18,7 +18,7 @@
maven.xdoc.version=${pom.currentVersion}
maven.xdoc.developmentProcessUrl=http://jakarta.apache.org/commons/charter.html
maven.xdoc.includeProjectDocumentation=yes
-maven.xdoc.xml.copy=usecases/rdc-group/*.xml
+maven.xdoc.xml.copy=usecases/rdc-group/*.xml,usecases/shale-dialogs/*.xml
maven.javadoc.links=http://java.sun.com/j2se/1.4.2/docs/api/
Modified: jakarta/commons/sandbox/scxml/trunk/xdocs/navigation.xml
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/scxml/trunk/xdocs/navigation.xml?rev=321280&r1=321279&r2=321280&view=diff
==============================================================================
--- jakarta/commons/sandbox/scxml/trunk/xdocs/navigation.xml (original)
+++ jakarta/commons/sandbox/scxml/trunk/xdocs/navigation.xml Fri Oct 14 19:41:20 2005
@@ -27,6 +27,9 @@
<item name="SCXML in RDC group container"
href="/usecases/scxml-in-rdc-group.html" />
+ <item name="SCXML in Shale dialogs"
+ href="/usecases/scxml-in-shale-dialogs.html" />
+
</item>
</menu>
Modified: jakarta/commons/sandbox/scxml/trunk/xdocs/usecases.xml
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/scxml/trunk/xdocs/usecases.xml?rev=321280&r1=321279&r2=321280&view=diff
==============================================================================
--- jakarta/commons/sandbox/scxml/trunk/xdocs/usecases.xml (original)
+++ jakarta/commons/sandbox/scxml/trunk/xdocs/usecases.xml Fri Oct 14 19:41:20 2005
@@ -49,6 +49,8 @@
<a href="http://jakarta.apache.org/taglibs/doc/rdc-doc/intro.html">
Reusable Dialog Components (RDC) Framework</a> <group>
container.</li>
+ <li><a href="usecases/scxml-in-shale-dialogs.html">Usecase 2</a> -
+ Use in <a href="http://struts.apache.org/shale">Shale</a> dialogs</li>
</ul>
</p>
<br/>
Added: jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/scxml-in-shale-dialogs.xml
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/scxml-in-shale-dialogs.xml?rev=321280&view=auto
==============================================================================
--- jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/scxml-in-shale-dialogs.xml (added)
+++ jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/scxml-in-shale-dialogs.xml Fri Oct 14 19:41:20 2005
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2003-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.
+-->
+
+<document>
+
+ <properties>
+ <title>Commons SCXML Usecases - Shale dialogs</title>
+ <author email="commons-dev@jakarta.apache.org">Commons Documentation Team</author>
+ </properties>
+
+ <body>
+
+ <section name="SCXML documents to describe Shale dialogs">
+
+ <p><a href="http://struts.apache.org/shale">Shale</a> is
+ "<i>a proposal for a modern web application framework, fundamentaly
+ based on JavaServer Faces</i>". The Shale Framework includes a Dialog
+ Manager, to describe "conversations" or "dialogs"
+ (involving multiple views) with the user. Such a dialog is described
+ using a state-machine like declarative notation defined by the Shale
+ Framework. An alternative is using SCXML to describe the Shale dialogs
+ by introducing a <code>DialogNavigationHandler</code> that uses the
+ Commons SCXML engine.
+ </p>
+
+ <subsection name="Motivation">
+ <ul>
+ <li>SCXML semantics support parallelism, allowing multiple dialogs
+ to execute at the same time (a.k.a regions), and interact with each
+ other. This will be useful as Shale Dialog Managers evolve.</li>
+ <li>The Commons SCXML implementation allows for registering listeners
+ that get notified as the state machine executes (onentry, onexit,
+ ontransition).</li>
+ <li>Those developing multi-channel applications, or using frameworks
+ that use SCXML for the controller bits in other contexts (e.g.
+ RDC framework), may be inclined towards SCXML-based authoring for Shale
+ dialogs.</li>
+ </ul>
+ </subsection>
+
+ <subsection name="Proof of concept">
+ <p>There are two war files below, the first one uses SCXML
+ documents to describe the Shale dialogs, and the second
+ one is the Shale source distro as-is, built locally
+ (use cases of interest are the log on / create profile dialogs).
+ <ul>
+ <!--
+ The next two links point to my personal web space since I
+ was not too keen on polluting the Commons SCXML space in SVN
+ with usecases war files.
+ -->
+ <li><a href="http://people.apache.org/~rahul/scxml-in-shale/struts-shale-usecases-scxml.war">
+ struts-shale-usecases-scxml.war</a>
+ - Shale usecases war file with SCXML dialogs (note absence of
+ <code>dialog-config.xml</code> in <code>WEB-INF/</code>, since
+ SCXML documents are used to describe the Shale dialogs instead)</li>
+ <li><a href="http://people.apache.org/~rahul/scxml-in-shale/struts-shale-usecases.war">
+ struts-shale-usecases.war</a>
+ - Shale usecases war file (09/28/05 snapshot, not an official
+ nightly build)</li>
+ </ul>
+ </p>
+ </subsection>
+
+ <subsection name="Building">
+ <p>For the proof of concept, we delegate the SCXML documents based
+ Shale Dialog Management to a
+ "<code>SCXMLDialogNavigationHandler</code>", instead of
+ the <code>DialogNavigationHandler</code> in <code>shale-core</code>.
+ </p>
+
+ <p>Some of the Javadoc is reproduced here:</p>
+
+ <p>Recipe for using SCXML documents to drive Shale dialogs:
+ <ol>
+ <li>Build the <code>SCXMLDialogNavigationHandler</code> (available
+ below, use a Commons SCXML nightly build 10/09/05 or later) and make it
+ available to your web application classpath (<code>WEB-INF/classes</code>).
+ </li>
+ <li>Update the "<code>WEB-INF/faces-config.xml</code>"
+ for your web application such that the
+ "<code>faces-config/application/navigation-handler</code>"
+ entry points to
+ "<code>org.apache.commons.scxml.usecases.SCXMLDialogNavigationHandler</code>"
+ (with the appropriate package name, if you changed it).
+ </li>
+ <li>As an alternative to (1) and (2), you can place a <i>jar</i> in the
+ <code>WEB-INF/lib</code> directory which contains the
+ <code>SCXMLDialogNavigationHandler</code> and a
+ <code>META-INF/faces-config.xml</code> with just the entry in (2).</li>
+ <li>Use SCXML documents to describe Shale dialog flows (details below)
+ in your application. You may have multiple mappings from transition
+ targets to JSF views to support multi-channel applications.</li>
+ <li>The SCXML-based dialog is entered when
+ <code>handleNavigation()</code> is called with a logical outcome
+ of the form "<code>dialog:xxx</code>" and there is no current
+ dialog in progress, where "<code>xxx</code>" is the URL pointing
+ to the SCXML document.</li>
+ </ol>
+ </p>
+
+ <p>Using SCXML documents to define the Shale dialog "flows":
+ <ul>
+ <li>ActionState instances may be mapped to executable content
+ in UML <code><onentry></code> (and may be chained similarly).</li>
+ <li>ViewState instances may be mapped to UML transition
+ targets.</li>
+ <li>SubdialogState instances may be mapped to external SCXML
+ documents.</li>
+ <li>EndState instances may be mapped to SCXML final states.</li>
+ <li>The SCXMLDialogNavigationHandler defines a
+ <code>"faces.outcome"</code> event which the relevant SCXML
+ transitions from a "view state" can wait for.</li>
+ </ul>
+ </p>
+ </subsection>
+
+ <subsection name="Artifacts">
+ <p>Relevant artifacts:
+ <ol>
+ <li><a href="shale-dialogs/SCXMLDialogNavigationHandler.java">
+ SCXMLDialogNavigationHandler.java</a></li>
+ <li><a href="shale-dialogs/SCXMLDialogNavigationHandler.java.txt">
+ SCXMLDialogNavigationHandler.java.txt</a>
+ (for browsers that insist of enforcing mime-type by filename
+ extension)</li>
+ <li><a href="shale-dialogs/dialog-config.xml">dialog-config.xml</a>
+ (from Shale distro, 09/28/05 snapshot)</li>
+ <li><a href="shale-dialogs/log-on-config.xml">log-on-config.xml</a>
+ (SCXML document describing the "Log On" dialog)</li>
+ <li><a href="shale-dialogs/edit-profile-config.xml">
+ edit-profile-config.xml</a> (SCXML document describing
+ the "Edit Profile" dialog)</li>
+ <li><a href="shale-dialogs/dialogstate2view.xml">dialogstate2view.xml</a>
+ (Map UML states and activities)</li>
+ </ol>
+ </p>
+ </subsection>
+
+ </section>
+
+ </body>
+
+</document>
Propchange: jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/scxml-in-shale-dialogs.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/scxml-in-shale-dialogs.xml
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/SCXMLDialogNavigationHandler.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/SCXMLDialogNavigationHandler.java?rev=321280&view=auto
==============================================================================
--- jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/SCXMLDialogNavigationHandler.java (added)
+++ jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/SCXMLDialogNavigationHandler.java Fri Oct 14 19:41:20 2005
@@ -0,0 +1,509 @@
+/*
+ * Copyright 2004-2005 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.
+ */
+/*
+ * You may build in a package on your choice. Dependency information:
+ *
+ * Commons SCXML dependencies -
+ * http://jakarta.apache.org/commons/sandbox/scxml/dependencies.html
+ *
+ * Struts Shale dependencies -
+ * http://struts.apache.org/shale/
+ * (Currently under "Foundations" section)
+ */
+package org.apache.commons.scxml.usecases;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import javax.faces.application.NavigationHandler;
+import javax.faces.application.ViewHandler;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.FacesContext;
+
+import org.apache.commons.digester.Digester;
+import org.apache.commons.digester.Rule;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.commons.scxml.SCXMLDigester;
+import org.apache.commons.scxml.SCXMLExecutor;
+import org.apache.commons.scxml.TriggerEvent;
+import org.apache.commons.scxml.env.SimpleDispatcher;
+import org.apache.commons.scxml.env.SimpleErrorHandler;
+import org.apache.commons.scxml.env.SimpleErrorReporter;
+import org.apache.commons.scxml.env.SimpleSCXMLListener;
+import org.apache.commons.scxml.env.faces.SessionContext;
+import org.apache.commons.scxml.env.faces.ShaleDialogELEvaluator;
+import org.apache.commons.scxml.model.ModelException;
+import org.apache.commons.scxml.model.SCXML;
+import org.apache.commons.scxml.model.TransitionTarget;
+
+import org.apache.shale.dialog.Globals;
+import org.apache.shale.dialog.Status;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+
+/**
+ * <p>SCXML configuration file(s) driven Shale dialog navigation handler.</p>
+ *
+ * <p>Recipe for using SCXML documents to drive Shale dialogs:
+ * <ol>
+ * <li>Build the <code>SCXMLDialogNavigationHandler</code> (available
+ * below, use a Commons SCXML nightly build 10/09/05 or later) and make it
+ * available to your web application classpath (<code>WEB-INF/classes</code>).
+ * </li>
+ * <li>Update the "<code>WEB-INF/faces-config.xml</code>"
+ * for your web application such that the
+ * "<code>faces-config/application/navigation-handler</code>"
+ * entry points to
+ * "<code>org.apache.commons.scxml.usecases.SCXMLDialogNavigationHandler</code>"
+ * (with the appropriate package name, if you changed it).
+ * </li>
+ * <li>As an alternative to (1) and (2), you can place a <i>jar</i> in the
+ * <code>WEB-INF/lib</code> directory which contains the
+ * <code>SCXMLDialogNavigationHandler</code> and a
+ * <code>META-INF/faces-config.xml</code> with just the entry in (2).</li>
+ * <li>Use SCXML documents to describe Shale dialog flows (details below)
+ * in your application. You may have multiple mappings from transition
+ * targets to JSF views to support multi-channel applications.</li>
+ * <li>The SCXML-based dialog is entered when
+ * <code>handleNavigation()</code> is called with a logical outcome
+ * of the form "<code>dialog:xxx</code>" and there is no current
+ * dialog in progress, where "<code>xxx</code>" is the URL pointing
+ * to the SCXML document.</li>
+ * </ol>
+ * </p>
+ *
+ * <p>Using SCXML documents to define the Shale dialog "flows":
+ * <ul>
+ * <li>ActionState instances may be mapped to executable content
+ * in UML <onentry> (and may be chained similarly).</li>
+ * <li>ViewState instances may be mapped to UML transition
+ * targets.</li>
+ * <li>SubdialogState instances may be mapped to external SCXML
+ * documents.</li>
+ * <li>EndState instances may be mapped to SCXML final states.</li>
+ * <li>The {@link SCXMLDialogNavigationHandler} defines a
+ * "faces.outcome" event which the relevant SCXML
+ * transitions from a "view state" can wait for.</li>
+ * </ul>
+ * </p>
+ *
+ * <p>Towards pluggable dialog management in Shale - A "black box"
+ * dialog may consist of the following tuple:
+ * <ul>
+ * <li>Unique dialog identifier</li>
+ * <li>A generic NavigationHandler (i.e. dialog strategy)</li>
+ * <li>An dialog/flow configuration resource (Ex: SCXML document)</li>
+ * <li>Optionally, multiple other configuration resources,
+ * (Ex: one for each channel - web, voice, small device, etc.)</li>
+ * </ul>
+ * The Shale DialogNavigationHandler may then delegate appropriately.
+ * </p>
+ */
+public final class SCXMLDialogNavigationHandler extends NavigationHandler {
+
+ // ------------------------------------------------------------ Constructors
+ /**
+ * <p>Create a new {@link SCXMLDialogNavigationHandler}, wrapping the
+ * specified standard navigation handler implementation.</p>
+ *
+ * @param handler Standard <code>NavigationHandler</code> we are wrapping
+ */
+ public SCXMLDialogNavigationHandler(NavigationHandler handler) {
+
+ this.handler = handler;
+
+ }
+
+ // -------------------------------------------------------- Static Variables
+ /**
+ * <p>The prefix on a logical outcome String that indicates the remainder
+ * of the string is the URL of a SCXML-based Shale dialog to be entered.</p>
+ */
+ public static final String PREFIX = "dialog:";
+
+ // ------------------------------------------------------ Instance Variables
+
+ /**
+ * <p>The standard <code>NavigationHandler</code> implementation that
+ * we are wrapping.</p>
+ */
+ private NavigationHandler handler = null;
+
+ /**
+ * <p>The <code>Log</code> instance for this class.</p>
+ */
+ private final Log log = LogFactory.getLog(getClass());
+
+ /**
+ * <p>Key under which we will store the SCXMLExecutor (more generally,
+ * some session scoped state pertaining to the current dialog).</p>
+ */
+ private String dialogKey = null; // Cached on first use
+
+ /**
+ * <p>Map storing SCXML state IDs as keys and JSF view IDs as values.</p>
+ */
+ private Map target2viewMap = null;
+
+ // ----------------------------------------------- NavigationHandler Methods
+
+ /**
+ * <p>Handle the navigation request implied by the specified parameters.</p>
+ *
+ * @param context <code>FacesContext</code> for the current request
+ * @param fromAction The action binding expression that was evaluated
+ * to retrieve the specified outcome (if any)
+ * @param outcome The logical outcome returned by the specified action
+ *
+ * @exception IllegalArgumentException if the configuration information
+ * for a previously saved position cannot be found
+ * @exception IllegalArgumentException if an unknown State type is found
+ */
+ public void handleNavigation(FacesContext context, String fromAction,
+ String outcome) {
+
+ if (log.isDebugEnabled()) {
+ log.debug("handleNavigation(viewId=" +
+ context.getViewRoot().getViewId() +
+ ",fromAction=" + fromAction +
+ ",outcome=" + outcome + ")");
+ }
+
+ SCXMLExecutor exec = getDialogExecutor(context);
+ String viewId = null;
+
+ if (exec == null && outcome != null && outcome.startsWith(PREFIX)) {
+
+ /**** DIALOG ENTRY ****/
+ // dialog is a state machine, parse & obtain an executor
+ exec = initDialogExecutor(context, outcome.substring(PREFIX.
+ length()));
+
+ if (exec != null) {
+ // cache executor in session scope
+ // TODO: Shale caches Dialog instances. SCXMLExecutor
+ // knows what state(s) the dialog is in, so Dialog#findState()
+ // is not needed.
+ setDialogExecutor(context, exec);
+ // obtain our initial view
+ viewId = getCurrentViewId(exec);
+ }
+ // else delegate
+
+ } else if (exec != null) {
+
+ /**** SUBSEQUENT TURNS OF DIALOG ****/
+ // pass a handle to the current ctx (for evaluating binding exprs)
+ updateEvaluator(context, outcome);
+ // fire a "faces.outcome" event on the dialog's state machine
+ TriggerEvent[] te = { new TriggerEvent("faces.outcome",
+ TriggerEvent.SIGNAL_EVENT) };
+ try {
+ exec.triggerEvents(te);
+ } catch (ModelException me) {
+ log.error(me.getMessage(), me);
+ }
+ // obtain next view
+ viewId = getCurrentViewId(exec);
+ }
+
+ if (viewId != null) {
+
+ // we understood this "outcome" and we have a new view to render
+ log.info("Rendering view: " + viewId);
+ updateDialogStatus(context, exec);
+ render(context, viewId);
+
+ } else {
+
+ /**** DELEGATE BY DEFAULT ****/
+ handler.handleNavigation(context, fromAction, outcome);
+
+ }
+
+
+ }
+
+ /**
+ * <p>Return the SCXMLExecutor for the specified SCXML document, if it
+ * exists; otherwise, return <code>null</code>.</p>
+ *
+ * @param context <code>FacesContext</code> for the current request
+ * @param dialogIdentifier URL of the SCXML document for the requested
+ * dialog
+ */
+ private SCXMLExecutor initDialogExecutor(FacesContext context,
+ String dialogIdentifier) {
+
+ assert context != null;
+ assert dialogIdentifier != null;
+
+ // We're parsing the SCXML dialog just in time here
+ URL scxmlDocument = null;
+ try {
+ scxmlDocument = context.getExternalContext().
+ getResource(dialogIdentifier);
+ } catch (MalformedURLException mue) {
+ log.error(mue.getMessage(), mue);
+ }
+
+ if (scxmlDocument == null) {
+ log.warn("No SCXML document at: " + dialogIdentifier);
+ return null;
+ }
+
+ SCXML scxml = null;
+ ShaleDialogELEvaluator evaluator = new ShaleDialogELEvaluator();
+ evaluator.setFacesContext(context);
+ try {
+ scxml = SCXMLDigester.digest(scxmlDocument,
+ new SimpleErrorHandler(), new SessionContext(context),
+ evaluator);
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ }
+
+ if (scxml == null) {
+ log.warn("Could not parse SCXML document at: " + dialogIdentifier);
+ return null;
+ }
+
+ SCXMLExecutor exec = null;
+ try {
+ exec = new SCXMLExecutor(evaluator, new SimpleDispatcher(),
+ new SimpleErrorReporter());
+ scxml.addListener(new SimpleSCXMLListener());
+ exec.setSuperStep(true);
+ exec.setStateMachine(scxml);
+ } catch (ModelException me) {
+ log.warn(me.getMessage(), me);
+ return null;
+ }
+
+ // read SCXML state IDs to JSF view IDs map, channel dependent
+ readState2ViewMap(context, dialogIdentifier, null);
+
+ // FIXME: Remove dependence on the org.apache.shale.dialog.impl package
+ // below (introduced so we can reuse the existing StatusImpl and the
+ // AbstractFacesBean subtypes in the usecases war for the proof of
+ // concept).
+ // Ignoring STATUS_PARAM since usecases war doesn't use it for the
+ // log on / edit profile dialogs.
+ // TODO: The next line should be Dialog Manager implementation agnostic
+ Status status = new org.apache.shale.dialog.impl.StatusImpl();
+
+ context.getExternalContext().getSessionMap().put(Globals.STATUS, status);
+ status.push(new Status.Position(dialogIdentifier, getCurrentViewId(exec)));
+
+ return exec;
+
+ }
+
+ /**
+ * <p>Set the {@link SCXMLExecutor} instance for the current user.</p>
+ *
+ * @param context <code>FacesContext</code> for the current request
+ * @param exec <code>SCXMLExecutor</code> that will run the dialog
+ */
+ private void setDialogExecutor(FacesContext context, SCXMLExecutor exec) {
+
+ assert context != null;
+ assert exec != null;
+
+ Map map = context.getExternalContext().getSessionMap();
+ String key = getDialogKey(context);
+ assert key != null;
+ map.put(key, exec);
+
+ }
+
+ /**
+ * <p>Return the {@link SCXMLExecutor} instance for the current user.</p>
+ *
+ * @param context <code>FacesContext</code> for the current request
+ */
+ private SCXMLExecutor getDialogExecutor(FacesContext context) {
+
+ assert context != null;
+
+ Map map = context.getExternalContext().getSessionMap();
+ String key = getDialogKey(context);
+ return (SCXMLExecutor) map.get(key);
+
+ }
+
+ /**
+ * Update evaluator with current FacesContext for evaluation of
+ * binding expressions used in Shale dialog.
+ */
+ private void updateEvaluator(FacesContext context, String outcome) {
+
+ assert context != null;
+
+ ((ShaleDialogELEvaluator) getDialogExecutor(context).getEvaluator()).
+ setFacesContext(context);
+ context.getExternalContext().getSessionMap().put("outcome", outcome);
+ }
+
+ /**
+ * Update dialog Status
+ *
+ * @param context The FacesContext
+ * @param exec The SCXMLExecutor
+ */
+ private void updateDialogStatus(FacesContext context, SCXMLExecutor exec) {
+
+ assert context != null;
+ assert exec != null;
+
+ // TODO: Test this
+ Status status = (Status) context.getExternalContext().getSessionMap().
+ get(Globals.STATUS);
+ if (exec.getCurrentStatus().isFinal()) {
+ setDialogExecutor(context, null);
+ status.pop();
+ } else {
+ status.peek().setStateName(getCurrentViewId(exec));
+ }
+ }
+
+ /**
+ * Get next view to render, assuming one view at a time.
+ *
+ * @param currentStates The set of current states
+ * @return String The JSF viewId of the next view
+ */
+ private String getCurrentViewId(SCXMLExecutor exec) {
+
+ assert exec != null;
+
+ Set currentStates = exec.getCurrentStatus().getStates();
+ for (Iterator i = currentStates.iterator(); i.hasNext(); ) {
+ String targetId = ((TransitionTarget) i.next()).getId();
+ if (target2viewMap.containsKey(targetId)) {
+ return (String) target2viewMap.get(targetId);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * <p>Return the session scope attribute key under which we will
+ * store dialog state for the current user. The value
+ * is specified by a context init parameter named by constant
+ * <code>Globals.DIALOG_STATE_PARAM</code>, or defaults to the value
+ * specified by constant <code>Globals.DIALOG_STATE</code>.</p>
+ *
+ * @param context <code>FacesContext</code> for the current request
+ */
+ private String getDialogKey(FacesContext context) {
+
+ assert context != null;
+
+ if (dialogKey == null) {
+ dialogKey =
+ context.getExternalContext().
+ getInitParameter(Globals.DIALOG_STATE_PARAM);
+ if (dialogKey == null) {
+ dialogKey = Globals.DIALOG_STATE;
+ }
+ }
+ return dialogKey;
+
+ }
+
+ /**
+ * <p>Render the view corresponding to the specified view identifier.</p>
+ *
+ * @param context <code>FacesContext</code> for the current request
+ * @param viewId View identifier to be rendered, or <code>null</code>
+ * to rerender the current view
+ */
+ private void render(FacesContext context, String viewId) {
+
+ assert context != null;
+
+ if (log.isDebugEnabled()) {
+ log.debug("render(viewId=" + viewId + ")");
+ }
+
+ // Stay on the same view if requested
+ if (viewId == null) {
+ return;
+ }
+
+ // Create the specified view so that it can be rendered
+ ViewHandler vh = context.getApplication().getViewHandler();
+ UIViewRoot view = vh.createView(context, viewId);
+ view.setViewId(viewId);
+ context.setViewRoot(view);
+
+ }
+
+ /**
+ * FIXME: - Placeholder for SCXML state ID to JSF view ID mapper.
+ * Provides multi-channel aspect to Shale dialog management.
+ *
+ */
+ private void readState2ViewMap(FacesContext context,
+ String dialogIdentifier, String channel) {
+
+ assert context != null;
+
+ String STATE_TO_VIEW_MAP = "/WEB-INF/dialogstate2view.xml";
+ target2viewMap = new HashMap();
+
+ Digester digester = new Digester();
+ digester.clear();
+ digester.setNamespaceAware(false);
+ digester.setUseContextClassLoader(false);
+ digester.setValidating(false);
+ digester.addRule("map/entry", new Rule() {
+ /** SCXML target ID. */
+ private String targetId;
+ /** JSF view ID. */
+ private String viewId;
+ /** {@inheritDoc} */
+ public final void begin(final String namespace, final String name,
+ final Attributes attributes) {
+ targetId = attributes.getValue("targetId");
+ viewId = attributes.getValue("viewId");
+ }
+ /** {@inheritDoc} */
+ public void end(final String namespace, final String name) {
+ target2viewMap.put(targetId, viewId);
+ }
+ });
+
+ try {
+ URL mapURL = context.getExternalContext().getResource(STATE_TO_VIEW_MAP);
+ InputSource source = new InputSource(mapURL.toExternalForm());
+ source.setByteStream(mapURL.openStream());
+ digester.parse(source);
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ }
+ }
+
+}
Propchange: jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/SCXMLDialogNavigationHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/SCXMLDialogNavigationHandler.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/SCXMLDialogNavigationHandler.java.txt
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/SCXMLDialogNavigationHandler.java.txt?rev=321280&view=auto
==============================================================================
--- jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/SCXMLDialogNavigationHandler.java.txt (added)
+++ jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/SCXMLDialogNavigationHandler.java.txt Fri Oct 14 19:41:20 2005
@@ -0,0 +1,509 @@
+/*
+ * Copyright 2004-2005 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.
+ */
+/*
+ * You may build in a package on your choice. Dependency information:
+ *
+ * Commons SCXML dependencies -
+ * http://jakarta.apache.org/commons/sandbox/scxml/dependencies.html
+ *
+ * Struts Shale dependencies -
+ * http://struts.apache.org/shale/
+ * (Currently under "Foundations" section)
+ */
+package org.apache.commons.scxml.usecases;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import javax.faces.application.NavigationHandler;
+import javax.faces.application.ViewHandler;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.FacesContext;
+
+import org.apache.commons.digester.Digester;
+import org.apache.commons.digester.Rule;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.commons.scxml.SCXMLDigester;
+import org.apache.commons.scxml.SCXMLExecutor;
+import org.apache.commons.scxml.TriggerEvent;
+import org.apache.commons.scxml.env.SimpleDispatcher;
+import org.apache.commons.scxml.env.SimpleErrorHandler;
+import org.apache.commons.scxml.env.SimpleErrorReporter;
+import org.apache.commons.scxml.env.SimpleSCXMLListener;
+import org.apache.commons.scxml.env.faces.SessionContext;
+import org.apache.commons.scxml.env.faces.ShaleDialogELEvaluator;
+import org.apache.commons.scxml.model.ModelException;
+import org.apache.commons.scxml.model.SCXML;
+import org.apache.commons.scxml.model.TransitionTarget;
+
+import org.apache.shale.dialog.Globals;
+import org.apache.shale.dialog.Status;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+
+/**
+ * <p>SCXML configuration file(s) driven Shale dialog navigation handler.</p>
+ *
+ * <p>Recipe for using SCXML documents to drive Shale dialogs:
+ * <ol>
+ * <li>Build the <code>SCXMLDialogNavigationHandler</code> (available
+ * below, use a Commons SCXML nightly build 10/09/05 or later) and make it
+ * available to your web application classpath (<code>WEB-INF/classes</code>).
+ * </li>
+ * <li>Update the "<code>WEB-INF/faces-config.xml</code>"
+ * for your web application such that the
+ * "<code>faces-config/application/navigation-handler</code>"
+ * entry points to
+ * "<code>org.apache.commons.scxml.usecases.SCXMLDialogNavigationHandler</code>"
+ * (with the appropriate package name, if you changed it).
+ * </li>
+ * <li>As an alternative to (1) and (2), you can place a <i>jar</i> in the
+ * <code>WEB-INF/lib</code> directory which contains the
+ * <code>SCXMLDialogNavigationHandler</code> and a
+ * <code>META-INF/faces-config.xml</code> with just the entry in (2).</li>
+ * <li>Use SCXML documents to describe Shale dialog flows (details below)
+ * in your application. You may have multiple mappings from transition
+ * targets to JSF views to support multi-channel applications.</li>
+ * <li>The SCXML-based dialog is entered when
+ * <code>handleNavigation()</code> is called with a logical outcome
+ * of the form "<code>dialog:xxx</code>" and there is no current
+ * dialog in progress, where "<code>xxx</code>" is the URL pointing
+ * to the SCXML document.</li>
+ * </ol>
+ * </p>
+ *
+ * <p>Using SCXML documents to define the Shale dialog "flows":
+ * <ul>
+ * <li>ActionState instances may be mapped to executable content
+ * in UML <onentry> (and may be chained similarly).</li>
+ * <li>ViewState instances may be mapped to UML transition
+ * targets.</li>
+ * <li>SubdialogState instances may be mapped to external SCXML
+ * documents.</li>
+ * <li>EndState instances may be mapped to SCXML final states.</li>
+ * <li>The {@link SCXMLDialogNavigationHandler} defines a
+ * "faces.outcome" event which the relevant SCXML
+ * transitions from a "view state" can wait for.</li>
+ * </ul>
+ * </p>
+ *
+ * <p>Towards pluggable dialog management in Shale - A "black box"
+ * dialog may consist of the following tuple:
+ * <ul>
+ * <li>Unique dialog identifier</li>
+ * <li>A generic NavigationHandler (i.e. dialog strategy)</li>
+ * <li>An dialog/flow configuration resource (Ex: SCXML document)</li>
+ * <li>Optionally, multiple other configuration resources,
+ * (Ex: one for each channel - web, voice, small device, etc.)</li>
+ * </ul>
+ * The Shale DialogNavigationHandler may then delegate appropriately.
+ * </p>
+ */
+public final class SCXMLDialogNavigationHandler extends NavigationHandler {
+
+ // ------------------------------------------------------------ Constructors
+ /**
+ * <p>Create a new {@link SCXMLDialogNavigationHandler}, wrapping the
+ * specified standard navigation handler implementation.</p>
+ *
+ * @param handler Standard <code>NavigationHandler</code> we are wrapping
+ */
+ public SCXMLDialogNavigationHandler(NavigationHandler handler) {
+
+ this.handler = handler;
+
+ }
+
+ // -------------------------------------------------------- Static Variables
+ /**
+ * <p>The prefix on a logical outcome String that indicates the remainder
+ * of the string is the URL of a SCXML-based Shale dialog to be entered.</p>
+ */
+ public static final String PREFIX = "dialog:";
+
+ // ------------------------------------------------------ Instance Variables
+
+ /**
+ * <p>The standard <code>NavigationHandler</code> implementation that
+ * we are wrapping.</p>
+ */
+ private NavigationHandler handler = null;
+
+ /**
+ * <p>The <code>Log</code> instance for this class.</p>
+ */
+ private final Log log = LogFactory.getLog(getClass());
+
+ /**
+ * <p>Key under which we will store the SCXMLExecutor (more generally,
+ * some session scoped state pertaining to the current dialog).</p>
+ */
+ private String dialogKey = null; // Cached on first use
+
+ /**
+ * <p>Map storing SCXML state IDs as keys and JSF view IDs as values.</p>
+ */
+ private Map target2viewMap = null;
+
+ // ----------------------------------------------- NavigationHandler Methods
+
+ /**
+ * <p>Handle the navigation request implied by the specified parameters.</p>
+ *
+ * @param context <code>FacesContext</code> for the current request
+ * @param fromAction The action binding expression that was evaluated
+ * to retrieve the specified outcome (if any)
+ * @param outcome The logical outcome returned by the specified action
+ *
+ * @exception IllegalArgumentException if the configuration information
+ * for a previously saved position cannot be found
+ * @exception IllegalArgumentException if an unknown State type is found
+ */
+ public void handleNavigation(FacesContext context, String fromAction,
+ String outcome) {
+
+ if (log.isDebugEnabled()) {
+ log.debug("handleNavigation(viewId=" +
+ context.getViewRoot().getViewId() +
+ ",fromAction=" + fromAction +
+ ",outcome=" + outcome + ")");
+ }
+
+ SCXMLExecutor exec = getDialogExecutor(context);
+ String viewId = null;
+
+ if (exec == null && outcome != null && outcome.startsWith(PREFIX)) {
+
+ /**** DIALOG ENTRY ****/
+ // dialog is a state machine, parse & obtain an executor
+ exec = initDialogExecutor(context, outcome.substring(PREFIX.
+ length()));
+
+ if (exec != null) {
+ // cache executor in session scope
+ // TODO: Shale caches Dialog instances. SCXMLExecutor
+ // knows what state(s) the dialog is in, so Dialog#findState()
+ // is not needed.
+ setDialogExecutor(context, exec);
+ // obtain our initial view
+ viewId = getCurrentViewId(exec);
+ }
+ // else delegate
+
+ } else if (exec != null) {
+
+ /**** SUBSEQUENT TURNS OF DIALOG ****/
+ // pass a handle to the current ctx (for evaluating binding exprs)
+ updateEvaluator(context, outcome);
+ // fire a "faces.outcome" event on the dialog's state machine
+ TriggerEvent[] te = { new TriggerEvent("faces.outcome",
+ TriggerEvent.SIGNAL_EVENT) };
+ try {
+ exec.triggerEvents(te);
+ } catch (ModelException me) {
+ log.error(me.getMessage(), me);
+ }
+ // obtain next view
+ viewId = getCurrentViewId(exec);
+ }
+
+ if (viewId != null) {
+
+ // we understood this "outcome" and we have a new view to render
+ log.info("Rendering view: " + viewId);
+ updateDialogStatus(context, exec);
+ render(context, viewId);
+
+ } else {
+
+ /**** DELEGATE BY DEFAULT ****/
+ handler.handleNavigation(context, fromAction, outcome);
+
+ }
+
+
+ }
+
+ /**
+ * <p>Return the SCXMLExecutor for the specified SCXML document, if it
+ * exists; otherwise, return <code>null</code>.</p>
+ *
+ * @param context <code>FacesContext</code> for the current request
+ * @param dialogIdentifier URL of the SCXML document for the requested
+ * dialog
+ */
+ private SCXMLExecutor initDialogExecutor(FacesContext context,
+ String dialogIdentifier) {
+
+ assert context != null;
+ assert dialogIdentifier != null;
+
+ // We're parsing the SCXML dialog just in time here
+ URL scxmlDocument = null;
+ try {
+ scxmlDocument = context.getExternalContext().
+ getResource(dialogIdentifier);
+ } catch (MalformedURLException mue) {
+ log.error(mue.getMessage(), mue);
+ }
+
+ if (scxmlDocument == null) {
+ log.warn("No SCXML document at: " + dialogIdentifier);
+ return null;
+ }
+
+ SCXML scxml = null;
+ ShaleDialogELEvaluator evaluator = new ShaleDialogELEvaluator();
+ evaluator.setFacesContext(context);
+ try {
+ scxml = SCXMLDigester.digest(scxmlDocument,
+ new SimpleErrorHandler(), new SessionContext(context),
+ evaluator);
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ }
+
+ if (scxml == null) {
+ log.warn("Could not parse SCXML document at: " + dialogIdentifier);
+ return null;
+ }
+
+ SCXMLExecutor exec = null;
+ try {
+ exec = new SCXMLExecutor(evaluator, new SimpleDispatcher(),
+ new SimpleErrorReporter());
+ scxml.addListener(new SimpleSCXMLListener());
+ exec.setSuperStep(true);
+ exec.setStateMachine(scxml);
+ } catch (ModelException me) {
+ log.warn(me.getMessage(), me);
+ return null;
+ }
+
+ // read SCXML state IDs to JSF view IDs map, channel dependent
+ readState2ViewMap(context, dialogIdentifier, null);
+
+ // FIXME: Remove dependence on the org.apache.shale.dialog.impl package
+ // below (introduced so we can reuse the existing StatusImpl and the
+ // AbstractFacesBean subtypes in the usecases war for the proof of
+ // concept).
+ // Ignoring STATUS_PARAM since usecases war doesn't use it for the
+ // log on / edit profile dialogs.
+ // TODO: The next line should be Dialog Manager implementation agnostic
+ Status status = new org.apache.shale.dialog.impl.StatusImpl();
+
+ context.getExternalContext().getSessionMap().put(Globals.STATUS, status);
+ status.push(new Status.Position(dialogIdentifier, getCurrentViewId(exec)));
+
+ return exec;
+
+ }
+
+ /**
+ * <p>Set the {@link SCXMLExecutor} instance for the current user.</p>
+ *
+ * @param context <code>FacesContext</code> for the current request
+ * @param exec <code>SCXMLExecutor</code> that will run the dialog
+ */
+ private void setDialogExecutor(FacesContext context, SCXMLExecutor exec) {
+
+ assert context != null;
+ assert exec != null;
+
+ Map map = context.getExternalContext().getSessionMap();
+ String key = getDialogKey(context);
+ assert key != null;
+ map.put(key, exec);
+
+ }
+
+ /**
+ * <p>Return the {@link SCXMLExecutor} instance for the current user.</p>
+ *
+ * @param context <code>FacesContext</code> for the current request
+ */
+ private SCXMLExecutor getDialogExecutor(FacesContext context) {
+
+ assert context != null;
+
+ Map map = context.getExternalContext().getSessionMap();
+ String key = getDialogKey(context);
+ return (SCXMLExecutor) map.get(key);
+
+ }
+
+ /**
+ * Update evaluator with current FacesContext for evaluation of
+ * binding expressions used in Shale dialog.
+ */
+ private void updateEvaluator(FacesContext context, String outcome) {
+
+ assert context != null;
+
+ ((ShaleDialogELEvaluator) getDialogExecutor(context).getEvaluator()).
+ setFacesContext(context);
+ context.getExternalContext().getSessionMap().put("outcome", outcome);
+ }
+
+ /**
+ * Update dialog Status
+ *
+ * @param context The FacesContext
+ * @param exec The SCXMLExecutor
+ */
+ private void updateDialogStatus(FacesContext context, SCXMLExecutor exec) {
+
+ assert context != null;
+ assert exec != null;
+
+ // TODO: Test this
+ Status status = (Status) context.getExternalContext().getSessionMap().
+ get(Globals.STATUS);
+ if (exec.getCurrentStatus().isFinal()) {
+ setDialogExecutor(context, null);
+ status.pop();
+ } else {
+ status.peek().setStateName(getCurrentViewId(exec));
+ }
+ }
+
+ /**
+ * Get next view to render, assuming one view at a time.
+ *
+ * @param currentStates The set of current states
+ * @return String The JSF viewId of the next view
+ */
+ private String getCurrentViewId(SCXMLExecutor exec) {
+
+ assert exec != null;
+
+ Set currentStates = exec.getCurrentStatus().getStates();
+ for (Iterator i = currentStates.iterator(); i.hasNext(); ) {
+ String targetId = ((TransitionTarget) i.next()).getId();
+ if (target2viewMap.containsKey(targetId)) {
+ return (String) target2viewMap.get(targetId);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * <p>Return the session scope attribute key under which we will
+ * store dialog state for the current user. The value
+ * is specified by a context init parameter named by constant
+ * <code>Globals.DIALOG_STATE_PARAM</code>, or defaults to the value
+ * specified by constant <code>Globals.DIALOG_STATE</code>.</p>
+ *
+ * @param context <code>FacesContext</code> for the current request
+ */
+ private String getDialogKey(FacesContext context) {
+
+ assert context != null;
+
+ if (dialogKey == null) {
+ dialogKey =
+ context.getExternalContext().
+ getInitParameter(Globals.DIALOG_STATE_PARAM);
+ if (dialogKey == null) {
+ dialogKey = Globals.DIALOG_STATE;
+ }
+ }
+ return dialogKey;
+
+ }
+
+ /**
+ * <p>Render the view corresponding to the specified view identifier.</p>
+ *
+ * @param context <code>FacesContext</code> for the current request
+ * @param viewId View identifier to be rendered, or <code>null</code>
+ * to rerender the current view
+ */
+ private void render(FacesContext context, String viewId) {
+
+ assert context != null;
+
+ if (log.isDebugEnabled()) {
+ log.debug("render(viewId=" + viewId + ")");
+ }
+
+ // Stay on the same view if requested
+ if (viewId == null) {
+ return;
+ }
+
+ // Create the specified view so that it can be rendered
+ ViewHandler vh = context.getApplication().getViewHandler();
+ UIViewRoot view = vh.createView(context, viewId);
+ view.setViewId(viewId);
+ context.setViewRoot(view);
+
+ }
+
+ /**
+ * FIXME: - Placeholder for SCXML state ID to JSF view ID mapper.
+ * Provides multi-channel aspect to Shale dialog management.
+ *
+ */
+ private void readState2ViewMap(FacesContext context,
+ String dialogIdentifier, String channel) {
+
+ assert context != null;
+
+ String STATE_TO_VIEW_MAP = "/WEB-INF/dialogstate2view.xml";
+ target2viewMap = new HashMap();
+
+ Digester digester = new Digester();
+ digester.clear();
+ digester.setNamespaceAware(false);
+ digester.setUseContextClassLoader(false);
+ digester.setValidating(false);
+ digester.addRule("map/entry", new Rule() {
+ /** SCXML target ID. */
+ private String targetId;
+ /** JSF view ID. */
+ private String viewId;
+ /** {@inheritDoc} */
+ public final void begin(final String namespace, final String name,
+ final Attributes attributes) {
+ targetId = attributes.getValue("targetId");
+ viewId = attributes.getValue("viewId");
+ }
+ /** {@inheritDoc} */
+ public void end(final String namespace, final String name) {
+ target2viewMap.put(targetId, viewId);
+ }
+ });
+
+ try {
+ URL mapURL = context.getExternalContext().getResource(STATE_TO_VIEW_MAP);
+ InputSource source = new InputSource(mapURL.toExternalForm());
+ source.setByteStream(mapURL.openStream());
+ digester.parse(source);
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ }
+ }
+
+}
Propchange: jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/SCXMLDialogNavigationHandler.java.txt
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/SCXMLDialogNavigationHandler.java.txt
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/dialog-config.xml
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/dialog-config.xml?rev=321280&view=auto
==============================================================================
--- jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/dialog-config.xml (added)
+++ jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/dialog-config.xml Fri Oct 14 19:41:20 2005
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+
+ Copyright 2004-2005 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.
+
+ $Id$
+
+-->
+
+<!--
+
+ Dialog definitions for Shale Use Cases Example Web Application
+
+-->
+
+<!DOCTYPE dialogs PUBLIC
+ "-//Apache Software Foundation//DTD Shale Dialog Configuration 1.0//EN"
+ "http://struts.apache.org/dtds/shale-dialog-config_1_0.dtd">
+
+<dialogs>
+
+
+ <!-- Log On / Create Profile Dialog -->
+ <dialog name="Log On"
+ start="Check Cookie">
+
+ <action name="Check Cookie"
+ method="#{profile$logon.check}">
+ <transition outcome="authenticated"
+ target="Exit"/>
+ <transition outcome="unauthenticated"
+ target="Logon Form"/>
+ </action>
+
+ <view name="Logon Form"
+ viewId="/profile/logon.jsp">
+ <transition outcome="authenticated"
+ target="Exit"/>
+ <transition outcome="create"
+ target="Create Profile"/>
+ </view>
+
+ <subdialog name="Create Profile"
+ dialogName="Edit Profile">
+ <transition outcome="success"
+ target="Exit"/>
+ </subdialog>
+
+ <end name="Exit"
+ viewId="/usecases.jsp"/>
+
+ </dialog>
+
+
+ <!-- Edit Profile Dialog -->
+ <dialog name="Edit Profile"
+ start="Setup">
+
+ <!-- Global transitioh definitions -->
+ <transition outcome="cancel"
+ target="Cancel"/>
+ <transition outcome="finish"
+ target="Finish"/>
+
+ <action name="Setup"
+ method="#{profile$edit.setup}">
+ <transition outcome="success"
+ target="Page 1"/>
+ </action>
+
+ <view name="Page 1"
+ viewId="/profile/profile1.jsp">
+ <transition outcome="next"
+ target="Page 2"/>
+ </view>
+
+ <view name="Page 2"
+ viewId="/profile/profile2.jsp">
+ <transition outcome="next"
+ target="Page 3"/>
+ <transition outcome="previous"
+ target="Page 1"/>
+ </view>
+
+ <view name="Page 3"
+ viewId="/profile/profile3.jsp">
+ <transition outcome="next"
+ target="Exit"/>
+ <transition outcome="previous"
+ target="Page 2"/>
+ </view>
+
+ <action name="Cancel"
+ method="#{profile$edit.cancel}">
+ <transition outcome="success"
+ target="Exit"/>
+ </action>
+
+ <action name="Finish"
+ method="#{profile$edit.finish}">
+ <transition outcome="password"
+ target="Page 1"/>
+ <transition outcome="success"
+ target="Exit"/>
+ <transition outcome="username"
+ target="Page 1"/>
+ </action>
+
+ <end name="Exit"
+ viewId="/usecases.jsp"/>
+
+ </dialog>
+
+
+</dialogs>
Propchange: jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/dialog-config.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/dialog-config.xml
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/dialogstate2view.xml
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/dialogstate2view.xml?rev=321280&view=auto
==============================================================================
--- jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/dialogstate2view.xml (added)
+++ jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/dialogstate2view.xml Fri Oct 14 19:41:20 2005
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!--
+ Copyright 2004-2005 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.
+-->
+<map>
+ <entry targetId="logon" viewId="/profile/logon.jsp" />
+ <entry targetId="page1" viewId="/profile/profile1.jsp" />
+ <entry targetId="page2" viewId="/profile/profile2.jsp" />
+ <entry targetId="page3" viewId="/profile/profile3.jsp" />
+ <entry targetId="exit" viewId="/usecases.jsp" />
+</map>
Propchange: jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/dialogstate2view.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/dialogstate2view.xml
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/edit-profile-config.xml
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/edit-profile-config.xml?rev=321280&view=auto
==============================================================================
--- jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/edit-profile-config.xml (added)
+++ jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/edit-profile-config.xml Fri Oct 14 19:41:20 2005
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright 2004-2005 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.
+
+ $Id$
+
+-->
+
+<!--
+
+ Dialog definitions for Shale Use Cases Example Web Application
+ written out as SCXML to demonstrate use of Commons SCXML as one
+ of Shale's Dialog Manager implementations.
+
+ Related artifacts from <dialog name="Edit Profile">...</dialog>
+ in original dialogs definition file from Shale nightlies.
+
+-->
+
+<scxml xmlns="http://www.w3.org/2005/01/SCXML" version="1.0"
+ initialstate="edit">
+
+ <state id="edit">
+
+ <initial>
+ <transition>
+ <target next="setup"/>
+ </transition>
+ </initial>
+
+ <!-- global transitions (within state "edit") -->
+
+ <transition event="faces.outcome"
+ cond="${outcome eq 'cancel'}">
+ <target next="cancel"/>
+ </transition>
+
+ <transition event="faces.outcome"
+ cond="${outcome eq 'finish'}">
+ <target next="finish"/>
+ </transition>
+
+ <state id="setup">
+
+ <onentry>
+ <var name="setupOutcome"
+ expr="#{profile$edit.setup}" />
+ </onentry>
+
+ <transition cond="${setupOutcome eq 'success'}">
+ <target next="page1"/>
+ </transition>
+
+ </state>
+
+ <state id="page1">
+
+ <transition event="faces.outcome"
+ cond="${outcome eq 'next'}">
+ <target next="page2"/>
+ </transition>
+
+ </state>
+
+ <state id="page2">
+
+ <transition event="faces.outcome"
+ cond="${outcome eq 'previous'}">
+ <target next="page1"/>
+ </transition>
+
+ <transition event="faces.outcome"
+ cond="${outcome eq 'next'}">
+ <target next="page3"/>
+ </transition>
+
+ </state>
+
+ <state id="page3">
+
+ <transition event="faces.outcome"
+ cond="${outcome eq 'previous'}">
+ <target next="page2"/>
+ </transition>
+
+ <transition event="faces.outcome"
+ cond="${outcome eq 'next'}">
+ <target next="editExit"/>
+ </transition>
+
+ </state>
+
+ </state>
+
+ <state id="cancel">
+
+ <onentry>
+ <var name="cancelOutcome"
+ expr="#{profile$edit.cancel}" />
+ </onentry>
+
+ <transition cond="${cancelOutcome eq 'success'}">
+ <var name="outcome"
+ expr="cancel"/>
+ <target next="editExit"/>
+ </transition>
+
+ </state>
+
+ <state id="finish">
+
+ <onentry>
+ <var name="finishOutcome"
+ expr="#{profile$edit.finish}" />
+ </onentry>
+
+ <transition cond="${finishOutcome eq 'username'}">
+ <target next="page1"/>
+ </transition>
+
+ <transition cond="${finishOutcome eq 'password'}">
+ <target next="page1"/>
+ </transition>
+
+ <transition cond="${finishOutcome eq 'success'}">
+ <var name="outcome"
+ expr="success"/>
+ <target next="editExit"/>
+ </transition>
+
+ </state>
+
+ <state id="editExit"
+ final="true" />
+
+</scxml>
Propchange: jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/edit-profile-config.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/edit-profile-config.xml
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/log-on-config.xml
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/log-on-config.xml?rev=321280&view=auto
==============================================================================
--- jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/log-on-config.xml (added)
+++ jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/log-on-config.xml Fri Oct 14 19:41:20 2005
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright 2004-2005 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.
+
+ $Id$
+
+-->
+
+<!--
+
+ Dialog definitions for Shale Use Cases Example Web Application
+ written out as SCXML to demonstrate use of Commons SCXML as one
+ of Shale's Dialog Manager implementations.
+
+ Related artifacts from <dialog name="Log On">...</dialog>
+ in original dialogs definition file from Shale nightlies.
+
+-->
+
+<scxml xmlns="http://www.w3.org/2005/01/SCXML" version="1.0"
+ initialstate="checkCookie">
+
+
+ <state id="checkCookie">
+
+ <onentry>
+ <var name="cookieOutcome"
+ expr="#{profile$logon.check}" />
+ </onentry>
+
+ <transition cond="${cookieOutcome eq 'authenticated'}">
+ <target next="exit"/>
+ </transition>
+
+ <transition cond="${cookieOutcome eq 'unauthenticated'}">
+ <target next="logon"/>
+ </transition>
+
+ </state>
+
+ <state id="logon">
+
+ <transition event="faces.outcome"
+ cond="${outcome eq 'authenticated'}">
+ <target next="exit"/>
+ </transition>
+
+ <transition event="faces.outcome"
+ cond="${outcome eq 'create'}">
+ <target next="createProfile"/>
+ </transition>
+
+ </state>
+
+ <state id="createProfile"
+ src="edit-profile-config.xml" >
+
+ <transition event="createProfile.done"
+ cond="${outcome eq 'success' or outcome eq 'cancel'}">
+ <target next="exit"/>
+ </transition>
+
+ </state>
+
+ <state id="exit"
+ final="true" />
+
+</scxml>
Propchange: jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/log-on-config.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/commons/sandbox/scxml/trunk/xdocs/usecases/shale-dialogs/log-on-config.xml
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org