commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From a..@apache.org
Subject commons-scxml git commit: SCXML-268 Support <donedata> and complete the handling of <final> and <finalize>
Date Sun, 10 Dec 2017 20:42:15 GMT
Repository: commons-scxml
Updated Branches:
  refs/heads/master 144d205df -> 8cfccaf4c


SCXML-268 Support <donedata> and complete the handling of <final> and <finalize>


Project: http://git-wip-us.apache.org/repos/asf/commons-scxml/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-scxml/commit/8cfccaf4
Tree: http://git-wip-us.apache.org/repos/asf/commons-scxml/tree/8cfccaf4
Diff: http://git-wip-us.apache.org/repos/asf/commons-scxml/diff/8cfccaf4

Branch: refs/heads/master
Commit: 8cfccaf4c36d98e397ba24083bb99be2509462ed
Parents: 144d205
Author: Ate Douma <ate@apache.org>
Authored: Sun Dec 10 21:42:09 2017 +0100
Committer: Ate Douma <ate@apache.org>
Committed: Sun Dec 10 21:42:09 2017 +0100

----------------------------------------------------------------------
 src/changes/changes.xml                         |  4 ++
 .../apache/commons/scxml2/SCXMLExecutor.java    |  7 ++
 .../commons/scxml2/SCXMLSystemContext.java      |  5 ++
 .../apache/commons/scxml2/io/SCXMLReader.java   | 71 +++++++++++++++++++-
 .../apache/commons/scxml2/io/SCXMLWriter.java   | 14 ++++
 .../apache/commons/scxml2/model/DoneData.java   | 65 ++++++++++++++++++
 .../org/apache/commons/scxml2/model/Final.java  | 55 +++++++++++++++
 .../scxml2/semantics/SCXMLSemanticsImpl.java    | 37 +++++++---
 .../commons/scxml2/SCXMLExecutorTest.java       |  8 +++
 .../apache/commons/scxml2/final-donedata.xml    | 23 +++++++
 .../org/apache/commons/scxml2/w3c/tests.xml     | 18 ++---
 11 files changed, 285 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/8cfccaf4/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 3238f53..56195b7 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -35,6 +35,10 @@
     <release version="2.0" date="In Git master"
       description="Latest unreleased code">
 
+      <action dev="ate" type="add" issue="SCXML-268">
+        [12-10-2017] Support &lt;donedata&gt; and complete the handling of &lt;final&gt;
and &lt;finalize&gt;
+      </action>
+
       <action dev="ate" type="add" issue="SCXML-267">
         [12-10-2017] Support &lt;data&gt; src attribute and &lt;assign&gt;
inline data
       </action>

http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/8cfccaf4/src/main/java/org/apache/commons/scxml2/SCXMLExecutor.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/scxml2/SCXMLExecutor.java b/src/main/java/org/apache/commons/scxml2/SCXMLExecutor.java
index a2b6bfd..3be0c7f 100644
--- a/src/main/java/org/apache/commons/scxml2/SCXMLExecutor.java
+++ b/src/main/java/org/apache/commons/scxml2/SCXMLExecutor.java
@@ -139,6 +139,13 @@ public class SCXMLExecutor implements SCXMLIOProcessor {
     }
 
     /**
+     * @return the (optionally) <final><donedata/></final> produced data
after the current statemachine completed its execution.
+     */
+    public Object getFinalDoneData() {
+        return getGlobalContext().getSystemContext().getPlatformVariables().get(SCXMLSystemContext.FINAL_DONE_DATA_KEY);
+    }
+
+    /**
      * starts the state machine with a specific active configuration, as the result of a
(first) step
      * <p>
      * This will first (re)initialize the current state machine: clearing all variable contexts,
histories and current

http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/8cfccaf4/src/main/java/org/apache/commons/scxml2/SCXMLSystemContext.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/scxml2/SCXMLSystemContext.java b/src/main/java/org/apache/commons/scxml2/SCXMLSystemContext.java
index f19db2b..acbcc8e 100644
--- a/src/main/java/org/apache/commons/scxml2/SCXMLSystemContext.java
+++ b/src/main/java/org/apache/commons/scxml2/SCXMLSystemContext.java
@@ -51,6 +51,11 @@ public class SCXMLSystemContext implements Context, Serializable {
      * status instance **/
     public static final String STATUS_KEY = "status";
 
+    /** The Commons SCXML internal {@link #getPlatformVariables() platform variable key}
holding the (optionally)
+     * <final><donedata/></final> produced data after the current SCXML
completed its execution.
+     * **/
+    public static final String FINAL_DONE_DATA_KEY = "finalDoneData";
+
     /**
      * The set of protected system variables names
      */

http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/8cfccaf4/src/main/java/org/apache/commons/scxml2/io/SCXMLReader.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/scxml2/io/SCXMLReader.java b/src/main/java/org/apache/commons/scxml2/io/SCXMLReader.java
index d5618d1..0015320 100644
--- a/src/main/java/org/apache/commons/scxml2/io/SCXMLReader.java
+++ b/src/main/java/org/apache/commons/scxml2/io/SCXMLReader.java
@@ -62,6 +62,7 @@ import org.apache.commons.scxml2.model.ContentContainer;
 import org.apache.commons.scxml2.model.CustomAction;
 import org.apache.commons.scxml2.model.Data;
 import org.apache.commons.scxml2.model.Datamodel;
+import org.apache.commons.scxml2.model.DoneData;
 import org.apache.commons.scxml2.model.Else;
 import org.apache.commons.scxml2.model.ElseIf;
 import org.apache.commons.scxml2.model.EnterableState;
@@ -271,6 +272,7 @@ public final class SCXMLReader {
     private static final String ELEM_STATE = "state";
     private static final String ELEM_TRANSITION = "transition";
     private static final String ELEM_VAR = "var";
+    private static final String ELEM_DONEDATA = "donedata";
 
     //---- ATTRIBUTE NAMES ----//
     private static final String ATTR_ARRAY = "array";
@@ -911,6 +913,8 @@ public final class SCXMLReader {
                             readOnEntry(reader, configuration, end);
                         } else if (ELEM_ONEXIT.equals(name)) {
                             readOnExit(reader, configuration, end);
+                        } else if (ELEM_DONEDATA.equals(name) && end.getDoneData()
== null) {
+                            readDoneData(reader, configuration, end);
                         } else {
                             reportIgnoredElement(reader, configuration, ELEM_FINAL, nsURI,
name);
                         }
@@ -927,6 +931,61 @@ public final class SCXMLReader {
     }
 
     /**
+     * Read the contents of this &lt;donedata&gt; element.
+     *
+     * @param reader The {@link XMLStreamReader} providing the SCXML document to parse.
+     * @param configuration The {@link Configuration} to use while parsing.
+     * @param parent The parent {@link State} for this final (null for top level state).
+     *
+     * @throws IOException An IO error during parsing.
+     * @throws XMLStreamException An exception processing the underlying {@link XMLStreamReader}.
+     * @throws ModelException The Commons SCXML object model is incomplete or inconsistent
(includes
+     *                        errors in the SCXML document that may not be identified by
the schema).
+     */
+    private static void readDoneData(final XMLStreamReader reader, final Configuration configuration,
final Final parent)
+            throws XMLStreamException, ModelException, IOException {
+
+        DoneData doneData = new DoneData();
+        parent.setDoneData(doneData);
+
+        loop : while (reader.hasNext()) {
+            String name, nsURI;
+            switch (reader.next()) {
+                case XMLStreamConstants.START_ELEMENT:
+                    pushNamespaces(reader, configuration);
+                    nsURI = reader.getNamespaceURI();
+                    name = reader.getLocalName();
+                    if (XMLNS_SCXML.equals(nsURI)) {
+                        if (ELEM_PARAM.equals(name)) {
+                            if (doneData.getContent() == null) {
+                                readParam(reader, configuration, doneData);
+                            }
+                            else {
+                                reportIgnoredElement(reader, configuration, ELEM_DONEDATA,
nsURI, name);
+                            }
+                        } else if (ELEM_CONTENT.equals(name)) {
+                            if (doneData.getParams().isEmpty()) {
+                                readContent(reader, configuration, doneData);
+                            }
+                            else {
+                                reportIgnoredElement(reader, configuration, ELEM_DONEDATA,
nsURI, name);
+                            }
+                        } else {
+                            reportIgnoredElement(reader, configuration, ELEM_DONEDATA, nsURI,
name);
+                        }
+                    } else {
+                        reportIgnoredElement(reader, configuration, ELEM_DONEDATA, nsURI,
name);
+                    }
+                    break;
+                case XMLStreamConstants.END_ELEMENT:
+                    popNamespaces(reader, configuration);
+                    break loop;
+                default:
+            }
+        }
+    }
+
+    /**
      * Parse the contents of the SCXML document that this "src" attribute value of a &lt;state&gt;
or &lt;parallel&gt;
      * element points to. Without a URL fragment, the entire state machine is imported as
contents of the
      * &lt;state&gt; or &lt;parallel&gt;. If a URL fragment is present, the
fragment must specify the id of the
@@ -1560,7 +1619,11 @@ public final class SCXMLReader {
                     name = reader.getLocalName();
                     if (XMLNS_SCXML.equals(nsURI)) {
                         if (ELEM_RAISE.equals(name)) {
-                            readRaise(reader, configuration, executable, parent);
+                            if (executable instanceof Finalize) {
+                                reportIgnoredElement(reader, configuration, ELEM_FINALIZE,
nsURI, name);
+                            } else {
+                                readRaise(reader, configuration, executable, parent);
+                            }
                         } else if (ELEM_FOREACH.equals(name)) {
                             readForeach(reader, configuration, executable, parent);
                         } else if (ELEM_IF.equals(name)) {
@@ -1570,7 +1633,11 @@ public final class SCXMLReader {
                         } else if (ELEM_ASSIGN.equals(name)) {
                             readAssign(reader, configuration, executable, parent);
                         } else if (ELEM_SEND.equals(name)) {
-                            readSend(reader, configuration, executable, parent);
+                            if (executable instanceof Finalize) {
+                                reportIgnoredElement(reader, configuration, ELEM_FINALIZE,
nsURI, name);
+                            } else {
+                                readSend(reader, configuration, executable, parent);
+                            }
                         } else if (ELEM_CANCEL.equals(name)) {
                             readCancel(reader, configuration, executable, parent);
                         } else if (ELEM_SCRIPT.equals(name)) {

http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/8cfccaf4/src/main/java/org/apache/commons/scxml2/io/SCXMLWriter.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/scxml2/io/SCXMLWriter.java b/src/main/java/org/apache/commons/scxml2/io/SCXMLWriter.java
index 1a12531..a91acf7 100644
--- a/src/main/java/org/apache/commons/scxml2/io/SCXMLWriter.java
+++ b/src/main/java/org/apache/commons/scxml2/io/SCXMLWriter.java
@@ -48,6 +48,7 @@ import org.apache.commons.scxml2.model.Cancel;
 import org.apache.commons.scxml2.model.Content;
 import org.apache.commons.scxml2.model.Data;
 import org.apache.commons.scxml2.model.Datamodel;
+import org.apache.commons.scxml2.model.DoneData;
 import org.apache.commons.scxml2.model.Else;
 import org.apache.commons.scxml2.model.ElseIf;
 import org.apache.commons.scxml2.model.EnterableState;
@@ -154,6 +155,7 @@ public class SCXMLWriter {
     private static final String ELEM_STATE = "state";
     private static final String ELEM_TRANSITION = "transition";
     private static final String ELEM_VAR = "var";
+    private static final String ELEM_DONEDATA = "donedata";
 
     //---- ATTRIBUTE NAMES ----//
     private static final String ATTR_ARRAY = "array";
@@ -687,6 +689,18 @@ public class SCXMLWriter {
         for (OnExit onexit : end.getOnExits()) {
             writeOnExit(writer, onexit);
         }
+        if (end.getDoneData() != null) {
+            writer.writeStartElement(ELEM_DONEDATA);
+            for (Param p : end.getDoneData().getParams()) {
+                writer.writeStartElement(ELEM_PARAM);
+                writeAV(writer, ATTR_NAME, p.getName());
+                writeAV(writer, ATTR_LOCATION, p.getLocation());
+                writeAV(writer, ATTR_EXPR, escapeXML(p.getExpr()));
+                writer.writeEndElement();
+            }
+            writeContent(writer, end.getDoneData().getContent());
+            writer.writeEndElement();
+        }
         writer.writeEndElement();
     }
 

http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/8cfccaf4/src/main/java/org/apache/commons/scxml2/model/DoneData.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/scxml2/model/DoneData.java b/src/main/java/org/apache/commons/scxml2/model/DoneData.java
new file mode 100644
index 0000000..d752d64
--- /dev/null
+++ b/src/main/java/org/apache/commons/scxml2/model/DoneData.java
@@ -0,0 +1,65 @@
+/*
+ * 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.commons.scxml2.model;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The class in this SCXML object model that corresponds to the SCXML &lt;donedata&gt;
element.
+ */
+public class DoneData implements ContentContainer, ParamsContainer, Serializable {
+
+    /**
+     * The &lt;content/&gt; of this send
+     */
+    private Content content;
+
+    /**
+     * The List of the params to be sent
+     */
+    private final List<Param> paramsList = new ArrayList<>();
+
+    /**
+     * Returns the content
+     *
+     * @return the content
+     */
+    public Content getContent() {
+        return content;
+    }
+
+    /**
+     * Sets the content
+     *
+     * @param content the content to set
+     */
+    public void setContent(final Content content) {
+        this.content = content;
+    }
+
+    /**
+     * Get the list of {@link Param}s.
+     *
+     * @return List The params list.
+     */
+    public List<Param> getParams() {
+        return paramsList;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/8cfccaf4/src/main/java/org/apache/commons/scxml2/model/Final.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/scxml2/model/Final.java b/src/main/java/org/apache/commons/scxml2/model/Final.java
index b22efa0..28a8063 100644
--- a/src/main/java/org/apache/commons/scxml2/model/Final.java
+++ b/src/main/java/org/apache/commons/scxml2/model/Final.java
@@ -16,6 +16,17 @@
  */
 package org.apache.commons.scxml2.model;
 
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.apache.commons.scxml2.Context;
+import org.apache.commons.scxml2.Evaluator;
+import org.apache.commons.scxml2.EventBuilder;
+import org.apache.commons.scxml2.SCXMLExecutionContext;
+import org.apache.commons.scxml2.SCXMLExpressionException;
+import org.apache.commons.scxml2.TriggerEvent;
+import org.apache.commons.scxml2.semantics.ErrorConstants;
+
 /**
  * The class in this SCXML object model that corresponds to the
  * &lt;final&gt; SCXML element.
@@ -29,6 +40,8 @@ public class Final extends EnterableState {
      */
     private static final long serialVersionUID = 1L;
 
+    private DoneData doneData;
+
     /**
      * Default no-args constructor.
      */
@@ -59,5 +72,47 @@ public class Final extends EnterableState {
     public final boolean isAtomicState() {
         return true;
     }
+
+    public DoneData getDoneData() {
+        return doneData;
+    }
+
+    public void setDoneData(final DoneData doneData) {
+        this.doneData = doneData;
+    }
+
+    public Object processDoneData(SCXMLExecutionContext exctx) throws ModelException {
+        Object result = null;
+        if (doneData != null) {
+            try {
+                Content content = doneData.getContent();
+                Evaluator eval = exctx.getEvaluator();
+                Context ctx = exctx.getScInstance().getGlobalContext();
+                if (content != null) {
+                    if (content.getExpr() != null) {
+                        result = eval.cloneData(eval.eval(ctx, content.getExpr()));
+                    } else if (content.getValue() != null) {
+                        result = content.getValue();
+                    }
+                    else if (content.getBody() != null){
+                        result = eval.cloneData(content.getBody());
+                    }
+                } else {
+                    Map<String, Object> payloadDataMap = new LinkedHashMap<>();
+                    PayloadBuilder.addParamsToPayload(exctx.getScInstance().getGlobalContext(),
+                            exctx.getEvaluator(), doneData.getParams(), payloadDataMap);
+                    if (!payloadDataMap.isEmpty()) {
+                        result = payloadDataMap;
+                    }
+                }
+            } catch (SCXMLExpressionException e) {
+                result = null;
+                exctx.getInternalIOProcessor().addEvent(new EventBuilder(TriggerEvent.ERROR_EXECUTION,
TriggerEvent.ERROR_EVENT).build());
+                exctx.getErrorReporter().onError(ErrorConstants.EXPRESSION_ERROR,
+                        "Failed to process final donedata due to error: "+ e.getMessage(),
getParent());
+            }
+        }
+        return result;
+    }
 }
 

http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/8cfccaf4/src/main/java/org/apache/commons/scxml2/semantics/SCXMLSemanticsImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/scxml2/semantics/SCXMLSemanticsImpl.java b/src/main/java/org/apache/commons/scxml2/semantics/SCXMLSemanticsImpl.java
index a860d0f..7c35767 100644
--- a/src/main/java/org/apache/commons/scxml2/semantics/SCXMLSemanticsImpl.java
+++ b/src/main/java/org/apache/commons/scxml2/semantics/SCXMLSemanticsImpl.java
@@ -44,6 +44,7 @@ import org.apache.commons.scxml2.model.DocumentOrder;
 import org.apache.commons.scxml2.model.EnterableState;
 import org.apache.commons.scxml2.model.Executable;
 import org.apache.commons.scxml2.model.Final;
+import org.apache.commons.scxml2.model.Finalize;
 import org.apache.commons.scxml2.model.History;
 import org.apache.commons.scxml2.model.Invoke;
 import org.apache.commons.scxml2.model.ModelException;
@@ -210,7 +211,7 @@ public class SCXMLSemanticsImpl implements SCXMLSemantics {
         if (exctx.isRunning()) {
             return;
         }
-        ArrayList<EnterableState> configuration = new ArrayList<EnterableState>(exctx.getScInstance().getStateConfiguration().getActiveStates());
+        ArrayList<EnterableState> configuration = new ArrayList<>(exctx.getScInstance().getStateConfiguration().getActiveStates());
         Collections.sort(configuration, DocumentOrder.reverseDocumentOrderComparator);
         for (EnterableState es : configuration) {
             for (OnExit onexit : es.getOnExits()) {
@@ -225,12 +226,14 @@ public class SCXMLSemanticsImpl implements SCXMLSemantics {
             exctx.getNotificationRegistry().fireOnExit(es, es);
             exctx.getNotificationRegistry().fireOnExit(exctx.getStateMachine(), es);
             if (es instanceof Final && es.getParent() == null) {
+                Object donedata = ((Final)es).processDoneData(exctx);
+                exctx.getScInstance().getGlobalContext().getSystemContext().getPlatformVariables().put(SCXMLSystemContext.FINAL_DONE_DATA_KEY,
donedata);
                 if (exctx.getSCXMLExecutor().getParentSCXMLIOProcessor() != null) {
                     ParentSCXMLIOProcessor ioProcessor = exctx.getSCXMLExecutor().getParentSCXMLIOProcessor();
                     if (!ioProcessor.isClosed()) {
                         ioProcessor.addEvent(
                                 new EventBuilder("done.invoke."+ioProcessor.getInvokeId(),
TriggerEvent.SIGNAL_EVENT)
-                                        .invokeId(ioProcessor.getInvokeId()).build());
+                                        .invokeId(ioProcessor.getInvokeId()).data(donedata).build());
                         ioProcessor.close();
                     }
                 }
@@ -238,8 +241,6 @@ public class SCXMLSemanticsImpl implements SCXMLSemantics {
             else {
                 exctx.getScInstance().getStateConfiguration().exitState(es);
             }
-            // else: keep final Final
-            // TODO: returnDoneEvent(s.donedata)?
         }
     }
 
@@ -1045,7 +1046,8 @@ public class SCXMLSemanticsImpl implements SCXMLSemantics {
                     exctx.stop();
                 }
                 else {
-                    exctx.getInternalIOProcessor().addEvent(new EventBuilder("done.state."+parent.getId(),TriggerEvent.CHANGE_EVENT).build());
+                    Object donedata = ((Final)es).processDoneData(exctx);
+                    exctx.getInternalIOProcessor().addEvent(new EventBuilder("done.state."+parent.getId(),TriggerEvent.CHANGE_EVENT).data(donedata).build());
                     if (parent.isRegion()) {
                         if (isInFinalState(parent.getParent(), exctx.getScInstance().getStateConfiguration().getActiveStates()))
{
                             exctx.getInternalIOProcessor().addEvent(new EventBuilder("done.state."+parent.getParent().getId()
@@ -1079,7 +1081,7 @@ public class SCXMLSemanticsImpl implements SCXMLSemantics {
     }
 
     /**
-     * Forward events to invoked activities, execute finalize handlers.
+     * execute finalize handlers, forward events to invoked activities.
      *
      * @param exctx provides the execution context
      * @param event The events to be forwarded
@@ -1090,6 +1092,24 @@ public class SCXMLSemanticsImpl implements SCXMLSemantics {
         for (Map.Entry<Invoke, String> entry : exctx.getInvokeIds().entrySet()) {
             if (entry.getValue().equals(event.getInvokeId())) {
                 Invoke invoke = entry.getKey();
+                Finalize finalize = invoke.getFinalize();
+                if (finalize != null) {
+                    if (finalize.getActions().isEmpty()) {
+                        /*
+                           The current https://www.w3.org/TR/2015/REC-scxml-20150901/#finalize
specification for
+                           using an empty <finalize/> (no actions) is rather complex
when:
+                           - the invoke also has a namelist attribute and/or params with
a location attribute
+                           - and the event payload has values reachable by those namelist
and/or params 'location' attributes
+                           then the statemachine data at those locations should be updated
with the payload values.
+
+                           As the same functionality can be achieved (even if less convenient)
by using a <finalize>
+                           with <assign/> elements for each of these locations, *and*
there are no SCXML IRP tests
+                           for using an empty <finalize/>, the above logic is NOT implemented.
+                        */
+                    } else {
+                        executeContent(exctx, finalize);
+                    }
+                }
                 if (entry.getKey().isAutoForward() &&
                         !(event.getName().equals("done.invoke."+entry.getValue()) ||
                                 event.getName().startsWith("done.invoke."+entry.getValue()+".")))
{
@@ -1101,11 +1121,6 @@ public class SCXMLSemanticsImpl implements SCXMLSemantics {
                     }
                 }
             }
-            /*
-            else {
-                // TODO: applyFinalize
-            }
-            */
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/8cfccaf4/src/test/java/org/apache/commons/scxml2/SCXMLExecutorTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/scxml2/SCXMLExecutorTest.java b/src/test/java/org/apache/commons/scxml2/SCXMLExecutorTest.java
index c7ab878..947d211 100644
--- a/src/test/java/org/apache/commons/scxml2/SCXMLExecutorTest.java
+++ b/src/test/java/org/apache/commons/scxml2/SCXMLExecutorTest.java
@@ -281,6 +281,14 @@ public class SCXMLExecutorTest {
         Assert.assertEquals("twenty_two", currentStates.iterator().next().getId());
     }
 
+    @Test
+    public void testSCXMLExecutorFinalDoneData() throws Exception {
+        SCXMLExecutor exec = SCXMLTestHelper.getExecutor("org/apache/commons/scxml2/final-donedata.xml");
+        Assert.assertNull(exec.getFinalDoneData());
+        exec.go();
+        Assert.assertEquals("done", exec.getFinalDoneData());
+    }
+
     private void checkMicrowave01Sample(SCXMLExecutor exec) throws Exception {
         Set<EnterableState> currentStates = SCXMLTestHelper.fireEvent(exec, "turn_on");
         Assert.assertEquals(1, currentStates.size());

http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/8cfccaf4/src/test/java/org/apache/commons/scxml2/final-donedata.xml
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/scxml2/final-donedata.xml b/src/test/java/org/apache/commons/scxml2/final-donedata.xml
new file mode 100644
index 0000000..342c6b6
--- /dev/null
+++ b/src/test/java/org/apache/commons/scxml2/final-donedata.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!--
+ * 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.
+-->
+<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" datamodel="jexl" initial="final">
+    <final id="final">
+        <donedata><content>done</content></donedata>
+    </final>
+</scxml>
+

http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/8cfccaf4/src/test/java/org/apache/commons/scxml2/w3c/tests.xml
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/scxml2/w3c/tests.xml b/src/test/java/org/apache/commons/scxml2/w3c/tests.xml
index f8719cb..392597a 100644
--- a/src/test/java/org/apache/commons/scxml2/w3c/tests.xml
+++ b/src/test/java/org/apache/commons/scxml2/w3c/tests.xml
@@ -61,13 +61,13 @@
   <test id="286" mandatory="true"                    manual="false" jexl="true"  ecma="true"/>
   <test id="287" mandatory="true"                    manual="false" jexl="true"  ecma="true"/>
   <test id="487" mandatory="true"                    manual="false" jexl="true"  ecma="true"/>
-  <test id="294" mandatory="true"                    manual="false" jexl="false" ecma="false"/>
-  <test id="527" mandatory="true"                    manual="false" jexl="false" ecma="false"/>
-  <test id="528" mandatory="true"                    manual="false" jexl="false" ecma="false"/>
-  <test id="529" mandatory="true"                    manual="false" jexl="false" ecma="false"/>
-  <test id="298" mandatory="true"                    manual="false" jexl="false" ecma="false"/>
-  <test id="343" mandatory="true"                    manual="false" jexl="false" ecma="false"/>
-  <test id="488" mandatory="true"                    manual="false" jexl="false" ecma="false"/>
+  <test id="294" mandatory="true"                    manual="false" jexl="true"  ecma="true"/>
+  <test id="527" mandatory="true"                    manual="false" jexl="true"  ecma="true"/>
+  <test id="528" mandatory="true"                    manual="false" jexl="true"  ecma="true"/>
+  <test id="529" mandatory="true"                    manual="false" jexl="true"  ecma="true"/>
+  <test id="298" mandatory="true"                    manual="false" jexl="true"  ecma="true"/>
+  <test id="343" mandatory="true"                    manual="false" jexl="true"  ecma="true"/>
+  <test id="488" mandatory="true"                    manual="false" jexl="true"  ecma="true"/>
   <test id="301" mandatory="true"                    manual="true"  jexl="true"  ecma="true"
finalState="java.net.MalformedURLException"/>
   <test id="302" mandatory="true"                    manual="false" jexl="true"  ecma="true"/>
   <test id="303" mandatory="true"                    manual="false" jexl="true"  ecma="true"/>
@@ -132,8 +132,8 @@
   <test id="229" mandatory="true"                    manual="false" jexl="true"  ecma="true"/>
   <test id="230" mandatory="true"                    manual="true"  jexl="true"  ecma="true"
finalState="final"/>
   <test id="232" mandatory="true"                    manual="false" jexl="true"  ecma="true"/>
-  <test id="233" mandatory="true"                    manual="false" jexl="false" ecma="false"/>
-  <test id="234" mandatory="true"                    manual="false" jexl="false" ecma="false"/>
+  <test id="233" mandatory="true"                    manual="false" jexl="true"  ecma="true"/>
+  <test id="234" mandatory="true"                    manual="false" jexl="true"  ecma="true"/>
   <test id="235" mandatory="true"                    manual="false" jexl="true"  ecma="true"/>
   <test id="236" mandatory="true"                    manual="false" jexl="true"  ecma="true"/>
   <test id="237" mandatory="true"                    manual="false" jexl="true"  ecma="true"/>


Mime
View raw message