commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From a..@apache.org
Subject svn commit: r1639829 [3/4] - 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/j...
Date Sat, 15 Nov 2014 03:08:00 GMT
Modified: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Assign.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Assign.java?rev=1639829&r1=1639828&r2=1639829&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Assign.java (original)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Assign.java Sat Nov 15 03:07:58 2014
@@ -28,8 +28,6 @@ import org.apache.commons.scxml2.Context
 import org.apache.commons.scxml2.Evaluator;
 import org.apache.commons.scxml2.PathResolver;
 import org.apache.commons.scxml2.SCXMLExpressionException;
-import org.apache.commons.scxml2.TriggerEvent;
-import org.apache.commons.scxml2.semantics.ErrorConstants;
 import org.w3c.dom.*;
 import org.xml.sax.SAXException;
 
@@ -46,12 +44,6 @@ public class Assign extends Action imple
     private static final long serialVersionUID = 1L;
 
     /**
-     * Left hand side expression evaluating to a previously
-     * defined variable.
-     */
-    private String name;
-
-    /**
      * Left hand side expression evaluating to a location within
      * a previously defined XML data tree.
      */
@@ -68,33 +60,25 @@ public class Assign extends Action imple
     private String expr;
 
     /**
-     * {@link PathResolver} for resolving the "src" result.
+     * Defines the nature of the insertion to be performed, default {@link Evaluator.AssignType#REPLACE_CHILDREN}
      */
-    private PathResolver pathResolver;
+    private Evaluator.AssignType type;
 
     /**
-     * Constructor.
+     * The attribute name to add at the specified location when using {@link Evaluator.AssignType#ADD_ATTRIBUTE}
      */
-    public Assign() {
-        super();
-    }
+    private String attr;
 
     /**
-     * Get the variable to be assigned a new value.
-     *
-     * @return Returns the name.
+     * {@link PathResolver} for resolving the "src" result.
      */
-    public String getName() {
-        return name;
-    }
+    private PathResolver pathResolver;
 
     /**
-     * Get the variable to be assigned a new value.
-     *
-     * @param name The name to set.
+     * Constructor.
      */
-    public void setName(final String name) {
-        this.name = name;
+    public Assign() {
+        super();
     }
 
     /**
@@ -169,6 +153,22 @@ public class Assign extends Action imple
         this.pathResolver = pathResolver;
     }
 
+    public Evaluator.AssignType getType() {
+        return type;
+    }
+
+    public void setType(final Evaluator.AssignType type) {
+        this.type = type;
+    }
+
+    public String getAttr() {
+        return attr;
+    }
+
+    public void setAttr(final String attr) {
+        this.attr = attr;
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -176,115 +176,29 @@ public class Assign extends Action imple
     public void execute(ActionExecutionContext exctx) throws ModelException, SCXMLExpressionException {
         EnterableState parentState = getParentEnterableState();
         Context ctx = exctx.getContext(parentState);
-        Evaluator eval = exctx.getEvaluator();
+        Evaluator evaluator = exctx.getEvaluator();
         ctx.setLocal(getNamespacesKey(), getNamespaces());
-        // "location" gets preference over "name"
-        if (location != null) {
-            Node oldNode = eval.evalLocation(ctx, location);
-            if (oldNode != null) {
-                //// rvalue may be ...
-                // a Node, if so, import it at location
-                Node newNode;
-                try {
-                    if (src != null && src.trim().length() > 0) {
-                        newNode = getSrcNode();
-                    } else {
-                        newNode = eval.evalLocation(ctx, expr);
-                    }
-                    // Remove all children
-                    Node removeChild = oldNode.getFirstChild();
-                    while (removeChild != null) {
-                        Node nextChild = removeChild.getNextSibling();
-                        oldNode.removeChild(removeChild);
-                        removeChild = nextChild;
-                    }
-                    if (newNode != null) {
-                        // Adopt new children
-                        for (Node child = newNode.getFirstChild();
-                                child != null;
-                                child = child.getNextSibling()) {
-                            Node importedNode = oldNode.getOwnerDocument().
-                                importNode(child, true);
-                            oldNode.appendChild(importedNode);
-                        }
-                    }
-                } catch (SCXMLExpressionException see) {
-                    // or something else, stuff toString() into lvalue
-                    Object valueObject = eval.eval(ctx, expr);
-                    setNodeValue(oldNode, valueObject.toString());
-                }
-                if (exctx.getAppLog().isDebugEnabled()) {
-                    exctx.getAppLog().debug("<assign>: data node '" + oldNode.getNodeName()
-                        + "' updated");
-                }
-                /* TODO: send to notificationRegistry instead?
-                TriggerEvent ev = new TriggerEvent(name + ".change",
-                    TriggerEvent.CHANGE_EVENT);
-                exctx.addInternalEvent(ev);
-                */
-            } else {
-                exctx.getAppLog().error("<assign>: location does not point to"
-                    + " a <data> node");
-            }
+        Object data;
+        if (src != null && src.trim().length() > 0) {
+            data = getSrcNode();
         } else {
-            // lets try "name" (usage as in Sep '05 WD, useful with <var>)
-            if (!ctx.has(name)) {
-                exctx.getErrorReporter().onError(ErrorConstants.UNDEFINED_VARIABLE, name
-                    + " = null", parentState);
-            } else {
-                Object varObj;
-                if (src != null && src.trim().length() > 0) {
-                    varObj = getSrcNode();
-                } else {
-                    varObj = eval.eval(ctx, expr);
-                }
-                ctx.set(name, varObj);
-                if (exctx.getAppLog().isDebugEnabled()) {
-                    exctx.getAppLog().debug("<assign>: Set variable '" + name + "' to '"
-                        + String.valueOf(varObj) + "'");
-                }
-                TriggerEvent ev = new TriggerEvent(name + ".change", TriggerEvent.CHANGE_EVENT);
-                exctx.getInternalIOProcessor().addEvent(ev);
-            }
+            data = evaluator.eval(ctx, expr);
         }
-        ctx.setLocal(getNamespacesKey(), null);
-    }
 
-    /**
-     * Set node value, depending on its type, from a String.
-     *
-     * @param node A Node whose value is to be set
-     * @param value The new value
-     */
-    private void setNodeValue(final Node node, final String value) {
-        switch(node.getNodeType()) {
-            case Node.ATTRIBUTE_NODE:
-                node.setNodeValue(value);
-                break;
-            case Node.ELEMENT_NODE:
-                //remove all text children
-                if (node.hasChildNodes()) {
-                    Node child = node.getFirstChild();
-                    while (child != null) {
-                        if (child.getNodeType() == Node.TEXT_NODE) {
-                            node.removeChild(child);
-                        }
-                        child = child.getNextSibling();
-                    }
-                }
-                //create a new text node and append
-                Text txt = node.getOwnerDocument().createTextNode(value);
-                node.appendChild(txt);
-                break;
-            case Node.TEXT_NODE:
-            case Node.CDATA_SECTION_NODE:
-                ((CharacterData) node).setData(value);
-                break;
-            default:
-                String err = "Trying to set value of a strange Node type: "
-                        + node.getNodeType();
-                throw new IllegalArgumentException(err);
+        evaluator.evalAssign(ctx, location, data, type, attr);
+        if (exctx.getAppLog().isDebugEnabled()) {
+            exctx.getAppLog().debug("<assign>: '" + location + "' updated");
+        }
+        // TODO: introduce a optional 'trace.change' setting or something alike to enable .change events,
+       //        but don't do this by default as it can interfere with transitions not expecting such events
+        /*
+        if ((Evaluator.XPATH_DATA_MODEL.equals(evaluator.getSupportedDatamodel()) && location.startsWith("$") && ctx.has(location.substring(1))
+                || ctx.has(location))) {
+            TriggerEvent ev = new TriggerEvent(location + ".change", TriggerEvent.CHANGE_EVENT);
+            exctx.getInternalIOProcessor().addEvent(ev);
         }
+        */
+        ctx.setLocal(getNamespacesKey(), null);
     }
 
     /**
@@ -299,8 +213,7 @@ public class Assign extends Action imple
         }
         Document doc = null;
         try {
-            doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().
-                parse(resolvedSrc);
+            doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(resolvedSrc);
         } catch (FactoryConfigurationError t) {
             logError(t);
         } catch (SAXException e) {
@@ -324,5 +237,4 @@ public class Assign extends Action imple
             getLog(Assign.class);
         log.error(throwable.getMessage(), throwable);
     }
-
 }

Added: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Content.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Content.java?rev=1639829&view=auto
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Content.java (added)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Content.java Sat Nov 15 03:07:58 2014
@@ -0,0 +1,73 @@
+/*
+ * 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;
+
+/**
+ * The class in this SCXML object model that corresponds to the
+ * &lt;content&gt; SCXML element.
+ *
+ */
+public class Content implements Serializable {
+
+    /**
+     * Serial version UID.
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * The param expression, may be null.
+     */
+    private String expr;
+
+    /**
+     * The body of this content, may be null.
+     */
+    private Object body;
+
+    /**
+     * Get the expression for this content.
+     *
+     * @return String The expression for this content.
+     */
+    public final String getExpr() {
+        return expr;
+    }
+
+    /**
+     * Set the expression for this content.
+     *
+     * @param expr The expression for this content.
+     */
+    public final void setExpr(final String expr) {
+        this.expr = expr;
+    }
+
+    /**
+     * Returns the content body as DocumentFragment
+     *
+     * @return the content body as DocumentFragment
+     */
+    public Object getBody() {
+        return body;
+    }
+
+    public void setBody(final Object body) {
+        this.body = body;
+    }
+}

Propchange: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Content.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Content.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/ContentContainer.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/ContentContainer.java?rev=1639829&view=auto
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/ContentContainer.java (added)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/ContentContainer.java Sat Nov 15 03:07:58 2014
@@ -0,0 +1,38 @@
+/*
+ * 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;
+
+/**
+ * A <code>ContentContainer</code> represents an element in the SCXML
+ * document that may have a (single) child &lt;content/&gt; element
+ */
+
+public interface ContentContainer {
+
+    /**
+     * Returns the content
+     *
+     * @return the content
+     */
+    Content getContent();
+
+    /**
+     * Sets the content
+     * @param content the content to set
+     */
+    void setContent(Content content);
+}

Propchange: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/ContentContainer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/ContentContainer.java
------------------------------------------------------------------------------
    svn:keywords = Id

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=1639829&r1=1639828&r2=1639829&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 Sat Nov 15 03:07:58 2014
@@ -16,21 +16,29 @@
  */
 package org.apache.commons.scxml2.model;
 
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
+import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.commons.scxml2.ActionExecutionContext;
+import org.apache.commons.scxml2.Context;
+import org.apache.commons.scxml2.Evaluator;
+import org.apache.commons.scxml2.InvokerManager;
 import org.apache.commons.scxml2.PathResolver;
+import org.apache.commons.scxml2.SCXMLExpressionException;
+import org.apache.commons.scxml2.SCXMLIOProcessor;
+import org.apache.commons.scxml2.SCXMLSystemContext;
+import org.apache.commons.scxml2.TriggerEvent;
+import org.apache.commons.scxml2.invoke.Invoker;
+import org.apache.commons.scxml2.invoke.InvokerException;
+import org.apache.commons.scxml2.semantics.ErrorConstants;
+import org.w3c.dom.Node;
 
 /**
  * The class in this SCXML object model that corresponds to the
  * &lt;invoke&gt; SCXML element.
  *
  */
-public class Invoke implements NamespacePrefixesHolder, PathResolverHolder,
-        Serializable {
+public class Invoke extends NamelistHolder implements PathResolverHolder, ContentContainer {
 
     /**
      * Serial version UID.
@@ -38,16 +46,36 @@ public class Invoke implements Namespace
     private static final long serialVersionUID = 1L;
 
     /**
+     * The default context variable key under which the InvokerManager is provided
+     */
+    private static final String INVOKER_MANAGER_KEY = "_INVOKER_MANAGER";
+
+    /**
+     * The default target type.
+     */
+    private static final String TYPE_SCXML = "scxml";
+
+    /**
      * Identifier for this Invoke.
      * */
     private String id;
 
     /**
+     * Path expression evaluating to a location within a previously defined XML data tree.
+     */
+    private String idlocation;
+
+    /**
      * The type of target to be invoked.
      */
     private String type;
 
     /**
+     * An expression defining the type of the target to be invoked.
+     */
+    private String typeexpr;
+
+    /**
      * The source URL for the external service.
      */
     private String src;
@@ -64,11 +92,6 @@ public class Invoke implements Namespace
     private Boolean autoForward;
 
     /**
-     * The List of the params to be sent to the invoked process.
-     */
-    private final List<Param> paramsList;
-
-    /**
      * The &lt;finalize&gt; child, may be null.
      */
     private Finalize finalize;
@@ -79,17 +102,11 @@ public class Invoke implements Namespace
     private PathResolver pathResolver;
 
     /**
-     * The current XML namespaces in the SCXML document for this action node,
-     * preserved for deferred XPath evaluation.
+     * The &lt;content/&gt; of this invoke
      */
-    private Map<String, String> namespaces;
+    private Content content;
 
-    /**
-     * Default no-args constructor.
-     */
-    public Invoke() {
-        paramsList = Collections.synchronizedList(new ArrayList<Param>());
-    }
+    private EnterableState parent;
 
     /**
      * Get the identifier for this invoke (may be null).
@@ -110,6 +127,21 @@ public class Invoke implements Namespace
     }
 
     /**
+     * @return the idlocation
+     */
+    public String getIdlocation() {
+        return idlocation;
+    }
+
+    /**
+     * Set the idlocation expression
+     * @param idlocation The idlocation expression
+     */
+    public void setIdlocation(final String idlocation) {
+        this.idlocation = idlocation;
+    }
+
+    /**
      * Get the type for this &lt;invoke&gt; element.
      *
      * @return String Returns the type.
@@ -128,6 +160,21 @@ public class Invoke implements Namespace
     }
 
     /**
+     * @return The type expression
+     */
+    public String getTypeexpr() {
+        return typeexpr;
+    }
+
+    /**
+     * Sets the type expression
+     * @param typeexpr The type expression to set
+     */
+    public void setTypeexpr(final String typeexpr) {
+        this.typeexpr = typeexpr;
+    }
+
+    /**
      * Get the URL for the external service.
      *
      * @return String The URL.
@@ -189,24 +236,6 @@ public class Invoke implements Namespace
     }
 
     /**
-     * Get the list of {@link Param}s.
-     *
-     * @return List The params list.
-     */
-    public final List<Param> params() {
-        return paramsList;
-    }
-
-    /**
-     * Add this param to this invoke.
-     *
-     * @param param The invoke parameter.
-     */
-    public final void addParam(final Param param) {
-        paramsList.add(param);
-    }
-
-    /**
      * Get the Finalize for this Invoke.
      *
      * @return Finalize The Finalize for this Invoke.
@@ -243,24 +272,6 @@ public class Invoke implements Namespace
     }
 
     /**
-     * Get the XML namespaces at this action node in the SCXML document.
-     *
-     * @return Returns the map of namespaces.
-     */
-    public final Map<String, String> getNamespaces() {
-        return namespaces;
-    }
-
-    /**
-     * Set the XML namespaces at this action node in the SCXML document.
-     *
-     * @param namespaces The document namespaces.
-     */
-    public final void setNamespaces(final Map<String, String> namespaces) {
-        this.namespaces = namespaces;
-    }
-
-    /**
      * Enforce identity equality only
      * @param other other object to compare with
      * @return this == other
@@ -278,5 +289,139 @@ public class Invoke implements Namespace
     public final int hashCode() {
         return System.identityHashCode(this);
     }
-}
 
+    /**
+     * Returns the content
+     *
+     * @return the content
+     */
+    public Content getContent() {
+        return content;
+    }
+
+    /**
+     * @return The local context variable name under which the InvokerManager is provided to the Invoke
+     */
+    public String getInvokerManagerKey() {
+        return INVOKER_MANAGER_KEY;
+    }
+
+    /**
+     * Sets the content
+     *
+     * @param content the content to set
+     */
+    public void setContent(final Content content) {
+        this.content = content;
+    }
+
+    /**
+     * Get the parent EnterableState.
+     *
+     * @return Returns the parent state
+     */
+    public EnterableState getParentEnterableState() {
+        return parent;
+    }
+
+    /**
+     * Set the parent EnterableState.
+     * @param parent The parent state to set
+     */
+    public void setParentEnterableState(final EnterableState parent) {
+        if (parent == null) {
+            throw new IllegalArgumentException("Parent parameter cannot be null");
+        }
+        this.parent = parent;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void execute(final ActionExecutionContext exctx) throws ModelException {
+        EnterableState parentState = getParentEnterableState();
+        Context ctx = exctx.getContext(parentState);
+        InvokerManager invokerManager = (InvokerManager)ctx.getVars().get(getInvokerManagerKey());
+        if (invokerManager == null) {
+            throw new ModelException("Missing InvokerManager instance in context under key: "+getInvokerManagerKey());
+        }
+        try {
+            ctx.setLocal(getNamespacesKey(), getNamespaces());
+            Evaluator eval = exctx.getEvaluator();
+
+            String typeValue = type;
+            if (typeValue == null && typeexpr != null) {
+                typeValue = (String) getTextContentIfNodeResult(eval.eval(ctx, typeexpr));
+                if (typeValue == null) {
+                    throw new SCXMLExpressionException("<invoke> for state "+parentState.getId() +
+                            ": type expression \"" + typeexpr + "\" evaluated to null or empty String");
+                }
+            }
+            if (typeValue == null) {
+                typeValue = TYPE_SCXML;
+            }
+            Invoker invoker = invokerManager.newInvoker(typeValue);
+
+            String invokeId = getId();
+            if (invokeId == null) {
+                invokeId = parentState.getId() + "." + ctx.get(SCXMLSystemContext.SESSIONID_KEY);
+            }
+            if (getId() == null && getIdlocation() != null) {
+                eval.evalAssign(ctx, idlocation, invokeId, Evaluator.AssignType.REPLACE_CHILDREN, null);
+            }
+            invoker.setInvokeId(invokeId);
+
+            String src = getSrc();
+            if (src == null && getSrcexpr() != null) {
+                src = (String) getTextContentIfNodeResult(eval.eval(ctx, getSrcexpr()));
+            }
+            if (src != null) {
+                PathResolver pr = getPathResolver();
+                if (pr != null) {
+                    src = getPathResolver().resolvePath(src);
+                }
+            }
+            Node srcNode = null;
+            if (src == null && getContent() != null) {
+                Object contentValue;
+                if (content.getExpr() != null) {
+                    contentValue = eval.eval(ctx, content.getExpr());
+                } else {
+                    contentValue = content.getBody();
+                }
+                if (contentValue instanceof Node) {
+                    srcNode = ((Node)contentValue).cloneNode(true);
+                }
+                else if (contentValue != null) {
+                    src = String.valueOf(contentValue);
+                }
+            }
+            if (src == null && srcNode == null) {
+                throw new SCXMLExpressionException("<invoke> for state "+parentState.getId() +
+                        ": no src and no content defined");
+            }
+            Map<String, Object> payloadDataMap = new HashMap<String, Object>();
+            addNamelistDataToPayload(exctx, payloadDataMap);
+            addParamsToPayload(exctx, payloadDataMap);
+            SCXMLIOProcessor ioProcessor = ((Map<String,SCXMLIOProcessor>)ctx.get(SCXMLSystemContext.IOPROCESSORS_KEY)).
+                    get(SCXMLIOProcessor.SCXML_EVENT_PROCESSOR);
+            invoker.setParentIOProcessor(ioProcessor);
+            invoker.setEvaluator(exctx.getEvaluator());
+            if (src != null) {
+                invoker.invoke(src, payloadDataMap);
+            }
+            // TODO: } else { invoker.invoke(srcNode, payloadDataMap); }
+            invokerManager.registerInvoker(this, invoker);
+        }
+        catch (InvokerException e) {
+            exctx.getErrorReporter().onError(ErrorConstants.EXECUTION_ERROR, e.getMessage(), this);
+            exctx.getInternalIOProcessor().addEvent(new TriggerEvent(TriggerEvent.ERROR_EXECUTION, TriggerEvent.ERROR_EVENT));
+        }
+        catch (SCXMLExpressionException e) {
+            exctx.getInternalIOProcessor().addEvent(new TriggerEvent(TriggerEvent.ERROR_EXECUTION, TriggerEvent.ERROR_EVENT));
+            exctx.getErrorReporter().onError(ErrorConstants.EXPRESSION_ERROR, e.getMessage(), this);
+        }
+        finally {
+            ctx.setLocal(getNamespacesKey(), null);
+        }
+    }
+}
\ No newline at end of file

Modified: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Log.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Log.java?rev=1639829&r1=1639828&r2=1639829&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Log.java (original)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Log.java Sat Nov 15 03:07:58 2014
@@ -95,7 +95,7 @@ public class Log extends Action {
         Context ctx = exctx.getContext(getParentEnterableState());
         Evaluator eval = exctx.getEvaluator();
         ctx.setLocal(getNamespacesKey(), getNamespaces());
-        exctx.getAppLog().info(label + ": " + String.valueOf(eval.eval(ctx, expr)));
+        exctx.getAppLog().info(label + ": " + String.valueOf(getTextContentIfNodeResult(eval.eval(ctx, expr))));
         ctx.setLocal(getNamespacesKey(), null);
     }
 }

Added: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/NamelistHolder.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/NamelistHolder.java?rev=1639829&view=auto
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/NamelistHolder.java (added)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/NamelistHolder.java Sat Nov 15 03:07:58 2014
@@ -0,0 +1,97 @@
+/*
+ * 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.util.Map;
+import java.util.StringTokenizer;
+
+import org.apache.commons.scxml2.ActionExecutionContext;
+import org.apache.commons.scxml2.Context;
+import org.apache.commons.scxml2.Evaluator;
+import org.apache.commons.scxml2.SCXMLExpressionException;
+import org.apache.commons.scxml2.semantics.ErrorConstants;
+
+/**
+ * A <code>NamelistHolder</code> represents an element in the SCXML
+ * document that may have a namelist attribute to
+ * produce payload for events or external communication.
+ */
+public abstract class NamelistHolder extends ParamsContainer {
+
+    /**
+     * The namelist.
+     */
+    private String namelist;
+
+    /**
+     * Get the namelist.
+     *
+     * @return String Returns the namelist.
+     */
+    public final String getNamelist() {
+        return namelist;
+    }
+
+    /**
+     * Set the namelist.
+     *
+     * @param namelist The namelist to set.
+     */
+    public final void setNamelist(final String namelist) {
+        this.namelist = namelist;
+    }
+
+    /**
+     * Adds data to the payload data map based on the namelist which names are location expressions
+     * (typically data ids or for example XPath variables). The names and the values they 'point' at
+     * are added to the payload data map.
+     * @param exctx The ActionExecutionContext
+     * @param payload the payload data map to be updated
+     * @throws ModelException if this action has not an EnterableState as parent
+     * @throws SCXMLExpressionException if a malformed or invalid expression is evaluated
+     * @see PayloadProvider#addToPayload(String, Object, java.util.Map)
+     */
+    protected void addNamelistDataToPayload(ActionExecutionContext exctx, Map<String, Object> payload)
+            throws ModelException, SCXMLExpressionException {
+        if (namelist != null) {
+            EnterableState parentState = getParentEnterableState();
+            Context ctx = exctx.getContext(parentState);
+            try {
+                ctx.setLocal(getNamespacesKey(), getNamespaces());
+                Evaluator evaluator = exctx.getEvaluator();
+                StringTokenizer tkn = new StringTokenizer(namelist);
+                boolean xpathEvaluator = Evaluator.XPATH_DATA_MODEL.equals(evaluator.getSupportedDatamodel());
+                while (tkn.hasMoreTokens()) {
+                    String varName = tkn.nextToken();
+                    Object varObj = evaluator.eval(ctx, varName);
+                    if (varObj == null) {
+                        //considered as a warning here
+                        exctx.getErrorReporter().onError(ErrorConstants.UNDEFINED_VARIABLE,
+                                varName + " = null", parentState);
+                    }
+                    if (xpathEvaluator && varName.startsWith("$")) {
+                        varName = varName.substring(1);
+                    }
+                    addToPayload(varName, varObj, payload);
+                }
+            }
+            finally {
+                ctx.setLocal(getNamespacesKey(), null);
+            }
+        }
+    }
+}

Propchange: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/NamelistHolder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/NamelistHolder.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Param.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Param.java?rev=1639829&r1=1639828&r2=1639829&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Param.java (original)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/Param.java Sat Nov 15 03:07:58 2014
@@ -37,6 +37,12 @@ public class Param implements NamespaceP
     private String name;
 
     /**
+     * Left hand side expression evaluating to a location within
+     * a previously defined XML data tree.
+     */
+    private String location;
+
+    /**
      * The param expression, may be null.
      */
     private String expr;
@@ -73,6 +79,24 @@ public class Param implements NamespaceP
     }
 
     /**
+     * Get the location for a previously defined XML data tree.
+     *
+     * @return Returns the location.
+     */
+    public String getLocation() {
+        return location;
+    }
+
+    /**
+     * Set the location for a previously defined XML data tree.
+     *
+     * @param location The location.
+     */
+    public void setLocation(final String location) {
+        this.location = location;
+    }
+
+    /**
      * Get the expression for this param value.
      *
      * @return String The expression for this param value.

Added: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/ParamsContainer.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/ParamsContainer.java?rev=1639829&view=auto
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/ParamsContainer.java (added)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/ParamsContainer.java Sat Nov 15 03:07:58 2014
@@ -0,0 +1,85 @@
+/*
+ * 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.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.scxml2.ActionExecutionContext;
+import org.apache.commons.scxml2.Context;
+import org.apache.commons.scxml2.Evaluator;
+import org.apache.commons.scxml2.SCXMLExpressionException;
+
+/**
+ * A <code>ParamsContainer</code> represents an element in the SCXML
+ * document that may have one or more &lt;param/&gt; children which are used to
+ * produce payload for events or external communication.
+ */
+public abstract class ParamsContainer extends PayloadProvider {
+
+    /**
+     * The List of the params to be sent
+     */
+    private final List<Param> paramsList = new ArrayList<Param>();
+
+    /**
+     * Get the list of {@link Param}s.
+     *
+     * @return List The params list.
+     */
+    public List<Param> getParams() {
+        return paramsList;
+    }
+
+    /**
+     * Adds data to the payload data map based on the {@link Param}s of this {@link ParamsContainer}
+     * @param exctx The ActionExecutionContext
+     * @param payload the payload data map to be updated
+     * @throws ModelException if this action has not an EnterableState as parent
+     * @throws SCXMLExpressionException if a malformed or invalid expression is evaluated
+     * @see PayloadProvider#addToPayload(String, Object, java.util.Map)
+     */
+    protected void addParamsToPayload(ActionExecutionContext exctx, Map<String, Object> payload)
+            throws ModelException, SCXMLExpressionException {
+        if (!paramsList.isEmpty()) {
+            EnterableState parentState = getParentEnterableState();
+            Context ctx = exctx.getContext(parentState);
+            try {
+                ctx.setLocal(getNamespacesKey(), getNamespaces());
+                Evaluator evaluator = exctx.getEvaluator();
+                Object paramValue;
+                for (Param p : paramsList) {
+                    if (p.getExpr() != null) {
+                        paramValue = evaluator.eval(ctx, p.getExpr());
+                    }
+                    else if (p.getLocation() != null) {
+                        paramValue = evaluator.eval(ctx, p.getLocation());
+                    }
+                    else {
+                        // ignore invalid param definition
+                        continue;
+                    }
+                    addToPayload(p.getName(), paramValue, payload);
+                }
+            }
+            finally {
+                ctx.setLocal(getNamespacesKey(), null);
+            }
+        }
+    }
+}

Propchange: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/ParamsContainer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/ParamsContainer.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/PayloadProvider.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/PayloadProvider.java?rev=1639829&view=auto
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/PayloadProvider.java (added)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/PayloadProvider.java Sat Nov 15 03:07:58 2014
@@ -0,0 +1,188 @@
+/*
+ * 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.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.commons.scxml2.Evaluator;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * A <code>PayloadProvider</code> is an element in the SCXML document
+ * that can provide payload data for an event or an external process.
+ */
+public abstract class PayloadProvider extends Action {
+
+    /**
+     * Payload data values wrapper list needed when multiple variable entries use the same names.
+     * The multiple values are then wrapped in a list. The PayloadBuilder uses this 'marker' list
+     * to distinguish between entry values which are a list themselves and the wrapper list.
+     */
+    private static class DataValueList extends ArrayList {
+    }
+
+    /**
+     * Adds an attribute and value to a payload data map.
+     * <p>
+     * As the SCXML specification allows for multiple payload attributes with the same name, this
+     * method takes care of merging multiple values for the same attribute in a list of values.
+     * </p>
+     * <p>
+     * Furthermore, as modifications of payload data on either the sender or receiver side should affect the
+     * the other side, attribute values (notably: {@link Node} value only for now) is cloned first before being added
+     * to the payload data map. This includes 'nested' values within a {@link NodeList}, {@link List} or {@link Map}.
+     * </p>
+     * @param attrName the name of the attribute to add
+     * @param attrValue the value of the attribute to add
+     * @param payload the payload data map to be updated
+     */
+    @SuppressWarnings("unchecked")
+    protected void addToPayload(final String attrName, final Object attrValue, Map<String, Object> payload) {
+        DataValueList valueList = null;
+        Object value = payload.get(attrName);
+        if (value != null) {
+            if (value instanceof DataValueList) {
+                valueList = (DataValueList)value;
+            }
+            else {
+                valueList = new DataValueList();
+                valueList.add(value);
+                payload.put(attrName, valueList);
+            }
+        }
+        value = clonePayloadValue(attrValue);
+        if (value instanceof List) {
+            if (valueList == null) {
+                valueList = new DataValueList();
+                payload.put(attrName, valueList);
+            }
+            valueList.addAll((List)value);
+        }
+        else if (valueList != null) {
+            valueList.add(value);
+        }
+        else {
+            payload.put(attrName, value);
+        }
+    }
+
+    /**
+     * Clones a value object for adding to a payload data map.
+     * <p>
+     * Currently only clones {@link Node} values.
+     * </p>
+     * <p>
+     * If the value object is an instanceof {@link NodeList}, {@link List} or {@link Map}, its elements
+     * are also cloned (if possible) through recursive invocation of this same method, and put in
+     * a new {@link List} or {@link Map} before returning.
+     * </p>
+     * @param value the value to be cloned
+     * @return the cloned value if it could be cloned or otherwise the unmodified value parameter
+     */
+    @SuppressWarnings("unchecked")
+    protected Object clonePayloadValue(final Object value) {
+        if (value != null) {
+            if (value instanceof Node) {
+                return ((Node)value).cloneNode(true);
+            }
+            else if (value instanceof NodeList) {
+                NodeList nodeList = (NodeList)value;
+                ArrayList<Node> list = new ArrayList<Node>();
+                for (int i = 0, size = nodeList.getLength(); i < size; i++) {
+                    list.add(nodeList.item(i).cloneNode(true));
+                }
+                return list;
+            }
+            else if (value instanceof List) {
+                ArrayList<Object> list = new ArrayList<Object>();
+                for (Object v : (List)value) {
+                    list.add(clonePayloadValue(v));
+                }
+                return list;
+            }
+            else if (value instanceof Map) {
+                HashMap<Object, Object> map = new HashMap<Object, Object>();
+                for (Map.Entry<Object,Object> entry : ((Map<Object,Object>)value).entrySet()) {
+                    map.put(entry.getKey(), clonePayloadValue(entry.getValue()));
+                }
+                return map;
+            }
+            // TODO: cloning other type of data?
+        }
+        return value;
+    }
+
+    /**
+     * Converts a payload data map to be used for an event payload.
+     * <p>
+     * Event payload involving key-value pair attributes for an xpath datamodel requires special handling as the
+     * attributes needs to be contained and put in a "data" element under a 'root' Event payload element.
+     * </p>
+     * <p>
+     * For non-xpath datamodels this method simply returns the original payload parameter unmodified.
+     * </p>
+     * @param evaluator the evaluator to test for which datamodel type this event payload is intended
+     * @param payload the payload data map
+     * @return payload for an event
+     * @throws ModelException
+     */
+    protected Object makeEventPayload(final Evaluator evaluator, final Map<String, Object> payload)
+            throws ModelException {
+        if (payload != null && !payload.isEmpty() && Evaluator.XPATH_DATA_MODEL.equals(evaluator.getSupportedDatamodel())) {
+
+            try {
+                Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+                Element payloadNode = document.createElement("payload");
+                for (Map.Entry<String, Object> entry : payload.entrySet()) {
+                    Element dataNode = document.createElement("data");
+                    payloadNode.appendChild(dataNode);
+                    dataNode.setAttribute("id", entry.getKey());
+                    if (entry.getValue() instanceof Node) {
+                        dataNode.appendChild(document.importNode((Node)entry.getValue(), true));
+                    }
+                    else if (entry.getValue() instanceof DataValueList) {
+                        for (Object value : ((DataValueList)entry.getValue())) {
+                            if (value instanceof Node) {
+                                dataNode.appendChild(document.importNode((Node)entry.getValue(), true));
+                            }
+                            else {
+                                dataNode.setTextContent(String.valueOf(value));
+                            }
+                        }
+                    }
+                    else if (entry.getValue() != null) {
+                        dataNode.setTextContent(String.valueOf(entry.getValue()));
+                    }
+                }
+                return payloadNode;
+            }
+            catch (ParserConfigurationException pce) {
+                throw new ModelException("Cannot instantiate a DocumentBuilder", pce);
+            }
+        }
+        return payload;
+    }
+}

Propchange: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/PayloadProvider.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/PayloadProvider.java
------------------------------------------------------------------------------
    svn:keywords = Id

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=1639829&r1=1639828&r2=1639829&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 Sat Nov 15 03:07:58 2014
@@ -90,9 +90,9 @@ public class SCXML implements Serializab
 
 
     /**
-     * The datamodel (type) as specified as attribute on this document
+     * The datamodel name as specified as "datamodel" attribute on this document
      */
-    private String datamodelType;
+    private String datamodelName;
 
     /**
      * Optional property holding the data model for this SCXML document.
@@ -388,19 +388,19 @@ public class SCXML implements Serializab
 	}
 
     /**
-     * Get the datamodel type as specified as attribute on this document
-     * @return The datamodel type of this document
+     * Get the datamodel name as specified as attribute on this document
+     * @return The datamodel name of this document
      */
-    public String getDatamodelType() {
-        return datamodelType;
+    public String getDatamodelName() {
+        return datamodelName;
     }
 
     /**
-     * Sets the datamodel type as specified as attribute on this document
-     * @param datamodelType The datamodel type
+     * Sets the datamodel name as specified as attribute on this document
+     * @param datamodelName The datamodel name
      */
-    public void setDatamodelType(final String datamodelType) {
-        this.datamodelType = datamodelType;
+    public void setDatamodelName(final String datamodelName) {
+        this.datamodelName = datamodelName;
     }
 }
 

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=1639829&r1=1639828&r2=1639829&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 Sat Nov 15 03:07:58 2014
@@ -16,30 +16,23 @@
  */
 package org.apache.commons.scxml2.model;
 
-import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
-import java.util.StringTokenizer;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.scxml2.ActionExecutionContext;
 import org.apache.commons.scxml2.Context;
 import org.apache.commons.scxml2.Evaluator;
 import org.apache.commons.scxml2.SCXMLExpressionException;
+import org.apache.commons.scxml2.SCXMLIOProcessor;
 import org.apache.commons.scxml2.SCXMLSystemContext;
-import org.apache.commons.scxml2.TriggerEvent;
-import org.apache.commons.scxml2.semantics.ErrorConstants;
-import org.w3c.dom.Node;
-import org.w3c.dom.Text;
-import org.w3c.dom.CharacterData;
 
 /**
  * The class in this SCXML object model that corresponds to the
  * &lt;send&gt; SCXML element.
  *
  */
-public class Send extends Action implements ExternalContent {
+public class Send extends NamelistHolder implements ContentContainer {
 
     /**
      * Serial version UID.
@@ -52,25 +45,28 @@ public class Send extends Action impleme
     private static final String TYPE_SCXML = "scxml";
 
     /**
-     * The spec mandated derived event when target cannot be reached
-     * for TYPE_SCXML.
+     * The suffix in the delay string for milliseconds.
      */
-    private static final String EVENT_ERR_SEND_TARGETUNAVAILABLE =
-        "error.send.targetunavailable";
-
-    /** The suffix in the delay string for milliseconds. */
     private static final String MILLIS = "ms";
 
-    /** The suffix in the delay string for seconds. */
+    /**
+     * The suffix in the delay string for seconds.
+     */
     private static final String SECONDS = "s";
 
-    /** The suffix in the delay string for minutes. */
+    /**
+     * The suffix in the delay string for minutes.
+     */
     private static final String MINUTES = "m";
 
-    /** The number of milliseconds in a second. */
+    /**
+     * The number of milliseconds in a second.
+     */
     private static final long MILLIS_IN_A_SECOND = 1000L;
 
-    /** The number of milliseconds in a minute. */
+    /**
+     * The number of milliseconds in a minute.
+     */
     private static final long MILLIS_IN_A_MINUTE = 60000L;
 
     /**
@@ -115,22 +111,11 @@ public class Send extends Action impleme
     private String delayexpr;
 
     /**
-     * The data containing information which may be used by the
-     * implementing platform to configure the event processor.
+     * The data containing information which may be used by the implementing platform to configure the event processor.
      */
     private String hints;
 
     /**
-     * The namelist to the sent.
-     */
-    private String namelist;
-
-    /**
-     * The list of external nodes associated with this &lt;send&gt; element.
-     */
-    private List<Node> externalNodes;
-
-    /**
      * The type of event being generated.
      */
     private String event;
@@ -141,11 +126,15 @@ public class Send extends Action impleme
     private String eventexpr;
 
     /**
+     * The &lt;content/&gt; of this send
+     */
+    private Content content;
+
+    /**
      * Constructor.
      */
     public Send() {
         super();
-        this.externalNodes = new ArrayList<Node>();
     }
 
     /**
@@ -157,6 +146,7 @@ public class Send extends Action impleme
 
     /**
      * Set the idlocation expression
+     *
      * @param idlocation The idlocation expression
      */
     public void setIdlocation(final String idlocation) {
@@ -190,6 +180,7 @@ public class Send extends Action impleme
 
     /**
      * Set the delay expression
+     *
      * @param delayexpr The delay expression to set
      */
     public void setDelayexpr(final String delayexpr) {
@@ -197,15 +188,6 @@ public class Send extends Action impleme
     }
 
     /**
-     * Get the list of external namespaced child nodes.
-     *
-     * @return List Returns the list of externalnodes.
-     */
-    public final List<Node> getExternalNodes() {
-        return externalNodes;
-    }
-
-    /**
      * Get the hints for this &lt;send&gt; element.
      *
      * @return String Returns the hints.
@@ -224,24 +206,6 @@ public class Send extends Action impleme
     }
 
     /**
-     * Get the namelist.
-     *
-     * @return String Returns the namelist.
-     */
-    public final String getNamelist() {
-        return namelist;
-    }
-
-    /**
-     * Set the namelist.
-     *
-     * @param namelist The namelist to set.
-     */
-    public final void setNamelist(final String namelist) {
-        this.namelist = namelist;
-    }
-
-    /**
      * Get the identifier for this &lt;send&gt; element.
      *
      * @return String Returns the id.
@@ -286,6 +250,7 @@ public class Send extends Action impleme
 
     /**
      * Set the target expression
+     *
      * @param targetexpr The target expression to set
      */
     public void setTargetexpr(final String targetexpr) {
@@ -319,6 +284,7 @@ public class Send extends Action impleme
 
     /**
      * Sets the type expression
+     *
      * @param typeexpr The type expression to set
      */
     public void setTypeexpr(final String typeexpr) {
@@ -352,6 +318,7 @@ public class Send extends Action impleme
 
     /**
      * Sets the event expression
+     *
      * @param eventexpr The event expression to set
      */
     public void setEventexpr(final String eventexpr) {
@@ -359,8 +326,27 @@ public class Send extends Action impleme
     }
 
     /**
+     * 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;
+    }
+
+    /**
      * {@inheritDoc}
      */
+    @SuppressWarnings("unchecked")
     @Override
     public void execute(ActionExecutionContext exctx) throws ModelException, SCXMLExpressionException {
         // Send attributes evaluation
@@ -375,61 +361,53 @@ public class Send extends Action impleme
             hintsValue = eval.eval(ctx, hints);
         }
         if (id == null) {
-            id = ((SCXMLSystemContext)exctx.getGlobalContext().getParent()).generateSessionId();
+            id = ctx.getSystemContext().generateSessionId();
             if (idlocation != null) {
-                Node location = eval.evalLocation(ctx, idlocation);
-                if (location != null) {
-                    setNodeValue(location, id);
-                }
-                else {
-                    throw new ModelException("<send>: idlocation does not point to a <data> node");
-                }
+                eval.evalAssign(ctx, idlocation, id, Evaluator.AssignType.REPLACE_CHILDREN, null);
             }
         }
         String targetValue = target;
         if (targetValue == null && targetexpr != null) {
-            targetValue = (String) eval.eval(ctx, targetexpr);
+            targetValue = (String) getTextContentIfNodeResult(eval.eval(ctx, targetexpr));
             if ((targetValue == null || targetValue.trim().length() == 0)
                     && exctx.getAppLog().isWarnEnabled()) {
                 exctx.getAppLog().warn("<send>: target expression \"" + targetexpr
-                    + "\" evaluated to null or empty String");
+                        + "\" evaluated to null or empty String");
             }
         }
         String typeValue = type;
         if (typeValue == null && typeexpr != null) {
-            typeValue = (String) eval.eval(ctx, typeexpr);
+            typeValue = (String) getTextContentIfNodeResult(eval.eval(ctx, typeexpr));
             if ((typeValue == null || typeValue.trim().length() == 0)
                     && exctx.getAppLog().isWarnEnabled()) {
                 exctx.getAppLog().warn("<send>: type expression \"" + typeexpr
-                    + "\" evaluated to null or empty String");
+                        + "\" evaluated to null or empty String");
             }
         }
         if (typeValue == null) {
             // must default to 'scxml' when unspecified
             typeValue = TYPE_SCXML;
-        }
-        else if (!TYPE_SCXML.equals(typeValue) && typeValue.trim().equalsIgnoreCase(TYPE_SCXML)) {
+        } else if (!TYPE_SCXML.equals(typeValue) && typeValue.trim().equalsIgnoreCase(TYPE_SCXML)) {
             typeValue = TYPE_SCXML;
         }
-        Map<String, Object> params = null;
-        if (namelist != null) {
-            StringTokenizer tkn = new StringTokenizer(namelist);
-            params = new HashMap<String, Object>(tkn.countTokens());
-            while (tkn.hasMoreTokens()) {
-                String varName = tkn.nextToken();
-                Object varObj = ctx.get(varName);
-                if (varObj == null) {
-                    //considered as a warning here
-                    exctx.getErrorReporter().onError(ErrorConstants.UNDEFINED_VARIABLE,
-                            varName + " = null", parentState);
-                }
-                params.put(varName, varObj);
+        Object payload = null;
+        Map<String, Object> payloadDataMap = new HashMap<String, Object>();
+        addNamelistDataToPayload(exctx, payloadDataMap);
+        addParamsToPayload(exctx, payloadDataMap);
+        if (!payloadDataMap.isEmpty()) {
+            payload = makeEventPayload(eval, payloadDataMap);
+        }
+        else if (content != null) {
+            if (content.getExpr() != null) {
+                payload = clonePayloadValue(eval.eval(ctx, content.getExpr()));
+            } else {
+                payload = clonePayloadValue(content.getBody());
             }
         }
         long wait = 0L;
         String delayString = delay;
         if (delayString == null && delayexpr != null) {
-            Object delayValue = eval.eval(ctx, delay);
+            Object delayValue = getTextContentIfNodeResult(eval.eval(ctx, delayexpr));
             if (delayValue != null) {
                 delayString = delayValue.toString();
             }
@@ -439,63 +417,34 @@ public class Send extends Action impleme
         }
         String eventValue = event;
         if (eventValue == null && eventexpr != null) {
-            eventValue = (String) eval.eval(ctx, eventexpr);
+            eventValue = (String) getTextContentIfNodeResult(eval.eval(ctx, eventexpr));
             if ((eventValue == null || eventValue.trim().length() == 0) && exctx.getAppLog().isWarnEnabled()) {
                 throw new SCXMLExpressionException("<send>: event expression \"" + eventexpr
                         + "\" evaluated to null or empty String");
             }
         }
-        // Lets see if we should handle it ourselves
-        if (typeValue != null && TYPE_SCXML.equals(typeValue)) {
-            if (eventValue == null) {
-                // event required when type == http://www.w3.org/TR/scxml/#SCXMLEventProcessor
-                throw new ModelException("Event parameter is required for <send> with type=\"scxml\"");
-            }
-            if (targetValue == null || targetValue.trim().length() == 0) {
-                // TODO: Remove both short-circuit passes in v1.0
-                if (wait == 0L) {
-                    if (exctx.getAppLog().isDebugEnabled()) {
-                        exctx.getAppLog().debug("<send>: Enqueued event '" + eventValue
-                            + "' with no delay");
-                    }
-                    exctx.getInternalIOProcessor().addEvent(
-                            new TriggerEvent(eventValue, TriggerEvent.SIGNAL_EVENT, params));
-                    return;
-                }
-            } else {
-                // We know of no other
-                if (exctx.getAppLog().isWarnEnabled()) {
-                    exctx.getAppLog().warn("<send>: Unavailable target - "
-                        + targetValue);
-                }
-                exctx.getInternalIOProcessor().addEvent(
-                        new TriggerEvent(EVENT_ERR_SEND_TARGETUNAVAILABLE, TriggerEvent.ERROR_EVENT));
-                // short-circuit the EventDispatcher
-                return;
-            }
-        }
+        Map<String, SCXMLIOProcessor> ioProcessors = (Map<String, SCXMLIOProcessor>) ctx.get(SCXMLSystemContext.IOPROCESSORS_KEY);
         ctx.setLocal(getNamespacesKey(), null);
         if (exctx.getAppLog().isDebugEnabled()) {
             exctx.getAppLog().debug("<send>: Dispatching event '" + eventValue
-                + "' to target '" + targetValue + "' of target type '"
-                + typeValue + "' with suggested delay of " + wait
-                + "ms");
-        }
-        // Else, let the EventDispatcher take care of it
-        exctx.getEventDispatcher().send(id, targetValue, typeValue, eventValue,
-            params, hintsValue, wait, externalNodes);
+                    + "' to target '" + targetValue + "' of target type '"
+                    + typeValue + "' with suggested delay of " + wait
+                    + "ms");
+        }
+        exctx.getEventDispatcher().send(ioProcessors, id, targetValue, typeValue, eventValue,
+                payload, hintsValue, wait);
     }
 
     /**
      * Parse delay.
      *
      * @param delayString The String value of the delay, in CSS2 format
-     * @param appLog The application log
+     * @param appLog      The application log
      * @return The parsed delay in milliseconds
      * @throws SCXMLExpressionException If the delay cannot be parsed
      */
     private long parseDelay(final String delayString, final Log appLog)
-    throws SCXMLExpressionException {
+            throws SCXMLExpressionException {
 
         long wait = 0L;
         long multiplier = 1L;
@@ -525,42 +474,5 @@ public class Send extends Action impleme
         }
         return wait;
     }
-
-    /**
-     * Set node value, depending on its type, from a String.
-     *
-     * @param node A Node whose value is to be set
-     * @param value The new value
-     */
-    private void setNodeValue(final Node node, final String value) {
-        switch(node.getNodeType()) {
-            case Node.ATTRIBUTE_NODE:
-                node.setNodeValue(value);
-                break;
-            case Node.ELEMENT_NODE:
-                //remove all text children
-                if (node.hasChildNodes()) {
-                    Node child = node.getFirstChild();
-                    while (child != null) {
-                        if (child.getNodeType() == Node.TEXT_NODE) {
-                            node.removeChild(child);
-                        }
-                        child = child.getNextSibling();
-                    }
-                }
-                //create a new text node and append
-                Text txt = node.getOwnerDocument().createTextNode(value);
-                node.appendChild(txt);
-                break;
-            case Node.TEXT_NODE:
-            case Node.CDATA_SECTION_NODE:
-                ((CharacterData) node).setData(value);
-                break;
-            default:
-                String err = "Trying to set value of a strange Node type: "
-                        + node.getNodeType();
-                throw new IllegalArgumentException(err);
-        }
-    }
 }
 

Modified: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/TransitionalState.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/TransitionalState.java?rev=1639829&r1=1639828&r2=1639829&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/TransitionalState.java (original)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/model/TransitionalState.java Sat Nov 15 03:07:58 2014
@@ -217,6 +217,7 @@ public abstract class TransitionalState 
      */
     public final void addInvoke(final Invoke invoke) {
         this.invokes.add(invoke);
+        invoke.setParentEnterableState(this);
     }
 
     /**

Modified: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/semantics/ErrorConstants.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/semantics/ErrorConstants.java?rev=1639829&r1=1639828&r2=1639829&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/semantics/ErrorConstants.java (original)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/semantics/ErrorConstants.java Sat Nov 15 03:07:58 2014
@@ -60,6 +60,11 @@ public class ErrorConstants {
      */
     public static final String EXPRESSION_ERROR = "EXPRESSION_ERROR";
 
+    /**
+     * An execution error.
+     */
+    public static final String EXECUTION_ERROR = "EXECUTION_ERROR";
+
     //---------------------------------------------- STATIC CONSTANTS ONLY
 
     /**

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=1639829&r1=1639828&r2=1639829&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 Sat Nov 15 03:07:58 2014
@@ -25,10 +25,9 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.commons.scxml2.ActionExecutionContext;
 import org.apache.commons.scxml2.Context;
 import org.apache.commons.scxml2.ErrorReporter;
-import org.apache.commons.scxml2.Evaluator;
-import org.apache.commons.scxml2.PathResolver;
 import org.apache.commons.scxml2.SCInstance;
 import org.apache.commons.scxml2.SCXMLExecutionContext;
 import org.apache.commons.scxml2.SCXMLExpressionException;
@@ -47,7 +46,6 @@ import org.apache.commons.scxml2.model.H
 import org.apache.commons.scxml2.model.Invoke;
 import org.apache.commons.scxml2.model.OnEntry;
 import org.apache.commons.scxml2.model.OnExit;
-import org.apache.commons.scxml2.model.Param;
 import org.apache.commons.scxml2.model.Script;
 import org.apache.commons.scxml2.model.SimpleTransition;
 import org.apache.commons.scxml2.model.TransitionalState;
@@ -1074,82 +1072,15 @@ public class SCXMLSemanticsImpl implemen
      * @param statesToInvoke the set of activated states which invokes need to be invoked
      */
     public void initiateInvokes(final SCXMLExecutionContext exctx,
-                                final Set<TransitionalState> statesToInvoke) {
-        SCInstance scInstance = exctx.getScInstance();
-        Evaluator eval = exctx.getEvaluator();
+                                final Set<TransitionalState> statesToInvoke) throws ModelException {
+        ActionExecutionContext aexctx = exctx.getActionExecutionContext();
         for (TransitionalState ts : statesToInvoke) {
-            if (ts.getInvokes().isEmpty()) {
-                continue;
-            }
-            Context context = scInstance.getContext(ts);
-            for (Invoke i : ts.getInvokes()) {
-                String src = i.getSrc();
-                if (src == null) {
-                    String srcexpr = i.getSrcexpr();
-                    Object srcObj;
-                    try {
-                        context.setLocal(Context.NAMESPACES_KEY, i.getNamespaces());
-                        srcObj = eval.eval(context, srcexpr);
-                        context.setLocal(Context.NAMESPACES_KEY, null);
-                        src = String.valueOf(srcObj);
-                    } catch (SCXMLExpressionException see) {
-                        exctx.getInternalIOProcessor().addEvent(new TriggerEvent(TriggerEvent.ERROR_EXECUTION, TriggerEvent.ERROR_EVENT));
-                        exctx.getErrorReporter().onError(ErrorConstants.EXPRESSION_ERROR, see.getMessage(), i);
-                    }
-                }
-                String source = src;
-                PathResolver pr = i.getPathResolver();
-                if (pr != null) {
-                    source = i.getPathResolver().resolvePath(src);
-                }
-                Invoker inv;
-                try {
-                    inv = exctx.newInvoker(i.getType());
-                } catch (InvokerException ie) {
-                    exctx.getInternalIOProcessor().addEvent(new TriggerEvent("failed.invoke."+ts.getId(), TriggerEvent.ERROR_EVENT));
-                    continue;
-                }
-                List<Param> params = i.params();
-                Map<String, Object> args = new HashMap<String, Object>();
-                for (Param p : params) {
-                    String argExpr = p.getExpr();
-                    Object argValue = null;
-                    context.setLocal(Context.NAMESPACES_KEY, p.getNamespaces());
-                    // Do we have an "expr" attribute?
-                    if (argExpr != null && argExpr.trim().length() > 0) {
-                        try {
-                            argValue = eval.eval(context, argExpr);
-                        } catch (SCXMLExpressionException see) {
-                            exctx.getInternalIOProcessor().addEvent(new TriggerEvent(TriggerEvent.ERROR_EXECUTION, TriggerEvent.ERROR_EVENT));
-                            exctx.getErrorReporter().onError(ErrorConstants.EXPRESSION_ERROR, see.getMessage(), i);
-                        }
-                    } else {
-                        // No. Does value of "name" attribute refer to a valid
-                        // location in the data model?
-                        try {
-                            argValue = eval.evalLocation(context, p.getName());
-                            if (argValue == null) {
-                                // Generate error, 4.3.1 in WD-scxml-20080516
-                                exctx.getInternalIOProcessor().addEvent(new TriggerEvent(ts.getId() + ERR_ILLEGAL_ALLOC, TriggerEvent.ERROR_EVENT));
-                            }
-                        } catch (SCXMLExpressionException see) {
-                            exctx.getInternalIOProcessor().addEvent(new TriggerEvent(TriggerEvent.ERROR_EXECUTION, TriggerEvent.ERROR_EVENT));
-                            exctx.getErrorReporter().onError(ErrorConstants.EXPRESSION_ERROR, see.getMessage(), i);
-                        }
-                    }
-                    context.setLocal(Context.NAMESPACES_KEY, null);
-                    args.put(p.getName(), argValue);
-                }
-                String invokeId = exctx.setInvoker(i, inv);
-                inv.setInvokeId(invokeId);
-                inv.setParentIOProcessor(exctx.getExternalIOProcessor());
-                inv.setEvaluator(exctx.getEvaluator());
-                try {
-                    inv.invoke(source, args);
-                } catch (InvokerException ie) {
-                    exctx.getInternalIOProcessor().addEvent(new TriggerEvent("failed.invoke."+ts.getId(), TriggerEvent.ERROR_EVENT));
-                    exctx.removeInvoker(i);
-                }
+            for (Invoke invoke : ts.getInvokes()) {
+                Context ctx = aexctx.getContext(invoke.getParentEnterableState());
+                String invokerManagerKey = invoke.getInvokerManagerKey();
+                ctx.setLocal(invokerManagerKey, exctx);
+                invoke.execute(aexctx);
+                ctx.setLocal(invokerManagerKey, null);
             }
         }
     }

Modified: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/test/StandaloneUtils.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/test/StandaloneUtils.java?rev=1639829&r1=1639828&r2=1639829&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/test/StandaloneUtils.java (original)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/test/StandaloneUtils.java Sat Nov 15 03:07:58 2014
@@ -27,10 +27,8 @@ import javax.xml.stream.XMLStreamExcepti
 
 import org.apache.commons.scxml2.Context;
 import org.apache.commons.scxml2.Evaluator;
-import org.apache.commons.scxml2.EventDispatcher;
 import org.apache.commons.scxml2.SCXMLExecutor;
 import org.apache.commons.scxml2.TriggerEvent;
-import org.apache.commons.scxml2.env.SimpleScheduler;
 import org.apache.commons.scxml2.env.Tracer;
 import org.apache.commons.scxml2.invoke.SimpleSCXMLInvoker;
 import org.apache.commons.scxml2.io.SCXMLReader;
@@ -82,8 +80,6 @@ public final class StandaloneUtils {
             }
             System.out.println(SCXMLWriter.write(doc));
             SCXMLExecutor exec = new SCXMLExecutor(evaluator, null, trc);
-            EventDispatcher ed = new SimpleScheduler(exec);
-            exec.setEventdispatcher(ed);
             exec.setStateMachine(doc);
             exec.addListener(doc, trc);
             exec.registerInvokerClass("scxml", SimpleSCXMLInvoker.class);
@@ -113,7 +109,7 @@ public final class StandaloneUtils {
                     rootCtx.setLocal(name, value);
                     System.out.println("Set variable " + name + " to "
                         + value);
-                } else if (event == null || event.trim().length() == 0
+                } else if (event.trim().length() == 0
                            || event.equalsIgnoreCase("null")) {
                     TriggerEvent[] evts = {new TriggerEvent(null,
                         TriggerEvent.SIGNAL_EVENT, null)};

Modified: commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/EventDataTest.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/EventDataTest.java?rev=1639829&r1=1639828&r2=1639829&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/EventDataTest.java (original)
+++ commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/EventDataTest.java Sat Nov 15 03:07:58 2014
@@ -18,7 +18,6 @@ package org.apache.commons.scxml2;
 
 import java.util.Set;
 
-import org.apache.commons.scxml2.env.SimpleScheduler;
 import org.apache.commons.scxml2.env.Tracer;
 import org.apache.commons.scxml2.model.EnterableState;
 import org.apache.commons.scxml2.model.SCXML;
@@ -97,7 +96,6 @@ public class EventDataTest {
         SCXML scxml = SCXMLTestHelper.parse("org/apache/commons/scxml2/env/jexl/eventdata-03.xml");
         Tracer trc = new Tracer();
         SCXMLExecutor exec = new SCXMLExecutor(null, null, trc);
-        exec.setEventdispatcher(new SimpleScheduler(exec));
         exec.addListener(scxml, trc);
         exec.setStateMachine(scxml);
         exec.go();

Modified: commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/WizardsTest.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/WizardsTest.java?rev=1639829&r1=1639828&r2=1639829&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/WizardsTest.java (original)
+++ commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/WizardsTest.java Sat Nov 15 03:07:58 2014
@@ -16,18 +16,17 @@
  */
 package org.apache.commons.scxml2;
 
-import java.io.Serializable;
-import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.commons.scxml2.env.SimpleDispatcher;
 import org.apache.commons.scxml2.model.EnterableState;
 
 import org.junit.Assert;
 import org.junit.Test;
-import org.w3c.dom.Node;
+
 /**
- * Unit tests {@link org.apache.commons.scxml2.SCXMLExecutor}.
+ * Unit tests
  */
 public class WizardsTest {
 
@@ -74,25 +73,33 @@ public class WizardsTest {
         Assert.assertEquals("state4", currentStates.iterator().next().getId());
     }
 
-    static class TestEventDispatcher implements EventDispatcher, Serializable {
+    static class TestEventDispatcher extends SimpleDispatcher {
         private static final long serialVersionUID = 1L;
         // If you change this, you must also change testWizard02Sample()
+
         int callback = 0;
-        public void send(String id, String target, String type,
-                String event, Map<String, Object> params, Object hints, long delay,
-                List<Node> externalNodes) {
-            int i = ((Integer) params.get("aValue")).intValue();
-            switch (callback) {
-                case 0:
-                    Assert.assertTrue(i == 2); // state2
-                    callback++;
-                    break;
-                case 1:
-                    Assert.assertTrue(i == 4); // state4
-                    callback++;
-                    break;
-                default:
-                    Assert.fail("More than 2 TestEventDispatcher <send> callbacks");
+
+        @SuppressWarnings("unchecked")
+        public void send(Map<String, SCXMLIOProcessor> ioProcessors, String id, String target, String type,
+                String event, Object data, Object hints, long delay) {
+            if ("foo".equals(type)) {
+                Map<String, Object> params = (Map<String, Object>)data;
+                int i = ((Integer) params.get("aValue"));
+                switch (callback) {
+                    case 0:
+                        Assert.assertTrue(i == 2); // state2
+                        callback++;
+                        break;
+                    case 1:
+                        Assert.assertTrue(i == 4); // state4
+                        callback++;
+                        break;
+                    default:
+                        Assert.fail("More than 2 TestEventDispatcher <send> callbacks for type \"foo\"");
+                }
+            }
+            else {
+                super.send(ioProcessors, id, target, type, event, data, hints, delay);
             }
         }
         public void cancel(String sendId) {

Modified: commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/custom-hello-world-04-jexl.xml
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/custom-hello-world-04-jexl.xml?rev=1639829&r1=1639828&r2=1639829&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/custom-hello-world-04-jexl.xml (original)
+++ commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/custom-hello-world-04-jexl.xml Sat Nov 15 03:07:58 2014
@@ -29,7 +29,7 @@
         </onentry>
 
         <transition event="helloevent" target="middle1">
-            <assign name="helloName1" expr="_event.data" />
+            <assign location="helloName1" expr="_event.data" />
         </transition>
     </state>
 
@@ -47,7 +47,7 @@
         </onentry>
 
         <transition event="helloevent" target="custom3">
-            <assign name="helloName1" expr="_event.data" />
+            <assign location="helloName1" expr="_event.data" />
         </transition>
     </state>
 

Modified: commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/env/SimpleContextTest.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/env/SimpleContextTest.java?rev=1639829&r1=1639828&r2=1639829&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/env/SimpleContextTest.java (original)
+++ commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/env/SimpleContextTest.java Sat Nov 15 03:07:58 2014
@@ -57,7 +57,7 @@ public class SimpleContextTest {
         Map<String, Object> parentVars = new HashMap<String, Object>();
         parentVars.put("key", "value");
         
-        SimpleContext parentContext = new SimpleContext(parentVars);
+        SimpleContext parentContext = new SimpleContext(null, parentVars);
         
         Map<String, Object> vars = new HashMap<String, Object>();
         vars.put("key", "value");
@@ -73,7 +73,7 @@ public class SimpleContextTest {
         Map<String, Object> parentVars = new HashMap<String, Object>();
         parentVars.put("differentKey", "value");
         
-        SimpleContext parentContext = new SimpleContext(parentVars);
+        SimpleContext parentContext = new SimpleContext(null, parentVars);
         
         Map<String, Object> vars = new HashMap<String, Object>();
         vars.put("key", "value");
@@ -106,7 +106,7 @@ public class SimpleContextTest {
         Map<String, Object> parentVars = new HashMap<String, Object>();
         parentVars.put("differentKey", "differentValue");
         
-        SimpleContext parentContext = new SimpleContext(parentVars);
+        SimpleContext parentContext = new SimpleContext(null, parentVars);
         
         Map<String, Object> vars = new HashMap<String, Object>();
         vars.put("key", "value");
@@ -132,7 +132,7 @@ public class SimpleContextTest {
         Map<String, Object> parentVars = new HashMap<String, Object>();
         parentVars.put("differentKey", "differentValue");
         
-        SimpleContext parentContext = new SimpleContext(parentVars);
+        SimpleContext parentContext = new SimpleContext(null, parentVars);
         
         Map<String, Object> vars = new HashMap<String, Object>();
         vars.put("key", "value");
@@ -170,7 +170,7 @@ public class SimpleContextTest {
         Map<String, Object> parentVars = new HashMap<String, Object>();
         parentVars.put("differentKey", "differentValue");
         
-        SimpleContext parentContext = new SimpleContext(parentVars);
+        SimpleContext parentContext = new SimpleContext(null, parentVars);
         
         Map<String, Object> vars = new HashMap<String, Object>();
         vars.put("key", "value");

Modified: commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/env/groovy/GroovyContextTest.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/env/groovy/GroovyContextTest.java?rev=1639829&r1=1639828&r2=1639829&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/env/groovy/GroovyContextTest.java (original)
+++ commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/env/groovy/GroovyContextTest.java Sat Nov 15 03:07:58 2014
@@ -34,7 +34,7 @@ public class GroovyContextTest {
     public void testPrepopulated() {
         Map<String, Object> m = new HashMap<String, Object>();
         m.put("foo", "bar");
-        GroovyContext ctx = new GroovyContext(m, null);
+        GroovyContext ctx = new GroovyContext(null, m, null);
         Assert.assertNotNull(ctx);
         Assert.assertEquals(1, ctx.getVars().size());
         String fooValue = (String) ctx.get("foo");

Modified: commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/env/groovy/GroovyEvaluatorTest.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/env/groovy/GroovyEvaluatorTest.java?rev=1639829&r1=1639828&r2=1639829&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/env/groovy/GroovyEvaluatorTest.java (original)
+++ commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/env/groovy/GroovyEvaluatorTest.java Sat Nov 15 03:07:58 2014
@@ -33,10 +33,12 @@ public class GroovyEvaluatorTest {
 
     private String BAD_EXPRESSION = ">";
     private Context ctx;
+    private Context rootCtx;
 
     @Before
     public void before() {
-        ctx = new GroovyContext();
+        rootCtx = new GroovyContext();
+        ctx = new GroovyContext(new SCXMLSystemContext(rootCtx), null);
     }
 
     @Test
@@ -60,7 +62,7 @@ public class GroovyEvaluatorTest {
         state1.setId("state1");
         allStates.add(state1);
 
-        ctx.setLocal(SCXMLSystemContext.ALL_STATES_KEY, allStates);
+        rootCtx.set(SCXMLSystemContext.ALL_STATES_KEY, allStates);
 
         Assert.assertTrue(eval.evalCond(ctx, "In('state1')"));
     }

Modified: commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/env/groovy/StaticMethodTest.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/env/groovy/StaticMethodTest.java?rev=1639829&r1=1639828&r2=1639829&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/env/groovy/StaticMethodTest.java (original)
+++ commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/env/groovy/StaticMethodTest.java Sat Nov 15 03:07:58 2014
@@ -35,23 +35,4 @@ public class StaticMethodTest {
         Assert.assertEquals(1, currentStates.size());
         Assert.assertEquals("static", currentStates.iterator().next().getId());
     }
-
-    @Test
-    public void mytest() throws Exception {
-        Object o1, o2 = new Object();
-        o1 = new Object();
-
-        o2 = null;
-        o1 = null;
-        if (val(o1,o2)) {
-            System.out.println("hello");
-        }
-        else {
-            System.out.println("boo");
-        }
-    }
-
-    public boolean val(Object o1, Object o2) {
-        return (o1 == o2);
-    }
 }

Modified: commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/env/groovy/groovy-closure.xml
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/env/groovy/groovy-closure.xml?rev=1639829&r1=1639828&r2=1639829&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/env/groovy/groovy-closure.xml (original)
+++ commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/env/groovy/groovy-closure.xml Sat Nov 15 03:07:58 2014
@@ -85,7 +85,7 @@
             <transition cond="!In('closed')" target="idle"/>
 
             <transition event="time" target="cooking">
-              <assign name="timer" expr="timer + 1"/>
+              <assign location="timer" expr="timer + 1"/>
             </transition>
           </state>
         </state>



Mime
View raw message