shale-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ra...@apache.org
Subject svn commit: r477933 - in /shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml: ./ action/ config/
Date Tue, 21 Nov 2006 22:27:02 GMT
Author: rahul
Date: Tue Nov 21 14:27:01 2006
New Revision: 477933

URL: http://svn.apache.org/viewvc?view=rev&rev=477933
Log:
Allow use of redirects with Shale dialogs when using Commons SCXML implementation.

This is done by defining a custom Commons SCXML action (local name "redirect") which communicates
with the SCXMLDialogContext via a DialogProperties instance cached in the state machine's
root context under a well-known key.

Example SCXML snippet:

<scxml xmlns="http://www.w3.org/2005/07/scxml"
       xmlns:shale="http://shale.apache.org/dialog-scxml"
       ...>

 <!-- "view" state which needs to use a redirect -->
 <state id="page1">
  <onentry>
   <shale:redirect/>
  </onentry>
  ...
 </state>

SHALE-337

This is also a general recipe for Shale dialog domain specific tweaks using custom SCXML actions.
The dialog configuration file is a compound document with multiple namespaces:
 * The SCXML namespace provides the state machine abstraction and a set of "standard" actions
(var, assign, if etc.)
 * The Shale dialogs custom SCXML actions namespace, which contains actions defined out-of-the-box
by the shale-dialog-scxml library (currently, just <redirect>)
 * Potentially other namespaces by developers (might be application specific or merely repeatable
actions that are not in the shale-dialog-scxml library) -- it will be similarly possible (via
state machine's root context) to make the current FacesContext available to custom actions,
greatly improving their capabilities in the context of Shale dialogs

Furthermore, the example above can be further tweaked, such as:

<scxml:if cond="...">
 <shale:redirect/>
</scxml:if>

where the custom action is conditionally invoked (thats probably of limited use for the redirection
scenario, but potentially that could be a <shale:foo/> where it makes sense to do "foo"
conditionally).

Finally, its possible to use custom actions as one exits a state (descendent of <onexit>)
or as one transitions across states (descendent of <transition>) for further control
over their invocation.

Added:
    shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/DialogProperties.java
  (with props)
    shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/action/
    shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/action/RedirectAction.java
  (with props)
    shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/action/package.html
  (with props)
Modified:
    shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/Globals.java
    shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/SCXMLDialogContext.java
    shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/config/ConfigurationParser.java

Added: shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/DialogProperties.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/DialogProperties.java?view=auto&rev=477933
==============================================================================
--- shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/DialogProperties.java
(added)
+++ shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/DialogProperties.java
Tue Nov 21 14:27:01 2006
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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.shale.dialog.scxml;
+
+import java.io.Serializable;
+
+/**
+ * <p>Simple POJO properties class that gets stored in the root context
+ * of each state machine instance driving a Shale dialog.</p>
+ *
+ * @since 1.0.4
+ *
+ * $Id$
+ */
+public class DialogProperties implements Serializable {
+
+    //--------------------------------------------------------- Constructors
+
+    /**
+     * This is part of the internal contract of Shale dialogs and should never
+     * need to be instantiated outside the parent package.
+     */
+    DialogProperties() {
+        super();
+    }
+
+    //---------------------------------  Properties, with getters and setters
+
+
+    //------------------------------------------------------------- Redirects
+
+    /**
+     * Whether the next view rendered by this dialog should use a redirect.
+     */
+    private boolean nextRedirect = false;
+
+    /**
+     * Should next view rendered by this dialog be redirected.
+     *
+     * @return true, if next view is to be redirected.
+     */
+    public boolean isNextRedirect() {
+        return nextRedirect;
+    }
+
+    /**
+     * Set next view redirect property.
+     *
+     * @param nextRedirect Whether next view rendered should be redirected.
+     */
+    public void setNextRedirect(boolean nextRedirect) {
+        this.nextRedirect = nextRedirect;
+    }
+
+
+    //---------------------------------------------- Other instance variables
+
+    /**
+     * Serial version UID.
+     */
+    private static final long serialVersionUID = 1L;
+
+}

Propchange: shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/DialogProperties.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/DialogProperties.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Modified: shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/Globals.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/Globals.java?view=diff&rev=477933&r1=477932&r2=477933
==============================================================================
--- shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/Globals.java
(original)
+++ shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/Globals.java
Tue Nov 21 14:27:01 2006
@@ -71,5 +71,24 @@
     public static final String POSTBACK_OUTCOME =
             "outcome";
 
+
+    /**
+     * <p>The namespace URI for the custom Commons SCXML actions defined by
+     * the Shale dialogs Commons SCXML implementation.</p>
+     */
+    public static final String CUSTOM_SCXML_ACTIONS_URI =
+            "http://shale.apache.org/dialog-scxml";
+
+
+    /**
+     * <p>The key for saving dialog properties in the root context of the
+     * underlying Commons SCXML state machine. SCXML documents describing
+     * dialogs <em>must not</em> use this key as a &lt;var&gt; or &lt;data&gt;
+     * name.</p>
+     */
+    public static final String DIALOG_PROPERTIES =
+            "ReservedShaleDialogPropertiesKey";
+
+
 }
 

Modified: shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/SCXMLDialogContext.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/SCXMLDialogContext.java?view=diff&rev=477933&r1=477932&r2=477933
==============================================================================
--- shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/SCXMLDialogContext.java
(original)
+++ shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/SCXMLDialogContext.java
Tue Nov 21 14:27:01 2006
@@ -17,23 +17,29 @@
 
 package org.apache.shale.dialog.scxml;
 
+import java.io.IOException;
 import java.util.Iterator;
 
+import javax.faces.FacesException;
 import javax.faces.application.ViewHandler;
 import javax.faces.component.UIViewRoot;
+import javax.faces.context.ExternalContext;
 import javax.faces.context.FacesContext;
 import javax.faces.el.ValueBinding;
 
+import org.apache.commons.scxml.Context;
 import org.apache.commons.scxml.SCXMLExecutor;
 import org.apache.commons.scxml.SCXMLListener;
 import org.apache.commons.scxml.TriggerEvent;
 import org.apache.commons.scxml.env.SimpleDispatcher;
 import org.apache.commons.scxml.env.SimpleErrorReporter;
+import org.apache.commons.scxml.env.jsp.ELContext;
 import org.apache.commons.scxml.model.ModelException;
 import org.apache.commons.scxml.model.SCXML;
 import org.apache.commons.scxml.model.State;
 import org.apache.commons.scxml.model.Transition;
 import org.apache.commons.scxml.model.TransitionTarget;
+import org.apache.shale.dialog.Constants;
 import org.apache.shale.dialog.DialogContext;
 import org.apache.shale.dialog.DialogContextManager;
 import org.apache.shale.dialog.DialogListener;
@@ -83,6 +89,9 @@
                         new SimpleDispatcher(), new SimpleErrorReporter());
         SCXML statemachine = dialog.getStateMachine();
         this.executor.setStateMachine(statemachine);
+        Context rootCtx = new ELContext();
+        rootCtx.setLocal(Globals.DIALOG_PROPERTIES, new DialogProperties());
+        this.executor.setRootContext(rootCtx);
         this.executor.addListener(statemachine, new DelegatingSCXMLListener());
 
         // TODO - Consider adding an explicit root context backed by either the
@@ -229,13 +238,15 @@
 
         Iterator iterator = dialogExecutor.getCurrentStatus().getStates().iterator();
         this.stateId = ((State) iterator.next()).getId();
+        DialogProperties dp = (DialogProperties) dialogExecutor.getRootContext().
+            get(Globals.DIALOG_PROPERTIES);
 
         // If done, stop context
         if (dialogExecutor.getCurrentStatus().isFinal()) {
             stop(context);
         }
 
-        navigateTo(stateId, context);
+        navigateTo(stateId, context, dp);
 
     }
 
@@ -276,13 +287,15 @@
 
         Iterator iterator = dialogExecutor.getCurrentStatus().getStates().iterator();
         this.stateId = ((State) iterator.next()).getId();
+        DialogProperties dp = (DialogProperties) dialogExecutor.getRootContext().
+            get(Globals.DIALOG_PROPERTIES);
 
         // Might be done at the beginning itself, if so, stop context
         if (dialogExecutor.getCurrentStatus().isFinal()) {
             stop(context);
         }
 
-        navigateTo(stateId, context);
+        navigateTo(stateId, context, dp);
 
     }
 
@@ -322,8 +335,9 @@
      *
      * @param stateId The current state identifier for this dialog.
      * @param context The current <code>FacesContext</code>
+     * @param dp The <code>DialogProperties</code> for the current dialog
      */
-    private void navigateTo(String stateId, FacesContext context) {
+    private void navigateTo(String stateId, FacesContext context, DialogProperties dp) {
         ValueBinding vb = context.getApplication().createValueBinding
             ("#{" + Globals.STATE_MAPPER + "}");
         DialogStateMapper dsm = (DialogStateMapper) vb.getValue(context);
@@ -336,10 +350,29 @@
             viewId = "/" + viewId;
         }
         ViewHandler vh = context.getApplication().getViewHandler();
-        UIViewRoot view = vh.createView(context, viewId);
-        view.setViewId(viewId);
-        context.setViewRoot(view);
-        context.renderResponse();
+        if (dp.isNextRedirect()) {
+            // clear redirect flag
+            dp.setNextRedirect(false);
+            String actionURL = vh.getActionURL(context, viewId);
+            if (actionURL.indexOf('?') < 0) {
+                actionURL += '?';
+            } else {
+                actionURL += '&';
+            }
+            actionURL += Constants.DIALOG_ID + "=" + this.id;
+            try {
+                ExternalContext econtext = context.getExternalContext();
+                econtext.redirect(econtext.encodeActionURL(actionURL));
+                context.responseComplete();
+            } catch (IOException e) {
+                throw new FacesException("Cannot redirect to " + actionURL, e);
+            }
+        } else {
+            UIViewRoot view = vh.createView(context, viewId);
+            view.setViewId(viewId);
+            context.setViewRoot(view);
+            context.renderResponse();
+        }
     }
 
     /**
@@ -358,6 +391,9 @@
             SCXML stateMachine = ((SCXMLDialogManager) manager).dialog(context, name).
                 getStateMachine();
             this.executor.setStateMachine(stateMachine);
+            Context rootCtx = new ELContext();
+            rootCtx.setLocal(Globals.DIALOG_PROPERTIES, new DialogProperties());
+            this.executor.setRootContext(rootCtx);
             this.executor.addListener(stateMachine, new DelegatingSCXMLListener());
             this.executor.getCurrentStatus().getStates().add(stateMachine.getTargets().get(stateId));
         }

Added: shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/action/RedirectAction.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/action/RedirectAction.java?view=auto&rev=477933
==============================================================================
--- shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/action/RedirectAction.java
(added)
+++ shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/action/RedirectAction.java
Tue Nov 21 14:27:01 2006
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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.shale.dialog.scxml.action;
+
+import java.util.Collection;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.scxml.ErrorReporter;
+import org.apache.commons.scxml.EventDispatcher;
+import org.apache.commons.scxml.SCInstance;
+import org.apache.commons.scxml.SCXMLExpressionException;
+import org.apache.commons.scxml.model.Action;
+import org.apache.commons.scxml.model.ModelException;
+import org.apache.shale.dialog.scxml.DialogProperties;
+import org.apache.shale.dialog.scxml.Globals;
+
+/**
+ * <p>Custom Commons SCXML action to signal that the next rendered view
+ * in this dialog should use a <i>redirect</i>.</p>
+ *
+ * @since 1.0.4
+ *
+ * $Id$
+ */
+public class RedirectAction extends Action {
+
+    /**
+     * <p>Set redirection flag in dialog properties so the next rendered
+     * dialog view is issued as a redirect.</p>
+     *
+     * @param evtDispatcher The EventDispatcher for this execution instance
+     * @param errRep        The ErrorReporter
+     * @param scInstance    The state machine execution instance information
+     * @param appLog        The application log
+     * @param derivedEvents The collection of internal events
+     * @throws ModelException If execution causes a non-deterministic state
+     * @throws SCXMLExpressionException Bad expression
+     */
+    public void execute(EventDispatcher evtDispatcher, ErrorReporter errRep,
+            SCInstance scInstance, Log appLog, Collection derivedEvents)
+    throws ModelException, SCXMLExpressionException {
+
+        DialogProperties dp = (DialogProperties) scInstance.getRootContext().
+            get(Globals.DIALOG_PROPERTIES);
+        dp.setNextRedirect(true);
+
+    }
+
+}

Propchange: shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/action/RedirectAction.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/action/RedirectAction.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/action/package.html
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/action/package.html?view=auto&rev=477933
==============================================================================
--- shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/action/package.html
(added)
+++ shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/action/package.html
Tue Nov 21 14:27:01 2006
@@ -0,0 +1,27 @@
+<html>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to you 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.
+
+-->
+<head>
+</head>
+<body>
+
+  <p>Custom Commons SCXML actions for the Shale dialogs domain.</p>
+
+</body>
+</html>

Propchange: shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/action/package.html
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/action/package.html
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Modified: shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/config/ConfigurationParser.java
URL: http://svn.apache.org/viewvc/shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/config/ConfigurationParser.java?view=diff&rev=477933&r1=477932&r2=477933
==============================================================================
--- shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/config/ConfigurationParser.java
(original)
+++ shale/framework/trunk/shale-dialog-scxml/src/main/java/org/apache/shale/dialog/scxml/config/ConfigurationParser.java
Tue Nov 21 14:27:01 2006
@@ -19,16 +19,21 @@
 
 import java.io.IOException;
 import java.net.URL;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 
 import org.apache.commons.digester.Digester;
 import org.apache.commons.digester.Rule;
 import org.apache.commons.scxml.env.SimpleErrorHandler;
 import org.apache.commons.scxml.io.SCXMLDigester;
+import org.apache.commons.scxml.model.CustomAction;
 import org.apache.commons.scxml.model.ModelException;
 import org.apache.commons.scxml.model.SCXML;
+import org.apache.shale.dialog.scxml.Globals;
+import org.apache.shale.dialog.scxml.action.RedirectAction;
 import org.xml.sax.Attributes;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
@@ -229,6 +234,15 @@
 
         Iterator iterator = metadata.entrySet().iterator();
 
+        // Define the custom Commons SCXML actions used by Shale dialogs
+        CustomAction redirectAction =
+            new CustomAction(Globals.CUSTOM_SCXML_ACTIONS_URI,
+                "redirect", RedirectAction.class);
+
+        // Create a list of custom actions as needed by the SCXMLDigester API
+        List customDialogActions = new ArrayList();
+        customDialogActions.add(redirectAction);
+
         while (iterator.hasNext()) {
 
                 Map.Entry entry = (Map.Entry) iterator.next();
@@ -242,7 +256,9 @@
 
                 SCXML dialog = null;
                 try {
-                    dialog = SCXMLDigester.digest(source, new SimpleErrorHandler());
+                    // Parse document, with rules for custom actions in place
+                    dialog = SCXMLDigester.digest(source,
+                        new SimpleErrorHandler(), customDialogActions);
                 } catch (ModelException me) {
                     throw new SAXException(me.getMessage(), me);
                 }



Mime
View raw message