You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by at...@apache.org on 2014/04/03 09:13:44 UTC

svn commit: r1584272 [3/6] - in /commons/proper/scxml/trunk/src: main/java/org/apache/commons/scxml2/ main/java/org/apache/commons/scxml2/env/ main/java/org/apache/commons/scxml2/env/groovy/ main/java/org/apache/commons/scxml2/env/javascript/ main/java...

Modified: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/EnterableState.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/EnterableState.java?rev=1584272&r1=1584271&r2=1584272&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/EnterableState.java (original)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/EnterableState.java Thu Apr  3 07:13:42 2014
@@ -16,6 +16,9 @@
  */
 package org.apache.commons.scxml2.model;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * An abstract base class for state elements in SCXML that can be entered, such as State, Parallel or Final.
  */
@@ -27,23 +30,21 @@ public abstract class EnterableState ext
     private int order;
 
     /**
-     * Optional property holding executable content to be run upon
+     * List of optional OnEntry elements holding executable content to be run upon
      * entering this transition target.
      */
-    private OnEntry onEntry;
+    private List<OnEntry> onEntries;
 
     /**
-     * Optional property holding executable content to be run upon
+     * List of optional OnExit elements holding executable content to be run upon
      * exiting this transition target.
      */
-    private OnExit onExit;
+    private List<OnExit> onExits;
 
     public EnterableState() {
         super();
-        onEntry = new OnEntry(); //empty defaults
-        onEntry.setParent(this);
-        onExit = new OnExit();   //empty defaults
-        onExit.setParent(this);
+        onEntries = new ArrayList<OnEntry>();
+        onExits = new ArrayList<OnExit>();
     }
 
     /**
@@ -65,40 +66,49 @@ public abstract class EnterableState ext
     }
 
     /**
-     * Get the onentry property.
+     * Get the OnEntry elements.
      *
-     * @return Returns the onEntry.
+     * @return Returns the onEntry elements
      */
-    public final OnEntry getOnEntry() {
-        return onEntry;
+    public final List<OnEntry> getOnEntries() {
+        return onEntries;
     }
 
     /**
-     * Set the onentry property.
+     * Adds an OnEntry element
      *
-     * @param onEntry The onEntry to set.
+     * @param onEntry The onEntry to add.
      */
-    public final void setOnEntry(final OnEntry onEntry) {
-        this.onEntry = onEntry;
-        this.onEntry.setParent(this);
+    public final void addOnEntry(final OnEntry onEntry) {
+        onEntry.setParent(this);
+        onEntries.add(onEntry);
     }
 
     /**
-     * Get the onexit property.
+     * Get the OnExit elements
      *
-     * @return Returns the onExit.
+     * @return Returns the onExit elements
      */
-    public final OnExit getOnExit() {
-        return onExit;
+    public final List<OnExit> getOnExits() {
+        return onExits;
     }
 
     /**
-     * Set the onexit property.
+     * Add an OnExit element
      *
-     * @param onExit The onExit to set.
+     * @param onExit The onExit to add.
      */
-    public final void setOnExit(final OnExit onExit) {
-        this.onExit = onExit;
-        this.onExit.setParent(this);
+    public final void addOnExit(final OnExit onExit) {
+        onExit.setParent(this);
+        onExits.add(onExit);
     }
+
+    /**
+     * Check whether this is an atomic state.
+     * <p>
+     * An atomic state is a state of type Final or of type State without children,
+     * </p>
+     * @return Returns true if this is an atomic state.
+     */
+    public abstract boolean isAtomicState();
 }

Modified: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Final.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Final.java?rev=1584272&r1=1584271&r2=1584272&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Final.java (original)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Final.java Thu Apr  3 07:13:42 2014
@@ -51,5 +51,13 @@ public class Final extends EnterableStat
     public final void setParent(State parent) {
         super.setParent(parent);
     }
+
+    /**
+     * {@inheritDoc}
+     * @return Returns always true (a state of type Final is always atomic)
+     */
+    public final boolean isAtomicState() {
+        return true;
+    }
 }
 

Modified: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Invoke.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Invoke.java?rev=1584272&r1=1584271&r2=1584272&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Invoke.java (original)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Invoke.java Thu Apr  3 07:13:42 2014
@@ -59,6 +59,11 @@ public class Invoke implements Namespace
     private String srcexpr;
 
     /**
+     * A flag indicating whether to forward events to the invoked process.
+     */
+    private Boolean autoForward;
+
+    /**
      * The List of the params to be sent to the invoked process.
      */
     private final List<Param> paramsList;
@@ -160,6 +165,29 @@ public class Invoke implements Namespace
         this.srcexpr = srcexpr;
     }
 
+
+    /**
+     * @return Returns true if all external events should be forwarded to the invoked process.
+     */
+    public final boolean isAutoForward() {
+        return autoForward != null && autoForward;
+    }
+
+    /**
+     * @return Returns the flag indicating whether to forward events to the invoked process.
+     */
+    public final Boolean getAutoForward() {
+        return autoForward;
+    }
+
+    /**
+     * Set the flag indicating whether to forward events to the invoked process.
+     * @param autoForward the flag
+     */
+    public final void setAutoForward(final Boolean autoForward) {
+        this.autoForward = autoForward;
+    }
+
     /**
      * Get the list of {@link Param}s.
      *

Modified: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/OnEntry.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/OnEntry.java?rev=1584272&r1=1584271&r2=1584272&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/OnEntry.java (original)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/OnEntry.java Thu Apr  3 07:13:42 2014
@@ -31,6 +31,11 @@ public class OnEntry extends Executable 
     private static final long serialVersionUID = 1L;
 
     /**
+     * An indicator whether to raise the non-standard "entry.state.id" internal event after executing this OnEntry
+     */
+    private Boolean raiseEvent;
+
+    /**
      * Constructor.
      */
     public OnEntry() {
@@ -46,5 +51,28 @@ public class OnEntry extends Executable 
     public final void setParent(final EnterableState parent) {
         super.setParent(parent);
     }
+
+    /**
+     * @return true if the non-standard internal "entry.state.id" event will be raised after executing this OnEntry
+     */
+    public final boolean isRaiseEvent() {
+        return raiseEvent != null && raiseEvent;
+    }
+
+    /**
+     * @return The indicator whether to raise the non-standard "entry.state.id" internal event after executing
+     *         this OnEntry. When null no event will be raised
+     */
+    public final Boolean getRaiseEvent() {
+        return raiseEvent;
+    }
+
+    /**
+     * Set the indicator whether to raise the non-standard "entry.state.id" internal event after executing this OnEntry.
+     * @param raiseEvent The indicator, when null no event will be raised
+     */
+    public final void setRaiseEvent(final Boolean raiseEvent) {
+        this.raiseEvent = raiseEvent;
+    }
 }
 

Modified: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/OnExit.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/OnExit.java?rev=1584272&r1=1584271&r2=1584272&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/OnExit.java (original)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/OnExit.java Thu Apr  3 07:13:42 2014
@@ -31,6 +31,11 @@ public class OnExit extends Executable {
     private static final long serialVersionUID = 1L;
 
     /**
+     * An indicator whether to raise the non-standard "exit.state.id" internal event after executing this OnExit
+     */
+    private Boolean raiseEvent;
+
+    /**
      * Constructor.
      */
     public OnExit() {
@@ -46,5 +51,28 @@ public class OnExit extends Executable {
     public final void setParent(final EnterableState parent) {
         super.setParent(parent);
     }
+
+    /**
+     * @return Returns true if the non-standard internal "exit.state.id" event will be raised after executing this OnExit
+     */
+    public final boolean isRaiseEvent() {
+        return raiseEvent != null && raiseEvent;
+    }
+
+    /**
+     * @return Returns the indicator whether to raise the non-standard "exit.state.id" internal event after executing
+     *         this OnExit. When null no event will be raised
+     */
+    public final Boolean getRaiseEvent() {
+        return raiseEvent;
+    }
+
+    /**
+     * Set the indicator whether to raise the non-standard "exit.state.id" internal event after executing this OnExit.
+     * @param raiseEvent The indicator, when null no event will be raised
+     */
+    public final void setRaiseEvent(final Boolean raiseEvent) {
+        this.raiseEvent = raiseEvent;
+    }
 }
 

Modified: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Parallel.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Parallel.java?rev=1584272&r1=1584271&r2=1584272&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Parallel.java (original)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Parallel.java Thu Apr  3 07:13:42 2014
@@ -39,6 +39,13 @@ public class Parallel extends Transition
     }
 
     /**
+     * {@inheritDoc}
+     * @return Returns always false (a state of type Parallel is never atomic)
+     */
+    public final boolean isAtomicState() {
+        return false;
+    }
+    /**
      * Add a TransitionalState (State or Parallel) child
      * @param ts the child to add
      */

Modified: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/SCXML.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/SCXML.java?rev=1584272&r1=1584271&r2=1584272&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/SCXML.java (original)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/SCXML.java Thu Apr  3 07:13:42 2014
@@ -48,11 +48,6 @@ public class SCXML implements Serializab
     public static final String GENERATED_TT_ID_PREFIX = "_generated_tt_id_";
 
     /**
-     * The pseudo SCXML {@link SimpleTransition#getTransitionDomain()}
-     */
-    public static final TransitionalState SCXML_TRANSITION_DOMAIN = new TransitionalState(){};
-
-    /**
      * The predefined observableId with value 0 (zero) for this SCXML state machine
      */
     private static final Integer SCXML_OBSERVABLE_ID = 0;

Modified: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Send.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Send.java?rev=1584272&r1=1584271&r2=1584272&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Send.java (original)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Send.java Thu Apr  3 07:13:42 2014
@@ -27,7 +27,6 @@ import org.apache.commons.scxml2.ActionE
 import org.apache.commons.scxml2.Context;
 import org.apache.commons.scxml2.Evaluator;
 import org.apache.commons.scxml2.SCXMLExpressionException;
-import org.apache.commons.scxml2.SCXMLHelper;
 import org.apache.commons.scxml2.TriggerEvent;
 import org.apache.commons.scxml2.semantics.ErrorConstants;
 import org.w3c.dom.Node;
@@ -269,22 +268,22 @@ public class Send extends Action impleme
         // Most attributes of <send> are expressions so need to be
         // evaluated before the EventDispatcher callback
         Object hintsValue = null;
-        if (!SCXMLHelper.isStringEmpty(hints)) {
+        if (hints != null) {
             hintsValue = eval.eval(ctx, hints);
         }
         String targetValue = target;
-        if (!SCXMLHelper.isStringEmpty(target)) {
+        if (target != null) {
             targetValue = (String) eval.eval(ctx, target);
-            if (SCXMLHelper.isStringEmpty(targetValue)
+            if ((targetValue == null || targetValue.trim().length() == 0)
                     && exctx.getAppLog().isWarnEnabled()) {
                 exctx.getAppLog().warn("<send>: target expression \"" + target
                     + "\" evaluated to null or empty String");
             }
         }
         String typeValue;
-        if (!SCXMLHelper.isStringEmpty(type)) {
+        if (type != null) {
             typeValue = (String) eval.eval(ctx, type);
-            if (SCXMLHelper.isStringEmpty(typeValue)
+            if ((typeValue == null || typeValue.trim().length() == 0)
                     && exctx.getAppLog().isWarnEnabled()) {
                 exctx.getAppLog().warn("<send>: type expression \"" + type
                     + "\" evaluated to null or empty String");
@@ -294,7 +293,7 @@ public class Send extends Action impleme
             typeValue = TYPE_SCXML;
         }
         Map<String, Object> params = null;
-        if (!SCXMLHelper.isStringEmpty(namelist)) {
+        if (namelist != null) {
             StringTokenizer tkn = new StringTokenizer(namelist);
             params = new HashMap<String, Object>(tkn.countTokens());
             while (tkn.hasMoreTokens()) {
@@ -309,7 +308,7 @@ public class Send extends Action impleme
             }
         }
         long wait = 0L;
-        if (!SCXMLHelper.isStringEmpty(delay)) {
+        if (delay != null) {
             Object delayValue = eval.eval(ctx, delay);
             if (delayValue != null) {
                 String delayString = delayValue.toString();
@@ -317,10 +316,9 @@ public class Send extends Action impleme
             }
         }
         String eventValue = event;
-        if (!SCXMLHelper.isStringEmpty(event)) {
+        if (event != null) {
             eventValue = (String) eval.eval(ctx, event);
-            if (SCXMLHelper.isStringEmpty(eventValue)
-                    && exctx.getAppLog().isWarnEnabled()) {
+            if ((eventValue == null || eventValue.trim().length() == 0) && exctx.getAppLog().isWarnEnabled()) {
                 exctx.getAppLog().warn("<send>: event expression \"" + event
                     + "\" evaluated to null or empty String");
             }
@@ -328,7 +326,7 @@ public class Send extends Action impleme
         // Lets see if we should handle it ourselves
         if (typeValue != null
               && typeValue.trim().equalsIgnoreCase(TYPE_SCXML)) {
-            if (SCXMLHelper.isStringEmpty(targetValue)) {
+            if (targetValue == null || targetValue.trim().length() == 0) {
                 // TODO: Remove both short-circuit passes in v1.0
                 if (wait == 0L) {
                     if (exctx.getAppLog().isDebugEnabled()) {
@@ -378,7 +376,7 @@ public class Send extends Action impleme
         long wait = 0L;
         long multiplier = 1L;
 
-        if (!SCXMLHelper.isStringEmpty(delayString)) {
+        if (delayString != null && delayString.trim().length() > 0) {
 
             String trimDelay = delayString.trim();
             String numericDelay = trimDelay;

Modified: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/SimpleTransition.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/SimpleTransition.java?rev=1584272&r1=1584271&r2=1584272&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/SimpleTransition.java (original)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/SimpleTransition.java Thu Apr  3 07:13:42 2014
@@ -16,9 +16,9 @@
  */
 package org.apache.commons.scxml2.model;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * The class in this SCXML object model that corresponds to the
@@ -52,18 +52,23 @@ public class SimpleTransition extends Ex
     private TransitionalState transitionDomain;
 
     /**
+     * Internal flag indicating a null transitionDomain was derived to be the SCXML Document itself.
+     */
+    private boolean scxmlTransitionDomain;
+
+    /**
      * Derived effective Transition type.
      * @see #isTypeInternal()
      */
     private Boolean typeInternal;
 
     /**
-     * Optional property that specifies the new state(s) or parallel
+     * Optional property that specifies the new state(s) or parallel(s)
      * element to transition to. May be specified by reference or in-line.
      * If multiple state(s) are specified, they must belong to the regions
      * of the same parallel.
      */
-    private List<TransitionTarget> targets;
+    private Set<TransitionTarget> targets;
 
     /**
      * The transition target ID
@@ -71,13 +76,6 @@ public class SimpleTransition extends Ex
     private String next;
 
     /**
-     * The path(s) for this transition, one per target, in the same order
-     * as <code>targets</code>.
-     * @see Path
-     */
-    private List<Path> paths;
-
-    /**
      * The current XML namespaces in the SCXML document for this action node,
      * preserved for deferred XPath evaluation.
      */
@@ -88,8 +86,7 @@ public class SimpleTransition extends Ex
      */
     public SimpleTransition() {
         super();
-        this.targets = new ArrayList<TransitionTarget>();
-        this.paths = new ArrayList<Path>();
+        this.targets = new HashSet<TransitionTarget>();
     }
 
     private boolean isCompoundStateParent(TransitionalState ts) {
@@ -171,14 +168,11 @@ public class SimpleTransition extends Ex
             typeInternal = TransitionType.internal == type && isCompoundStateParent(getParent());
 
             if (typeInternal && targets.size() > 0) {
-                for (Path p : getPaths()) {
-                    // TODO: testing the following actual works and always is correct
-                    if (p.getPathScope() == null || p.getPathScope() == getParent()) {
-                        continue;
+                for (TransitionTarget tt : targets) {
+                    if (!tt.isDescendantOf(getParent())) {
+                        typeInternal = false;
+                        break;
                     }
-                    // not a proper descendant
-                    typeInternal = false;
-                    break;
                 }
             }
         }
@@ -188,7 +182,10 @@ public class SimpleTransition extends Ex
     /**
      * Returns the transition domain of this transition
      * <p>
-     * If this transition is target-less, null is returned.
+     * If this transition is target-less OR if its transition domain is the SCXML document itself, null is returned.
+     * </p>
+     * <p>
+     * This method therefore only is useful to be invoked if the transition has targets!
      * </p>
      * <p>
      * If the transition has targets then the transition domain is the compound State parent such that:
@@ -197,13 +194,14 @@ public class SimpleTransition extends Ex
      *   <li>no descendant of it has this property</li>
      * </ul>
      * If there is no such compound state parent, the transition domain effectively becomes the SCXML document itself,
-     * which is indicated by the returned pseudo {@link SCXML#SCXML_TRANSITION_DOMAIN} transitionDomain.
+     * which is not a (Transitional)State, and thus null will be returned instead.
      * </p>
      *
      * @return The transition domain of this transition
      */
     public TransitionalState getTransitionDomain() {
-        if (transitionDomain == null && targets.size() > 0) {
+        TransitionalState ts = transitionDomain;
+        if (ts == null && targets.size() > 0 && !scxmlTransitionDomain) {
 
             if (getParent() != null) {
                 if (isTypeInternal()) {
@@ -215,7 +213,7 @@ public class SimpleTransition extends Ex
                         if (isCompoundStateParent(getParent().getAncestor(i))) {
                             boolean allDescendants = true;
                             for (TransitionTarget tt : targets) {
-                                if (i > tt.getNumberOfAncestors()) {
+                                if (i >= tt.getNumberOfAncestors()) {
                                     i = tt.getNumberOfAncestors();
                                     allDescendants = false;
                                     break;
@@ -233,11 +231,12 @@ public class SimpleTransition extends Ex
                     }
                 }
             }
-            if (transitionDomain == null) {
-                transitionDomain = SCXML.SCXML_TRANSITION_DOMAIN;
+            ts = transitionDomain;
+            if (ts == null) {
+                scxmlTransitionDomain = true;
             }
         }
-        return transitionDomain;
+        return ts;
     }
 
     /**
@@ -259,35 +258,14 @@ public class SimpleTransition extends Ex
     }
 
     /**
-     * Get the list of transition targets (may be an empty list).
+     * Get the set of transition targets (may be an empty list).
      *
      * @return Returns the target(s) as specified in SCXML markup.
      * <p>Remarks: Is <code>empty</code> for &quot;stay&quot; transitions.
-     * Contains parent (the source node) for &quot;self&quot; transitions.</p>
      *
      * @since 0.7
      */
-    public final List<TransitionTarget> getTargets() {
-        return targets;
-    }
-
-    /**
-     * Get the list of runtime transition target, which always contains
-     * atleast one TransitionTarget instance.
-     *
-     * @return Returns the actual targets of a transition at runtime.
-     * <p>Remarks: For both the &quot;stay&quot; and &quot;self&quot;
-     * transitions it returns parent (the source node). This method should
-     * never return an empty list or <code>null</code>.</p>
-     *
-     * @since 0.7
-     */
-    public final List<TransitionTarget> getRuntimeTargets() {
-        if (targets.size() == 0) {
-            List<TransitionTarget> runtimeTargets = new ArrayList<TransitionTarget>();
-            runtimeTargets.add(getParent());
-            return runtimeTargets;
-        }
+    public final Set<TransitionTarget> getTargets() {
         return targets;
     }
 
@@ -310,26 +288,4 @@ public class SimpleTransition extends Ex
     public final void setNext(final String next) {
         this.next = next;
     }
-
-    /**
-     * Get the path(s) of this transiton.
-     *
-     * @see Path
-     * @return List returns the list of transition path(s)
-     *
-     * @since 0.7
-     */
-    public final List<Path> getPaths() {
-        if (paths.size() == 0) {
-            if (targets.size() > 0) {
-                int i = 0;
-                for (TransitionTarget tt : targets) {
-                    paths.add(i++, new Path(getParent(), tt));
-                }
-            } else {
-                paths.add(new Path(getParent(), null));
-            }
-        }
-        return paths;
-    }
 }

Modified: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/State.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/State.java?rev=1584272&r1=1584271&r2=1584272&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/State.java (original)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/State.java Thu Apr  3 07:13:42 2014
@@ -93,12 +93,20 @@ public class State extends TransitionalS
     }
 
     /**
+     * {@inheritDoc}
+     * @return Returns true if this State has no children
+     */
+    public final boolean isAtomicState() {
+        return getChildren().isEmpty();
+    }
+
+    /**
      * Check whether this is a simple (leaf) state (UML terminology).
      *
      * @return true if this is a simple state, otherwise false
      */
     public final boolean isSimple() {
-        return getChildren().isEmpty();
+        return isAtomicState();
     }
 
     /**

Modified: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Transition.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Transition.java?rev=1584272&r1=1584271&r2=1584272&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Transition.java (original)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Transition.java Thu Apr  3 07:13:42 2014
@@ -21,8 +21,6 @@ import java.util.Collections;
 import java.util.List;
 import java.util.StringTokenizer;
 
-import org.apache.commons.scxml2.SCXMLHelper;
-
 /**
  * The class in this SCXML object model that corresponds to the
  * &lt;transition&gt; SCXML element. Transition rules are triggered
@@ -103,7 +101,7 @@ public class Transition extends SimpleTr
      * @param cond The cond to set.
      */
     public void setCond(final String cond) {
-        this.cond = SCXMLHelper.isStringEmpty(cond) ? null : cond;
+        this.cond = cond;
     }
 
     /**
@@ -123,7 +121,7 @@ public class Transition extends SimpleTr
      * @param event The event to set.
      */
     public void setEvent(final String event) {
-        this.event = SCXMLHelper.isStringEmpty(event) ? null : event.trim();
+        this.event = event == null ? null : event.trim();
         if (this.event != null) {
             // 'event' is a space separated list of event descriptors
             events = new ArrayList<String>();

Modified: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/TransitionTarget.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/TransitionTarget.java?rev=1584272&r1=1584271&r2=1584272&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/TransitionTarget.java (original)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/TransitionTarget.java Thu Apr  3 07:13:42 2014
@@ -146,6 +146,19 @@ public abstract class TransitionTarget i
     }
 
     /**
+     * Checks whether this transition target (State or Parallel) is a
+     * descendant of the transition target context.
+     *
+     * @param context
+     *            TransitionTarget context - a potential ancestor
+     * @return true if this is a descendant of context, false otherwise
+     */
+    public final boolean isDescendantOf(TransitionTarget context) {
+        return getNumberOfAncestors() > context.getNumberOfAncestors()
+                && getAncestor(context.getNumberOfAncestors()) == context;
+    }
+    
+    /**
      * Enforce identity equality only
      * @param other other object to compare with
      * @return this == other