Repository: commons-scxml Updated Branches: refs/heads/master b5dd05b28 -> 4e13be179
SCXML-264 Support <invoke> with inline (<content> body) SCXML statemachine definition Project: http://git-wip-us.apache.org/repos/asf/commons-scxml/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-scxml/commit/4e13be17 Tree: http://git-wip-us.apache.org/repos/asf/commons-scxml/tree/4e13be17 Diff: http://git-wip-us.apache.org/repos/asf/commons-scxml/diff/4e13be17 Branch: refs/heads/master Commit: 4e13be179dccbf311fced2a2eeb71a04db170bb7 Parents: b5dd05b Author: Ate Douma <a...@apache.org> Authored: Sun Dec 10 16:24:17 2017 +0100 Committer: Ate Douma <a...@apache.org> Committed: Sun Dec 10 16:24:17 2017 +0100 ---------------------------------------------------------------------- src/changes/changes.xml | 6 +- .../apache/commons/scxml2/invoke/Invoker.java | 17 ++++- .../scxml2/invoke/SimpleSCXMLInvoker.java | 29 +++++++- .../apache/commons/scxml2/io/ContentParser.java | 20 ++++++ .../apache/commons/scxml2/io/SCXMLReader.java | 35 +++++++-- .../apache/commons/scxml2/io/SCXMLWriter.java | 1 + .../org/apache/commons/scxml2/model/Assign.java | 29 +------- .../apache/commons/scxml2/model/Content.java | 39 ++++++++-- .../org/apache/commons/scxml2/model/Invoke.java | 75 ++++++++++---------- .../scxml2/model/PathResolverHolder.java | 43 ----------- .../org/apache/commons/scxml2/model/SCXML.java | 25 +++++++ .../org/apache/commons/scxml2/model/Send.java | 5 +- .../scxml2/invoke/InvokeParamNameTest.java | 21 ++++-- .../org/apache/commons/scxml2/w3c/tests.xml | 56 +++++++-------- 14 files changed, 239 insertions(+), 162 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/4e13be17/src/changes/changes.xml ---------------------------------------------------------------------- diff --git a/src/changes/changes.xml b/src/changes/changes.xml index f5c434c..363de8c 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -35,7 +35,11 @@ <release version="2.0" date="In Git master" description="Latest unreleased code"> - <action dev="ate" type="update" issue="SCXML-263"> + <action dev="ate" type="fix" issue="SCXML-264"> + [12-10-2017] Support <invoke> with inline (<content> body) SCXML statemachine definition + </action> + + <action dev="ate" type="fix" issue="SCXML-263"> [12-10-2017] Javascript engine (Nashorn) cannot be shared between multiple SCXML instance executions </action> http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/4e13be17/src/main/java/org/apache/commons/scxml2/invoke/Invoker.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/scxml2/invoke/Invoker.java b/src/main/java/org/apache/commons/scxml2/invoke/Invoker.java index 09dcf84..663a985 100644 --- a/src/main/java/org/apache/commons/scxml2/invoke/Invoker.java +++ b/src/main/java/org/apache/commons/scxml2/invoke/Invoker.java @@ -96,17 +96,28 @@ public interface Invoker { SCXMLIOProcessor getChildIOProcessor(); /** - * Begin this invocation. + * Invoke the SCXML document located at an external URL. * - * @param source The source URI of the activity being invoked. + * @param url The source URL of the SCXML document to invoke. * @param params The <param> values * @throws InvokerException In case there is a fatal problem with * invoking the source. */ - void invoke(String source, Map<String, Object> params) + void invoke(String url, Map<String, Object> params) throws InvokerException; /** + * Invoke the SCXML document provided as inline XML content + * + * @param content The SCXML document as inline XML content + * @param params The <param> values + * @throws InvokerException In case there is a fatal problem with + * invoking the source. + */ + void invokeContent(String content, Map<String, Object> params) + throws InvokerException; + + /** * Forwards the event triggered on the parent state machine * on to the invoked activity. * http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/4e13be17/src/main/java/org/apache/commons/scxml2/invoke/SimpleSCXMLInvoker.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/scxml2/invoke/SimpleSCXMLInvoker.java b/src/main/java/org/apache/commons/scxml2/invoke/SimpleSCXMLInvoker.java index ee7262f..9277e0a 100644 --- a/src/main/java/org/apache/commons/scxml2/invoke/SimpleSCXMLInvoker.java +++ b/src/main/java/org/apache/commons/scxml2/invoke/SimpleSCXMLInvoker.java @@ -18,12 +18,12 @@ package org.apache.commons.scxml2.invoke; import java.io.IOException; import java.io.Serializable; +import java.io.StringReader; import java.net.URL; import java.util.Map; import javax.xml.stream.XMLStreamException; -import org.apache.commons.scxml2.Context; import org.apache.commons.scxml2.EventBuilder; import org.apache.commons.scxml2.SCXMLExecutor; import org.apache.commons.scxml2.SCXMLIOProcessor; @@ -89,11 +89,11 @@ public class SimpleSCXMLInvoker implements Invoker, Serializable { * {@inheritDoc}. */ @Override - public void invoke(final String source, final Map<String, Object> params) + public void invoke(final String url, final Map<String, Object> params) throws InvokerException { SCXML scxml; try { - scxml = SCXMLReader.read(new URL(source)); + scxml = SCXMLReader.read(new URL(url)); } catch (ModelException me) { throw new InvokerException(me.getMessage(), me.getCause()); } catch (IOException ioe) { @@ -101,6 +101,29 @@ public class SimpleSCXMLInvoker implements Invoker, Serializable { } catch (XMLStreamException xse) { throw new InvokerException(xse.getMessage(), xse.getCause()); } + execute(scxml, params); + } + + /** + * {@inheritDoc}. + */ + @Override + public void invokeContent(final String content, final Map<String, Object> params) + throws InvokerException { + SCXML scxml; + try { + scxml = SCXMLReader.read(new StringReader(content)); + } catch (ModelException me) { + throw new InvokerException(me.getMessage(), me.getCause()); + } catch (IOException ioe) { + throw new InvokerException(ioe.getMessage(), ioe.getCause()); + } catch (XMLStreamException xse) { + throw new InvokerException(xse.getMessage(), xse.getCause()); + } + execute(scxml, params); + } + + protected void execute(SCXML scxml, final Map<String, Object> params) throws InvokerException { try { executor = new SCXMLExecutor(parentSCXMLExecutor, invokeId, scxml); } http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/4e13be17/src/main/java/org/apache/commons/scxml2/io/ContentParser.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/scxml2/io/ContentParser.java b/src/main/java/org/apache/commons/scxml2/io/ContentParser.java index e3ae09d..1f4290e 100644 --- a/src/main/java/org/apache/commons/scxml2/io/ContentParser.java +++ b/src/main/java/org/apache/commons/scxml2/io/ContentParser.java @@ -18,10 +18,18 @@ package org.apache.commons.scxml2.io; import java.io.IOException; import java.io.InputStream; +import java.io.StringWriter; import java.net.URL; +import java.util.Properties; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.ObjectMapper; @@ -172,6 +180,18 @@ public class ContentParser { return doc != null ? doc.getDocumentElement() : null; } + public String transformXml(final Node node) throws TransformerException { + StringWriter writer = new StringWriter(); + Transformer transformer = TransformerFactory.newInstance().newTransformer(); + Properties outputProps = new Properties(); + outputProps.put(OutputKeys.OMIT_XML_DECLARATION, "no"); + outputProps.put(OutputKeys.STANDALONE, "no"); + outputProps.put(OutputKeys.INDENT, "yes"); + transformer.setOutputProperties(outputProps); + transformer.transform(new DOMSource(node), new StreamResult(writer)); + return writer.toString(); + } + /** * Parse a string into a content object, following the SCXML rules as specified for the ECMAscript (section B.2.1) Data Model * <ul> http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/4e13be17/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 ab06d6f..9918196 100644 --- a/src/main/java/org/apache/commons/scxml2/io/SCXMLReader.java +++ b/src/main/java/org/apache/commons/scxml2/io/SCXMLReader.java @@ -41,6 +41,7 @@ import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.util.XMLEventAllocator; import javax.xml.transform.Source; +import javax.xml.transform.TransformerException; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; @@ -589,6 +590,7 @@ public final class SCXMLReader { throws IOException, ModelException, XMLStreamException { SCXML scxml = new SCXML(); + scxml.setPathResolver(configuration.pathResolver); while (reader.hasNext()) { String name, nsURI; switch (reader.next()) { @@ -1163,11 +1165,11 @@ public final class SCXMLReader { Invoke invoke = new Invoke(); invoke.setId(readAV(reader, ATTR_ID)); + invoke.setIdlocation(readAV(reader, ATTR_IDLOCATION)); invoke.setSrc(readAV(reader, ATTR_SRC)); invoke.setSrcexpr(readAV(reader, ATTR_SRCEXPR)); invoke.setType(readAV(reader, ATTR_TYPE)); invoke.setAutoForward(readBooleanAV(reader, ELEM_INVOKE, ATTR_AUTOFORWARD)); - invoke.setPathResolver(configuration.pathResolver); readNamespaces(configuration, invoke); loop : while (reader.hasNext()) { @@ -1281,12 +1283,35 @@ public final class SCXMLReader { else { Node body = readNode(reader, configuration, XMLNS_SCXML, ELEM_CONTENT, new String[]{}); if (body.hasChildNodes()) { + content.setBody(body); NodeList children = body.getChildNodes(); if (children.getLength() == 1 && children.item(0).getNodeType() == Node.TEXT_NODE) { - content.setBody(children.item(0).getNodeValue()); + try { + content.setValue(ContentParser.DEFAULT_PARSER.parseContent(children.item(0).getNodeValue())); + } + catch (IOException ioe) { + throw new XMLStreamException(ioe); + } } else { - content.setBody(body); + // find only use first child element + for (int i = 0, size = children.getLength(); i < size; i++) { + Node child = children.item(i); + if (child.getNodeType() == Node.ELEMENT_NODE) { + if (contentContainer instanceof Invoke) { + // transform invoke <content/> to string upfront as we currently only can handle string input + try { + content.setValue(ContentParser.DEFAULT_PARSER.transformXml(child)); + } catch (TransformerException e) { + throw new XMLStreamException(e); + } + } + else { + content.setValue(child); + } + break; + } + } } } } @@ -1767,7 +1792,6 @@ public final class SCXMLReader { assign.setExpr(readAV(reader, ATTR_EXPR)); assign.setLocation(readRequiredAV(reader, ELEM_ASSIGN, ATTR_LOCATION)); assign.setSrc(readAV(reader, ATTR_SRC)); - assign.setPathResolver(configuration.pathResolver); readNamespaces(configuration, assign); assign.setParent(executable); if (parent != null) { @@ -2254,9 +2278,10 @@ public final class SCXMLReader { case XMLStreamConstants.CHARACTERS: case XMLStreamConstants.ENTITY_REFERENCE: case XMLStreamConstants.CDATA: - case XMLStreamConstants.COMMENT: body.append(reader.getText()); break; + case XMLStreamConstants.COMMENT: + break; case XMLStreamConstants.END_ELEMENT: break loop; default: // rest is ignored http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/4e13be17/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 d0ea429..82a6e48 100644 --- a/src/main/java/org/apache/commons/scxml2/io/SCXMLWriter.java +++ b/src/main/java/org/apache/commons/scxml2/io/SCXMLWriter.java @@ -815,6 +815,7 @@ public class SCXMLWriter { writer.writeStartElement(ELEM_INVOKE); writeAV(writer, ATTR_ID, invoke.getId()); + writeAV(writer, ATTR_IDLOCATION, invoke.getIdlocation()); writeAV(writer, ATTR_SRC, invoke.getSrc()); writeAV(writer, ATTR_SRCEXPR, invoke.getSrcexpr()); writeAV(writer, ATTR_TYPE, invoke.getType()); http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/4e13be17/src/main/java/org/apache/commons/scxml2/model/Assign.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/scxml2/model/Assign.java b/src/main/java/org/apache/commons/scxml2/model/Assign.java index 6677520..f2ca819 100644 --- a/src/main/java/org/apache/commons/scxml2/model/Assign.java +++ b/src/main/java/org/apache/commons/scxml2/model/Assign.java @@ -30,7 +30,7 @@ import org.apache.commons.scxml2.io.ContentParser; * <assign> SCXML element. * */ -public class Assign extends Action implements PathResolverHolder { +public class Assign extends Action { /** * Serial version UID. @@ -54,11 +54,6 @@ public class Assign extends Action implements PathResolverHolder { private String expr; /** - * {@link PathResolver} for resolving the "src" result. - */ - private PathResolver pathResolver; - - /** * Constructor. */ public Assign() { @@ -120,24 +115,6 @@ public class Assign extends Action implements PathResolverHolder { } /** - * Get the {@link PathResolver}. - * - * @return Returns the pathResolver. - */ - public PathResolver getPathResolver() { - return pathResolver; - } - - /** - * Set the {@link PathResolver}. - * - * @param pathResolver The pathResolver to set. - */ - public void setPathResolver(final PathResolver pathResolver) { - this.pathResolver = pathResolver; - } - - /** * {@inheritDoc} */ @Override @@ -148,7 +125,7 @@ public class Assign extends Action implements PathResolverHolder { ctx.setLocal(getNamespacesKey(), getNamespaces()); Object data; if (src != null && src.trim().length() > 0) { - data = getSrcData(); + data = getSrcData(exctx.getStateMachine().getPathResolver()); } else { data = evaluator.eval(ctx, expr); } @@ -171,7 +148,7 @@ public class Assign extends Action implements PathResolverHolder { * * @return The data the "src" attribute points to. */ - private Object getSrcData() { + private Object getSrcData(final PathResolver pathResolver) { String resolvedSrc = src; if (pathResolver != null) { resolvedSrc = pathResolver.resolvePath(src); http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/4e13be17/src/main/java/org/apache/commons/scxml2/model/Content.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/scxml2/model/Content.java b/src/main/java/org/apache/commons/scxml2/model/Content.java index b0a5928..2df2844 100644 --- a/src/main/java/org/apache/commons/scxml2/model/Content.java +++ b/src/main/java/org/apache/commons/scxml2/model/Content.java @@ -18,6 +18,8 @@ package org.apache.commons.scxml2.model; import java.io.Serializable; +import org.w3c.dom.Node; + /** * The class in this SCXML object model that corresponds to the * <content> SCXML element. @@ -36,9 +38,14 @@ public class Content implements Serializable { private String expr; /** - * The body of this content, may be null. + * The body of this content parsed as Node, may be null. + */ + private Node body; + + /** + * The parsed content of the body of this content, may be null. */ - private Object body; + private Object value; /** * Get the expression for this content. @@ -59,15 +66,35 @@ public class Content implements Serializable { } /** - * Returns the content body as DocumentFragment + * Returns the content body as Node * - * @return the content body as DocumentFragment + * @return the content body as Node */ - public Object getBody() { + public Node getBody() { return body; } - public void setBody(final Object body) { + /** + * Sets the content body as Node + * @param body the content body as Node + */ + public void setBody(final Node body) { this.body = body; } + + /** + * Returns the parsed content of the body + * @return the parsed content of the body + */ + public Object getValue() { + return value; + } + + /** + * Sets the parsed content of the body + * @param value the parsed content of the body + */ + public void setValue(final Object value) { + this.value = value; + } } http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/4e13be17/src/main/java/org/apache/commons/scxml2/model/Invoke.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/scxml2/model/Invoke.java b/src/main/java/org/apache/commons/scxml2/model/Invoke.java index c14985c..588dace 100644 --- a/src/main/java/org/apache/commons/scxml2/model/Invoke.java +++ b/src/main/java/org/apache/commons/scxml2/model/Invoke.java @@ -19,6 +19,8 @@ package org.apache.commons.scxml2.model; import java.util.HashMap; import java.util.Map; +import javax.xml.transform.TransformerException; + import org.apache.commons.scxml2.ActionExecutionContext; import org.apache.commons.scxml2.Context; import org.apache.commons.scxml2.Evaluator; @@ -30,15 +32,16 @@ import org.apache.commons.scxml2.TriggerEvent; import org.apache.commons.scxml2.EventBuilder; import org.apache.commons.scxml2.invoke.Invoker; import org.apache.commons.scxml2.invoke.InvokerException; +import org.apache.commons.scxml2.io.ContentParser; import org.apache.commons.scxml2.semantics.ErrorConstants; -import org.w3c.dom.Node; +import org.w3c.dom.Element; /** * The class in this SCXML object model that corresponds to the * <invoke> SCXML element. * */ -public class Invoke extends NamelistHolder implements PathResolverHolder, ContentContainer { +public class Invoke extends NamelistHolder implements ContentContainer { /** * Serial version UID. @@ -92,11 +95,6 @@ public class Invoke extends NamelistHolder implements PathResolverHolder, Conten private Finalize finalize; /** - * {@link PathResolver} for resolving the "src" or "srcexpr" result. - */ - private PathResolver pathResolver; - - /** * The <content/> of this invoke */ private Content content; @@ -254,24 +252,6 @@ public class Invoke extends NamelistHolder implements PathResolverHolder, Conten } /** - * Get the {@link PathResolver}. - * - * @return Returns the pathResolver. - */ - public PathResolver getPathResolver() { - return pathResolver; - } - - /** - * Set the {@link PathResolver}. - * - * @param pathResolver The pathResolver to set. - */ - public void setPathResolver(final PathResolver pathResolver) { - this.pathResolver = pathResolver; - } - - /** * Enforce identity equality only * @param other other object to compare with * @return this == other @@ -375,27 +355,42 @@ public class Invoke extends NamelistHolder implements PathResolverHolder, Conten src = (String)eval.eval(ctx, getSrcexpr()); } if (src != null) { - PathResolver pr = getPathResolver(); + PathResolver pr = exctx.getStateMachine().getPathResolver(); if (pr != null) { - src = getPathResolver().resolvePath(src); + src = pr.resolvePath(src); } } - Node srcNode = null; - if (src == null && getContent() != null) { - Object contentValue; + Object contentValue = null; + if (src == null && content != null) { 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 (content.getValue() != null) { + contentValue = content.getValue(); } - else if (contentValue != null) { - src = String.valueOf(contentValue); + if (contentValue instanceof String) { + // inline content + } else if (contentValue instanceof Element) { + // xml based content (must be assigned through data) + Element contentElement = (Element)contentValue; + if (contentElement.getLocalName().equals("scxml")) { + // statemachine definition: transform to string as we cannot (yet) pass XML directly to invoker + try { + contentValue = ContentParser.DEFAULT_PARSER.transformXml(contentElement); + } + catch (TransformerException e) { + throw new ActionExecutionError("<invoke> for state "+parentState.getId() + + ": invalid <content> definition"); + } + } else { + throw new ActionExecutionError("<invoke> for state "+parentState.getId() + + ": invalid <content> definition"); + } + } else { + throw new ActionExecutionError("<invoke> for state "+parentState.getId() + + ": invalid <content> definition"); } } - if (src == null && srcNode == null) { + if (src == null && contentValue == null) { throw new ActionExecutionError("<invoke> for state "+parentState.getId() + ": no src and no content defined"); } @@ -406,7 +401,9 @@ public class Invoke extends NamelistHolder implements PathResolverHolder, Conten if (src != null) { invoker.invoke(src, payloadDataMap); } - // TODO: } else { invoker.invoke(srcNode, payloadDataMap); } + else { + invoker.invokeContent((String)contentValue, payloadDataMap); + } exctx.registerInvoker(this, invoker); } catch (InvokerException|ActionExecutionError|SCXMLExpressionException e) { http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/4e13be17/src/main/java/org/apache/commons/scxml2/model/PathResolverHolder.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/scxml2/model/PathResolverHolder.java b/src/main/java/org/apache/commons/scxml2/model/PathResolverHolder.java deleted file mode 100644 index 629f74e..0000000 --- a/src/main/java/org/apache/commons/scxml2/model/PathResolverHolder.java +++ /dev/null @@ -1,43 +0,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. - */ -package org.apache.commons.scxml2.model; - -import org.apache.commons.scxml2.PathResolver; - -/** - * A <code>PathResolverHolder</code> is an entity that holds a - * {@link PathResolver}. - * - */ -public interface PathResolverHolder { - - /** - * Set the {@link PathResolver} to use. - * - * @param pathResolver The path resolver to use. - */ - void setPathResolver(PathResolver pathResolver); - - /** - * Get the {@link PathResolver}. - * - * @return The path resolver in use. - */ - PathResolver getPathResolver(); - -} - http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/4e13be17/src/main/java/org/apache/commons/scxml2/model/SCXML.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/scxml2/model/SCXML.java b/src/main/java/org/apache/commons/scxml2/model/SCXML.java index f6764ca..fd62f82 100644 --- a/src/main/java/org/apache/commons/scxml2/model/SCXML.java +++ b/src/main/java/org/apache/commons/scxml2/model/SCXML.java @@ -22,6 +22,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.apache.commons.scxml2.PathResolver; + /** * The class in this SCXML object model that corresponds to the * <scxml> root element, and serves as the "document @@ -110,6 +112,11 @@ public class SCXML implements Serializable, Observable, NamespacePrefixesHolder private Script globalScript; /** + * used to resolve SCXML context sensitive paths + */ + private PathResolver pathResolver; + + /** * The immediate child targets of this SCXML document root. */ private List<EnterableState> children; @@ -164,6 +171,24 @@ public class SCXML implements Serializable, Observable, NamespacePrefixesHolder } /** + * Get the {@link PathResolver}. + * + * @return Returns the pathResolver. + */ + public PathResolver getPathResolver() { + return pathResolver; + } + + /** + * Set the {@link PathResolver}. + * + * @param pathResolver The pathResolver to set. + */ + public void setPathResolver(final PathResolver pathResolver) { + this.pathResolver = pathResolver; + } + + /** * Get the initial Transition. * * @return Returns the initial transition for this state machine. http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/4e13be17/src/main/java/org/apache/commons/scxml2/model/Send.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/scxml2/model/Send.java b/src/main/java/org/apache/commons/scxml2/model/Send.java index b7ed695..ae00889 100644 --- a/src/main/java/org/apache/commons/scxml2/model/Send.java +++ b/src/main/java/org/apache/commons/scxml2/model/Send.java @@ -395,7 +395,10 @@ public class Send extends NamelistHolder implements ContentContainer { else if (content != null) { if (content.getExpr() != null) { payload = eval.cloneData(eval.eval(ctx, content.getExpr())); - } else { + } else if (content.getValue() != null) { + payload = content.getValue(); + } + else if (content.getBody() != null){ payload = eval.cloneData(content.getBody()); } } http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/4e13be17/src/test/java/org/apache/commons/scxml2/invoke/InvokeParamNameTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/scxml2/invoke/InvokeParamNameTest.java b/src/test/java/org/apache/commons/scxml2/invoke/InvokeParamNameTest.java index 1a198c1..f828cfa 100644 --- a/src/test/java/org/apache/commons/scxml2/invoke/InvokeParamNameTest.java +++ b/src/test/java/org/apache/commons/scxml2/invoke/InvokeParamNameTest.java @@ -34,7 +34,7 @@ public class InvokeParamNameTest { private SCXMLExecutor exec; - static String lastSource; + static String lastURL; static Map<String, Object> lastParams; @Before @@ -51,7 +51,7 @@ public class InvokeParamNameTest { private void trigger() throws ModelException { lastParams = null; - lastSource = null; + lastURL = null; exec.triggerEvent(new EventBuilder("test.trigger", TriggerEvent.SIGNAL_EVENT).build()); } @@ -59,7 +59,7 @@ public class InvokeParamNameTest { @Test public void testNameAndExpr() throws Exception { trigger(); - Assert.assertTrue(lastSource.endsWith("TestSrc")); + Assert.assertTrue(lastURL.endsWith("TestSrc")); final Map.Entry<String, Object> e = lastParams.entrySet().iterator().next(); Assert.assertEquals("ding", e.getKey()); @@ -81,14 +81,21 @@ public class InvokeParamNameTest { private String invokeId; @Override - public void invoke(String source, Map<String, Object> params) + public void invoke(String url, Map<String, Object> params) throws InvokerException { - lastSource = source; + lastURL = url; lastParams = params; } - public String lastSource() { - return lastSource; + @Override + public void invokeContent(String content, Map<String, Object> params) + throws InvokerException { + lastURL = null; + lastParams = params; + } + + public String lastURL() { + return lastURL; } public Map<String, Object> lastParams() { http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/4e13be17/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 82ea402..692df21 100644 --- a/src/test/java/org/apache/commons/scxml2/w3c/tests.xml +++ b/src/test/java/org/apache/commons/scxml2/w3c/tests.xml @@ -96,7 +96,7 @@ <test id="335" mandatory="true" manual="false" jexl="true" ecma="true"/> <test id="336" mandatory="true" manual="false" jexl="true" ecma="true"/> <test id="337" mandatory="true" manual="false" jexl="true" ecma="true"/> - <test id="338" mandatory="true" manual="false" jexl="false" ecma="false" implemented="false"/> + <test id="338" mandatory="true" manual="false" jexl="true" ecma="true"/> <test id="339" mandatory="true" manual="false" jexl="true" ecma="true"/> <test id="342" mandatory="true" manual="false" jexl="true" ecma="true"/> <test id="346" mandatory="true" profile="minimal" manual="false" jexl="true" ecma="true"/> @@ -110,7 +110,7 @@ <test id="183" mandatory="true" manual="false" jexl="true" ecma="true"/> <test id="185" mandatory="true" manual="false" jexl="true" ecma="true"/> <test id="186" mandatory="true" manual="false" jexl="true" ecma="true"/> - <test id="187" mandatory="true" manual="false" jexl="false" ecma="false"/> + <test id="187" mandatory="true" manual="false" jexl="true" ecma="true"/> <test id="194" mandatory="true" manual="false" jexl="true" ecma="true"/> <test id="198" mandatory="true" manual="false" jexl="true" ecma="true"/> <test id="199" mandatory="true" manual="false" jexl="true" ecma="true"/> @@ -118,36 +118,36 @@ <test id="205" mandatory="true" manual="false" jexl="true" ecma="true"/> <test id="521" mandatory="true" manual="false" jexl="true" ecma="true"/> <test id="553" mandatory="true" manual="false" jexl="true" ecma="true"/> - <test id="207" mandatory="true" manual="false" jexl="false" ecma="false" implemented="false"/> + <test id="207" mandatory="true" manual="false" jexl="true" ecma="true"/> <test id="208" mandatory="true" manual="false" jexl="true" ecma="true"/> <test id="210" mandatory="true" manual="false" jexl="true" ecma="true"/> - <test id="215" mandatory="true" manual="false" jexl="false" ecma="false"/> + <test id="215" mandatory="true" manual="false" jexl="true" ecma="true"/> <test id="216" mandatory="true" manual="false" jexl="true" ecma="true"/> - <test id="220" mandatory="true" manual="false" jexl="false" ecma="false"/> - <test id="223" mandatory="true" manual="false" jexl="false" ecma="false"/> - <test id="224" mandatory="true" manual="false" jexl="false" ecma="false"/> - <test id="225" mandatory="true" manual="false" jexl="false" ecma="false"/> + <test id="220" mandatory="true" manual="false" jexl="true" ecma="true"/> + <test id="223" mandatory="true" manual="false" jexl="true" ecma="true"/> + <test id="224" mandatory="true" manual="false" jexl="true" ecma="true"/> + <test id="225" mandatory="true" manual="false" jexl="true" ecma="true"/> <test id="226" mandatory="true" manual="false" jexl="true" ecma="true"/> - <test id="228" mandatory="true" manual="false" jexl="false" ecma="false"/> - <test id="229" mandatory="true" manual="false" jexl="false" ecma="false"/> - <test id="230" mandatory="true" manual="true" jexl="false" ecma="false" finalState="final"/> - <test id="232" mandatory="true" manual="false" jexl="false" ecma="false"/> + <test id="228" mandatory="true" manual="false" jexl="true" ecma="true"/> + <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="235" mandatory="true" manual="false" jexl="false" ecma="false"/> - <test id="236" mandatory="true" manual="false" jexl="false" ecma="false" implemented="false"/> - <test id="237" mandatory="true" manual="false" jexl="false" ecma="false"/> - <test id="239" mandatory="true" manual="false" jexl="false" ecma="false"/> + <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"/> + <test id="239" mandatory="true" manual="false" jexl="true" ecma="true"/> <test id="240" mandatory="true" manual="false" jexl="false" ecma="false"/> <test id="241" mandatory="true" manual="false" jexl="false" ecma="false"/> - <test id="242" mandatory="true" manual="false" jexl="false" ecma="false"/> - <test id="243" mandatory="true" manual="false" jexl="false" ecma="false"/> + <test id="242" mandatory="true" manual="false" jexl="true" ecma="true"/> + <test id="243" mandatory="true" manual="false" jexl="true" ecma="true"/> <test id="244" mandatory="true" manual="false" jexl="false" ecma="false"/> - <test id="245" mandatory="true" manual="false" jexl="false" ecma="false"/> - <test id="247" mandatory="true" manual="false" jexl="false" ecma="false"/> - <test id="250" mandatory="true" manual="true" jexl="false" ecma="false" finalState="final"/> - <test id="252" mandatory="true" manual="false" jexl="false" ecma="false"/> - <test id="253" mandatory="true" manual="false" jexl="false" ecma="false"/> + <test id="245" mandatory="true" manual="false" jexl="true" ecma="true"/> + <test id="247" mandatory="true" manual="false" jexl="true" ecma="true"/> + <test id="250" mandatory="true" manual="true" jexl="true" ecma="true" finalState="final"/> + <test id="252" mandatory="true" manual="false" jexl="true" ecma="true"/> + <test id="253" mandatory="true" manual="false" jexl="true" ecma="true"/> <test id="530" mandatory="true" manual="false" jexl="false" ecma="false"/> <test id="554" mandatory="true" manual="false" jexl="false" ecma="false"/> <test id="436" mandatory="true" profile="minimal" manual="false" minimal="true"/> @@ -164,19 +164,19 @@ <test id="557" mandatory="false" profile="ecma" manual="false" ecma="false"/> <test id="558" mandatory="false" profile="ecma" manual="false" ecma="false"/> <test id="560" mandatory="false" profile="ecma" manual="false" ecma="true"/> - <test id="578" mandatory="false" profile="ecma" manual="false" ecma="false"/> + <test id="578" mandatory="false" profile="ecma" manual="false" ecma="true"/> <test id="561" mandatory="false" profile="ecma" manual="false" ecma="false"/> - <test id="562" mandatory="false" profile="ecma" manual="false" ecma="false"/> + <test id="562" mandatory="false" profile="ecma" manual="false" ecma="true"/> <test id="569" mandatory="false" profile="ecma" manual="false" ecma="true"/> <test id="457" mandatory="false" profile="ecma" manual="false" ecma="true"/> <test id="459" mandatory="false" profile="ecma" manual="false" ecma="true"/> <test id="460" mandatory="false" profile="ecma" manual="false" ecma="true"/> <test id="189" mandatory="true" manual="false" jexl="true" ecma="true"/> <test id="190" mandatory="true" manual="false" jexl="true" ecma="true"/> - <test id="191" mandatory="true" manual="false" jexl="false" ecma="false"/> - <test id="192" mandatory="true" manual="false" jexl="false" ecma="false"/> + <test id="191" mandatory="true" manual="false" jexl="true" ecma="true"/> + <test id="192" mandatory="true" manual="false" jexl="true" ecma="true"/> <test id="193" mandatory="true" manual="false" jexl="true" ecma="true"/> - <test id="347" mandatory="true" manual="false" jexl="false" ecma="false"/> + <test id="347" mandatory="true" manual="false" jexl="true" ecma="true"/> <test id="348" mandatory="true" manual="false" jexl="true" ecma="true"/> <test id="349" mandatory="true" manual="false" jexl="true" ecma="true"/> <test id="350" mandatory="true" manual="false" jexl="true" ecma="true"/>