You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by ra...@apache.org on 2006/12/07 22:32:42 UTC

svn commit: r483674 - in /jakarta/commons/proper/scxml/trunk/src: main/java/org/apache/commons/scxml/ main/java/org/apache/commons/scxml/env/jexl/ main/java/org/apache/commons/scxml/env/jsp/ main/java/org/apache/commons/scxml/io/ main/java/org/apache/c...

Author: rahul
Date: Thu Dec  7 13:32:41 2006
New Revision: 483674

URL: http://svn.apache.org/viewvc?view=rev&rev=483674
Log:
 * Improved processing of namespace prefixes in deferred evaluation of XPath expressions.
 * Associated test cases
 * Remove the CustomDigester class
 * Requires Digester 1.8
SCXML-33

Added:
    jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/NamespacePrefixesHolder.java   (with props)
    jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/NamespacePrefixedXPathsTest.java   (with props)
    jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/jexl/datamodel-02.xml   (with props)
    jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/jexl/datamodel-03.xml   (with props)
    jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/jsp/datamodel-02.xml   (with props)
    jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/jsp/datamodel-03.xml   (with props)
Removed:
    jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/io/CustomDigester.java
Modified:
    jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/Builtin.java
    jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/SCXMLHelper.java
    jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/env/jexl/JexlEvaluator.java
    jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/env/jsp/ELEvaluator.java
    jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/io/SCXMLDigester.java
    jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/io/SCXMLSerializer.java
    jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Action.java
    jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Assign.java
    jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Data.java
    jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/If.java
    jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Invoke.java
    jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Log.java
    jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Param.java
    jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Send.java
    jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Transition.java
    jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Var.java
    jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/semantics/SCXMLSemanticsImpl.java
    jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/SCXMLTestSuite.java
    jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/model/DatamodelTest.java

Modified: jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/Builtin.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/Builtin.java?view=diff&rev=483674&r1=483673&r2=483674
==============================================================================
--- jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/Builtin.java (original)
+++ jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/Builtin.java Thu Dec  7 13:32:41 2006
@@ -18,6 +18,7 @@
 
 import java.io.Serializable;
 import java.util.Iterator;
+import java.util.Map;
 import java.util.Set;
 
 import javax.xml.transform.TransformerException;
@@ -25,7 +26,10 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.commons.scxml.model.TransitionTarget;
+import org.apache.xml.utils.PrefixResolver;
+import org.apache.xpath.XPath;
 import org.apache.xpath.XPathAPI;
+import org.apache.xpath.XPathContext;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 
@@ -72,12 +76,114 @@
      * Manifests within "location" attribute of <assign> element,
      * for Commons JEXL and Commons EL based documents.
      *
+     * @param namespaces The current document namespaces map at XPath location
      * @param data The context Node, though the method accepts an Object
      *             so error is reported by Commons SCXML, rather
      *             than the underlying expression language.
      * @param path The XPath expression.
      * @return The first node matching the path, or null if no nodes match.
      */
+    public static Node dataNode(final Map namespaces, final Object data,
+            final String path) {
+        if (data == null || !(data instanceof Node)) {
+            Log log = LogFactory.getLog(Builtin.class);
+            log.error("Data(): Cannot evaluate an XPath expression"
+                + " in the absence of a context Node, null returned");
+            return null;
+        }
+        Node dataNode = (Node) data;
+        NodeList result = null;
+        try {
+            if (namespaces == null || namespaces.size() == 0) {
+                Log log = LogFactory.getLog(Builtin.class);
+                if (log.isDebugEnabled()) {
+                    log.debug("Turning off namespaced XPath evaluation since "
+                        + "no namespace information is available for path: "
+                        + path);
+                }
+                result = XPathAPI.selectNodeList(dataNode, path);
+            } else {
+                XPathContext xpathSupport = new XPathContext();
+                PrefixResolver prefixResolver =
+                    new DataPrefixResolver(namespaces);
+                XPath xpath = new XPath(path, null, prefixResolver,
+                    XPath.SELECT);
+                int ctxtNode = xpathSupport.getDTMHandleFromNode(dataNode);
+                result = xpath.execute(xpathSupport, ctxtNode,
+                    prefixResolver).nodelist();
+            }
+        } catch (TransformerException te) {
+            Log log = LogFactory.getLog(Builtin.class);
+            log.error(te.getMessage(), te);
+            return null;
+        }
+        int length = result.getLength();
+        if (length == 0) {
+            Log log = LogFactory.getLog(Builtin.class);
+            log.warn("Data(): No nodes matching the XPath expression \""
+                + path + "\", returning null");
+            return null;
+        } else {
+            if (length > 1) {
+                Log log = LogFactory.getLog(Builtin.class);
+                log.warn("Data(): Multiple nodes matching XPath expression"
+                    + path + "\", returning first");
+            }
+            return result.item(0);
+        }
+    }
+
+    /**
+     * A variant of the Data() function for Commons SCXML documents,
+     * coerced to a Double, a Long or a String, whichever succeeds,
+     * in that order.
+     * Manifests within rvalue expressions in the document,
+     * for Commons JEXL and Commons EL based documents..
+     *
+     * @param namespaces The current document namespaces map at XPath location
+     * @param data The context Node, though the method accepts an Object
+     *             so error is reported by Commons SCXML, rather
+     *             than the underlying expression language.
+     * @param path The XPath expression.
+     * @return The first node matching the path, coerced to a String, or null
+     *         if no nodes match.
+     */
+    public static Object data(final Map namespaces, final Object data,
+            final String path) {
+        Object retVal = null;
+        String strVal = SCXMLHelper.getNodeValue(dataNode(namespaces,
+            data, path));
+        // try as a double
+        try {
+            double d = Double.parseDouble(strVal);
+            retVal = new Double(d);
+        } catch (NumberFormatException notADouble) {
+            // else as a long
+            try {
+                long l = Long.parseLong(strVal);
+                retVal = new Long(l);
+            } catch (NumberFormatException notALong) {
+                // fallback to string
+                retVal = strVal;
+            }
+        }
+        return retVal;
+    }
+
+    /**
+     * Implements the Data() function for Commons SCXML documents, that
+     * can be used to obtain a node from one of the XML data trees.
+     * Manifests within "location" attribute of <assign> element,
+     * for Commons JEXL and Commons EL based documents.
+     *
+     * @param data The context Node, though the method accepts an Object
+     *             so error is reported by Commons SCXML, rather
+     *             than the underlying expression language.
+     * @param path The XPath expression.
+     * @return The first node matching the path, or null if no nodes match.
+     *
+     * @deprecated Use {@link #dataNode(Map,Object,String)} instead
+     */
     public static Node dataNode(final Object data, final String path) {
         if (data == null || !(data instanceof Node)) {
             Log log = LogFactory.getLog(Builtin.class);
@@ -123,6 +229,8 @@
      * @param path The XPath expression.
      * @return The first node matching the path, coerced to a String, or null
      *         if no nodes match.
+     *
+     * @deprecated Use {@link #data(Map,Object,String)} instead
      */
     public static Object data(final Object data, final String path) {
         Object retVal = null;
@@ -142,6 +250,45 @@
             }
         }
         return retVal;
+    }
+
+    /**
+     * Prefix resolver for XPaths pointing to <data> nodes.
+     */
+    private static class DataPrefixResolver implements PrefixResolver {
+
+        /** Cached namespaces. */
+        private Map namespaces;
+
+        /**
+         * Constructor.
+         * @param namespaces The prefix to namespace URI map.
+         */
+        private DataPrefixResolver(final Map namespaces) {
+            this.namespaces = namespaces;
+        }
+
+        /** {@inheritDoc} */
+        public String getNamespaceForPrefix(final String prefix) {
+            return (String) namespaces.get(prefix);
+        }
+
+        /** {@inheritDoc} */
+        public String getNamespaceForPrefix(final String prefix,
+                final Node nsContext) {
+            return (String) namespaces.get(prefix);
+        }
+
+        /** {@inheritDoc} */
+        public String getBaseIdentifier() {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        public boolean handlesNullPrefixes() {
+            return false;
+        }
+
     }
 
 }

Modified: jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/SCXMLHelper.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/SCXMLHelper.java?view=diff&rev=483674&r1=483673&r2=483674
==============================================================================
--- jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/SCXMLHelper.java (original)
+++ jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/SCXMLHelper.java Thu Dec  7 13:32:41 2006
@@ -451,7 +451,9 @@
                     getExpr())) {
                 Object value = null;
                 try {
+                    ctx.setLocal(NAMESPACES_KEY, datum.getNamespaces());
                     value = evaluator.eval(ctx, datum.getExpr());
+                    ctx.setLocal(NAMESPACES_KEY, null);
                 } catch (SCXMLExpressionException see) {
                     if (log != null) {
                         log.error(see.getMessage(), see);
@@ -473,6 +475,12 @@
     private SCXMLHelper() {
         super();
     }
+
+    /**
+     * Current document namespaces are saved under this key in the parent
+     * state's context.
+     */
+    private static final String NAMESPACES_KEY = "_ALL_NAMESPACES";
 
 }
 

Modified: jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/env/jexl/JexlEvaluator.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/env/jexl/JexlEvaluator.java?view=diff&rev=483674&r1=483673&r2=483674
==============================================================================
--- jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/env/jexl/JexlEvaluator.java (original)
+++ jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/env/jexl/JexlEvaluator.java Thu Dec  7 13:32:41 2006
@@ -79,7 +79,7 @@
             String evalExpr = inFct.matcher(expr).
                 replaceAll("_builtin.isMember(_ALL_STATES, ");
             evalExpr = dataFct.matcher(evalExpr).
-                replaceAll("_builtin.data(");
+                replaceAll("_builtin.data(_ALL_NAMESPACES, ");
             exp = ExpressionFactory.createExpression(evalExpr);
             return exp.evaluate(getEffectiveContext(jexlCtx));
         } catch (Exception e) {
@@ -106,7 +106,7 @@
             String evalExpr = inFct.matcher(expr).
                 replaceAll("_builtin.isMember(_ALL_STATES, ");
             evalExpr = dataFct.matcher(evalExpr).
-                replaceAll("_builtin.data(");
+                replaceAll("_builtin.data(_ALL_NAMESPACES, ");
             exp = ExpressionFactory.createExpression(evalExpr);
             return (Boolean) exp.evaluate(getEffectiveContext(jexlCtx));
         } catch (Exception e) {
@@ -133,9 +133,9 @@
             String evalExpr = inFct.matcher(expr).
                 replaceAll("_builtin.isMember(_ALL_STATES, ");
             evalExpr = dataFct.matcher(evalExpr).
-                replaceFirst("_builtin.dataNode(");
+                replaceFirst("_builtin.dataNode(_ALL_NAMESPACES, ");
             evalExpr = dataFct.matcher(evalExpr).
-                replaceAll("_builtin.data(");
+                replaceAll("_builtin.data(_ALL_NAMESPACES, ");
             exp = ExpressionFactory.createExpression(evalExpr);
             return (Node) exp.evaluate(getEffectiveContext(jexlCtx));
         } catch (Exception e) {

Modified: jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/env/jsp/ELEvaluator.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/env/jsp/ELEvaluator.java?view=diff&rev=483674&r1=483673&r2=483674
==============================================================================
--- jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/env/jsp/ELEvaluator.java (original)
+++ jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/env/jsp/ELEvaluator.java Thu Dec  7 13:32:41 2006
@@ -18,6 +18,7 @@
 
 import java.io.Serializable;
 import java.lang.reflect.Method;
+import java.util.Map;
 import java.util.Set;
 import java.util.regex.Pattern;
 
@@ -100,6 +101,8 @@
         try {
             String evalExpr = inFct.matcher(expr).
                 replaceAll("In(_ALL_STATES, ");
+            evalExpr = dataFct.matcher(evalExpr).
+                replaceAll("Data(_ALL_NAMESPACES, ");
             Object rslt = getEvaluator().evaluate(evalExpr, Object.class, vr,
                 builtinFnMapper);
             if (log.isTraceEnabled()) {
@@ -128,6 +131,8 @@
         try {
             String evalExpr = inFct.matcher(expr).
                 replaceAll("In(_ALL_STATES, ");
+            evalExpr = dataFct.matcher(evalExpr).
+                replaceAll("Data(_ALL_NAMESPACES, ");
             Boolean rslt = (Boolean) getEvaluator().evaluate(evalExpr,
                 Boolean.class, vr, builtinFnMapper);
             if (log.isDebugEnabled()) {
@@ -157,6 +162,8 @@
             String evalExpr = inFct.matcher(expr).
                 replaceAll("In(_ALL_STATES, ");
             evalExpr = dataFct.matcher(evalExpr).
+                replaceAll("Data(_ALL_NAMESPACES, ");
+            evalExpr = dataFct.matcher(evalExpr).
                 replaceFirst("LData(");
             Node rslt = (Node) getEvaluator().evaluate(evalExpr, Node.class,
                 vr, builtinFnMapper);
@@ -261,7 +268,8 @@
                 }
             } else if (localName.equals("Data")) {
                 // rvalue in expressions, coerce to String
-                Class[] attrs = new Class[] {Object.class, String.class};
+                Class[] attrs =
+                    new Class[] {Map.class, Object.class, String.class};
                 try {
                     return Builtin.class.getMethod("data", attrs);
                 } catch (SecurityException e) {
@@ -271,7 +279,8 @@
                 }
             } else if (localName.equals("LData")) {
                 // lvalue in expressions, retain as Node
-                Class[] attrs = new Class[] {Object.class, String.class};
+                Class[] attrs =
+                    new Class[] {Map.class, Object.class, String.class};
                 try {
                     return Builtin.class.getMethod("dataNode", attrs);
                 } catch (SecurityException e) {

Modified: jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/io/SCXMLDigester.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/io/SCXMLDigester.java?view=diff&rev=483674&r1=483673&r2=483674
==============================================================================
--- jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/io/SCXMLDigester.java (original)
+++ jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/io/SCXMLDigester.java Thu Dec  7 13:32:41 2006
@@ -56,6 +56,7 @@
 import org.apache.commons.scxml.model.Invoke;
 import org.apache.commons.scxml.model.Log;
 import org.apache.commons.scxml.model.ModelException;
+import org.apache.commons.scxml.model.NamespacePrefixesHolder;
 import org.apache.commons.scxml.model.OnEntry;
 import org.apache.commons.scxml.model.OnExit;
 import org.apache.commons.scxml.model.Parallel;
@@ -643,9 +644,6 @@
     /** Slash. */
     private static final String STR_SLASH = "/";
 
-    /** Prefix for universal digester patterns. */
-    private static final String STR_UNIVERSAL = "!*";
-
     //---------------------- PRIVATE UTILITY METHODS ----------------------//
     /*
      * Private utility functions for configuring digester rule base for SCXML.
@@ -790,6 +788,7 @@
         scxmlRules.add(xp, new ObjectCreateRule(Datamodel.class));
         scxmlRules.add(xp + XPF_DATA, new ObjectCreateRule(Data.class));
         scxmlRules.add(xp + XPF_DATA, new SetPropertiesRule());
+        scxmlRules.add(xp + XPF_DATA, new SetCurrentNamespacesRule());
         scxmlRules.add(xp + XPF_DATA, new SetNextRule("addData"));
         try {
             scxmlRules.add(xp + XPF_DATA, new ParseDataRule(pr));
@@ -817,9 +816,11 @@
             final PathResolver pr, final SCXML scxml) {
         scxmlRules.add(xp, new ObjectCreateRule(Invoke.class));
         scxmlRules.add(xp, new SetPropertiesRule());
+        scxmlRules.add(xp, new SetCurrentNamespacesRule());
         scxmlRules.add(xp, new SetPathResolverRule(pr));
         scxmlRules.add(xp + XPF_PRM, new ObjectCreateRule(Param.class));
         scxmlRules.add(xp + XPF_PRM, new SetPropertiesRule());
+        scxmlRules.add(xp + XPF_PRM, new SetCurrentNamespacesRule());
         scxmlRules.add(xp + XPF_PRM, new SetNextRule("addParam"));
         scxmlRules.add(xp + XPF_FIN, new ObjectCreateRule(Finalize.class));
         scxmlRules.add(xp + XPF_FIN, new UpdateFinalizeRule());
@@ -944,6 +945,7 @@
         scxmlRules.add(xp, new SetPropertiesRule(
             new String[] {"event", "cond", "target"},
             new String[] {"event", "cond", "next"}));
+        scxmlRules.add(xp, new SetCurrentNamespacesRule());
         scxmlRules.add(xp + XPF_TAR, new SetPropertiesRule());
         addActionRules(xp, scxmlRules, pr, customActions);
         scxmlRules.add(xp + XPF_EXT, new Rule() {
@@ -1117,6 +1119,7 @@
             final ExtendedBaseRules scxmlRules, final Class klass) {
         addSimpleRulesTuple(xp, scxmlRules, klass, null, null, "addAction");
         scxmlRules.add(xp, new SetExecutableParentRule());
+        scxmlRules.add(xp, new SetCurrentNamespacesRule());
     }
 
     /**
@@ -1512,6 +1515,25 @@
             // state/invoke/finalize --> peek(2)
             TransitionTarget tt = (TransitionTarget) getDigester().peek(2);
             finalize.setParent(tt);
+        }
+    }
+
+
+    /**
+     * Custom digestion rule for attaching a snapshot of current namespaces
+     * to SCXML actions for deferred XPath evaluation.
+     *
+     */
+    private static class SetCurrentNamespacesRule extends Rule {
+
+        /**
+         * @see Rule#begin(String, String, Attributes)
+         */
+        public final void begin(final String namespace, final String name,
+                final Attributes attributes) {
+            NamespacePrefixesHolder nsHolder =
+                (NamespacePrefixesHolder) getDigester().peek();
+            nsHolder.setNamespaces(getDigester().getCurrentNamespaces());
         }
     }
 

Modified: jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/io/SCXMLSerializer.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/io/SCXMLSerializer.java?view=diff&rev=483674&r1=483673&r2=483674
==============================================================================
--- jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/io/SCXMLSerializer.java (original)
+++ jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/io/SCXMLSerializer.java Thu Dec  7 13:32:41 2006
@@ -52,6 +52,7 @@
 import org.apache.commons.scxml.model.OnEntry;
 import org.apache.commons.scxml.model.OnExit;
 import org.apache.commons.scxml.model.Parallel;
+import org.apache.commons.scxml.model.Param;
 import org.apache.commons.scxml.model.SCXML;
 import org.apache.commons.scxml.model.Send;
 import org.apache.commons.scxml.model.State;
@@ -209,12 +210,12 @@
             b.append(" srcexpr=\"").append(srcexpr).append("\"");
         }
         b.append(">\n");
-        Map params = i.getParams();
-        for (Iterator iter = params.entrySet().iterator(); iter.hasNext();) {
-            Map.Entry e = (Map.Entry) iter.next();
+        List params = i.params();
+        for (Iterator iter = params.iterator(); iter.hasNext();) {
+            Param p = (Param) iter.next();
             b.append(indent).append(INDENT).append("<param name=\"").
-                append(e.getKey()).append("\" expr=\"").
-                append(e.getValue()).append("\"/>\n");
+                append(p.getName()).append("\" expr=\"").
+                append(p.getExpr()).append("\"/>\n");
         }
         Finalize f = i.getFinalize();
         if (f != null) {

Modified: jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Action.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Action.java?view=diff&rev=483674&r1=483673&r2=483674
==============================================================================
--- jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Action.java (original)
+++ jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Action.java Thu Dec  7 13:32:41 2006
@@ -18,6 +18,7 @@
 
 import java.io.Serializable;
 import java.util.Collection;
+import java.util.Map;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.scxml.ErrorReporter;
@@ -30,7 +31,8 @@
  * such as &lt;assign&gt;, &lt;log&gt; etc.
  *
  */
-public abstract class Action implements Serializable {
+public abstract class Action implements NamespacePrefixesHolder,
+        Serializable {
 
     /**
      * Link to its parent or container.
@@ -38,11 +40,24 @@
     private Executable parent;
 
     /**
+     * The current XML namespaces in the SCXML document for this action node,
+     * preserved for deferred XPath evaluation.
+     */
+    private Map namespaces;
+
+    /**
+     * Current document namespaces are saved under this key in the parent
+     * state's context.
+     */
+    private static final String NAMESPACES_KEY = "_ALL_NAMESPACES";
+
+    /**
      * Constructor.
      */
     public Action() {
         super();
         this.parent = null;
+        this.namespaces = null;
     }
 
     /**
@@ -64,6 +79,24 @@
     }
 
     /**
+     * Get the XML namespaces at this action node in the SCXML document.
+     *
+     * @return Returns the map of namespaces.
+     */
+    public final Map 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 namespaces) {
+        this.namespaces = namespaces;
+    }
+
+    /**
      * Return the parent state.
      *
      * @return The parent State
@@ -104,6 +137,16 @@
         final ErrorReporter errRep, final SCInstance scInstance,
         final Log appLog, final Collection derivedEvents)
     throws ModelException, SCXMLExpressionException;
+
+    /**
+     * Return the key under which the current document namespaces are saved
+     * in the parent state's context.
+     *
+     * @return The namespaces key
+     */
+    protected static String getNamespacesKey() {
+        return NAMESPACES_KEY;
+    }
 
 }
 

Modified: jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Assign.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Assign.java?view=diff&rev=483674&r1=483673&r2=483674
==============================================================================
--- jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Assign.java (original)
+++ jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Assign.java Thu Dec  7 13:32:41 2006
@@ -181,6 +181,7 @@
         State parentState = getParentState();
         Context ctx = scInstance.getContext(parentState);
         Evaluator eval = scInstance.getEvaluator();
+        ctx.setLocal(getNamespacesKey(), getNamespaces());
         // "location" gets preference over "name"
         if (!SCXMLHelper.isStringEmpty(location)) {
             Node oldNode = eval.evalLocation(ctx, location);
@@ -242,6 +243,7 @@
                 derivedEvents.add(ev);
             }
         }
+        ctx.setLocal(getNamespacesKey(), null);
     }
 
     /**

Modified: jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Data.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Data.java?view=diff&rev=483674&r1=483673&r2=483674
==============================================================================
--- jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Data.java (original)
+++ jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Data.java Thu Dec  7 13:32:41 2006
@@ -17,6 +17,7 @@
 package org.apache.commons.scxml.model;
 
 import java.io.Serializable;
+import java.util.Map;
 
 import org.w3c.dom.Node;
 
@@ -25,7 +26,7 @@
  * &lt;data&gt; child element of the &lt;datamodel&gt; element.
  *
  */
-public class Data implements Serializable {
+public class Data implements NamespacePrefixesHolder, Serializable {
 
     /**
      * Serial version UID.
@@ -54,6 +55,13 @@
     private Node node;
 
     /**
+     * The current XML namespaces in the SCXML document for this action node,
+     * preserved for deferred XPath evaluation. Easier than to scrape node
+     * above, given the Builtin API.
+     */
+    private Map namespaces;
+
+    /**
      * Constructor.
      */
     public Data() {
@@ -133,6 +141,24 @@
      */
     public final void setNode(final Node node) {
         this.node = node;
+    }
+
+    /**
+     * Get the XML namespaces at this action node in the SCXML document.
+     *
+     * @return Returns the map of namespaces.
+     */
+    public final Map 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 namespaces) {
+        this.namespaces = namespaces;
     }
 
 }

Modified: jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/If.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/If.java?view=diff&rev=483674&r1=483673&r2=483674
==============================================================================
--- jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/If.java (original)
+++ jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/If.java Thu Dec  7 13:32:41 2006
@@ -119,7 +119,9 @@
         State parentState = getParentState();
         Context ctx = scInstance.getContext(parentState);
         Evaluator eval = scInstance.getEvaluator();
+        ctx.setLocal(getNamespacesKey(), getNamespaces());
         execute = eval.evalCond(ctx, cond).booleanValue();
+        ctx.setLocal(getNamespacesKey(), null);
         // The "if" statement is a "container"
         for (Iterator ifiter = actions.iterator(); ifiter.hasNext();) {
             Action aa = (Action) ifiter.next();
@@ -133,8 +135,10 @@
             } else if (aa instanceof Else) {
                 execute = true;
             } else if (aa instanceof ElseIf) {
+                ctx.setLocal(getNamespacesKey(), getNamespaces());
                 execute = eval.evalCond(ctx, ((ElseIf) aa).getCond())
                         .booleanValue();
+                ctx.setLocal(getNamespacesKey(), null);
             }
         }
     }

Modified: jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Invoke.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Invoke.java?view=diff&rev=483674&r1=483673&r2=483674
==============================================================================
--- jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Invoke.java (original)
+++ jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Invoke.java Thu Dec  7 13:32:41 2006
@@ -17,7 +17,9 @@
 package org.apache.commons.scxml.model;
 
 import java.io.Serializable;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import org.apache.commons.scxml.PathResolver;
@@ -27,7 +29,8 @@
  * &lt;invoke&gt; SCXML element.
  *
  */
-public class Invoke implements PathResolverHolder, Serializable {
+public class Invoke implements NamespacePrefixesHolder, PathResolverHolder,
+        Serializable {
 
     /**
      * Serial version UID.
@@ -52,10 +55,17 @@
 
     /**
      * The Map of the params to be sent to the invoked process.
+     *
+     * Remove with deprecated getParams() in 1.0
      */
     private Map params;
 
     /**
+     * The List of the params to be sent to the invoked process.
+     */
+    private List paramsList;
+
+    /**
      * The &lt;finalize&gt; child, may be null.
      */
     private Finalize finalize;
@@ -66,10 +76,17 @@
     private PathResolver pathResolver;
 
     /**
+     * The current XML namespaces in the SCXML document for this action node,
+     * preserved for deferred XPath evaluation.
+     */
+    private Map namespaces;
+
+    /**
      * Default no-args constructor for Digester.
      */
     public Invoke() {
         params = new HashMap();
+        paramsList = new ArrayList();
     }
 
     /**
@@ -132,18 +149,29 @@
      * Get the params Map.
      *
      * @return Map The params map.
+     * @deprecated Remove in v1.0, use params() instead
      */
     public final Map getParams() {
         return params;
     }
 
     /**
+     * Get the list of {@link Param}s.
+     *
+     * @return List The params list.
+     */
+    public final List params() {
+        return paramsList;
+    }
+
+    /**
      * Add this param to this invoke.
      *
      * @param param The invoke parameter.
      */
     public final void addParam(final Param param) {
         params.put(param.getName(), param.getExpr());
+        paramsList.add(param);
     }
 
     /**
@@ -180,6 +208,24 @@
      */
     public void setPathResolver(final PathResolver pathResolver) {
         this.pathResolver = pathResolver;
+    }
+
+    /**
+     * Get the XML namespaces at this action node in the SCXML document.
+     *
+     * @return Returns the map of namespaces.
+     */
+    public final Map 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 namespaces) {
+        this.namespaces = namespaces;
     }
 
 }

Modified: jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Log.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Log.java?view=diff&rev=483674&r1=483673&r2=483674
==============================================================================
--- jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Log.java (original)
+++ jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Log.java Thu Dec  7 13:32:41 2006
@@ -101,7 +101,9 @@
     throws ModelException, SCXMLExpressionException {
         Context ctx = scInstance.getContext(getParentState());
         Evaluator eval = scInstance.getEvaluator();
+        ctx.setLocal(getNamespacesKey(), getNamespaces());
         appLog.info(label + ": " + String.valueOf(eval.eval(ctx, expr)));
+        ctx.setLocal(getNamespacesKey(), null);
     }
 }
 

Added: jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/NamespacePrefixesHolder.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/NamespacePrefixesHolder.java?view=auto&rev=483674
==============================================================================
--- jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/NamespacePrefixesHolder.java (added)
+++ jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/NamespacePrefixesHolder.java Thu Dec  7 13:32:41 2006
@@ -0,0 +1,44 @@
+/*
+ * 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.scxml.model;
+
+import java.util.Map;
+
+/**
+ * A <code>NamespacePrefixesHolder</code> is an entity that retains
+ * namespace prefix information from the document for deferred XPath
+ * evaluation.
+ *
+ */
+public interface NamespacePrefixesHolder {
+
+    /**
+     * Get the map of namespaces, with keys as prefixes and values as URIs.
+     *
+     * @param namespaces The namespaces prefix map.
+     */
+    void setNamespaces(Map namespaces);
+
+    /**
+     * Get the map of namespaces, with keys as prefixes and values as URIs.
+     *
+     * @return The namespaces prefix map.
+     */
+    Map getNamespaces();
+
+}
+

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

Propchange: jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/NamespacePrefixesHolder.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Modified: jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Param.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Param.java?view=diff&rev=483674&r1=483673&r2=483674
==============================================================================
--- jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Param.java (original)
+++ jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Param.java Thu Dec  7 13:32:41 2006
@@ -17,13 +17,14 @@
 package org.apache.commons.scxml.model;
 
 import java.io.Serializable;
+import java.util.Map;
 
 /**
  * The class in this SCXML object model that corresponds to the
  * &lt;param&gt; SCXML element.
  *
  */
-public class Param implements Serializable {
+public class Param implements NamespacePrefixesHolder, Serializable {
 
     /**
      * Serial version UID.
@@ -41,6 +42,12 @@
     private String expr;
 
     /**
+     * The current XML namespaces in the SCXML document for this action node,
+     * preserved for deferred XPath evaluation.
+     */
+    private Map namespaces;
+
+    /**
      * Default no-args constructor for Digester.
      */
     public Param() {
@@ -81,6 +88,24 @@
      */
     public final void setExpr(final String expr) {
         this.expr = expr;
+    }
+
+    /**
+     * Get the XML namespaces at this action node in the SCXML document.
+     *
+     * @return Returns the map of namespaces.
+     */
+    public final Map 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 namespaces) {
+        this.namespaces = namespaces;
     }
 
 }

Modified: jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Send.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Send.java?view=diff&rev=483674&r1=483673&r2=483674
==============================================================================
--- jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Send.java (original)
+++ jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Send.java Thu Dec  7 13:32:41 2006
@@ -273,6 +273,7 @@
         // Send attributes evaluation
         State parentState = getParentState();
         Context ctx = scInstance.getContext(parentState);
+        ctx.setLocal(getNamespacesKey(), getNamespaces());
         Evaluator eval = scInstance.getEvaluator();
         Object hintsValue = null;
         if (!SCXMLHelper.isStringEmpty(hints)) {
@@ -314,6 +315,7 @@
                 return;
             }
         }
+        ctx.setLocal(getNamespacesKey(), null);
         // Else, let the EventDispatcher take care of it
         evtDispatcher.send(sendid, target, targettype, event, params,
             hintsValue, wait, externalNodes);

Modified: jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Transition.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Transition.java?view=diff&rev=483674&r1=483673&r2=483674
==============================================================================
--- jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Transition.java (original)
+++ jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Transition.java Thu Dec  7 13:32:41 2006
@@ -16,6 +16,8 @@
  */
 package org.apache.commons.scxml.model;
 
+import java.util.Map;
+
 /**
  * The class in this SCXML object model that corresponds to the
  * &lt;transition&gt; SCXML element. Transition rules are triggered
@@ -23,7 +25,8 @@
  * &quot;guard-conditions&quot;.
  *
  */
-public class Transition extends Executable {
+public class Transition extends Executable
+        implements NamespacePrefixesHolder {
 
     /**
      * Serial version UID.
@@ -58,6 +61,12 @@
     private Path path;
 
     /**
+     * The current XML namespaces in the SCXML document for this action node,
+     * preserved for deferred XPath evaluation.
+     */
+    private Map namespaces;
+
+    /**
      * Constructor.
      */
     public Transition() {
@@ -102,6 +111,24 @@
      */
     public final void setEvent(final String event) {
         this.event = event;
+    }
+
+    /**
+     * Get the XML namespaces at this action node in the SCXML document.
+     *
+     * @return Returns the map of namespaces.
+     */
+    public final Map 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 namespaces) {
+        this.namespaces = namespaces;
     }
 
     /**

Modified: jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Var.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Var.java?view=diff&rev=483674&r1=483673&r2=483674
==============================================================================
--- jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Var.java (original)
+++ jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/model/Var.java Thu Dec  7 13:32:41 2006
@@ -103,7 +103,9 @@
     throws ModelException, SCXMLExpressionException {
         Context ctx = scInstance.getContext(getParentState());
         Evaluator eval = scInstance.getEvaluator();
+        ctx.setLocal(getNamespacesKey(), getNamespaces());
         Object varObj = eval.eval(ctx, expr);
+        ctx.setLocal(getNamespacesKey(), null);
         ctx.setLocal(name, varObj);
         if (appLog.isDebugEnabled()) {
             appLog.debug("<var>: Defined variable '" + name

Modified: jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/semantics/SCXMLSemanticsImpl.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/semantics/SCXMLSemanticsImpl.java?view=diff&rev=483674&r1=483673&r2=483674
==============================================================================
--- jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/semantics/SCXMLSemanticsImpl.java (original)
+++ jakarta/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml/semantics/SCXMLSemanticsImpl.java Thu Dec  7 13:32:41 2006
@@ -54,6 +54,7 @@
 import org.apache.commons.scxml.model.OnEntry;
 import org.apache.commons.scxml.model.OnExit;
 import org.apache.commons.scxml.model.Parallel;
+import org.apache.commons.scxml.model.Param;
 import org.apache.commons.scxml.model.Path;
 import org.apache.commons.scxml.model.SCXML;
 import org.apache.commons.scxml.model.State;
@@ -87,6 +88,12 @@
         new TransitionTargetComparator();
 
     /**
+     * Current document namespaces are saved under this key in the parent
+     * state's context.
+     */
+    private static final String NAMESPACES_KEY = "_ALL_NAMESPACES";
+
+    /**
      * @param input
      *            SCXML state machine
      * @return normalized SCXML state machine, pseudo states are removed, etc.
@@ -390,8 +397,11 @@
                 rslt = Boolean.TRUE;
             } else {
                 try {
-                    rslt = scInstance.getEvaluator().evalCond(scInstance.
-                            getContext(t.getParent()), t.getCond());
+                    Context ctx = scInstance.getContext(t.getParent());
+                    ctx.setLocal(NAMESPACES_KEY, t.getNamespaces());
+                    rslt = scInstance.getEvaluator().evalCond(ctx,
+                        t.getCond());
+                    ctx.setLocal(NAMESPACES_KEY, null);
                 } catch (SCXMLExpressionException e) {
                     rslt = Boolean.FALSE;
                     errRep.onError(ErrorConstants.EXPRESSION_ERROR, e
@@ -766,7 +776,9 @@
                     String srcexpr = i.getSrcexpr();
                     Object srcObj = null;
                     try {
+                        ctx.setLocal(NAMESPACES_KEY, i.getNamespaces());
                         srcObj = eval.eval(ctx, srcexpr);
+                        ctx.setLocal(NAMESPACES_KEY, null);
                         src = String.valueOf(srcObj);
                     } catch (SCXMLExpressionException see) {
                         errRep.onError(ErrorConstants.EXPRESSION_ERROR,
@@ -790,23 +802,23 @@
                 }
                 inv.setParentStateId(s.getId());
                 inv.setSCInstance(scInstance);
-                Map params = i.getParams();
+                List params = i.params();
                 Map args = new HashMap();
-                for (Iterator pIter = params.entrySet().iterator();
-                        pIter.hasNext();) {
-                    Map.Entry entry = (Map.Entry) pIter.next();
-                    String argName = (String) entry.getKey();
-                    String argExpr = (String) entry.getValue();
+                for (Iterator pIter = params.iterator(); pIter.hasNext();) {
+                    Param p = (Param) pIter.next();
+                    String argExpr = p.getExpr();
                     Object argValue = null;
                     if (argExpr != null && argExpr.trim().length() > 0) {
                         try {
+                            ctx.setLocal(NAMESPACES_KEY, p.getNamespaces());
                             argValue = eval.eval(ctx, argExpr);
+                            ctx.setLocal(NAMESPACES_KEY, null);
                         } catch (SCXMLExpressionException see) {
                             errRep.onError(ErrorConstants.EXPRESSION_ERROR,
                                 see.getMessage(), i);
                         }
                     }
-                    args.put(argName, argValue);
+                    args.put(p.getName(), argValue);
                 }
                 try {
                     inv.invoke(source, args);

Added: jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/NamespacePrefixedXPathsTest.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/NamespacePrefixedXPathsTest.java?view=auto&rev=483674
==============================================================================
--- jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/NamespacePrefixedXPathsTest.java (added)
+++ jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/NamespacePrefixedXPathsTest.java Thu Dec  7 13:32:41 2006
@@ -0,0 +1,154 @@
+/*
+ * 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.scxml;
+
+import java.net.URL;
+import java.util.Set;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+
+import org.apache.commons.scxml.env.jsp.ELContext;
+import org.apache.commons.scxml.env.jsp.ELEvaluator;
+import org.apache.commons.scxml.model.State;
+
+/**
+ * Unit tests for namespace prefixes in XPaths pointing bits in a &lt;data&gt;.
+ */
+public class NamespacePrefixedXPathsTest extends TestCase {
+
+    /**
+     * Construct a new instance of NamespacePrefixedXPathsTest with
+     * the specified name
+     */
+    public NamespacePrefixedXPathsTest(String name) {
+        super(name);
+    }
+
+    public static Test suite() {
+        TestSuite suite = new TestSuite(NamespacePrefixedXPathsTest.class);
+        suite.setName("Namespace Prefixed XPaths Tests");
+        return suite;
+    }
+
+    // Test data
+    private URL datamodel03jexl, datamodel03jsp;
+    private SCXMLExecutor exec01, exec02;
+
+    /**
+     * Set up instance variables required by this test case.
+     */
+    public void setUp() {
+        datamodel03jexl = this.getClass().getClassLoader().
+            getResource("org/apache/commons/scxml/env/jexl/datamodel-03.xml");
+        datamodel03jsp = this.getClass().getClassLoader().
+            getResource("org/apache/commons/scxml/env/jsp/datamodel-03.xml");
+        exec01 = SCXMLTestHelper.getExecutor(datamodel03jexl);
+        exec02 = SCXMLTestHelper.getExecutor(datamodel03jsp, new ELContext(), new ELEvaluator());
+    }
+
+    /**
+     * Tear down instance variables required by this test case.
+     */
+    public void tearDown() {
+        datamodel03jexl = datamodel03jsp = null;
+        exec01 = exec02 = null;
+    }
+
+    /**
+     * Test the XPath evaluation
+     */
+    // JEXL
+    public void testNamespacePrefixedXPathsJexl() {
+        runtest(exec01);
+    }
+
+    // EL
+    public void testNamespacePrefixedXPathsEL() {
+        runtest(exec02);
+    }
+
+    // Same test, since same documents (different expression languages)
+    private void runtest(SCXMLExecutor exec) {
+
+        try {
+
+            // must be in state "ten" at the onset
+            Set currentStates = exec.getCurrentStatus().getStates();
+            assertEquals(1, currentStates.size());
+            assertEquals("ten", ((State)currentStates.iterator().
+                next()).getId());
+
+            // should move to "twenty"
+            currentStates = SCXMLTestHelper.fireEvent(exec, "ten.done");
+            assertEquals(1, currentStates.size());
+            assertEquals("twenty", ((State)currentStates.iterator().
+                next()).getId());
+
+            // This is set while exiting "ten"
+            Double retval = (Double) exec.getRootContext().get("retval");
+            assertEquals(Double.valueOf("11"), retval);
+
+            // On to "thirty"
+            currentStates = SCXMLTestHelper.fireEvent(exec, "twenty.done");
+            assertEquals(1, currentStates.size());
+            assertEquals("thirty", ((State)currentStates.iterator().
+                next()).getId());
+            exec = SCXMLTestHelper.testExecutorSerializability(exec);
+
+            // Tests XPath on SCXML actions, set while exiting "twenty"
+            String retvalstr = (String) exec.getRootContext().get("retval");
+            assertEquals("Equal to 20", retvalstr);
+
+            // and so on ...
+            currentStates = SCXMLTestHelper.fireEvent(exec, "thirty.done");
+            assertEquals(1, currentStates.size());
+            assertEquals("forty", ((State)currentStates.iterator().
+                next()).getId());
+
+            currentStates = SCXMLTestHelper.fireEvent(exec, "forty.done");
+            assertEquals(1, currentStates.size());
+            assertEquals("fifty", ((State)currentStates.iterator().
+                next()).getId());
+
+            currentStates = SCXMLTestHelper.fireEvent(exec, "fifty.done");
+            assertEquals(1, currentStates.size());
+            assertEquals("sixty", ((State)currentStates.iterator().
+                next()).getId());
+
+            currentStates = SCXMLTestHelper.fireEvent(exec, "sixty.done");
+            assertEquals(1, currentStates.size());
+            assertEquals("seventy", ((State)currentStates.iterator().
+                next()).getId());
+
+            // done
+            assertTrue(exec.getCurrentStatus().isFinal());
+
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+
+    }
+
+    public static void main(String args[]) {
+        TestRunner.run(suite());
+    }
+
+}
+

Propchange: jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/NamespacePrefixedXPathsTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/NamespacePrefixedXPathsTest.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Modified: jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/SCXMLTestSuite.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/SCXMLTestSuite.java?view=diff&rev=483674&r1=483673&r2=483674
==============================================================================
--- jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/SCXMLTestSuite.java (original)
+++ jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/SCXMLTestSuite.java Thu Dec  7 13:32:41 2006
@@ -49,6 +49,7 @@
         suite.setName("Commons-SCXML Tests");
         suite.addTest(BuiltinTest.suite());
         suite.addTest(EventDataTest.suite());
+        suite.addTest(NamespacePrefixedXPathsTest.suite());
         suite.addTest(SCInstanceTest.suite());
         suite.addTest(SCXMLExecutorTest.suite());
         suite.addTest(SCXMLHelperTest.suite());

Added: jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/jexl/datamodel-02.xml
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/jexl/datamodel-02.xml?view=auto&rev=483674
==============================================================================
--- jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/jexl/datamodel-02.xml (added)
+++ jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/jexl/datamodel-02.xml Thu Dec  7 13:32:41 2006
@@ -0,0 +1,89 @@
+<?xml version="1.0"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<!-- A fictitious state machine used by test cases. Meant to illustrate
+     prefixed XPath expressions in the Commons SCXML Data() function -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml"
+       version="1.0"
+       initialstate="ten">
+
+    <!-- Start with same prefixes, defined in two different places -->
+    <state id="ten">
+
+        <datamodel>
+            <data name="data10" xmlns:ns1="http://namespace.test.domain/1">
+                <root xmlns="">
+                    <ns1:foo>
+                      <bar>10</bar>
+                    </ns1:foo>
+                </root>
+            </data>
+        </datamodel>
+
+        <transition xmlns:ns1="http://namespace.test.domain/1"
+                    event="ten.done" cond="Data(data10,'root/ns1:foo/bar') eq 10"
+                    target="twenty" />
+
+    </state>
+
+    <!-- Already defined (and different) prefixes -->
+    <state id="twenty" xmlns:ns1="http://namespace.test.domain/1"
+                       xmlns:ns2="http://namespace.test.domain/2"
+                       xmlns:ns3="http://namespace.test.domain/1"
+                       xmlns:ns4="http://namespace.test.domain/2">
+
+        <datamodel>
+            <!-- Start with a prefixless XPath -->
+            <data name="data20">
+                <ns1:root>
+                    <ns2:foo>20</ns2:foo>
+                </ns1:root>
+            </data>
+        </datamodel>
+
+        <transition event="twenty.done" cond="Data(data20,'ns3:root/ns4:foo') eq 20"
+                    target="thirty" />
+
+    </state>
+
+    <!-- XPath looking at attribute -->
+    <state id="thirty">
+
+        <datamodel>
+            <!-- Start with a prefixless XPath -->
+            <data name="data30">
+                <root xmlns="http://namespace.test.domain/1">
+                    <foo xmlns="http://namespace.test.domain/2"
+                         xmlns:ns1="http://namespace.test.domain/3"
+                         ns1:content="30"/>
+                </root>
+            </data>
+        </datamodel>
+
+        <transition event="thirty.done"
+         xmlns:ns1="http://namespace.test.domain/1"
+         xmlns:ns2="http://namespace.test.domain/2"
+         xmlns:ns3="http://namespace.test.domain/3"
+         cond="Data(data30,'ns1:root/ns2:foo/@ns3:content') eq 30"
+         target="forty" />
+
+    </state>
+
+    <state id="forty" final="true" />
+
+</scxml>
+

Propchange: jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/jexl/datamodel-02.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/jexl/datamodel-02.xml
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/jexl/datamodel-03.xml
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/jexl/datamodel-03.xml?view=auto&rev=483674
==============================================================================
--- jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/jexl/datamodel-03.xml (added)
+++ jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/jexl/datamodel-03.xml Thu Dec  7 13:32:41 2006
@@ -0,0 +1,257 @@
+<?xml version="1.0"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<!-- A fictitious state machine used by test cases. Meant to illustrate
+     prefixed XPath expressions in the Commons SCXML Data() function.
+     Used by org.apache.commons.scxml.NamespacePrefixedPathsTest.
+     Also serves as testing the underlying functionality of the
+     underlying parsing technology (here, Digester 1.8) -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml"
+       version="1.0"
+       initialstate="ten">
+
+     <!-- Root data model -->
+     <datamodel>
+
+        <!-- We'll use this for XPaths -->
+        <data name="rootdata"
+              xmlns:ns1="scheme://namespace.test.domain/1"
+              xmlns:ns2="scheme://namespace.test.domain/2"
+              xmlns:ns3="scheme://namespace.test.domain/3">
+             <ns1:root>
+                <ns2:foo>
+                  <ns3:bar>1</ns3:bar>
+                </ns2:foo>
+            </ns1:root>
+        </data>
+
+        <!-- We'll use this for the JUnit test
+             NamespacePrefixedPathsTest.java (scxml package) -->
+        <data name="retval" />
+
+    </datamodel>
+
+    <!-- State data model -->
+    <state id="ten">
+
+        <datamodel>
+
+            <data name="data10" xmlns:ns4="scheme://namespace.test.domain/1">
+                <root xmlns="">
+                    <ns4:foo>
+                      <bar>10</bar>
+                    </ns4:foo>
+                </root>
+            </data>
+
+        </datamodel>
+
+        <onentry>
+            <var xmlns:pre1="scheme://namespace.test.domain/1"
+                 xmlns:pre2="scheme://namespace.test.domain/2"
+                 xmlns:pre3="scheme://namespace.test.domain/3"
+                 name="tentest"
+                 expr="Data(rootdata,'pre1:root/pre2:foo/pre3:bar') + Data(data10,'root/pre1:foo/bar')" />
+        </onentry>
+
+        <transition event="ten.done"
+                    cond="tentest eq 11"
+                    target="twenty" />
+
+        <onexit>
+            <assign name="retval"
+                    expr="tentest" />
+        </onexit>
+
+    </state>
+
+    <!-- Already defined (and different) prefixes -->
+    <state id="twenty" xmlns:ns1="scheme://namespace.test.domain/1"
+                       xmlns:ns2="scheme://namespace.test.domain/2"
+                       xmlns:ns3="scheme://namespace.test.domain/3">
+
+        <datamodel>
+
+            <data name="data20">
+                <ns1:root>
+                    <ns2:foo>20</ns2:foo>
+                </ns1:root>
+            </data>
+
+        </datamodel>
+
+        <onentry>
+            <assign location="Data(rootdata,'ns1:root/ns2:foo/ns3:bar')"
+                    expr="2" />
+        </onentry>
+
+
+        <!-- Redefine namespace prefixes -->
+        <transition event="twenty.done"
+                    xmlns:ns1="scheme://namespace.test.domain/1"
+                    xmlns:ns2="scheme://namespace.test.domain/2"
+                    cond="Data(data20,'ns1:root/ns2:foo') eq 20 and Data(rootdata,'ns1:root/ns2:foo/ns3:bar') eq 2"
+                    target="thirty" />
+
+        <onexit>
+
+            <!-- Redefine different prefixes bound to above namespaces -->
+            <if xmlns:pre1="scheme://namespace.test.domain/1"
+                xmlns:pre2="scheme://namespace.test.domain/2"
+                cond="Data(data20,'pre1:root/pre2:foo') lt 20">
+
+                <assign name="retval" expr="'Less than 20'" />
+
+            <elseif cond="Data(data20,'pre1:root/pre2:foo') eq 20" />
+
+                <assign name="retval" expr="'Equal to 20'" />
+
+            <else/>
+
+                <assign name="retval" expr="'Greater than 20'" />
+
+            </if>
+
+        </onexit>
+
+    </state>
+
+    <!-- XPath looking at attribute -->
+    <state id="thirty">
+
+        <datamodel>
+
+            <data name="data30">
+                <root xmlns="scheme://namespace.test.domain/1">
+                    <foo xmlns="scheme://namespace.test.domain/2"
+                         xmlns:ns1="scheme://namespace.test.domain/3"
+                         ns1:attfoo="30" attbar="300"/>
+                </root>
+            </data>
+
+        </datamodel>
+
+        <transition event="thirty.done"
+         xmlns:ns1="scheme://namespace.test.domain/1"
+         xmlns:ns2="scheme://namespace.test.domain/2"
+         xmlns:ns3="scheme://namespace.test.domain/3"
+         cond="Data(data30,'ns1:root/ns2:foo/@ns3:attfoo') + Data(data30,'ns1:root/ns2:foo/@attbar') eq 330"
+         target="forty" />
+
+    </state>
+
+    <!-- Multiple data, already defined prefixes -->
+    <state id="forty" xmlns:ns1="scheme://namespace.test.domain/1"
+                      xmlns:ns2="scheme://namespace.test.domain/2"
+                      xmlns:ns3="scheme://namespace.test.domain/3"
+                      xmlns:ns4="scheme://namespace.test.domain/4">
+
+        <datamodel>
+
+            <data name="data40">
+                <root xmlns="">
+                    <ns1:foo ns2:attfoo="40"/>
+                </root>
+            </data>
+
+            <data name="data41">
+                <ns3:root>
+                    <ns4:foo>41</ns4:foo>
+                </ns3:root>
+            </data>
+
+        </datamodel>
+
+        <transition event="forty.done"
+         cond="Data(data40,'root/ns1:foo/@ns2:attfoo') + Data(data41,'ns3:root/ns4:foo') eq 81"
+         target="fifty" />
+
+    </state>
+
+    <!-- Multiple data, prefixes on elements -->
+    <state id="fifty">
+
+        <datamodel>
+
+            <data name="data50"  xmlns:ns1="scheme://namespace.test.domain/1"
+                                 xmlns:ns2="scheme://namespace.test.domain/2"
+                                 xmlns:ns3="scheme://namespace.test.domain/3">
+                <ns1:root>
+                    <ns2:foo ns3:attfoo="50"/>
+                </ns1:root>
+            </data>
+
+            <data name="data51" xmlns:ns3="scheme://namespace.test.domain/3"
+                                xmlns:ns4="scheme://namespace.test.domain/4">
+                <ns3:root>
+                    <ns4:foo attfoo="51"/>
+                </ns3:root>
+            </data>
+
+        </datamodel>
+
+        <transition event="fifty.done"
+         xmlns:ns1="scheme://namespace.test.domain/1"
+         xmlns:ns2="scheme://namespace.test.domain/2"
+         xmlns:ns3="scheme://namespace.test.domain/3"
+         xmlns:ns4="scheme://namespace.test.domain/4"
+         cond="Data(data50,'ns1:root/ns2:foo/@ns3:attfoo') + Data(rootdata,'ns1:root/ns2:foo/ns3:bar') eq 52"
+         target="sixty" />
+
+    </state>
+
+    <!-- Multiple data, prefixes on datamodel and transition elements -->
+    <state id="sixty">
+
+        <datamodel xmlns:ns1="scheme://namespace.test.domain/1"
+                   xmlns:ns2="scheme://namespace.test.domain/2"
+                   xmlns:ns3="scheme://namespace.test.domain/3"
+                   xmlns:ns4="scheme://namespace.test.domain/4">
+
+            <data name="data60">
+                <root xmlns="">
+                    <ns1:foo ns2:attfoo="60"/>
+                </root>
+            </data>
+
+            <data name="data61">
+                <ns3:root>
+                    <ns4:foo attfoo="61"/>
+                </ns3:root>
+            </data>
+
+        </datamodel>
+
+        <transition event="sixty.done"
+         xmlns:pre1="scheme://namespace.test.domain/1"
+         xmlns:pre2="scheme://namespace.test.domain/2"
+         xmlns:pre3="scheme://namespace.test.domain/3"
+         xmlns:pre4="scheme://namespace.test.domain/4"
+         cond="Data(data60,'root/pre1:foo/@pre2:attfoo') + Data(data61,'pre3:root/pre4:foo/@attfoo') eq 121"
+         target="seventy">
+
+            <!-- should be 121 -->
+            <log expr="Data(data60,'root/pre1:foo/@pre2:attfoo') + Data(data61,'pre3:root/pre4:foo/@attfoo')"/>
+
+        </transition>
+
+    </state>
+
+    <state id="seventy" final="true" />
+
+</scxml>
+

Propchange: jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/jexl/datamodel-03.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/jexl/datamodel-03.xml
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/jsp/datamodel-02.xml
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/jsp/datamodel-02.xml?view=auto&rev=483674
==============================================================================
--- jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/jsp/datamodel-02.xml (added)
+++ jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/jsp/datamodel-02.xml Thu Dec  7 13:32:41 2006
@@ -0,0 +1,82 @@
+<?xml version="1.0"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<!-- A fictitious state machine used by test cases. Meant to illustrate
+     prefixed XPath expressions in the Commons SCXML Data() function -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml"
+       version="1.0"
+       initialstate="ten">
+
+    <!-- Start with a prefixless XPath (see transition cond) -->
+    <state id="ten">
+
+        <datamodel>
+            <data name="data10">
+                <root xmlns="">
+                    <foo>10</foo>
+                </root>
+            </data>
+        </datamodel>
+
+        <transition event="ten.done" cond="${Data(data10,'root/foo') eq 10}"
+                    target="twenty" />
+
+    </state>
+
+    <!-- Already defined (and identical) prefixes -->
+    <state id="twenty" xmlns:ns1="http://namespace.test.domain/1"
+                       xmlns:ns2="http://namespace.test.domain/2">
+
+        <datamodel>
+            <!-- Start with a prefixless XPath -->
+            <data name="data20">
+                <ns1:root>
+                    <ns2:foo>20</ns2:foo>
+                </ns1:root>
+            </data>
+        </datamodel>
+
+        <transition event="twenty.done" cond="${Data(data20,'ns1:root/ns2:foo') eq 20}"
+                    target="thirty" />
+
+    </state>
+
+    <!-- Data without prefixes -->
+    <state id="thirty">
+
+        <datamodel>
+            <!-- Start with a prefixless XPath -->
+            <data name="data30">
+                <root xmlns="http://namespace.test.domain/1">
+                    <foo xmlns="http://namespace.test.domain/2">30</foo>
+                </root>
+            </data>
+        </datamodel>
+
+        <transition event="thirty.done"
+         xmlns:ns1="http://namespace.test.domain/1"
+         xmlns:ns2="http://namespace.test.domain/2"
+         xmlns:ns3="http://namespace.test.domain/3"
+         cond="${Data(data30,'ns1:root/ns2:foo') eq 30}"
+         target="forty" />
+
+    </state>
+
+    <state id="forty" final="true" />
+
+</scxml>
+

Propchange: jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/jsp/datamodel-02.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/jsp/datamodel-02.xml
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/jsp/datamodel-03.xml
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/jsp/datamodel-03.xml?view=auto&rev=483674
==============================================================================
--- jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/jsp/datamodel-03.xml (added)
+++ jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/jsp/datamodel-03.xml Thu Dec  7 13:32:41 2006
@@ -0,0 +1,257 @@
+<?xml version="1.0"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<!-- A fictitious state machine used by test cases. Meant to illustrate
+     prefixed XPath expressions in the Commons SCXML Data() function.
+     Used by org.apache.commons.scxml.NamespacePrefixedPathsTest
+     Also serves as testing the underlying functionality of the
+     underlying parsing technology (here, Digester 1.8) -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml"
+       version="1.0"
+       initialstate="ten">
+
+     <!-- Root data model -->
+     <datamodel>
+
+        <!-- We'll use this for XPaths -->
+        <data name="rootdata"
+              xmlns:ns1="scheme://namespace.test.domain/1"
+              xmlns:ns2="scheme://namespace.test.domain/2"
+              xmlns:ns3="scheme://namespace.test.domain/3">
+             <ns1:root>
+                <ns2:foo>
+                  <ns3:bar>1</ns3:bar>
+                </ns2:foo>
+            </ns1:root>
+        </data>
+
+        <!-- We'll use this for the JUnit test
+             NamespacePrefixedPathsTest.java (scxml package) -->
+        <data name="retval" />
+
+    </datamodel>
+
+    <!-- State data model -->
+    <state id="ten">
+
+        <datamodel>
+
+            <data name="data10" xmlns:ns4="scheme://namespace.test.domain/1">
+                <root xmlns="">
+                    <ns4:foo>
+                      <bar>10</bar>
+                    </ns4:foo>
+                </root>
+            </data>
+
+        </datamodel>
+
+        <onentry>
+            <var xmlns:pre1="scheme://namespace.test.domain/1"
+                 xmlns:pre2="scheme://namespace.test.domain/2"
+                 xmlns:pre3="scheme://namespace.test.domain/3"
+                 name="tentest"
+                 expr="${Data(rootdata,'pre1:root/pre2:foo/pre3:bar') + Data(data10,'root/pre1:foo/bar')}" />
+        </onentry>
+
+        <transition event="ten.done"
+                    cond="${tentest eq 11}"
+                    target="twenty" />
+
+        <onexit>
+            <assign name="retval"
+                    expr="${tentest}" />
+        </onexit>
+
+    </state>
+
+    <!-- Already defined (and different) prefixes -->
+    <state id="twenty" xmlns:ns1="scheme://namespace.test.domain/1"
+                       xmlns:ns2="scheme://namespace.test.domain/2"
+                       xmlns:ns3="scheme://namespace.test.domain/3">
+
+        <datamodel>
+
+            <data name="data20">
+                <ns1:root>
+                    <ns2:foo>20</ns2:foo>
+                </ns1:root>
+            </data>
+
+        </datamodel>
+
+        <onentry>
+            <assign location="${Data(rootdata,'ns1:root/ns2:foo/ns3:bar')}"
+                    expr="${2}" />
+        </onentry>
+
+
+        <!-- Redefine namespace prefixes -->
+        <transition event="twenty.done"
+                    xmlns:ns1="scheme://namespace.test.domain/1"
+                    xmlns:ns2="scheme://namespace.test.domain/2"
+                    cond="${Data(data20,'ns1:root/ns2:foo') eq 20 and Data(rootdata,'ns1:root/ns2:foo/ns3:bar') eq 2}"
+                    target="thirty" />
+
+        <onexit>
+
+            <!-- Redefine different prefixes bound to above namespaces -->
+            <if xmlns:pre1="scheme://namespace.test.domain/1"
+                xmlns:pre2="scheme://namespace.test.domain/2"
+                cond="${Data(data20,'pre1:root/pre2:foo') lt 20}">
+
+                <assign name="retval" expr="Less than 20" />
+
+            <elseif cond="${Data(data20,'pre1:root/pre2:foo') eq 20}" />
+
+                <assign name="retval" expr="Equal to 20" />
+
+            <else/>
+
+                <assign name="retval" expr="Greater than 20" />
+
+            </if>
+
+        </onexit>
+
+    </state>
+
+    <!-- XPath looking at attribute -->
+    <state id="thirty">
+
+        <datamodel>
+
+            <data name="data30">
+                <root xmlns="scheme://namespace.test.domain/1">
+                    <foo xmlns="scheme://namespace.test.domain/2"
+                         xmlns:ns1="scheme://namespace.test.domain/3"
+                         ns1:attfoo="30" attbar="300"/>
+                </root>
+            </data>
+
+        </datamodel>
+
+        <transition event="thirty.done"
+         xmlns:ns1="scheme://namespace.test.domain/1"
+         xmlns:ns2="scheme://namespace.test.domain/2"
+         xmlns:ns3="scheme://namespace.test.domain/3"
+         cond="${Data(data30,'ns1:root/ns2:foo/@ns3:attfoo') + Data(data30,'ns1:root/ns2:foo/@attbar') eq 330}"
+         target="forty" />
+
+    </state>
+
+    <!-- Multiple data, already defined prefixes -->
+    <state id="forty" xmlns:ns1="scheme://namespace.test.domain/1"
+                      xmlns:ns2="scheme://namespace.test.domain/2"
+                      xmlns:ns3="scheme://namespace.test.domain/3"
+                      xmlns:ns4="scheme://namespace.test.domain/4">
+
+        <datamodel>
+
+            <data name="data40">
+                <root xmlns="">
+                    <ns1:foo ns2:attfoo="40"/>
+                </root>
+            </data>
+
+            <data name="data41">
+                <ns3:root>
+                    <ns4:foo>41</ns4:foo>
+                </ns3:root>
+            </data>
+
+        </datamodel>
+
+        <transition event="forty.done"
+         cond="${Data(data40,'root/ns1:foo/@ns2:attfoo') + Data(data41,'ns3:root/ns4:foo') eq 81}"
+         target="fifty" />
+
+    </state>
+
+    <!-- Multiple data, prefixes on elements -->
+    <state id="fifty">
+
+        <datamodel>
+
+            <data name="data50"  xmlns:ns1="scheme://namespace.test.domain/1"
+                                 xmlns:ns2="scheme://namespace.test.domain/2"
+                                 xmlns:ns3="scheme://namespace.test.domain/3">
+                <ns1:root>
+                    <ns2:foo ns3:attfoo="50"/>
+                </ns1:root>
+            </data>
+
+            <data name="data51" xmlns:ns3="scheme://namespace.test.domain/3"
+                                xmlns:ns4="scheme://namespace.test.domain/4">
+                <ns3:root>
+                    <ns4:foo attfoo="51"/>
+                </ns3:root>
+            </data>
+
+        </datamodel>
+
+        <transition event="fifty.done"
+         xmlns:ns1="scheme://namespace.test.domain/1"
+         xmlns:ns2="scheme://namespace.test.domain/2"
+         xmlns:ns3="scheme://namespace.test.domain/3"
+         xmlns:ns4="scheme://namespace.test.domain/4"
+         cond="${Data(data50,'ns1:root/ns2:foo/@ns3:attfoo') + Data(rootdata,'ns1:root/ns2:foo/ns3:bar') eq 52}"
+         target="sixty" />
+
+    </state>
+
+    <!-- Multiple data, prefixes on datamodel and transition elements -->
+    <state id="sixty">
+
+        <datamodel xmlns:ns1="scheme://namespace.test.domain/1"
+                   xmlns:ns2="scheme://namespace.test.domain/2"
+                   xmlns:ns3="scheme://namespace.test.domain/3"
+                   xmlns:ns4="scheme://namespace.test.domain/4">
+
+            <data name="data60">
+                <root xmlns="">
+                    <ns1:foo ns2:attfoo="60"/>
+                </root>
+            </data>
+
+            <data name="data61">
+                <ns3:root>
+                    <ns4:foo attfoo="61"/>
+                </ns3:root>
+            </data>
+
+        </datamodel>
+
+        <transition event="sixty.done"
+         xmlns:pre1="scheme://namespace.test.domain/1"
+         xmlns:pre2="scheme://namespace.test.domain/2"
+         xmlns:pre3="scheme://namespace.test.domain/3"
+         xmlns:pre4="scheme://namespace.test.domain/4"
+         cond="${Data(data60,'root/pre1:foo/@pre2:attfoo') + Data(data61,'pre3:root/pre4:foo/@attfoo') eq 121}"
+         target="seventy">
+
+            <!-- should be 121 -->
+            <log expr="${Data(data60,'root/pre1:foo/@pre2:attfoo') + Data(data61,'pre3:root/pre4:foo/@attfoo')}"/>
+
+        </transition>
+
+    </state>
+
+    <state id="seventy" final="true" />
+
+</scxml>
+

Propchange: jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/jsp/datamodel-03.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/jsp/datamodel-03.xml
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Modified: jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/model/DatamodelTest.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/model/DatamodelTest.java?view=diff&rev=483674&r1=483673&r2=483674
==============================================================================
--- jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/model/DatamodelTest.java (original)
+++ jakarta/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/model/DatamodelTest.java Thu Dec  7 13:32:41 2006
@@ -50,7 +50,7 @@
     }
 
     // Test data
-    private URL datamodel01jexl, datamodel01jsp;
+    private URL datamodel01jexl, datamodel02jexl, datamodel01jsp, datamodel02jsp;
     private SCXMLExecutor exec01, exec02;
 
     /**
@@ -59,15 +59,19 @@
     public void setUp() {
         datamodel01jexl = this.getClass().getClassLoader().
             getResource("org/apache/commons/scxml/env/jexl/datamodel-01.xml");
+        datamodel02jexl = this.getClass().getClassLoader().
+           getResource("org/apache/commons/scxml/env/jexl/datamodel-02.xml");
         datamodel01jsp = this.getClass().getClassLoader().
             getResource("org/apache/commons/scxml/env/jsp/datamodel-01.xml");
+        datamodel02jsp = this.getClass().getClassLoader().
+            getResource("org/apache/commons/scxml/env/jsp/datamodel-02.xml");
     }
 
     /**
      * Tear down instance variables required by this test case.
      */
     public void tearDown() {
-        datamodel01jexl = datamodel01jsp = null;
+        datamodel01jexl = datamodel02jexl = datamodel01jsp = datamodel02jsp = null;
     }
 
     /**
@@ -89,6 +93,17 @@
             new ELContext(), new ELEvaluator());
         assertNotNull(exec01);
         exec02 = SCXMLTestHelper.getExecutor(datamodel01jsp,
+            new ELContext(), new ELEvaluator());
+        assertNotNull(exec02);
+        assertFalse(exec01 == exec02);
+        runtest();
+    }
+
+    public void testDatamodelNamespacePrefixedXPaths() {
+        exec01 = SCXMLTestHelper.getExecutor(datamodel02jexl,
+            new JexlContext(), new JexlEvaluator());
+        assertNotNull(exec01);
+        exec02 = SCXMLTestHelper.getExecutor(datamodel02jsp,
             new ELContext(), new ELEvaluator());
         assertNotNull(exec02);
         assertFalse(exec01 == exec02);



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org