commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ra...@apache.org
Subject svn commit: r659232 - in /commons/proper/scxml/branches/J6: ./ src/main/java/org/apache/commons/scxml/ src/main/java/org/apache/commons/scxml/env/xpath/ src/test/java/org/apache/commons/scxml/env/xpath/
Date Thu, 22 May 2008 20:06:41 GMT
Author: rahul
Date: Thu May 22 13:06:39 2008
New Revision: 659232

URL: http://svn.apache.org/viewvc?rev=659232&view=rev
Log:
Add support for XPath as the expression language.
 * New oacs.env.xpath package.
 * Reworked some of the JavaScript test document into a test case.
 * ExpressionNSContext class is duplicated as a private static nested class (in Builtin.java
and XPathEvaluator.java). It is expected to go away (from both places) as the parser evolves;
added Javadoc notes to that effect.

Added:
    commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/env/xpath/
    commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/env/xpath/FunctionResolver.java
  (with props)
    commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/env/xpath/XPathContext.java
  (with props)
    commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/env/xpath/XPathEvaluator.java
  (with props)
    commons/proper/scxml/branches/J6/src/test/java/org/apache/commons/scxml/env/xpath/
    commons/proper/scxml/branches/J6/src/test/java/org/apache/commons/scxml/env/xpath/EnvXPathTestSuite.java
  (with props)
    commons/proper/scxml/branches/J6/src/test/java/org/apache/commons/scxml/env/xpath/XPathExampleTest.java
  (with props)
    commons/proper/scxml/branches/J6/src/test/java/org/apache/commons/scxml/env/xpath/example-01.xml
  (with props)
Modified:
    commons/proper/scxml/branches/J6/build.xml
    commons/proper/scxml/branches/J6/pom.xml
    commons/proper/scxml/branches/J6/project.xml
    commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/Builtin.java

Modified: commons/proper/scxml/branches/J6/build.xml
URL: http://svn.apache.org/viewvc/commons/proper/scxml/branches/J6/build.xml?rev=659232&r1=659231&r2=659232&view=diff
==============================================================================
--- commons/proper/scxml/branches/J6/build.xml (original)
+++ commons/proper/scxml/branches/J6/build.xml Thu May 22 13:06:39 2008
@@ -135,6 +135,8 @@
           </include>
           <include name="org/apache/commons/scxml/env/servlet/EnvServletTestSuite.java">
           </include>
+          <include name="org/apache/commons/scxml/env/xpath/EnvXPathTestSuite.java">
+          </include>
           <include name="org/apache/commons/scxml/invoke/InvokeTestSuite.java">
           </include>
           <include name="org/apache/commons/scxml/io/IOTestSuite.java">

Modified: commons/proper/scxml/branches/J6/pom.xml
URL: http://svn.apache.org/viewvc/commons/proper/scxml/branches/J6/pom.xml?rev=659232&r1=659231&r2=659232&view=diff
==============================================================================
--- commons/proper/scxml/branches/J6/pom.xml (original)
+++ commons/proper/scxml/branches/J6/pom.xml Thu May 22 13:06:39 2008
@@ -209,6 +209,7 @@
             <include>org/apache/commons/scxml/env/jexl/EnvJexlTestSuite.java</include>
             <include>org/apache/commons/scxml/env/jsp/EnvJspTestSuite.java</include>
             <include>org/apache/commons/scxml/env/servlet/EnvServletTestSuite.java</include>
+            <include>org/apache/commons/scxml/env/xpath/EnvXPathTestSuite.java</include>
             <include>org/apache/commons/scxml/invoke/InvokeTestSuite.java</include>
             <include>org/apache/commons/scxml/io/IOTestSuite.java</include>
             <include>org/apache/commons/scxml/issues/IssuesTestSuite.java</include>

Modified: commons/proper/scxml/branches/J6/project.xml
URL: http://svn.apache.org/viewvc/commons/proper/scxml/branches/J6/project.xml?rev=659232&r1=659231&r2=659232&view=diff
==============================================================================
--- commons/proper/scxml/branches/J6/project.xml (original)
+++ commons/proper/scxml/branches/J6/project.xml Thu May 22 13:06:39 2008
@@ -292,6 +292,7 @@
         <include>org/apache/commons/scxml/env/jexl/EnvJexlTestSuite.java</include>
         <include>org/apache/commons/scxml/env/jsp/EnvJspTestSuite.java</include>
         <include>org/apache/commons/scxml/env/servlet/EnvServletTestSuite.java</include>
+        <include>org/apache/commons/scxml/env/xpath/EnvXPathTestSuite.java</include>
         <include>org/apache/commons/scxml/invoke/InvokeTestSuite.java</include>
         <include>org/apache/commons/scxml/io/IOTestSuite.java</include>
         <include>org/apache/commons/scxml/issues/IssuesTestSuite.java</include>

Modified: commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/Builtin.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/Builtin.java?rev=659232&r1=659231&r2=659232&view=diff
==============================================================================
--- commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/Builtin.java (original)
+++ commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/Builtin.java Thu
May 22 13:06:39 2008
@@ -168,6 +168,10 @@
 
     /**
      * XPath {@link NamespaceContext} for Commons SCXML expressions.
+     *
+     * <b>Code duplication:</b> Also in XPathEvaluator.java. Class is not
+     * meant to be part of any public API and will be removed when parser
+     * is no longer using Commons Digester.
      */
     private static final class ExpressionNSContext
     implements Serializable, NamespaceContext {

Added: commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/env/xpath/FunctionResolver.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/env/xpath/FunctionResolver.java?rev=659232&view=auto
==============================================================================
--- commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/env/xpath/FunctionResolver.java
(added)
+++ commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/env/xpath/FunctionResolver.java
Thu May 22 13:06:39 2008
@@ -0,0 +1,258 @@
+/*
+ * 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.env.xpath;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.namespace.QName;
+import javax.xml.xpath.XPathFunction;
+import javax.xml.xpath.XPathFunctionException;
+import javax.xml.xpath.XPathFunctionResolver;
+
+import org.apache.commons.scxml.Builtin;
+import org.apache.commons.scxml.Context;
+import org.apache.commons.scxml.model.TransitionTarget;
+
+/**
+ * A {@link XPathFunctionResolver} for the Commons SCXML environment.
+ *
+ */
+public class FunctionResolver implements XPathFunctionResolver, Serializable {
+
+    /** Serial version UID. */
+    private static final long serialVersionUID = -1735881753812903834L;
+
+    /** The Commons SCXML namespace. */
+    private static final String NAMESPACE_COMMONS_SCXML =
+        "http://commons.apache.org/scxml";
+    /** The {@link Context} key to retrieve all the current states. */
+    private static final String STATES = "_ALL_STATES";
+    /** The {@link Context} key to retrieve all the current namespaces. */
+    private static final String NAMESPACES = "_ALL_NAMESPACES";
+
+    /** Functions map. */
+    private final Map<FunctionKey, XPathFunction> functions =
+        new HashMap<FunctionKey, XPathFunction>();
+    /** In() function. */
+    private final XPathFunction inFct = new InFunction();
+    /** Data() function. */
+    private final XPathFunction dataFct = new DataFunction();
+    /** DataNode() function. */
+    private final XPathFunction dataNodeFct = new DataNodeFunction();
+    /** The execution context for the functions. */
+    private XPathContext xctx;
+
+    /**
+     * Constructor.
+     */
+    public FunctionResolver() {
+        functions.put(new FunctionKey(new QName(NAMESPACE_COMMONS_SCXML,
+                "In"), 1), inFct);
+        functions.put(new FunctionKey(new QName(NAMESPACE_COMMONS_SCXML,
+                "Data"), 2), dataFct);
+        functions.put(new FunctionKey(new QName(NAMESPACE_COMMONS_SCXML,
+                "DataNode"), 1), dataNodeFct);
+    }
+
+    /** 
+     * @see XPathFunctionResolver#resolveFunction(QName, int)
+     */
+    @Override
+    public XPathFunction resolveFunction(final QName functionName,
+            final int arity) {
+        return functions.get(new FunctionKey(functionName, arity));
+    }
+
+    /**
+     * Set the execution context for the subsequent functions.
+     */
+    void setContext(final XPathContext xctx) {
+        this.xctx = xctx;
+    }
+
+    /**
+     * Add these user defined XPath functions.
+     */
+    void addFunctions(final Map<FunctionKey, XPathFunction> fns) {
+        for (Map.Entry<FunctionKey, XPathFunction> entry : fns.entrySet()) {
+            functions.put(entry.getKey(), entry.getValue());
+        }
+    }
+
+    /**
+     * An {@link XPathFunction} for the SCXML In() function.
+     *
+     */
+    private final class InFunction implements XPathFunction, Serializable {
+
+        /** Serial version UID. */
+        private static final long serialVersionUID = 6580800854875437013L;
+
+        /**
+         * @see XPathFunction#evaluate(List)
+         * @see Builtin#isMember(Set, String)
+         */
+        @Override
+        @SuppressWarnings("unchecked")
+        public Object evaluate(final List args) throws XPathFunctionException {
+            Set<TransitionTarget> allStates =
+                (Set<TransitionTarget>) xctx.get(STATES);
+            return Builtin.isMember(allStates, (String) args.get(0));
+        }
+
+    }
+
+    /**
+     * An {@link XPathFunction} for the Commons SCXML Data() function.
+     *
+     */
+    private final class DataFunction implements XPathFunction, Serializable {
+
+        /** Serial version UID. */
+        private static final long serialVersionUID = 6812793739418439523L;
+
+        /**
+         * @see XPathFunction#evaluate(List)
+         * @see Builtin#data(Map, Object, String)
+         */
+        @Override
+        @SuppressWarnings("unchecked")
+        public Object evaluate(final List args) throws XPathFunctionException {
+            Map<String, String> namespaces =
+                (Map<String, String>) xctx.get(NAMESPACES);
+            Object node = xctx.get((String) args.get(0));
+            return Builtin.data(namespaces, node, (String) args.get(1));
+        }
+
+    }
+
+
+    /**
+     * An {@link XPathFunction} for the Commons SCXML LData() function.
+     *
+     */
+    private final class DataNodeFunction implements XPathFunction, Serializable {
+
+        /** Serial version UID. */
+        private static final long serialVersionUID = 2407212352705223138L;
+
+        /**
+         * @see XPathFunction#evaluate(List)
+         * @see Builtin#dataNode(Map, Object, String)
+         */
+        @Override
+        @SuppressWarnings("unchecked")
+        public Object evaluate(final List args) throws XPathFunctionException {
+            Map<String, String> namespaces =
+                (Map<String, String>) xctx.get(NAMESPACES);
+            Object node = xctx.get((String) args.get(0));
+            return Builtin.dataNode(namespaces, node, (String) args.get(1));
+        }
+
+    }
+
+    /**
+     * The keys used by the {@link FunctionResolver} to store XPath function
+     * definitions.
+     *
+     */
+    public static final class FunctionKey implements Serializable {
+        
+        /** Serial version UID. */
+        private static final long serialVersionUID = 5977444894712979556L;
+        /** The constant for manipulating key hashes. */
+        private static final int HASH_CONSTANT = 37;
+
+        /** The QName for the XPath function. */
+        private final QName name;
+        /** The number of arguments for the XPath function. */
+        private final int arity;
+
+        /**
+         * Constructor.
+         *
+         * @param name The QName used to identify the XPath function.
+         * @param arity The number of arguments accepted by the XPath
+         *              function.
+         */
+        public FunctionKey(final QName name, final int arity) {
+            if (name == null || name.getLocalPart() == null) {
+                throw new IllegalArgumentException("QName or its" +
+                        " local part cannot be null");
+            }
+            this.name = name;
+            this.arity = arity;
+        }
+
+        /**
+         * Get the {@link QName} associated with this function key.
+         *
+         * @return The QName associated with this key
+         */
+        public QName getQName() {
+            return name;
+        }
+
+        /**
+         * Get the arity associated with this function key.
+         *
+         * @return The arity associated with this key
+         */
+        public int getArity() {
+            return arity;
+        }
+
+        /**
+         * @see Object#equals(Object)
+         */
+        @Override
+        public boolean equals(final Object other) {
+            if (!(other instanceof FunctionKey)) {
+                return false;
+            }
+            FunctionKey key = (FunctionKey) other;
+            if (name.toString().equals(key.getQName().toString()) &&
+                    arity == key.getArity()) {
+                return true;
+            }
+            return false;
+        }
+
+        /**
+         * @see Object#hashCode()
+         */
+        @Override
+        public int hashCode() {
+            return name.toString().hashCode() + HASH_CONSTANT * arity;
+        }
+
+        /**
+         * @see Object#toString()
+         */
+        @Override
+        public String toString() {
+            return "FunctionKey[ qName=" + name.toString() +
+                ", arity=" + arity + " ]";
+        }
+
+    }
+
+}

Propchange: commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/env/xpath/FunctionResolver.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/env/xpath/FunctionResolver.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/env/xpath/XPathContext.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/env/xpath/XPathContext.java?rev=659232&view=auto
==============================================================================
--- commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/env/xpath/XPathContext.java
(added)
+++ commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/env/xpath/XPathContext.java
Thu May 22 13:06:39 2008
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.scxml.env.xpath;
+
+import javax.xml.namespace.QName;
+import javax.xml.xpath.XPathVariableResolver;
+
+import org.apache.commons.scxml.Context;
+import org.apache.commons.scxml.env.SimpleContext;
+
+/**
+ * A {@link Context} implementation for XPath environments.
+ *
+ */
+public class XPathContext extends SimpleContext
+implements Context, XPathVariableResolver {
+
+    /** Serial version UID. */
+    private static final long serialVersionUID = -6803159294612685806L;
+
+    /**
+     * No argument constructor.
+     *
+     */
+    public XPathContext() {
+        super();
+    }
+
+    /**
+     * Constructor for cascading contexts.
+     *
+     * @param parent The parent context. Can be null.
+     */
+    public XPathContext(final Context parent) {
+        super(parent);
+    }
+
+    /**
+     * Resolve variable by checking the backing {@link Context}.
+     * TODO: Investigate alternatives to String representation.
+     *
+     * @param variableName The QName whose String representation is the
+     *                     variable in the backing {@link Context}
+     * @return The variable value.
+     */
+    @Override
+    public Object resolveVariable(final QName variableName) {
+        return get(variableName.toString());
+    }
+
+}

Propchange: commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/env/xpath/XPathContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/env/xpath/XPathContext.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/env/xpath/XPathEvaluator.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/env/xpath/XPathEvaluator.java?rev=659232&view=auto
==============================================================================
--- commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/env/xpath/XPathEvaluator.java
(added)
+++ commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/env/xpath/XPathEvaluator.java
Thu May 22 13:06:39 2008
@@ -0,0 +1,255 @@
+/*
+ * 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.env.xpath;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+import javax.xml.xpath.XPathFunction;
+
+import org.apache.commons.scxml.Context;
+import org.apache.commons.scxml.Evaluator;
+import org.apache.commons.scxml.SCXMLExpressionException;
+import org.apache.commons.scxml.env.xpath.FunctionResolver.FunctionKey;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+/**
+ * An {@link Evaluator} implementation for XPath environments.
+ *
+ */
+public class XPathEvaluator implements Evaluator, Serializable {
+
+    /** Serial version UID. */
+    private static final long serialVersionUID = -3578920670869493294L;
+    /** Pattern for recognizing the Commons SCXML Data() builtin function. */
+    private static final Pattern dataFct = Pattern.compile("Data\\(");
+
+    /** The factory specialized for the Commons SCXML environment. */
+    private final XPathFactory factory;
+    /** The XPathFunctionResolver in use. */
+    private final FunctionResolver fnResolver;
+    /** The dummyContextNode node for XPath evaluation. */
+    private final Document dummyContextNode;
+
+    /**
+     * No argument constructor.
+     */
+    public XPathEvaluator() throws InstantiationException {
+        fnResolver = new FunctionResolver();
+        factory = XPathFactory.newInstance();
+        factory.setXPathFunctionResolver(fnResolver);
+        dummyContextNode = getDummyContextNode();
+    }
+
+    /**
+     * Constructor supporting user-defined {@link XPathFunction}s.
+     *
+     * @param functions The user-defined XPath functions to use.
+     */
+    public XPathEvaluator(final Map<FunctionKey, XPathFunction> functions)
+    throws InstantiationException {
+        this();
+        fnResolver.addFunctions(functions);
+    }
+
+    /**
+     * @see Evaluator#eval(Context, String)
+     */
+    @Override
+    public Object eval(final Context ctx, final String expr)
+            throws SCXMLExpressionException {
+        XPath xpath = getXPath(ctx);
+        try {
+            return xpath.evaluate(expr, dummyContextNode, XPathConstants.STRING);
+        } catch (XPathExpressionException xee) {
+            xee.printStackTrace();
+            throw new SCXMLExpressionException(xee.getMessage(), xee);
+        }
+    }
+
+    /**
+     * @see Evaluator#evalCond(Context, String)
+     */
+    @Override
+    public Boolean evalCond(final Context ctx, final String expr)
+            throws SCXMLExpressionException {
+        XPath xpath = getXPath(ctx);
+        try {
+            return (Boolean) xpath.evaluate(expr, dummyContextNode, XPathConstants.BOOLEAN);
+        } catch (XPathExpressionException xee) {
+            throw new SCXMLExpressionException(xee.getMessage(), xee);
+        }
+    }
+
+    /**
+     * @see Evaluator#evalLocation(Context, String)
+     */
+    @Override
+    public Node evalLocation(final Context ctx, final String expr)
+            throws SCXMLExpressionException {
+        String evalExpr = dataFct.matcher(expr).
+            replaceFirst("DataNode(");
+        XPath xpath = getXPath(ctx);
+        try {
+            return (Node) xpath.evaluate(evalExpr, dummyContextNode, XPathConstants.NODE);
+        } catch (XPathExpressionException xee) {
+            throw new SCXMLExpressionException(xee.getMessage(), xee);
+        }
+    }
+
+    /**
+     * @see Evaluator#newContext(Context)
+     */
+    @Override
+    public Context newContext(final Context parent) {
+        return new XPathContext(parent);
+    }
+
+    /**
+     * Get configures XPath from the factory.
+     */
+    @SuppressWarnings("unchecked")
+    private XPath getXPath(final Context ctx) throws SCXMLExpressionException {
+        if (!(ctx instanceof XPathContext)) {
+            throw new SCXMLExpressionException("XPathEvaluator needs XPathContext");
+        }
+        XPathContext xctx = (XPathContext) ctx;
+        factory.setXPathVariableResolver(xctx);
+        fnResolver.setContext(xctx);
+        XPath xpath = factory.newXPath();
+        NamespaceContext nsCtx =
+            new ExpressionNSContext((Map<String, String>) ctx.get("_ALL_NAMESPACES"));
+        xpath.setNamespaceContext(nsCtx);
+        return xpath;
+    }
+
+    /**
+     * Create dummy context node for XPath evaluation context.
+     */
+    private Document getDummyContextNode() throws InstantiationException {
+        try {
+            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+            dbf.setNamespaceAware(true);
+            return dbf.newDocumentBuilder().newDocument();
+        } catch (Exception e) {
+            throw new InstantiationException("Cannot create dummy context " +
+                " node for XPath evaluator");
+        }
+    }
+
+
+    /**
+     * XPath {@link NamespaceContext} for Commons SCXML expressions.
+     *
+     * <b>Code duplication:</b> Also in Builtin.java. Class is not meant to be
+     * part of any public API and will be removed when parser is no longer
+     * using Commons Digester.
+     */
+    private static final class ExpressionNSContext
+    implements Serializable, NamespaceContext {
+
+        /** Serial version UID. */
+        private static final long serialVersionUID = 8620558582288851315L;
+        /** Map supplied by digester. */
+        private final Map<String, String> namespaces;
+
+        /**
+         * Constructor.
+         *
+         * @param namespaces The current namespace map.
+         */
+        ExpressionNSContext(final Map<String, String> namespaces) {
+            this.namespaces = namespaces;
+        }
+
+        /**
+         * @see NamespaceContext#getNamespaceURI(String)
+         */
+        @Override
+        public String getNamespaceURI(final String prefix) {
+            return namespaces.get(prefix);
+        }
+
+        /**
+         * @see NamespaceContext#getPrefix(String)
+         *
+         * First matching key in iteration order is returned, and the
+         * iteration order depends on the underlying <code>namespaces</code>
+         * {@link Map} implementation.
+         */
+        @Override
+        public String getPrefix(final String namespaceURI) {
+            return (String) getKeys(namespaceURI, true);
+        }
+
+        /**
+         * @see NamespaceContext#getPrefixes(String)
+         *
+         * The iteration order depends on the underlying <code>namespaces</code>
+         * {@link Map} implementation.
+         */
+        @Override
+        @SuppressWarnings("unchecked")
+        public Iterator<String> getPrefixes(final String namespaceURI) {
+            return (Iterator<String>) getKeys(namespaceURI, false);
+        }
+
+        /**
+         * Get prefix key(s) for given namespaceURI value.
+         *
+         * If <code>one</code>, first matching key in iteration order is
+         * returned, and the iteration order depends on the underlying
+         * <code>namespaces</code> {@link Map} implementation.
+         * Otherwise, an iterator to all matching keys is returned.
+         *
+         * @param value The value whose key is required
+         * @param one At most one matching key is returned
+         * @return The required prefix key(s)
+         */
+        private Object getKeys(final String value, final boolean one) {
+            List<String> prefixes = new LinkedList<String>();
+            if (namespaces.containsValue(value)) {
+                for (Map.Entry<String, String> entry : namespaces.entrySet()) {
+                    String v = entry.getValue();
+                    if ((value == null && v == null) ||
+                            (value != null && value.equals(v))) {
+                        String prefix = entry.getKey();
+                        if (one) {
+                            return prefix;
+                        } else {
+                            prefixes.add(prefix);
+                        }
+                    }
+                }
+            }
+            return one ? null : prefixes.iterator();
+        }
+
+    }
+
+}

Propchange: commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/env/xpath/XPathEvaluator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/env/xpath/XPathEvaluator.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: commons/proper/scxml/branches/J6/src/test/java/org/apache/commons/scxml/env/xpath/EnvXPathTestSuite.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/branches/J6/src/test/java/org/apache/commons/scxml/env/xpath/EnvXPathTestSuite.java?rev=659232&view=auto
==============================================================================
--- commons/proper/scxml/branches/J6/src/test/java/org/apache/commons/scxml/env/xpath/EnvXPathTestSuite.java
(added)
+++ commons/proper/scxml/branches/J6/src/test/java/org/apache/commons/scxml/env/xpath/EnvXPathTestSuite.java
Thu May 22 13:06:39 2008
@@ -0,0 +1,57 @@
+/*
+ * 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.env.xpath;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+
+/**
+ * JUnit 3 test suite for the XPath environment.
+ */
+public class EnvXPathTestSuite extends TestCase {
+    // CLASS METHODS
+
+    /**
+     * Returns the test suite for the XPath environment.
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite("Commons-SCXML XPath Environment Tests");
+        suite.addTest(XPathExampleTest.suite());
+        return suite;
+    }
+
+    /**
+     * Command-line interface.
+     */
+    public static void main(String[] args) {
+        TestRunner.run(suite());
+    }
+
+    // CONSTRUCTOR
+
+    /**
+     * Instantiates and initializes a new test suite.
+     */
+    public EnvXPathTestSuite(String name) {
+        super(name);
+    }
+
+}
+

Propchange: commons/proper/scxml/branches/J6/src/test/java/org/apache/commons/scxml/env/xpath/EnvXPathTestSuite.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/scxml/branches/J6/src/test/java/org/apache/commons/scxml/env/xpath/EnvXPathTestSuite.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: commons/proper/scxml/branches/J6/src/test/java/org/apache/commons/scxml/env/xpath/XPathExampleTest.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/branches/J6/src/test/java/org/apache/commons/scxml/env/xpath/XPathExampleTest.java?rev=659232&view=auto
==============================================================================
--- commons/proper/scxml/branches/J6/src/test/java/org/apache/commons/scxml/env/xpath/XPathExampleTest.java
(added)
+++ commons/proper/scxml/branches/J6/src/test/java/org/apache/commons/scxml/env/xpath/XPathExampleTest.java
Thu May 22 13:06:39 2008
@@ -0,0 +1,96 @@
+/*
+ * 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.env.xpath;
+
+import java.net.URL;
+import java.util.Set;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.apache.commons.scxml.Context;
+import org.apache.commons.scxml.Evaluator;
+import org.apache.commons.scxml.SCXMLExecutor;
+import org.apache.commons.scxml.SCXMLTestHelper;
+import org.apache.commons.scxml.model.SCXML;
+import org.apache.commons.scxml.model.State;
+import org.apache.commons.scxml.model.TransitionTarget;
+
+/**
+ * SCXML application for the XPath example.
+ *
+ */
+public class XPathExampleTest extends TestCase {
+
+    public XPathExampleTest(String name) {
+        super(name);
+    }
+
+    public static Test suite() {
+        TestSuite suite = new TestSuite(XPathExampleTest.class);
+        suite.setName("SCXML XPath Environment Example Tests");
+        return suite;
+    }
+
+    // Test data
+    private URL example01;
+    private SCXMLExecutor exec;
+
+    /**
+     * Set up instance variables required by this test case.
+     */
+    public void setUp() {
+        example01 = this.getClass().getClassLoader().
+            getResource("org/apache/commons/scxml/env/xpath/example-01.xml");
+    }
+
+    /**
+     * Tear down instance variables required by this test case.
+     */
+    public void tearDown() {
+        example01 = null;
+    }
+
+    // TEST METHODS
+
+    public void testExample01Sample() {
+
+        SCXML scxml = SCXMLTestHelper.parse(example01);
+        Evaluator evaluator = null;
+        try {
+            evaluator = new XPathEvaluator();
+        } catch (InstantiationException ie) {
+            fail(ie.getMessage());
+        }
+        Context context = new XPathContext(null);
+        exec = SCXMLTestHelper.getExecutor(scxml, context, evaluator);
+
+        assertNotNull(exec);
+        try {
+            Set<TransitionTarget> currentStates = exec.getCurrentStatus().getStates();
+            assertEquals(1, currentStates.size());
+            assertEquals("end", ((State)currentStates.iterator().
+                next()).getId());
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+    }
+
+}
+

Propchange: commons/proper/scxml/branches/J6/src/test/java/org/apache/commons/scxml/env/xpath/XPathExampleTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/scxml/branches/J6/src/test/java/org/apache/commons/scxml/env/xpath/XPathExampleTest.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: commons/proper/scxml/branches/J6/src/test/java/org/apache/commons/scxml/env/xpath/example-01.xml
URL: http://svn.apache.org/viewvc/commons/proper/scxml/branches/J6/src/test/java/org/apache/commons/scxml/env/xpath/example-01.xml?rev=659232&view=auto
==============================================================================
--- commons/proper/scxml/branches/J6/src/test/java/org/apache/commons/scxml/env/xpath/example-01.xml
(added)
+++ commons/proper/scxml/branches/J6/src/test/java/org/apache/commons/scxml/env/xpath/example-01.xml
Thu May 22 13:06:39 2008
@@ -0,0 +1,55 @@
+<?xml version="1.0"?>
+<!--
+  * Licensed to the Apache Software Foundation (ASF) under one or more
+  * contributor license agreements.  See the NOTICE file distributed with
+  * this work for additional information regarding copyright ownership.
+  * The ASF licenses this file to You under the Apache License, Version 2.0
+  * (the "License"); you may not use this file except in compliance with
+  * the License.  You may obtain a copy of the License at
+  *
+  *     http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+-->
+<!-- SCXML XPath environment: example script -->
+<scxml xmlns="http://www.w3.org/2005/07/scxml"
+       xmlns:cs="http://commons.apache.org/scxml" initialstate="start"
+       version="1.0">
+
+    <datamodel>
+        <data name="jungle">
+            <animals xmlns="">
+                <lion>
+                    <name>Simba</name>
+                    <age>12</age>
+                </lion>
+                <tiger>
+                    <name>Sher Khan</name>
+                    <age>13</age>
+                </tiger>
+            </animals>
+        </data>
+    </datamodel>
+
+    <state id="start">
+        <onentry>
+            <log label="Lion"
+                 expr="cs:Data('jungle','animals/lion/name')" />
+        </onentry>
+        <transition cond="cs:Data('jungle','animals/lion/age') = 12"
+                    target="end" />
+    </state>
+
+    <final id="end">
+        <onentry>
+            <log label="Total age"
+                expr="cs:Data('jungle','animals/lion/age') +
+                      cs:Data('jungle','animals/tiger/age')" />
+        </onentry>
+    </final>
+
+</scxml>

Propchange: commons/proper/scxml/branches/J6/src/test/java/org/apache/commons/scxml/env/xpath/example-01.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/scxml/branches/J6/src/test/java/org/apache/commons/scxml/env/xpath/example-01.xml
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL



Mime
View raw message