commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From a..@apache.org
Subject svn commit: r1588973 - in /commons/proper/scxml/trunk/src: main/java/org/apache/commons/scxml2/ main/java/org/apache/commons/scxml2/semantics/ test/java/org/apache/commons/scxml2/
Date Mon, 21 Apr 2014 19:36:00 GMT
Author: ate
Date: Mon Apr 21 19:36:00 2014
New Revision: 1588973

URL: http://svn.apache.org/r1588973
Log:
SCXML-203: Calculation of states to be entered can be depending on states to be exited and
thereby also their possible history
- fixing this bug by temporarily pre-recording the histories of exited states in the Step
- this allows to still ensure that the resulting active states represent a valid configuration,
before actually taking the step
- also cleanup and improve the naming of the state history management APIs

Modified:
    commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/SCInstance.java
    commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/semantics/SCXMLSemanticsImpl.java
    commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/semantics/Step.java
    commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/SCInstanceTest.java

Modified: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/SCInstance.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/SCInstance.java?rev=1588973&r1=1588972&r2=1588973&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/SCInstance.java (original)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/SCInstance.java Mon
Apr 21 19:36:00 2014
@@ -17,6 +17,7 @@
 package org.apache.commons.scxml2;
 
 import java.io.Serializable;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -437,8 +438,7 @@ public class SCInstance implements Seria
     public Set<EnterableState> getLastConfiguration(final History history) {
         Set<EnterableState> lastConfiguration = histories.get(history);
         if (lastConfiguration == null) {
-            lastConfiguration = new HashSet<EnterableState>();
-            histories.put(history, lastConfiguration);
+            lastConfiguration = Collections.emptySet();
         }
         return lastConfiguration;
     }
@@ -451,20 +451,7 @@ public class SCInstance implements Seria
      */
     public void setLastConfiguration(final History history,
             final Set<EnterableState> lc) {
-        Set<EnterableState> lastConfiguration = getLastConfiguration(history);
-        lastConfiguration.clear();
-        lastConfiguration.addAll(lc);
-    }
-
-    /**
-     * Check whether we have prior history.
-     *
-     * @param history The history.
-     * @return Whether we have a non-empty last configuration
-     */
-    public boolean isEmpty(final History history) {
-        Set<EnterableState> lastConfiguration = histories.get(history);
-        return lastConfiguration == null || lastConfiguration.isEmpty();
+        histories.put(history, new HashSet<EnterableState>(lc));
     }
 
     /**
@@ -474,11 +461,8 @@ public class SCInstance implements Seria
      *
      * @param history The history.
      */
-    public void reset(final History history) {
-        Set<EnterableState> lastConfiguration = histories.get(history);
-        if (lastConfiguration != null) {
-            lastConfiguration.clear();
-        }
+    public void resetConfiguration(final History history) {
+        histories.remove(history);
     }
 }
 

Modified: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/semantics/SCXMLSemanticsImpl.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/semantics/SCXMLSemanticsImpl.java?rev=1588973&r1=1588972&r2=1588973&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/semantics/SCXMLSemanticsImpl.java
(original)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/semantics/SCXMLSemanticsImpl.java
Mon Apr 21 19:36:00 2014
@@ -248,6 +248,7 @@ public class SCXMLSemanticsImpl implemen
         exitStates(exctx, step, statesToInvoke);
         executeTransitionContent(exctx, step);
         enterStates(exctx, step, statesToInvoke);
+        step.clearIntermediateState();
     }
 
     /**
@@ -258,14 +259,11 @@ public class SCXMLSemanticsImpl implemen
      * @throws ModelException if the result of taking the transitions would lead to an illegal
configuration
      */
     public void buildStep(final SCXMLExecutionContext exctx, final Step step) throws ModelException
{
-        step.getExitSet().clear();
-        step.getEntrySet().clear();
-        step.getDefaultEntrySet().clear();
-        step.getDefaultHistoryTransitionEntryMap().clear();
+        step.clearIntermediateState();
 
-        // compute exitSet, if there is something to exit
+        // compute exitSet, if there is something to exit and record their History configurations
if applicable
         if (!exctx.getScInstance().getCurrentStatus().getStates().isEmpty()) {
-            computeExitSet(step, exctx.getScInstance().getCurrentStatus().getAllStates());
+            computeExitSet(step, exctx.getScInstance().getCurrentStatus());
         }
         // compute entrySet
         computeEntrySet(exctx, step);
@@ -339,11 +337,15 @@ public class SCXMLSemanticsImpl implemen
      * This method corresponds to the Algorithm for SCXML processing computeExitSet() procedure.
      * <p>
      * @param step The step containing the list of transitions to be taken
-     * @param configuration The current configuration of the state machine ({@link Status#getAllStates()}).
+     * @param currentStatus The current status of the state machine ({@link SCInstance#getCurrentStatus()}).
      */
-    public void computeExitSet(final Step step, final Set<EnterableState> configuration)
{
-        for (SimpleTransition st : step.getTransitList()) {
-            computeExitSet(st, step.getExitSet(), configuration);
+    public void computeExitSet(final Step step, final Status currentStatus) {
+        if (!currentStatus.getStates().isEmpty()) {
+            Set<EnterableState> configuration = currentStatus.getAllStates();
+            for (SimpleTransition st : step.getTransitList()) {
+                computeExitSet(st, step.getExitSet(), configuration);
+            }
+            recordHistory(step, currentStatus.getStates(), configuration);
         }
     }
 
@@ -374,6 +376,52 @@ public class SCXMLSemanticsImpl implemen
     }
 
     /**
+     * Record the history configurations for states to exit if applicable and temporarily
store this in the step.
+     * <p>
+     * These history configurations must be pre-recorded as they might impact (re)entrance
calculation during
+     * {@link #computeEntrySet(SCXMLExecutionContext, Step)}.
+     * </p>
+     * <p>
+     * Only after the new configuration has been validated (see: {@link #isLegalConfig(Set,
ErrorReporter)}), the
+     * history configurations will be persisted during the actual {@link #exitStates(SCXMLExecutionContext,
Step, Set)}
+     * processing.
+     * </p>
+     * @param step The step containing the list of states to exit, and the map to record
the new history configurations
+     * @param states The current set of active atomic states in the state machine
+     * @param allStates The current set of all active states in the state machine
+     */
+    public void recordHistory(final Step step, final Set<EnterableState> states, final
Set<EnterableState> allStates) {
+        for (EnterableState es : step.getExitSet()) {
+            if (es instanceof TransitionalState && ((TransitionalState)es).hasHistory())
{
+                TransitionalState ts = (TransitionalState)es;
+                Set<EnterableState> shallow = null;
+                Set<EnterableState> deep = null;
+                for (History h : ts.getHistory()) {
+                    if (h.isDeep()) {
+                        if (deep == null) {
+                            //calculate deep history for a given state once
+                            deep = new HashSet<EnterableState>();
+                            for (EnterableState ott : states) {
+                                if (ott.isDescendantOf(es)) {
+                                    deep.add(ott);
+                                }
+                            }
+                        }
+                        step.getNewHistoryConfigurations().put(h, deep);
+                    } else {
+                        if (shallow == null) {
+                            //calculate shallow history for a given state once
+                            shallow = new HashSet<EnterableState>(ts.getChildren());
+                            shallow.retainAll(allStates);
+                        }
+                        step.getNewHistoryConfigurations().put(h, shallow);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
      * Compute and store the set of states to enter for the current list of transitions in
the provided step.
      * <p>
      * This method corresponds to the Algorithm for SCXML processing computeEntrySet() procedure.
@@ -420,14 +468,18 @@ public class SCXMLSemanticsImpl implemen
                                               final TransitionTarget tt) {
         if (tt instanceof History) {
             History h = (History) tt;
-            if (exctx.getScInstance().isEmpty(h)) {
-                step.getDefaultHistoryTransitionEntryMap().put(h.getParent(), h.getTransition());
+            Set<EnterableState> lastConfiguration = step.getNewHistoryConfigurations().get(h);
+            if (lastConfiguration == null) {
+                lastConfiguration = exctx.getScInstance().getLastConfiguration(h);
+            }
+            if (lastConfiguration.isEmpty()) {
+                step.getDefaultHistoryTransitions().put(h.getParent(), h.getTransition());
                 for (TransitionTarget dtt : h.getTransition().getTargets()) {
                     addDescendantStatesToEnter(exctx, step, dtt);
                     addAncestorStatesToEnter(exctx, step, dtt, tt.getParent());
                 }
             } else {
-                for (TransitionTarget dtt : exctx.getScInstance().getLastConfiguration(h))
{
+                for (TransitionTarget dtt : lastConfiguration) {
                     addDescendantStatesToEnter(exctx, step, dtt);
                     addAncestorStatesToEnter(exctx, step, dtt, tt.getParent());
                 }
@@ -841,39 +893,15 @@ public class SCXMLSemanticsImpl implemen
         if (step.getExitSet().isEmpty()) {
             return;
         }
-        Set<EnterableState> configuration = null;
         ArrayList<EnterableState> exitList = new ArrayList<EnterableState>(step.getExitSet());
         Collections.sort(exitList, DocumentOrder.reverseDocumentOrderComparator);
 
         for (EnterableState es : exitList) {
 
             if (es instanceof TransitionalState && ((TransitionalState)es).hasHistory())
{
-                TransitionalState ts = (TransitionalState)es;
-                Set<EnterableState> shallow = null;
-                Set<EnterableState> deep = null;
-                for (History h : ts.getHistory()) {
-                    if (h.isDeep()) {
-                        if (deep == null) {
-                            //calculate deep history for a given state once
-                            deep = new HashSet<EnterableState>();
-                            for (EnterableState ott : exctx.getScInstance().getCurrentStatus().getStates())
{
-                                if (ott.isDescendantOf(es)) {
-                                    deep.add(ott);
-                                }
-                            }
-                        }
-                        exctx.getScInstance().setLastConfiguration(h, deep);
-                    } else {
-                        if (shallow == null) {
-                            //calculate shallow history for a given state once
-                            if (configuration == null) {
-                                configuration = exctx.getScInstance().getCurrentStatus().getAllStates();
-                            }
-                            shallow = new HashSet<EnterableState>(ts.getChildren());
-                            shallow.retainAll(configuration);
-                        }
-                        exctx.getScInstance().setLastConfiguration(h, shallow);
-                    }
+                // persist the new history configurations for this state to exit
+                for (History h : ((TransitionalState)es).getHistory()) {
+                    exctx.getScInstance().setLastConfiguration(h, step.getNewHistoryConfigurations().get(h));
                 }
             }
 
@@ -977,7 +1005,7 @@ public class SCXMLSemanticsImpl implemen
         Collections.sort(entryList, DocumentOrder.documentOrderComparator);
         for (EnterableState es : entryList) {
             if (es.isAtomicState()) {
-                // only track actomic active states in Status
+                // only track atomic active states in Status
                 exctx.getScInstance().getCurrentStatus().getStates().add(es);
             }
             if (es instanceof TransitionalState && !((TransitionalState)es).getInvokes().isEmpty())
{
@@ -999,7 +1027,7 @@ public class SCXMLSemanticsImpl implemen
                 executeContent(exctx, ((State)es).getInitial().getTransition());
             }
             if (es instanceof TransitionalState) {
-                SimpleTransition hTransition = step.getDefaultHistoryTransitionEntryMap().get(es);
+                SimpleTransition hTransition = step.getDefaultHistoryTransitions().get(es);
                 if (hTransition != null) {
                     executeContent(exctx, hTransition);
                 }

Modified: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/semantics/Step.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/semantics/Step.java?rev=1588973&r1=1588972&r2=1588973&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/semantics/Step.java
(original)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/semantics/Step.java
Mon Apr 21 19:36:00 2014
@@ -25,6 +25,7 @@ import java.util.Set;
 
 import org.apache.commons.scxml2.TriggerEvent;
 import org.apache.commons.scxml2.model.EnterableState;
+import org.apache.commons.scxml2.model.History;
 import org.apache.commons.scxml2.model.SimpleTransition;
 import org.apache.commons.scxml2.model.TransitionalState;
 
@@ -54,7 +55,16 @@ public class Step {
      */
     private Set<EnterableState> defaultEntrySet;
 
-    private Map<TransitionalState, SimpleTransition> defaultHistoryTransitionEntryMap;
+    /**
+     * The map of default History transitions to be executed as result of entering states
in this step.
+     */
+    private Map<TransitionalState, SimpleTransition> defaultHistoryTransitions;
+
+    /**
+     * The map of new History configurations created as result of exiting states in this
step
+     */
+    private Map<History, Set<EnterableState>> newHistoryConfigurations;
+
     /**
      * The list of Transitions taken during this step.
      */
@@ -68,11 +78,23 @@ public class Step {
         this.exitSet = new HashSet<EnterableState>();
         this.entrySet = new HashSet<EnterableState>();
         this.defaultEntrySet = new HashSet<EnterableState>();
-        this.defaultHistoryTransitionEntryMap = new HashMap<TransitionalState, SimpleTransition>();
+        this.defaultHistoryTransitions = new HashMap<TransitionalState, SimpleTransition>();
+        this.newHistoryConfigurations = new HashMap<History, Set<EnterableState>>();
         this.transitList = new ArrayList<SimpleTransition>();
     }
 
     /**
+     * Ensure the intermediate state of this step is cleared before start processing the
event and/or transitions
+     */
+    public void clearIntermediateState() {
+        exitSet.clear();
+        entrySet.clear();
+        defaultEntrySet.clear();
+        defaultHistoryTransitions.clear();
+        newHistoryConfigurations.clear();
+    }
+
+    /**
      * @return Returns the entrySet.
      */
     public Set<EnterableState> getEntrySet() {
@@ -87,10 +109,17 @@ public class Step {
     }
 
     /**
-     * @return Returns the defaultHistoryTransitionEntryMap.
+     * @return Returns the map of default History transitions to be executed as result of
entering states in this step
+     */
+    public Map<TransitionalState, SimpleTransition> getDefaultHistoryTransitions()
{
+        return defaultHistoryTransitions;
+    }
+
+    /**
+     * @return Returns the map of new History configurations created as result of exiting
states in this step
      */
-    public Map<TransitionalState, SimpleTransition> getDefaultHistoryTransitionEntryMap()
{
-        return defaultHistoryTransitionEntryMap;
+    public Map<History, Set<EnterableState>> getNewHistoryConfigurations() {
+        return newHistoryConfigurations;
     }
 
     /**

Modified: commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/SCInstanceTest.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/SCInstanceTest.java?rev=1588973&r1=1588972&r2=1588973&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/SCInstanceTest.java
(original)
+++ commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/SCInstanceTest.java
Mon Apr 21 19:36:00 2014
@@ -144,7 +144,7 @@ public class SCInstanceTest {
     
     @Test
     public void testIsEmpty() {
-        Assert.assertTrue(instance.isEmpty(new History()));
+        Assert.assertTrue(instance.getLastConfiguration(new History()).isEmpty());
     }
     
     @Test
@@ -158,7 +158,7 @@ public class SCInstanceTest {
         
         instance.setLastConfiguration(history, configuration);  
 
-        Assert.assertFalse(instance.isEmpty(history));
+        Assert.assertFalse(instance.getLastConfiguration(history).isEmpty());
     }
     
     @Test
@@ -172,9 +172,9 @@ public class SCInstanceTest {
         
         instance.setLastConfiguration(history, configuration);  
 
-        instance.reset(history);
+        instance.resetConfiguration(history);
         
-        Assert.assertTrue(instance.isEmpty(history));
+        Assert.assertTrue(instance.getLastConfiguration(history).isEmpty());
     }
     
 }



Mime
View raw message