Author: rahul
Date: Wed Sep 14 20:28:20 2005
New Revision: 289138

URL: http://svn.apache.org/viewcvs?rev=289138&view=rev
Log:
1) Update to handle outgoing transitions from a Parallel (Section 3.4)
2) Minor Javadoc tweaks
3) Update microwave samples to reset timer on leaving "cooking" state so state 
machines can be re-run n times

Modified:
    
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/SCXMLExecutor.java
    
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/SCXMLHelper.java
    
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/SCXMLSemantics.java
    
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/env/RootContext.java
    
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/env/Tracer.java
    
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/model/History.java
    
jakarta/commons/sandbox/scxml/trunk/src/test/java/org/apache/commons/scxml/microwave-01.xml
    
jakarta/commons/sandbox/scxml/trunk/src/test/java/org/apache/commons/scxml/microwave-02.xml

Modified: 
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/SCXMLExecutor.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/SCXMLExecutor.java?rev=289138&r1=289137&r2=289138&view=diff
==============================================================================
--- 
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/SCXMLExecutor.java
 (original)
+++ 
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/SCXMLExecutor.java
 Wed Sep 14 20:28:20 2005
@@ -23,6 +23,7 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.commons.scxml.model.History;
 import org.apache.commons.scxml.model.ModelException;
 import org.apache.commons.scxml.model.SCXML;
 import org.apache.commons.scxml.model.State;
@@ -100,13 +101,8 @@
                     errorReporter);
             // FilterTransitionSet
             semantics.filterTransitionsSet(step, evaluator, errorReporter);
-            // SeedTargetSet
-            semantics.seedTargetSet(step, errorReporter);
-            // DetermineTargetStates
-            semantics.determineTargetStates(
-                    step.getAfterStatus().getStates(), errorReporter);
-            // BuildOnExitOnEntryLists
-            semantics.buildOnExitOnEntryLists(step, errorReporter);
+            // FollowTransitions
+            semantics.followTransitions(step, errorReporter);
             // UpdateHistoryStates
             semantics.updateHistoryStates(step, errorReporter);
             // ExecuteActions
@@ -160,6 +156,8 @@
             TransitionTarget tt = (TransitionTarget) i.next();
             if (tt instanceof State) {
                 ((State) tt).getContext().reset();
+            } else if (tt instanceof History) {
+                ((History) tt).reset();
             }
         }
         // CreateEmptyStatus

Modified: 
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/SCXMLHelper.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/SCXMLHelper.java?rev=289138&r1=289137&r2=289138&view=diff
==============================================================================
--- 
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/SCXMLHelper.java
 (original)
+++ 
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/SCXMLHelper.java
 Wed Sep 14 20:28:20 2005
@@ -227,6 +227,18 @@
         Path p = t.getPath();
         //the easy part
         allStates.addAll(p.getUpwardSegment());
+        TransitionTarget source = t.getParent();
+        for (Iterator act = currentStates.iterator(); act.hasNext();) {
+            TransitionTarget a = (TransitionTarget) act.next();
+            if (isDescendant(a, source)) {
+                boolean added = false;
+                added = allStates.add(a);
+                while (added && a != source) {
+                    a = a.getParent();
+                    added = allStates.add(a);
+                }
+            }
+        }
         if (p.isCrossRegion()) {
             for (Iterator regions = p.getRegionsExited().iterator();
                     regions.hasNext();) {

Modified: 
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/SCXMLSemantics.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/SCXMLSemantics.java?rev=289138&r1=289137&r2=289138&view=diff
==============================================================================
--- 
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/SCXMLSemantics.java
 (original)
+++ 
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/SCXMLSemantics.java
 Wed Sep 14 20:28:20 2005
@@ -46,6 +46,7 @@
 import org.apache.commons.scxml.model.OnEntry;
 import org.apache.commons.scxml.model.OnExit;
 import org.apache.commons.scxml.model.Parallel;
+import org.apache.commons.scxml.model.Path;
 import org.apache.commons.scxml.model.SCXML;
 import org.apache.commons.scxml.model.Send;
 import org.apache.commons.scxml.model.State;
@@ -79,13 +80,14 @@
     /**
      * SCXML Logger for the application.
      */
-    protected static org.apache.commons.logging.Log appLog = LogFactory
+    protected static final org.apache.commons.logging.Log APP_LOG = LogFactory
             .getLog("scxml.app.log");
 
     /**
      * The TransitionTarget comparator.
      */
-    protected TransitionTargetComparator ttc = new 
TransitionTargetComparator();
+    protected TransitionTargetComparator ttc =
+        new TransitionTargetComparator();
 
     /**
      * @param input
@@ -226,7 +228,7 @@
             } else if (a instanceof Log) {
                 Log lg = (Log) a;
                 Object exprRslt = eval.eval(ctx, lg.getExpr());
-                appLog.info(lg.getLabel() + ": " + String.valueOf(exprRslt));
+                APP_LOG.info(lg.getLabel() + ": " + String.valueOf(exprRslt));
             } else if (a instanceof Send) {
                 Send snd = (Send) a;
                 Object hints = null;
@@ -529,37 +531,52 @@
     }
 
     /**
-     * @param step
-     *            transitional step
+     * Populate the target set.
+     * <ul>
+     * <li>take targets of selected transitions</li>
+     * <li>take exited regions into account and make sure every active
+     * parallel region has all siblings active
+     * [that is, explicitly visit or sibling regions in case of newly visited
+     * (revisited) orthogonal states]</li>
+     * </ul>
+     * @param residual [in]
+     * @param transitList [in]
      * @param errRep
      *            ErrorReporter callback [inout]
+     * @return Set The target set
      */
-    public void seedTargetSet(final Step step, final ErrorReporter errRep) {
-        Set sources = step.getBeforeStatus().getStates();
-        Set targets = step.getAfterStatus().getStates();
-        List transitions = step.getTransitList();
-        /* populate the target set by taking targets of selected transitions */
-        for (Iterator i = transitions.iterator(); i.hasNext();) {
+    public Set seedTargetSet(final Set residual, final List transitList,
+            final ErrorReporter errRep) {
+        Set seedSet = new HashSet();
+        Set regions = new HashSet();
+        for (Iterator i = transitList.iterator(); i.hasNext();) {
             Transition t = (Transition) i.next();
-            targets.add(t.getRuntimeTarget());
-        }
-        /* retain the source states, which are not affected by the
-           transitions */
-        for (Iterator i = sources.iterator(); i.hasNext();) {
-            State s = (State) i.next();
-            boolean retain = true;
-            for (Iterator j = transitions.iterator(); j.hasNext();) {
-                Transition t = (Transition) j.next();
-                State ts = (State) t.getParent();
-                if (s == ts || SCXMLHelper.isDescendant(s, ts)) {
-                    retain = false;
-                    break;
+            //iterate over transitions and add target states
+            if (t.getTarget() != null) {
+                seedSet.add(t.getTarget());
+            }
+            //build a set of all entered regions
+            Path p = t.getPath();
+            if (p.isCrossRegion()) {
+                List regs = p.getRegionsEntered();
+                for (Iterator j = regs.iterator(); j.hasNext();) {
+                    State region = (State) j.next();
+                    regions.addAll(((Parallel) region.getParent()).
+                        getStates());
                 }
             }
-            if (retain) {
-                targets.add(s);
-            }
         }
+        //check whether all active regions have their siblings active too
+        Set allStates = new HashSet(residual);
+        allStates.addAll(seedSet);
+        allStates = SCXMLHelper.getAncestorClosure(allStates, null);
+        regions.removeAll(allStates);
+        //iterate over inactive regions and visit them implicitly using initial
+        for (Iterator i = regions.iterator(); i.hasNext();) {
+            State reg = (State) i.next();
+            seedSet.add(reg);
+        }
+        return seedSet;
     }
 
     /**
@@ -568,7 +585,7 @@
      * @param errRep
      *            ErrorReporter callback [inout]
      * @throws ModelException On illegal configuration
-     * @see #seedTargetSet(Step, ErrorReporter)
+     * @see #seedTargetSet(Set, List, ErrorReporter)
      */
     public void determineTargetStates(final Set states,
             final ErrorReporter errRep) throws ModelException {
@@ -592,24 +609,32 @@
                     if (ini == null) {
                         errRep.onError(ErrorReporter.NO_INITIAL,
                             "Initial pseudostate is missing!", st);
-                    }
-                    // If we are here, transition target must be a State
-                    // or History
-                    TransitionTarget init = ini.getTransition().getTarget();
-                    if (init == null
-                        ||
-                        !(init instanceof State || init instanceof History)) {
-                        errRep.onError(ErrorReporter.ILLEGAL_INITIAL,
-                            "Initial does not point to a State or a History!",
-                            st);
                     } else {
-                        wrkSet.addLast(init);
+                        // If we are here, transition target must be a State
+                        // or History
+                        Transition initialTransition = ini.getTransition();
+                        if (initialTransition == null) {
+                            errRep.onError(ErrorReporter.ILLEGAL_INITIAL,
+                                "Initial transition is null!", st);
+                        } else {
+                            TransitionTarget init = initialTransition.
+                                getTarget();
+                            if (init == null
+                                ||
+                                !(init instanceof State
+                                  || init instanceof History)) {
+                                errRep.onError(ErrorReporter.ILLEGAL_INITIAL,
+                                "Initial not pointing to a State or History!",
+                                st);
+                            } else {
+                                wrkSet.addLast(init);
+                            }
+                        }
                     }
                 }
             } else if (tt instanceof Parallel) {
                 Parallel prl = (Parallel) tt;
-                Iterator i = prl.getStates().iterator();
-                while (i.hasNext()) {
+                for (Iterator i = prl.getStates().iterator(); i.hasNext();) {
                     //fork
                     wrkSet.addLast(i.next());
                 }
@@ -625,60 +650,11 @@
                         + tt.getClass().getName());
             }
         }
-        if (!SCXMLHelper.isLegalConfig(states, errRep)) {
-            throw new ModelException("Illegal state machine configuration!");
-        }
     }
 
     /**
-     * @param step
-     *            [inout]
-     * @param errRep
-     *            ErrorReporter callback [inout]
-     */
-    public void buildOnExitOnEntryLists(final Step step,
-            final ErrorReporter errRep) {
-        //set of exited states
-        Set onExit = SCXMLHelper.getAncestorClosure(step.getBeforeStatus()
-                .getStates(), null);
-        Set onExit2 = new HashSet(onExit);
-        //set of entered states
-        Set onEntry = SCXMLHelper.getAncestorClosure(step.getAfterStatus()
-                .getStates(), null);
-        //remove common sub-set
-        onExit.removeAll(onEntry);
-        onEntry.removeAll(onExit2);
-        //explicitly add self-transitions
-        for (Iterator i = step.getTransitList().iterator(); i.hasNext();) {
-            Transition t = (Transition) i.next();
-            if (t.getParent() == t.getTarget()) {
-                onExit.add(t.getParent());
-                onEntry.add(t.getTarget());
-            }
-        }
-        // sort onEntry and onExit according state hierarchy
-        Object[] oex = onExit.toArray();
-        onExit.clear();
-        Object[] oen = onEntry.toArray();
-        onEntry.clear();
-        Arrays.sort(oex, getTTComparator());
-        Arrays.sort(oen, getTTComparator());
-        step.getExitList().addAll(Arrays.asList(oex));
-        // we need to impose reverse order for the onEntry list
-        List entering = Arrays.asList(oen);
-        Collections.reverse(entering);
-        step.getEntryList().addAll(entering);
-        // reset 'done' flag
-        for (Iterator reset = entering.iterator(); reset.hasNext();) {
-            Object o = reset.next();
-            if (o instanceof State) {
-                ((State) o).setDone(false);
-            }
-        }
-    }
-
-    /**
-     * Go over the exit list and update history information for relevant 
states.
+     * Go over the exit list and update history information for
+     * relevant states.
      *
      * @param step
      *            [inout]
@@ -695,8 +671,8 @@
                 if (s.hasHistory()) {
                     Set shallow = null;
                     Set deep = null;
-                    Iterator j = s.getHistory().iterator();
-                    while (j.hasNext()) {
+                    for (Iterator j = s.getHistory().iterator();
+                            j.hasNext();) {
                         History h = (History) j.next();
                         if (h.isDeep()) {
                             if (deep == null) {
@@ -756,6 +732,70 @@
                 }
             }
             return false;
+        }
+    }
+
+    /**
+     * Follow the candidate transitions for this execution Step, and update the
+     * lists of entered and exited states accordingly.
+     *
+     * @param step The current Step
+     * @param errorReporter The ErrorReporter for the current environment
+     *
+     * @throws ModelException
+     *             in case there is a fatal SCXML object model problem.
+     */
+    public void followTransitions(final Step step,
+            final ErrorReporter errorReporter) throws ModelException {
+        Set currentStates = step.getBeforeStatus().getStates();
+        List transitions = step.getTransitList();
+        // DetermineExitedStates (currentStates, transitList) -> exitedStates
+        Set exitedStates = new HashSet();
+        for (Iterator i = transitions.iterator(); i.hasNext();) {
+            Transition t = (Transition) i.next();
+            Set ext = SCXMLHelper.getStatesExited(t, currentStates);
+            exitedStates.addAll(ext);
+        }
+        // compute residual states - these are preserved from the previous step
+        Set residual = new HashSet(currentStates);
+        residual.removeAll(exitedStates);
+        // SeedTargetSet (residual, transitList) -> seedSet
+        Set seedSet = seedTargetSet(residual, transitions, errorReporter);
+        // DetermineTargetStates (initialTargetSet) -> targetSet
+        Set targetSet = step.getAfterStatus().getStates();
+        targetSet.addAll(seedSet); //copy to preserve seedSet
+        determineTargetStates(targetSet, errorReporter);
+        // BuildOnEntryList (targetSet, seedSet) -> entryList
+        Set entered = SCXMLHelper.getAncestorClosure(targetSet, seedSet);
+        seedSet.clear();
+        for (Iterator i = transitions.iterator(); i.hasNext();) {
+            Transition t = (Transition) i.next();
+            entered.addAll(t.getPath().getDownwardSegment());
+        }
+        // Chech whether the computed state config is legal
+        targetSet.addAll(residual);
+        residual.clear();
+        if (!SCXMLHelper.isLegalConfig(targetSet, errorReporter)) {
+            throw new ModelException("Illegal state machine configuration!");
+        }
+        // sort onEntry and onExit according state hierarchy
+        Object[] oex = exitedStates.toArray();
+        exitedStates.clear();
+        Object[] oen = entered.toArray();
+        entered.clear();
+        Arrays.sort(oex, getTTComparator());
+        Arrays.sort(oen, getTTComparator());
+        step.getExitList().addAll(Arrays.asList(oex));
+        // we need to impose reverse order for the onEntry list
+        List entering = Arrays.asList(oen);
+        Collections.reverse(entering);
+        step.getEntryList().addAll(entering);
+        // reset 'done' flag
+        for (Iterator reset = entering.iterator(); reset.hasNext();) {
+            Object o = reset.next();
+            if (o instanceof State) {
+                ((State) o).setDone(false);
+            }
         }
     }
 

Modified: 
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/env/RootContext.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/env/RootContext.java?rev=289138&r1=289137&r2=289138&view=diff
==============================================================================
--- 
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/env/RootContext.java
 (original)
+++ 
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/env/RootContext.java
 Wed Sep 14 20:28:20 2005
@@ -32,7 +32,7 @@
 
     /** Host JSP's VariableResolver. */
     private VariableResolver vr;
-    /** Bark if JSP Context is null */
+    /** Bark if JSP Context is null. */
     private static final String ERR_HOST_JSP_CTX_NULL =
         "Host JSP Context cannot be null";
 

Modified: 
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/env/Tracer.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/env/Tracer.java?rev=289138&r1=289137&r2=289138&view=diff
==============================================================================
--- 
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/env/Tracer.java
 (original)
+++ 
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/env/Tracer.java
 Wed Sep 14 20:28:20 2005
@@ -195,15 +195,16 @@
         if (parent == null) {
             return "/" + tt.getId();
         } else {
-            LinkedList ll = new LinkedList();
+            LinkedList pathElements = new LinkedList();
+            pathElements.addFirst(tt);
             while (parent != null) {
-                ll.addFirst(parent);
+                pathElements.addFirst(parent);
                 parent = parent.getParent();
             }
             StringBuffer names = new StringBuffer();
-            for (Iterator i = ll.iterator(); i.hasNext();) {
-                TransitionTarget tmp = (TransitionTarget) i.next();
-                names.append('/').append(tmp.getId());
+            for (Iterator i = pathElements.iterator(); i.hasNext();) {
+                TransitionTarget pathElement = (TransitionTarget) i.next();
+                names.append('/').append(pathElement.getId());
             }
             return names.toString();
         }

Modified: 
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/model/History.java
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/model/History.java?rev=289138&r1=289137&r2=289138&view=diff
==============================================================================
--- 
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/model/History.java
 (original)
+++ 
jakarta/commons/sandbox/scxml/trunk/src/main/java/org/apache/commons/scxml/model/History.java
 Wed Sep 14 20:28:20 2005
@@ -127,5 +127,16 @@
         return false;
     }
 
+    /**
+     * Resets the history state.
+     *
+     * @see org.apache.commons.scxml.SCXMLExecutor#reset()
+     */
+    public final void reset() {
+        if (lastConfiguration != null) {
+            lastConfiguration.clear();
+        }
+    }
+
 }
 

Modified: 
jakarta/commons/sandbox/scxml/trunk/src/test/java/org/apache/commons/scxml/microwave-01.xml
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/sandbox/scxml/trunk/src/test/java/org/apache/commons/scxml/microwave-01.xml?rev=289138&r1=289137&r2=289138&view=diff
==============================================================================
--- 
jakarta/commons/sandbox/scxml/trunk/src/test/java/org/apache/commons/scxml/microwave-01.xml
 (original)
+++ 
jakarta/commons/sandbox/scxml/trunk/src/test/java/org/apache/commons/scxml/microwave-01.xml
 Wed Sep 14 20:28:20 2005
@@ -39,14 +39,14 @@
       <if cond="${empty cook_time}">
         <!-- default setting -->
         <var name="cook_time" expr="${5}"/>
+        <!-- timer variable -->
+        <var name="timer" expr="${0}"/>
       </if>
       <!-- again, door_closed should be a part of a global context -->
       <if cond="${empty door_closed}">
         <!-- default setting -->
         <var name="door_closed" expr="${true}"/>
       </if>
-      <!-- timer variable -->
-      <var name="timer" expr="${0}"/>
     </onentry>
 
     <transition event="turn_off">
@@ -79,6 +79,11 @@
         <target next="cooking"/>
       </transition>
     </state>
+
+    <onexit>
+      <!-- reset timer -->
+      <assign name="timer" expr="${0}"/>
+    </onexit>
 
   </state>
 

Modified: 
jakarta/commons/sandbox/scxml/trunk/src/test/java/org/apache/commons/scxml/microwave-02.xml
URL: 
http://svn.apache.org/viewcvs/jakarta/commons/sandbox/scxml/trunk/src/test/java/org/apache/commons/scxml/microwave-02.xml?rev=289138&r1=289137&r2=289138&view=diff
==============================================================================
--- 
jakarta/commons/sandbox/scxml/trunk/src/test/java/org/apache/commons/scxml/microwave-02.xml
 (original)
+++ 
jakarta/commons/sandbox/scxml/trunk/src/test/java/org/apache/commons/scxml/microwave-02.xml
 Wed Sep 14 20:28:20 2005
@@ -49,9 +49,9 @@
             <if cond="${empty cook_time}">
               <!-- default setting -->
               <var name="cook_time" expr="${5}"/>
+              <!-- timer variable -->
+              <var name="timer" expr="${0}"/>
             </if>
-            <!-- timer variable -->
-            <var name="timer" expr="${0}"/>
           </onentry>
           
           <transition event="turn_off">
@@ -77,6 +77,11 @@
               <target next="cooking"/>
             </transition>
           </state>
+
+          <onexit>
+            <!-- reset timer -->
+            <assign name="timer" expr="${0}"/>
+          </onexit>
         </state>
       </state>
 



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to