You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shale.apache.org by ra...@apache.org on 2006/09/29 21:42:47 UTC

svn commit: r451400 - in /shale/sandbox/shale-dialog2-scxml/src/main/java/org/apache/shale/dialog2/scxml: SCXMLDialogContext.java SCXMLDialogManager.java

Author: rahul
Date: Fri Sep 29 12:42:47 2006
New Revision: 451400

URL: http://svn.apache.org/viewvc?view=rev&rev=451400
Log:
Static code review tools pointed out serialization defect. It is anticipated that better solution(s) will exist in the next version of Commons SCXML (see SCXML-20 on the main ASF JIRA instance, for example), but for now, we re-parse the state machine and set it uo to start in the last known (dialog) state.

Modified:
    shale/sandbox/shale-dialog2-scxml/src/main/java/org/apache/shale/dialog2/scxml/SCXMLDialogContext.java
    shale/sandbox/shale-dialog2-scxml/src/main/java/org/apache/shale/dialog2/scxml/SCXMLDialogManager.java

Modified: shale/sandbox/shale-dialog2-scxml/src/main/java/org/apache/shale/dialog2/scxml/SCXMLDialogContext.java
URL: http://svn.apache.org/viewvc/shale/sandbox/shale-dialog2-scxml/src/main/java/org/apache/shale/dialog2/scxml/SCXMLDialogContext.java?view=diff&rev=451400&r1=451399&r2=451400
==============================================================================
--- shale/sandbox/shale-dialog2-scxml/src/main/java/org/apache/shale/dialog2/scxml/SCXMLDialogContext.java (original)
+++ shale/sandbox/shale-dialog2-scxml/src/main/java/org/apache/shale/dialog2/scxml/SCXMLDialogContext.java Fri Sep 29 12:42:47 2006
@@ -132,7 +132,15 @@
      * <p>The {@link SCXMLExecutor}, an instance of the state machine
      * defined for the SCXML document for this dialog.</p>
      */
-    private SCXMLExecutor executor = null;
+    private transient SCXMLExecutor executor = null;
+
+
+    /**
+     * <p>The current SCXML state ID for this dialog instance, maintained
+     * to reinitialize the transient {@link SCXMLExecutor} driving this
+     * dialog instance.</p>
+     */
+    private String stateId = null;
 
 
     // ----------------------------------------------------- DialogContext Properties
@@ -193,12 +201,13 @@
     /** {@inheritDoc} */
     public void advance(FacesContext context, String outcome) {
 
-        ((ShaleDialogELEvaluator) this.executor.getEvaluator()).
+        SCXMLExecutor dialogExecutor = getExecutor(context);
+        ((ShaleDialogELEvaluator) dialogExecutor.getEvaluator()).
                     setFacesContext(context);
-        this.executor.getRootContext().setLocal(Globals.POSTBACK_OUTCOME, outcome);
+        dialogExecutor.getRootContext().setLocal(Globals.POSTBACK_OUTCOME, outcome);
 
         try {
-                this.executor.triggerEvent(new TriggerEvent(Globals.POSTBACK_EVENT,
+            dialogExecutor.triggerEvent(new TriggerEvent(Globals.POSTBACK_EVENT,
                                 TriggerEvent.SIGNAL_EVENT));
         } catch (ModelException me) {
             // FIXME - Not an IAE
@@ -208,11 +217,12 @@
         // TODO - Re-evaluate before leaving sandbox
         // Using C/C, "View" state ID is JSF viewId, which is an acceptable
         // approach with Commons SCXML v0.5
-        Iterator iterator = this.executor.getCurrentStatus().getStates().iterator();
-        String viewId = ((State) iterator.next()).getId();
+        Iterator iterator = dialogExecutor.getCurrentStatus().getStates().iterator();
+        this.stateId = ((State) iterator.next()).getId();
+        String viewId = stateId; // to illustrate there could be some other transform here
 
         // If done, stop context
-        if (this.executor.getCurrentStatus().isFinal()) {
+        if (dialogExecutor.getCurrentStatus().isFinal()) {
             stop(context);
         }
 
@@ -246,24 +256,26 @@
             throw new FacesException(e);
         }
 
+        SCXMLExecutor dialogExecutor = getExecutor(context);
         // set state machine in motion
-        ((ShaleDialogELEvaluator) this.executor.getEvaluator()).
+        ((ShaleDialogELEvaluator) dialogExecutor.getEvaluator()).
             setFacesContext(context);
         try {
-            this.executor.go();
+            dialogExecutor.go();
         } catch (ModelException me) {
             // FIXME - Better exception, for extra credit:
-                // TODO - need DialogListener
+            // TODO - need DialogListener
             throw new IllegalArgumentException("SCXML dialog cannot start:" + name);
         }
 
         // Using C/C, "View" state ID is JSF viewId, which is an acceptable
         // approach with Commons SCXML v0.5 since it accepts spaces etc.
-        Iterator iterator = this.executor.getCurrentStatus().getStates().iterator();
-        String viewId = ((State) iterator.next()).getId();
+        Iterator iterator = dialogExecutor.getCurrentStatus().getStates().iterator();
+        this.stateId = ((State) iterator.next()).getId();
+        String viewId = stateId; // to illustrate there could be some other transform here
 
         // Might be done at the beginning itself, if so, stop context
-        if (this.executor.getCurrentStatus().isFinal()) {
+        if (dialogExecutor.getCurrentStatus().isFinal()) {
             stop(context);
         }
 
@@ -318,6 +330,29 @@
         view.setViewId(viewId);
         context.setViewRoot(view);
         context.renderResponse();
+    }
+
+    /**
+     * Get the {@link SCXMLExecutor} instance driving this dialog, replenish
+     * if needed.
+     *
+     * @param The {@link FacesContext} for this request
+     * @return The {@link SCXMLExecutor} instance driving this dialog 
+     */
+    private SCXMLExecutor getExecutor(FacesContext context) {
+
+        // We've just been deserialized, if null
+        if (this.executor == null) {
+            this.executor = new SCXMLExecutor(new ShaleDialogELEvaluator(),
+                new SimpleDispatcher(), new SimpleErrorReporter());
+            SCXML stateMachine = ((SCXMLDialogManager) manager).dialog(context, name).
+                getStateMachine();
+            this.executor.setStateMachine(stateMachine);
+            this.executor.addListener(stateMachine, new SimpleSCXMLListener());
+            this.executor.getCurrentStatus().getStates().add(stateMachine.getTargets().get(stateId));
+        }
+
+        return this.executor;
     }
 
 }

Modified: shale/sandbox/shale-dialog2-scxml/src/main/java/org/apache/shale/dialog2/scxml/SCXMLDialogManager.java
URL: http://svn.apache.org/viewvc/shale/sandbox/shale-dialog2-scxml/src/main/java/org/apache/shale/dialog2/scxml/SCXMLDialogManager.java?view=diff&rev=451400&r1=451399&r2=451400
==============================================================================
--- shale/sandbox/shale-dialog2-scxml/src/main/java/org/apache/shale/dialog2/scxml/SCXMLDialogManager.java (original)
+++ shale/sandbox/shale-dialog2-scxml/src/main/java/org/apache/shale/dialog2/scxml/SCXMLDialogManager.java Fri Sep 29 12:42:47 2006
@@ -103,13 +103,8 @@
     /** {@inheritDoc} */
     public DialogContext create(FacesContext context, String name, DialogContext parent) {
 
-        // Look up the specified dialog configuration
-        Map dialogs = dialogs(context);
-        DialogMetadata dialog = (DialogMetadata) dialogs.get(name);
-        if (dialog == null || dialog.getStateMachine() == null) {
-            throw new IllegalArgumentException("No definition for dialog name '"
-                                               + name + "' can be found");
-        }
+        // Obtain the dialog metadata for the specified dialog
+        DialogMetadata dialog = dialog(context, name);
 
         // Validate the specified parent (if any)
         String parentDialogId = null;
@@ -145,6 +140,44 @@
     }
 
 
+    //  ------------------------------------------------- Default Scoped Methods
+
+    /**
+     * <p>Return the dialog metadata for the dialog with the specified name.
+     * If the metadata isn't already loaded from the configuration files,
+     * it will get parsed now.</p>
+     *
+     * @param context FacesContext for the current request
+     * @param name The dialog name
+     * @return The {@link DialogMetadata} for the specified dialog name
+     */
+    DialogMetadata dialog(FacesContext context, String name) {
+
+        // Look up the specified dialog configuration
+        Map dialogs = dialogs(context, false);
+        DialogMetadata dialog = (DialogMetadata) dialogs.get(name);
+        // No such dialog
+        if (dialog == null) {
+            throw new IllegalArgumentException("No definition for dialog name '"
+                                               + name + "' can be found");
+        }
+
+        // We've just been deserialized
+        if (dialog.getStateMachine() == null) {
+            dialogs = dialogs(context, true);
+            dialog = (DialogMetadata) dialogs.get(name);
+            // Shouldn't happen
+            if (dialog.getStateMachine() == null) {
+                throw new IllegalStateException("Null statemachine for dialog name '"
+                    + name + "'");
+            }
+        }
+
+        return dialog;
+
+    }
+
+
     // --------------------------------------------------------- Private Methods
 
 
@@ -154,19 +187,20 @@
      * configuration resources will be processed.</p>
      *
      * @param context FacesContext for the current request
+     * @param refresh Whether to force a refresh of the dialog configurations
      * @return Map of {@link SCXML} instances, keyed by logical dialog name
      */
-    private Map dialogs(FacesContext context) {
+    private Map dialogs(FacesContext context, boolean refresh) {
 
         // Return the cached instance (if any)
-        if (this.dialogs != null) {
+        if (this.dialogs != null && !refresh) {
             return this.dialogs;
         }
 
         // Return the previously configured application scope instance (if any)
         this.dialogs = (Map)
           context.getExternalContext().getApplicationMap().get(Globals.DIALOGS);
-        if (this.dialogs != null) {
+        if (this.dialogs != null && !refresh) {
             return this.dialogs;
         }