You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ode.apache.org by mr...@apache.org on 2008/12/18 19:31:28 UTC

svn commit: r727785 [2/2] - in /ode/trunk: bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/v1/ bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/v1/xpath10/jaxp/ bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/v2/ bpel-compiler...

Added: ode/trunk/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/v2/xpath10/jaxp/JaxpXPath10ExpressionCompilerImpl.java
URL: http://svn.apache.org/viewvc/ode/trunk/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/v2/xpath10/jaxp/JaxpXPath10ExpressionCompilerImpl.java?rev=727785&view=auto
==============================================================================
--- ode/trunk/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/v2/xpath10/jaxp/JaxpXPath10ExpressionCompilerImpl.java (added)
+++ ode/trunk/bpel-compiler/src/main/java/org/apache/ode/bpel/compiler/v2/xpath10/jaxp/JaxpXPath10ExpressionCompilerImpl.java Thu Dec 18 10:31:27 2008
@@ -0,0 +1,120 @@
+/*
+ * 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.ode.bpel.compiler.v2.xpath10.jaxp;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ode.bpel.compiler.XPathMessages;
+import org.apache.ode.bpel.compiler.api.CompilationException;
+import org.apache.ode.bpel.compiler.bom.Expression;
+import org.apache.ode.bpel.compiler.v2.CompilerContext;
+import org.apache.ode.bpel.compiler.v2.ExpressionCompiler;
+import org.apache.ode.bpel.rtrep.v2.xpath10.OXPath10Expression;
+import org.apache.ode.utils.DOMUtils;
+import org.apache.ode.utils.msg.MessageBundle;
+import org.w3c.dom.Node;
+
+/**
+ * XPath compiler based on the default JAXP implementation. Supports both 2.0 and 1.1 BPEL.
+ */
+public abstract class JaxpXPath10ExpressionCompilerImpl implements ExpressionCompiler {
+    /** Class-level logger. */
+    private static final Log __log = LogFactory.getLog(JaxpXPath10ExpressionCompilerImpl.class);
+
+    private static final XPathMessages __msgs = MessageBundle.getMessages(XPathMessages.class);
+
+    protected CompilerContext _compilerContext;
+
+    /** Namespace of the BPEL functions (for v2 to v1 compatibility) . */
+    private String _bpelNsURI;
+
+    protected QName _qnFnGetVariableData;
+
+    protected QName _qnFnGetVariableProperty;
+
+    protected QName _qnFnGetLinkStatus;
+
+    protected Map<String, String> _properties = new HashMap<String, String>();
+
+    /**
+     * Construtor.
+     * 
+     * @param bpelNsURI
+     *            the BPEL extension function namespace; varies depending on BPEL version.
+     */
+    public JaxpXPath10ExpressionCompilerImpl(String bpelNsURI) {
+        _bpelNsURI = bpelNsURI;
+        _qnFnGetVariableData = new QName(_bpelNsURI, "getVariableData");
+        _qnFnGetVariableProperty = new QName(_bpelNsURI, "getVariableProperty");
+        _qnFnGetLinkStatus = new QName(_bpelNsURI, "getLinkStatus");
+        _properties.put("runtime-class", "org.apache.ode.bpel.rtrep.v2.xpath10.jaxp.JaxpXPath10ExpressionRuntime");
+    }
+
+    /**
+     * @see org.apache.ode.bpel.compiler.v2.ExpressionCompiler#setCompilerContext(org.apache.ode.bpel.compiler.v2.CompilerContext)
+     */
+    public void setCompilerContext(CompilerContext compilerContext) {
+        _compilerContext = compilerContext;
+    }
+
+    /**
+     * @see org.apache.ode.bpel.compiler.v2.ExpressionCompiler#getProperties()
+     */
+    public Map<String, String> getProperties() {
+        return _properties;
+    }
+
+    /**
+     * Verifies validity of a xpath expression.
+     */
+    protected void doJaxpCompile(OXPath10Expression out, Expression source) throws CompilationException {
+        String xpathStr;
+        Node node = source.getExpression();
+        if (node == null) {
+            throw new IllegalStateException("XPath string and xpath node are both null");
+        }
+
+        xpathStr = node.getNodeValue();
+        xpathStr = xpathStr.trim();
+        if (xpathStr.length() == 0) {
+            throw new CompilationException(__msgs.errXPathSyntax(xpathStr));
+        }
+
+        try {
+            __log.debug("JAXP compile: xpath = " + xpathStr);
+            // use default XPath implementation
+            XPathFactory xpf = XPathFactory.newInstance();
+            __log.debug("JAXP compile: XPathFactory impl = " + xpf.getClass());
+            XPath xpath = xpf.newXPath();
+            xpath.setXPathFunctionResolver(new JaxpFunctionResolver(_compilerContext, out, source
+                .getNamespaceContext(), _bpelNsURI));
+            xpath.setXPathVariableResolver(new JaxpVariableResolver(_compilerContext, out));
+            xpath.setNamespaceContext(source.getNamespaceContext());
+            XPathExpression xpe = xpath.compile(xpathStr);
+            // dummy evaluation to resolve variables and functions (hopefully complete...)
+            xpe.evaluate(DOMUtils.newDocument());
+            out.xpath = xpathStr;
+        } catch (XPathExpressionException e) {
+            throw new CompilationException(__msgs.errUnexpectedCompilationError(e.getMessage()), e);
+        }
+    }
+}

Added: ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/xpath10/jaxp/JaxpFunctionResolver.java
URL: http://svn.apache.org/viewvc/ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/xpath10/jaxp/JaxpFunctionResolver.java?rev=727785&view=auto
==============================================================================
--- ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/xpath10/jaxp/JaxpFunctionResolver.java (added)
+++ ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/xpath10/jaxp/JaxpFunctionResolver.java Thu Dec 18 10:31:27 2008
@@ -0,0 +1,256 @@
+/*
+ * 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.ode.bpel.rtrep.v1.xpath10.jaxp;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.xpath.XPathFunction;
+import javax.xml.xpath.XPathFunctionException;
+import javax.xml.xpath.XPathFunctionResolver;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ode.bpel.common.FaultException;
+import org.apache.ode.bpel.rtrep.common.Constants;
+import org.apache.ode.bpel.rtrep.v1.EvaluationContext;
+import org.apache.ode.bpel.rtrep.v1.OLink;
+import org.apache.ode.bpel.rtrep.v1.OProcess;
+import org.apache.ode.bpel.rtrep.v1.OScope;
+import org.apache.ode.bpel.rtrep.v1.OXslSheet;
+import org.apache.ode.bpel.rtrep.v1.xpath10.OXPath10Expression;
+import org.apache.ode.bpel.rtrep.v1.xpath10.OXPath10ExpressionBPEL20;
+import org.apache.ode.bpel.rtrep.v1.xpath10.XslRuntimeUriResolver;
+import org.apache.ode.utils.DOMUtils;
+import org.apache.ode.utils.Namespaces;
+import org.apache.ode.utils.xsl.XslTransformHandler;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * JAXP function resolver for BPEL XPath functions
+ */
+public class JaxpFunctionResolver implements XPathFunctionResolver {
+
+    private static final Log __log = LogFactory.getLog(JaxpFunctionResolver.class);
+
+    private EvaluationContext _ectx;
+
+    private OXPath10Expression _oxpath;
+
+    public JaxpFunctionResolver(EvaluationContext ectx, OXPath10Expression oxpath) {
+        _ectx = ectx;
+        _oxpath = oxpath;
+    }
+
+    public XPathFunction resolveFunction(QName functionName, int arity) {
+        __log.debug("JAXP runtime: Resolving function " + functionName);
+        final String namespaceURI = functionName.getNamespaceURI();
+        if (namespaceURI == null) {
+            throw new NullPointerException("Undeclared namespace for " + functionName);
+        }
+        if (namespaceURI.equals(Namespaces.BPEL11_NS)
+            || namespaceURI.equals(Namespaces.WS_BPEL_20_NS)
+            || namespaceURI.equals(Namespaces.WSBPEL2_0_FINAL_EXEC)) {
+            String localName = functionName.getLocalPart();
+            if (Constants.EXT_FUNCTION_GETVARIABLEDATA.equals(localName)) {
+                return new GetVariableData();
+            }
+            if (Constants.EXT_FUNCTION_GETVARIABLEPROPERTY.equals(localName)) {
+                return new GetVariableProperty();
+            }
+            if (Constants.EXT_FUNCTION_GETLINKSTATUS.equals(localName)) {
+                return new GetLinkStatus();
+            }
+            if (Constants.EXT_FUNCTION_DOXSLTRANSFORM.equals(localName)) {
+                return new DoXslTransform();
+            }
+            throw new NullPointerException("Unknown BPEL function: " + functionName);
+        }
+        return null;
+    }
+
+    public class GetLinkStatus implements XPathFunction {
+        public Object evaluate(List args) throws XPathFunctionException {
+            if (args.size() != 1)
+                throw new XPathFunctionException(new FaultException(new QName(Namespaces.ODE_EXTENSION_NS,
+                    "getLinkStatusInvalidSource"), "Illegal Arguments"));
+
+            OLink olink = _oxpath.links.get(args.get(0));
+            try {
+                return _ectx.isLinkActive(olink) ? Boolean.TRUE : Boolean.FALSE;
+            } catch (FaultException e) {
+                throw new XPathFunctionException(new FaultException(new QName(Namespaces.ODE_EXTENSION_NS,
+                    "getLinkStatusInvalidSource"), e));
+            }
+        }
+    }
+
+    public class GetVariableData implements XPathFunction {
+        public Object evaluate(List args) throws XPathFunctionException {
+            if (__log.isDebugEnabled()) {
+                __log.debug("call(context=" + _ectx + " args=" + args + ")");
+            }
+
+            String varname = (String) args.get(0);
+            String partname = args.size() > 1 ? (String) args.get(1) : null;
+            String xpathStr = args.size() > 2 ? (String) args.get(2) : null;
+
+            OXPath10Expression.OSigGetVariableData sig =
+                _oxpath.resolveGetVariableDataSig(varname, partname, xpathStr);
+            if (sig == null) {
+                String msg = "InternalError: Attempt to use an unknown getVariableData signature: " + args;
+                if (__log.isFatalEnabled())
+                    __log.fatal(msg);
+                throw new XPathFunctionException(msg);
+            }
+
+            try {
+                Node ret = _ectx.readVariable(sig.variable, sig.part);
+                if (sig.location != null)
+                    ret = _ectx.evaluateQuery(ret, sig.location);
+
+                if (__log.isDebugEnabled()) {
+                    __log.debug("bpws:getVariableData(" + args + ")' = " + ret);
+                }
+
+                return ret;
+            } catch (FaultException e) {
+                __log.error("bpws:getVariableData(" + args + ") threw FaultException");
+                throw new XPathFunctionException(e);
+            }
+        }
+    }
+
+    public class GetVariableProperty implements XPathFunction {
+        public Object evaluate(List args) throws XPathFunctionException {
+            if (args.size() != 2) {
+                throw new XPathFunctionException(new FaultException(new QName(Namespaces.ODE_EXTENSION_NS,
+                    "getVariablePropertyInvalidSource"), "Missing required arguments"));
+            }
+
+            OScope.Variable var = _oxpath.vars.get(args.get(0));
+            OProcess.OProperty property = _oxpath.properties.get(args.get(1));
+
+            if (__log.isDebugEnabled()) {
+                __log.debug("function call:'bpws:getVariableProperty(" + var + "," + property + ")'");
+            }
+
+            try {
+                return _ectx.readMessageProperty(var, property);
+            } catch (FaultException e) {
+                throw new XPathFunctionException(e);
+            }
+        }
+    }
+
+    public class DoXslTransform implements XPathFunction {
+
+        public Object evaluate(List args) throws XPathFunctionException {
+            if (args.size() < 2 || (args.size() % 2) != 0)
+                throw new XPathFunctionException(new FaultException(new QName(Namespaces.ODE_EXTENSION_NS,
+                    "doXslTransformInvalidSource"), "Invalid arguments"));
+
+            if (__log.isDebugEnabled()) {
+                __log.debug("call(context=" + _ectx + " args=" + args + ")");
+            }
+            if (!(_oxpath instanceof OXPath10ExpressionBPEL20)) {
+                throw new IllegalStateException("XPath function bpws:doXslTransform not supported in BPEL 1.1!");
+            }
+
+            Element varElmt;
+            try {
+                if (args.get(1) instanceof List) {
+                    List elmts = (List) args.get(1);
+                    if (elmts.size() != 1)
+                        throw new XPathFunctionException(new FaultException(
+                            _oxpath.getOwner().constants.qnXsltInvalidSource,
+                            "Second parameter of the bpws:doXslTransform function MUST point to a single "
+                                + "element node."));
+                    varElmt = (Element) elmts.get(0);
+                } else {
+                    varElmt = (Element) args.get(1);
+                }
+            } catch (ClassCastException e) {
+                throw new XPathFunctionException(new FaultException(
+                    _oxpath.getOwner().constants.qnXsltInvalidSource,
+                    "Second parameter of the bpws:doXslTransform function MUST point to a single "
+                        + "element node."));
+            }
+
+            URI xslUri;
+            try {
+                xslUri = new URI((String) args.get(0));
+            } catch (URISyntaxException use) {
+                // Shouldn't happen, checked at compilation time
+                throw new XPathFunctionException("First parameter of the bpws:doXslTransform isn't a valid URI!");
+            }
+            OXslSheet xslSheet = _oxpath.xslSheets.get(xslUri);
+            // Shouldn't happen, checked at compilation time
+            if (xslSheet == null)
+                throw new XPathFunctionException("Couldn't find the XSL sheet " + args.get(0)
+                    + ", process compilation or deployment was probably incomplete!");
+
+            if (!(varElmt instanceof Element)) {
+                throw new XPathFunctionException(new FaultException(
+                    _oxpath.getOwner().constants.qnXsltInvalidSource,
+                    "Second parameter of the bpws:doXslTransform function MUST point to a single "
+                        + "element node."));
+            }
+
+            HashMap<QName, Object> parametersMap = null;
+            if (args.size() > 2) {
+                parametersMap = new HashMap<QName, Object>();
+                for (int idx = 2; idx < args.size(); idx += 2) {
+                    QName keyQName = _oxpath.namespaceCtx.derefQName((String) args.get(idx));
+                    Object paramElmt;
+                    if (args.get(idx + 1) instanceof List) {
+                        paramElmt = ((List) args.get(idx + 1)).get(0);
+                    } else
+                        paramElmt = args.get(idx + 1);
+
+                    parametersMap.put(keyQName, paramElmt);
+                }
+            }
+
+            if (__log.isDebugEnabled())
+                __log.debug("Executing XSL sheet " + args.get(0) + " on element " + DOMUtils.domToString(varElmt));
+
+            Document varDoc = DOMUtils.newDocument();
+            varDoc.appendChild(varDoc.importNode(varElmt, true));
+
+            Object result;
+            DOMSource source = new DOMSource(varDoc);
+            XslRuntimeUriResolver resolver = new XslRuntimeUriResolver(_oxpath, _ectx.getBaseResourceURI());
+            XslTransformHandler.getInstance().cacheXSLSheet(_ectx.getBaseResourceURI(), xslUri, xslSheet.sheetBody, resolver);
+            try {
+                result = XslTransformHandler.getInstance().transform(_ectx.getBaseResourceURI(), xslUri, source, parametersMap, resolver);
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new XPathFunctionException(new FaultException(
+                    _oxpath.getOwner().constants.qnSubLanguageExecutionFault, e.toString()));
+            }
+            if (result instanceof Node)
+                return ((Node) result).getChildNodes();
+            else
+                return result;
+        }
+    }
+
+}

Added: ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/xpath10/jaxp/JaxpVariableResolver.java
URL: http://svn.apache.org/viewvc/ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/xpath10/jaxp/JaxpVariableResolver.java?rev=727785&view=auto
==============================================================================
--- ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/xpath10/jaxp/JaxpVariableResolver.java (added)
+++ ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/xpath10/jaxp/JaxpVariableResolver.java Thu Dec 18 10:31:27 2008
@@ -0,0 +1,149 @@
+/*
+ * 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.ode.bpel.rtrep.v1.xpath10.jaxp;
+
+import javax.xml.namespace.QName;
+import javax.xml.xpath.XPathVariableResolver;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ode.bpel.common.FaultException;
+import org.apache.ode.bpel.rtrep.v1.EvaluationContext;
+import org.apache.ode.bpel.rtrep.v1.OLink;
+import org.apache.ode.bpel.rtrep.v1.OMessageVarType;
+import org.apache.ode.bpel.rtrep.v1.OScope;
+import org.apache.ode.bpel.rtrep.v1.OXsdTypeVarType;
+import org.apache.ode.bpel.rtrep.v1.xpath10.OXPath10Expression;
+import org.apache.ode.bpel.rtrep.v1.xpath10.OXPath10ExpressionBPEL20;
+import org.apache.ode.utils.Namespaces;
+import org.apache.ode.utils.xsd.XSTypes;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * JAXP function resolver for BPEL XPath functions
+ */
+public class JaxpVariableResolver implements XPathVariableResolver {
+
+    private static final Log __log = LogFactory.getLog(JaxpVariableResolver.class);
+
+    private EvaluationContext _ectx;
+
+    private OXPath10Expression _oxpath;
+
+    public JaxpVariableResolver(EvaluationContext ectx, OXPath10Expression oxpath) {
+        _ectx = ectx;
+        _oxpath = oxpath;
+    }
+
+    public Object resolveVariable(QName variableName) {
+        __log.debug("JAXP runtime: Resolving variable " + variableName);
+
+        if (!(_oxpath instanceof OXPath10ExpressionBPEL20)) {
+            throw new IllegalStateException("XPath variables not supported for bpel 1.1");
+        }
+
+        // Custom variables
+        if (variableName.getNamespaceURI().equals(Namespaces.ODE_EXTENSION_NS)) {
+            if ("pid".equals(variableName.getLocalPart())) {
+                return _ectx.getProcessId();
+            }
+        }
+
+        if (_oxpath instanceof OXPath10ExpressionBPEL20 && ((OXPath10ExpressionBPEL20) _oxpath).isJoinExpression) {
+            OLink olink = _oxpath.links.get(variableName.getLocalPart());
+            try {
+                return _ectx.isLinkActive(olink) ? Boolean.TRUE : Boolean.FALSE;
+            } catch (FaultException e) {
+                throw new WrappedFaultException(e);
+            }
+        } else {
+            String varName;
+            String partName;
+            int dotloc = variableName.getLocalPart().indexOf('.');
+            if (dotloc == -1) {
+                varName = variableName.getLocalPart();
+                partName = null;
+            } else {
+                varName = variableName.getLocalPart().substring(0, dotloc);
+                partName = variableName.getLocalPart().substring(dotloc + 1);
+            }
+            OScope.Variable variable = _oxpath.vars.get(varName);
+            OMessageVarType.Part part =
+                partName == null ? null : ((OMessageVarType) variable.type).parts.get(partName);
+
+            try {
+                Node variableNode = _ectx.readVariable(variable, part);
+                if (variableNode == null)
+                    throw new FaultException(variable.getOwner().constants.qnSelectionFailure, "Unknown variable "
+                        + variableName.getLocalPart());
+                if (_ectx.narrowTypes()) {
+                    if (variable.type instanceof OXsdTypeVarType && ((OXsdTypeVarType) variable.type).simple)
+                        return getSimpleContent(variableNode, ((OXsdTypeVarType) variable.type).xsdType);
+                    if (part != null && part.type instanceof OXsdTypeVarType
+                        && ((OXsdTypeVarType) part.type).simple)
+                        return getSimpleContent(variableNode, ((OXsdTypeVarType) part.type).xsdType);
+                }
+
+                // Saxon expects a node list, this nodelist should contain exactly one item, the attribute
+                // value
+                return new SingletonNodeList(variableNode);
+
+            } catch (FaultException e) {
+                throw new WrappedFaultException(e);
+            }
+        }
+    }
+
+    private Object getSimpleContent(Node simpleNode, QName type) {
+        String text = simpleNode.getTextContent();
+        try {
+            return XSTypes.toJavaObject(type, text);
+        } catch (Exception e) {
+        }
+        // Elegant way failed, trying brute force
+        try {
+            return Integer.valueOf(text);
+        } catch (NumberFormatException e) {
+        }
+        try {
+            return Double.valueOf(text);
+        } catch (NumberFormatException e) {
+        }
+        // Remember: always a node set
+        if (simpleNode.getParentNode() != null)
+            return simpleNode.getParentNode().getChildNodes();
+        else
+            return text;
+    }
+
+    private static class SingletonNodeList implements NodeList {
+        private Node _node;
+
+        SingletonNodeList(Node node) {
+            _node = node;
+        }
+
+        public Node item(int index) {
+            if (index != 0)
+                throw new IndexOutOfBoundsException("" + index);
+            return _node;
+        }
+
+        public int getLength() {
+            return 1;
+        }
+
+    }
+}

Added: ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/xpath10/jaxp/JaxpXPath10ExpressionRuntime.java
URL: http://svn.apache.org/viewvc/ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/xpath10/jaxp/JaxpXPath10ExpressionRuntime.java?rev=727785&view=auto
==============================================================================
--- ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/xpath10/jaxp/JaxpXPath10ExpressionRuntime.java (added)
+++ ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/xpath10/jaxp/JaxpXPath10ExpressionRuntime.java Thu Dec 18 10:31:27 2008
@@ -0,0 +1,216 @@
+/*
+ * 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.ode.bpel.rtrep.v1.xpath10.jaxp;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ode.bpel.common.FaultException;
+import org.apache.ode.bpel.rtrep.common.ConfigurationException;
+import org.apache.ode.bpel.rtrep.v1.EvaluationContext;
+import org.apache.ode.bpel.rtrep.v1.ExpressionLanguageRuntime;
+import org.apache.ode.bpel.rtrep.v1.OExpression;
+import org.apache.ode.bpel.rtrep.v1.xpath10.OXPath10Expression;
+import org.apache.ode.utils.DOMUtils;
+import org.apache.ode.utils.ISO8601DateParser;
+import org.apache.ode.utils.xsd.Duration;
+import org.apache.ode.utils.xsl.XslTransformHandler;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+/**
+ * JAXP based XPath 1.0 Expression Language run-time subsytem.
+ */
+public class JaxpXPath10ExpressionRuntime implements ExpressionLanguageRuntime {
+    /** Class-level logger. */
+    private static final Log __log = LogFactory.getLog(JaxpXPath10ExpressionRuntime.class);
+
+    public void initialize(Map properties) throws ConfigurationException {
+        TransformerFactory trsf = TransformerFactory.newInstance();
+        __log.debug("JAXP runtime: TransformerFactory impl = " + trsf.getClass());
+        XslTransformHandler.getInstance().setTransformerFactory(trsf);
+    }
+
+    public String evaluateAsString(OExpression cexp, EvaluationContext ctx) throws FaultException {
+        return (String) evaluate(cexp, ctx, XPathConstants.STRING);
+    }
+
+    public boolean evaluateAsBoolean(OExpression cexp, EvaluationContext ctx) throws FaultException {
+        return (Boolean) evaluate(cexp, ctx, XPathConstants.BOOLEAN);
+    }
+
+    public Number evaluateAsNumber(OExpression cexp, EvaluationContext ctx) throws FaultException {
+        return (Number) evaluate(cexp, ctx, XPathConstants.NUMBER);
+    }
+
+    public List evaluate(OExpression cexp, EvaluationContext ctx) throws FaultException {
+        List result;
+        Object someRes = null;
+        try {
+            someRes = evaluate(cexp, ctx, XPathConstants.NODESET);
+        } catch (FaultException ex) {
+            try {
+                // JDK implementation of evaluation seems to be more strict about result types than Saxon:
+                // basic return types are not converted to lists automatically.
+                // this simulates Saxon behaviour: get a string result and put it in a list.
+                List resultList = new ArrayList(1);
+                resultList.add(evaluateAsString(cexp, ctx));
+                someRes = resultList;
+            } catch (Exception ex2) {
+                // re-throw original exception if workaround does not work.
+                throw ex;
+            }
+        }
+        if (someRes instanceof List) {
+            result = (List) someRes;
+            __log.debug("Returned list of size " + result.size());
+            if ((result.size() == 1) && !(result.get(0) instanceof Node)) {
+                // Dealing with a Java class
+                Object simpleType = result.get(0);
+                // Dates get a separate treatment as we don't want to call toString on them
+                String textVal;
+                if (simpleType instanceof Date)
+                    textVal = ISO8601DateParser.format((Date) simpleType);
+                else
+                    textVal = simpleType.toString();
+
+                // Wrapping in a document
+                Document d = DOMUtils.newDocument();
+                // Giving our node a parent just in case it's an LValue expression
+                Element wrapper = d.createElement("wrapper");
+                Text text = d.createTextNode(textVal);
+                wrapper.appendChild(text);
+                d.appendChild(wrapper);
+                result = Collections.singletonList(text);
+            }
+        } else if (someRes instanceof NodeList) {
+            NodeList retVal = (NodeList) someRes;
+            __log.debug("Returned node list of size " + retVal.getLength());
+            result = new ArrayList(retVal.getLength());
+            for (int m = 0; m < retVal.getLength(); ++m) {
+                Node val = retVal.item(m);
+                if (val.getNodeType() == Node.DOCUMENT_NODE)
+                    val = ((Document) val).getDocumentElement();
+                result.add(val);
+            }
+        } else {
+            result = null;
+        }
+
+        return result;
+    }
+
+    public Node evaluateNode(OExpression cexp, EvaluationContext ctx) throws FaultException {
+        List retVal = evaluate(cexp, ctx);
+        if (retVal.size() == 0)
+            throw new FaultException(cexp.getOwner().constants.qnSelectionFailure, "No results for expression: "
+                + cexp);
+        if (retVal.size() > 1)
+            throw new FaultException(cexp.getOwner().constants.qnSelectionFailure,
+                "Multiple results for expression: " + cexp);
+        return (Node) retVal.get(0);
+    }
+
+    public Calendar evaluateAsDate(OExpression cexp, EvaluationContext context) throws FaultException {
+        List literal = DOMUtils.toList(evaluate(cexp, context, XPathConstants.NODESET));
+        if (literal.size() == 0)
+            throw new FaultException(cexp.getOwner().constants.qnSelectionFailure, "No results for expression: "
+                + cexp);
+        if (literal.size() > 1)
+            throw new FaultException(cexp.getOwner().constants.qnSelectionFailure,
+                "Multiple results for expression: " + cexp);
+
+        Object date = literal.get(0);
+        if (date instanceof Calendar)
+            return (Calendar) date;
+        if (date instanceof Date) {
+            Calendar cal = Calendar.getInstance();
+            cal.setTime((Date) date);
+            return cal;
+        }
+        if (date instanceof Element)
+            date = ((Element) date).getTextContent();
+
+        try {
+            return ISO8601DateParser.parseCal(date.toString());
+        } catch (Exception ex) {
+            String errmsg = "Invalid date format: " + literal;
+            __log.error(errmsg);
+            throw new FaultException(cexp.getOwner().constants.qnInvalidExpressionValue, errmsg);
+        }
+    }
+
+    public Duration evaluateAsDuration(OExpression cexp, EvaluationContext context) throws FaultException {
+        String literal = this.evaluateAsString(cexp, context);
+        try {
+            return new Duration(literal);
+        } catch (Exception ex) {
+            String errmsg = "Invalid duration: " + literal;
+            __log.error(errmsg, ex);
+            throw new FaultException(cexp.getOwner().constants.qnInvalidExpressionValue, errmsg);
+        }
+    }
+
+    private Object evaluate(OExpression cexp, EvaluationContext ctx, QName type) throws FaultException {
+        try {
+            OXPath10Expression oxpath = (OXPath10Expression) cexp;
+            __log.debug("JAXP runtime: evaluating " + oxpath.xpath);
+            // use default XPath implementation
+            XPathFactory xpf = XPathFactory.newInstance();
+            __log.debug("JAXP runtime: XPathFactory impl = " + xpf.getClass());
+            XPath xpe = xpf.newXPath();
+            xpe.setXPathFunctionResolver(new JaxpFunctionResolver(ctx, oxpath));
+            xpe.setXPathVariableResolver(new JaxpVariableResolver(ctx, oxpath));
+            xpe.setNamespaceContext(oxpath.namespaceCtx);
+            XPathExpression expr = xpe.compile(((OXPath10Expression) cexp).xpath);
+            Object evalResult =
+                expr.evaluate(ctx.getRootNode() == null ? DOMUtils.newDocument() : ctx.getRootNode(), type);
+            if (evalResult != null && __log.isDebugEnabled()) {
+                __log.debug("Expression " + cexp.toString() + " generated result " + evalResult + " - type="
+                    + evalResult.getClass().getName());
+                if (ctx.getRootNode() != null)
+                    __log.debug("Was using context node " + DOMUtils.domToString(ctx.getRootNode()));
+            }
+            return evalResult;
+        } catch (XPathExpressionException e) {
+            // Extracting the real cause from all this wrapping isn't a simple task
+            Throwable cause = e.getCause() != null ? e.getCause() : e;
+            throw new FaultException(cexp.getOwner().constants.qnSubLanguageExecutionFault, cause.getMessage(),
+                cause);
+        } catch (WrappedFaultException wre) {
+            __log.debug("Could not evaluate expression because of ", wre);
+            throw (FaultException) wre.getCause();
+        } catch (Throwable t) {
+            __log.debug("Could not evaluate expression because of ", t);
+            throw new FaultException(cexp.getOwner().constants.qnSubLanguageExecutionFault, t.getMessage(), t);
+        }
+
+    }
+}

Added: ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/xpath10/jaxp/WrappedFaultException.java
URL: http://svn.apache.org/viewvc/ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/xpath10/jaxp/WrappedFaultException.java?rev=727785&view=auto
==============================================================================
--- ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/xpath10/jaxp/WrappedFaultException.java (added)
+++ ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/xpath10/jaxp/WrappedFaultException.java Thu Dec 18 10:31:27 2008
@@ -0,0 +1,27 @@
+package org.apache.ode.bpel.rtrep.v1.xpath10.jaxp;
+
+import org.apache.ode.bpel.common.FaultException;
+
+/**
+ * wrapper for ODE exceptions thrown during XPath evaluation.
+ */
+public class WrappedFaultException extends RuntimeException {
+    private static final long serialVersionUID = -3575585514576583418L;
+
+    public FaultException _fault;
+
+    public WrappedFaultException(String message) {
+        super(message);
+    }
+
+    public WrappedFaultException(FaultException message) {
+        super(message);
+        _fault = message;
+    }
+
+    public WrappedFaultException(String message, FaultException cause) {
+        super(message, cause);
+        _fault = cause;
+    }
+
+}

Modified: ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/xpath20/XPath20ExpressionRuntime.java
URL: http://svn.apache.org/viewvc/ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/xpath20/XPath20ExpressionRuntime.java?rev=727785&r1=727784&r2=727785&view=diff
==============================================================================
--- ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/xpath20/XPath20ExpressionRuntime.java (original)
+++ ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v1/xpath20/XPath20ExpressionRuntime.java Thu Dec 18 10:31:27 2008
@@ -218,8 +218,9 @@
             OXPath20ExpressionBPEL20 oxpath20 = ((OXPath20ExpressionBPEL20) cexp);
             System.setProperty("javax.xml.xpath.XPathFactory:"+NamespaceConstant.OBJECT_MODEL_SAXON,
 		            "net.sf.saxon.xpath.XPathFactoryImpl");
-		    System.setProperty("javax.xml.xpath.XPathFactory:"+XPathConstants.DOM_OBJECT_MODEL,
-		            "net.sf.saxon.xpath.XPathFactoryImpl");
+            // JAXP based XPath 1.0 runtime does not work anymore after a XPath 2.0 has been evaluated if this is set.
+		    // System.setProperty("javax.xml.xpath.XPathFactory:"+XPathConstants.DOM_OBJECT_MODEL,
+		    //        "net.sf.saxon.xpath.XPathFactoryImpl");
 		    System.setProperty("javax.xml.xpath.XPathFactory:"+NamespaceConstant.OBJECT_MODEL_JDOM,
 		            "net.sf.saxon.xpath.XPathFactoryImpl");
 		    System.setProperty("javax.xml.xpath.XPathFactory:"+NamespaceConstant.OBJECT_MODEL_XOM,

Added: ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v2/xpath10/jaxp/JaxpFunctionResolver.java
URL: http://svn.apache.org/viewvc/ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v2/xpath10/jaxp/JaxpFunctionResolver.java?rev=727785&view=auto
==============================================================================
--- ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v2/xpath10/jaxp/JaxpFunctionResolver.java (added)
+++ ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v2/xpath10/jaxp/JaxpFunctionResolver.java Thu Dec 18 10:31:27 2008
@@ -0,0 +1,256 @@
+/*
+ * 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.ode.bpel.rtrep.v2.xpath10.jaxp;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.xpath.XPathFunction;
+import javax.xml.xpath.XPathFunctionException;
+import javax.xml.xpath.XPathFunctionResolver;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ode.bpel.common.FaultException;
+import org.apache.ode.bpel.rtrep.common.Constants;
+import org.apache.ode.bpel.rtrep.v2.EvaluationContext;
+import org.apache.ode.bpel.rtrep.v2.OLink;
+import org.apache.ode.bpel.rtrep.v2.OProcess;
+import org.apache.ode.bpel.rtrep.v2.OScope;
+import org.apache.ode.bpel.rtrep.v2.OXslSheet;
+import org.apache.ode.bpel.rtrep.v2.xpath10.OXPath10Expression;
+import org.apache.ode.bpel.rtrep.v2.xpath10.OXPath10ExpressionBPEL20;
+import org.apache.ode.bpel.rtrep.v2.xpath10.XslRuntimeUriResolver;
+import org.apache.ode.utils.DOMUtils;
+import org.apache.ode.utils.Namespaces;
+import org.apache.ode.utils.xsl.XslTransformHandler;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * JAXP function resolver for BPEL XPath functions
+ */
+public class JaxpFunctionResolver implements XPathFunctionResolver {
+
+    private static final Log __log = LogFactory.getLog(JaxpFunctionResolver.class);
+
+    private EvaluationContext _ectx;
+
+    private OXPath10Expression _oxpath;
+
+    public JaxpFunctionResolver(EvaluationContext ectx, OXPath10Expression oxpath) {
+        _ectx = ectx;
+        _oxpath = oxpath;
+    }
+
+    public XPathFunction resolveFunction(QName functionName, int arity) {
+        __log.debug("JAXP runtime: Resolving function " + functionName);
+        final String namespaceURI = functionName.getNamespaceURI();
+        if (namespaceURI == null) {
+            throw new NullPointerException("Undeclared namespace for " + functionName);
+        }
+        if (namespaceURI.equals(Namespaces.BPEL11_NS)
+            || namespaceURI.equals(Namespaces.WS_BPEL_20_NS)
+            || namespaceURI.equals(Namespaces.WSBPEL2_0_FINAL_EXEC)) {
+            String localName = functionName.getLocalPart();
+            if (Constants.EXT_FUNCTION_GETVARIABLEDATA.equals(localName)) {
+                return new GetVariableData();
+            }
+            if (Constants.EXT_FUNCTION_GETVARIABLEPROPERTY.equals(localName)) {
+                return new GetVariableProperty();
+            }
+            if (Constants.EXT_FUNCTION_GETLINKSTATUS.equals(localName)) {
+                return new GetLinkStatus();
+            }
+            if (Constants.EXT_FUNCTION_DOXSLTRANSFORM.equals(localName)) {
+                return new DoXslTransform();
+            }
+            throw new NullPointerException("Unknown BPEL function: " + functionName);
+        }
+        return null;
+    }
+
+    public class GetLinkStatus implements XPathFunction {
+        public Object evaluate(List args) throws XPathFunctionException {
+            if (args.size() != 1)
+                throw new XPathFunctionException(new FaultException(new QName(Namespaces.ODE_EXTENSION_NS,
+                    "getLinkStatusInvalidSource"), "Illegal Arguments"));
+
+            OLink olink = _oxpath.links.get(args.get(0));
+            try {
+                return _ectx.isLinkActive(olink) ? Boolean.TRUE : Boolean.FALSE;
+            } catch (FaultException e) {
+                throw new XPathFunctionException(new FaultException(new QName(Namespaces.ODE_EXTENSION_NS,
+                    "getLinkStatusInvalidSource"), e));
+            }
+        }
+    }
+
+    public class GetVariableData implements XPathFunction {
+        public Object evaluate(List args) throws XPathFunctionException {
+            if (__log.isDebugEnabled()) {
+                __log.debug("call(context=" + _ectx + " args=" + args + ")");
+            }
+
+            String varname = (String) args.get(0);
+            String partname = args.size() > 1 ? (String) args.get(1) : null;
+            String xpathStr = args.size() > 2 ? (String) args.get(2) : null;
+
+            OXPath10Expression.OSigGetVariableData sig =
+                _oxpath.resolveGetVariableDataSig(varname, partname, xpathStr);
+            if (sig == null) {
+                String msg = "InternalError: Attempt to use an unknown getVariableData signature: " + args;
+                if (__log.isFatalEnabled())
+                    __log.fatal(msg);
+                throw new XPathFunctionException(msg);
+            }
+
+            try {
+                Node ret = _ectx.readVariable(sig.variable, sig.part);
+                if (sig.location != null)
+                    ret = _ectx.evaluateQuery(ret, sig.location);
+
+                if (__log.isDebugEnabled()) {
+                    __log.debug("bpws:getVariableData(" + args + ")' = " + ret);
+                }
+
+                return ret;
+            } catch (FaultException e) {
+                __log.error("bpws:getVariableData(" + args + ") threw FaultException");
+                throw new XPathFunctionException(e);
+            }
+        }
+    }
+
+    public class GetVariableProperty implements XPathFunction {
+        public Object evaluate(List args) throws XPathFunctionException {
+            if (args.size() != 2) {
+                throw new XPathFunctionException(new FaultException(new QName(Namespaces.ODE_EXTENSION_NS,
+                    "getVariablePropertyInvalidSource"), "Missing required arguments"));
+            }
+
+            OScope.Variable var = _oxpath.vars.get(args.get(0));
+            OProcess.OProperty property = _oxpath.properties.get(args.get(1));
+
+            if (__log.isDebugEnabled()) {
+                __log.debug("function call:'bpws:getVariableProperty(" + var + "," + property + ")'");
+            }
+
+            try {
+                return _ectx.readMessageProperty(var, property);
+            } catch (FaultException e) {
+                throw new XPathFunctionException(e);
+            }
+        }
+    }
+
+    public class DoXslTransform implements XPathFunction {
+
+        public Object evaluate(List args) throws XPathFunctionException {
+            if (args.size() < 2 || (args.size() % 2) != 0)
+                throw new XPathFunctionException(new FaultException(new QName(Namespaces.ODE_EXTENSION_NS,
+                    "doXslTransformInvalidSource"), "Invalid arguments"));
+
+            if (__log.isDebugEnabled()) {
+                __log.debug("call(context=" + _ectx + " args=" + args + ")");
+            }
+            if (!(_oxpath instanceof OXPath10ExpressionBPEL20)) {
+                throw new IllegalStateException("XPath function bpws:doXslTransform not supported in BPEL 1.1!");
+            }
+
+            Element varElmt;
+            try {
+                if (args.get(1) instanceof List) {
+                    List elmts = (List) args.get(1);
+                    if (elmts.size() != 1)
+                        throw new XPathFunctionException(new FaultException(
+                            _oxpath.getOwner().constants.qnXsltInvalidSource,
+                            "Second parameter of the bpws:doXslTransform function MUST point to a single "
+                                + "element node."));
+                    varElmt = (Element) elmts.get(0);
+                } else {
+                    varElmt = (Element) args.get(1);
+                }
+            } catch (ClassCastException e) {
+                throw new XPathFunctionException(new FaultException(
+                    _oxpath.getOwner().constants.qnXsltInvalidSource,
+                    "Second parameter of the bpws:doXslTransform function MUST point to a single "
+                        + "element node."));
+            }
+
+            URI xslUri;
+            try {
+                xslUri = new URI((String) args.get(0));
+            } catch (URISyntaxException use) {
+                // Shouldn't happen, checked at compilation time
+                throw new XPathFunctionException("First parameter of the bpws:doXslTransform isn't a valid URI!");
+            }
+            OXslSheet xslSheet = _oxpath.xslSheets.get(xslUri);
+            // Shouldn't happen, checked at compilation time
+            if (xslSheet == null)
+                throw new XPathFunctionException("Couldn't find the XSL sheet " + args.get(0)
+                    + ", process compilation or deployment was probably incomplete!");
+
+            if (!(varElmt instanceof Element)) {
+                throw new XPathFunctionException(new FaultException(
+                    _oxpath.getOwner().constants.qnXsltInvalidSource,
+                    "Second parameter of the bpws:doXslTransform function MUST point to a single "
+                        + "element node."));
+            }
+
+            HashMap<QName, Object> parametersMap = null;
+            if (args.size() > 2) {
+                parametersMap = new HashMap<QName, Object>();
+                for (int idx = 2; idx < args.size(); idx += 2) {
+                    QName keyQName = _oxpath.namespaceCtx.derefQName((String) args.get(idx));
+                    Object paramElmt;
+                    if (args.get(idx + 1) instanceof List) {
+                        paramElmt = ((List) args.get(idx + 1)).get(0);
+                    } else
+                        paramElmt = args.get(idx + 1);
+
+                    parametersMap.put(keyQName, paramElmt);
+                }
+            }
+
+            if (__log.isDebugEnabled())
+                __log.debug("Executing XSL sheet " + args.get(0) + " on element " + DOMUtils.domToString(varElmt));
+
+            Document varDoc = DOMUtils.newDocument();
+            varDoc.appendChild(varDoc.importNode(varElmt, true));
+
+            Object result;
+            DOMSource source = new DOMSource(varDoc);
+            XslRuntimeUriResolver resolver = new XslRuntimeUriResolver(_oxpath, _ectx.getBaseResourceURI());
+            XslTransformHandler.getInstance().cacheXSLSheet(_ectx.getBaseResourceURI(), xslUri, xslSheet.sheetBody, resolver);
+            try {
+                result = XslTransformHandler.getInstance().transform(_ectx.getBaseResourceURI(), xslUri, source, parametersMap, resolver);
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new XPathFunctionException(new FaultException(
+                    _oxpath.getOwner().constants.qnSubLanguageExecutionFault, e.toString()));
+            }
+            if (result instanceof Node)
+                return ((Node) result).getChildNodes();
+            else
+                return result;
+        }
+    }
+
+}

Added: ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v2/xpath10/jaxp/JaxpVariableResolver.java
URL: http://svn.apache.org/viewvc/ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v2/xpath10/jaxp/JaxpVariableResolver.java?rev=727785&view=auto
==============================================================================
--- ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v2/xpath10/jaxp/JaxpVariableResolver.java (added)
+++ ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v2/xpath10/jaxp/JaxpVariableResolver.java Thu Dec 18 10:31:27 2008
@@ -0,0 +1,149 @@
+/*
+ * 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.ode.bpel.rtrep.v2.xpath10.jaxp;
+
+import javax.xml.namespace.QName;
+import javax.xml.xpath.XPathVariableResolver;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ode.bpel.common.FaultException;
+import org.apache.ode.bpel.rtrep.v2.EvaluationContext;
+import org.apache.ode.bpel.rtrep.v2.OLink;
+import org.apache.ode.bpel.rtrep.v2.OMessageVarType;
+import org.apache.ode.bpel.rtrep.v2.OScope;
+import org.apache.ode.bpel.rtrep.v2.OXsdTypeVarType;
+import org.apache.ode.bpel.rtrep.v2.xpath10.OXPath10Expression;
+import org.apache.ode.bpel.rtrep.v2.xpath10.OXPath10ExpressionBPEL20;
+import org.apache.ode.utils.Namespaces;
+import org.apache.ode.utils.xsd.XSTypes;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * JAXP variable resolver for BPEL XPath functions
+ */
+public class JaxpVariableResolver implements XPathVariableResolver {
+
+    private static final Log __log = LogFactory.getLog(JaxpVariableResolver.class);
+
+    private EvaluationContext _ectx;
+
+    private OXPath10Expression _oxpath;
+
+    public JaxpVariableResolver(EvaluationContext ectx, OXPath10Expression oxpath) {
+        _ectx = ectx;
+        _oxpath = oxpath;
+    }
+
+    public Object resolveVariable(QName variableName) {
+        __log.debug("JAXP runtime: Resolving variable " + variableName);
+
+        if (!(_oxpath instanceof OXPath10ExpressionBPEL20)) {
+            throw new IllegalStateException("XPath variables not supported for bpel 1.1");
+        }
+
+        // Custom variables
+        if (variableName.getNamespaceURI().equals(Namespaces.ODE_EXTENSION_NS)) {
+            if ("pid".equals(variableName.getLocalPart())) {
+                return _ectx.getProcessId();
+            }
+        }
+
+        if (_oxpath instanceof OXPath10ExpressionBPEL20 && ((OXPath10ExpressionBPEL20) _oxpath).isJoinExpression) {
+            OLink olink = _oxpath.links.get(variableName.getLocalPart());
+            try {
+                return _ectx.isLinkActive(olink) ? Boolean.TRUE : Boolean.FALSE;
+            } catch (FaultException e) {
+                throw new WrappedFaultException(e);
+            }
+        } else {
+            String varName;
+            String partName;
+            int dotloc = variableName.getLocalPart().indexOf('.');
+            if (dotloc == -1) {
+                varName = variableName.getLocalPart();
+                partName = null;
+            } else {
+                varName = variableName.getLocalPart().substring(0, dotloc);
+                partName = variableName.getLocalPart().substring(dotloc + 1);
+            }
+            OScope.Variable variable = _oxpath.vars.get(varName);
+            OMessageVarType.Part part =
+                partName == null ? null : ((OMessageVarType) variable.type).parts.get(partName);
+
+            try {
+                Node variableNode = _ectx.readVariable(variable, part);
+                if (variableNode == null)
+                    throw new FaultException(variable.getOwner().constants.qnSelectionFailure, "Unknown variable "
+                        + variableName.getLocalPart());
+                if (_ectx.narrowTypes()) {
+                    if (variable.type instanceof OXsdTypeVarType && ((OXsdTypeVarType) variable.type).simple)
+                        return getSimpleContent(variableNode, ((OXsdTypeVarType) variable.type).xsdType);
+                    if (part != null && part.type instanceof OXsdTypeVarType
+                        && ((OXsdTypeVarType) part.type).simple)
+                        return getSimpleContent(variableNode, ((OXsdTypeVarType) part.type).xsdType);
+                }
+
+                // Saxon expects a node list, this nodelist should contain exactly one item, the attribute
+                // value
+                return new SingletonNodeList(variableNode);
+
+            } catch (FaultException e) {
+                throw new WrappedFaultException(e);
+            }
+        }
+    }
+
+    private Object getSimpleContent(Node simpleNode, QName type) {
+        String text = simpleNode.getTextContent();
+        try {
+            return XSTypes.toJavaObject(type, text);
+        } catch (Exception e) {
+        }
+        // Elegant way failed, trying brute force
+        try {
+            return Integer.valueOf(text);
+        } catch (NumberFormatException e) {
+        }
+        try {
+            return Double.valueOf(text);
+        } catch (NumberFormatException e) {
+        }
+        // Remember: always a node set
+        if (simpleNode.getParentNode() != null)
+            return simpleNode.getParentNode().getChildNodes();
+        else
+            return text;
+    }
+
+    private static class SingletonNodeList implements NodeList {
+        private Node _node;
+
+        SingletonNodeList(Node node) {
+            _node = node;
+        }
+
+        public Node item(int index) {
+            if (index != 0)
+                throw new IndexOutOfBoundsException("" + index);
+            return _node;
+        }
+
+        public int getLength() {
+            return 1;
+        }
+
+    }
+}

Added: ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v2/xpath10/jaxp/JaxpXPath10ExpressionRuntime.java
URL: http://svn.apache.org/viewvc/ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v2/xpath10/jaxp/JaxpXPath10ExpressionRuntime.java?rev=727785&view=auto
==============================================================================
--- ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v2/xpath10/jaxp/JaxpXPath10ExpressionRuntime.java (added)
+++ ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v2/xpath10/jaxp/JaxpXPath10ExpressionRuntime.java Thu Dec 18 10:31:27 2008
@@ -0,0 +1,216 @@
+/*
+ * 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.ode.bpel.rtrep.v2.xpath10.jaxp;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ode.bpel.common.FaultException;
+import org.apache.ode.bpel.rtrep.common.ConfigurationException;
+import org.apache.ode.bpel.rtrep.v2.EvaluationContext;
+import org.apache.ode.bpel.rtrep.v2.ExpressionLanguageRuntime;
+import org.apache.ode.bpel.rtrep.v2.OExpression;
+import org.apache.ode.bpel.rtrep.v2.xpath10.OXPath10Expression;
+import org.apache.ode.utils.DOMUtils;
+import org.apache.ode.utils.ISO8601DateParser;
+import org.apache.ode.utils.xsd.Duration;
+import org.apache.ode.utils.xsl.XslTransformHandler;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+/**
+ * JAXP based XPath 1.0 Expression Language run-time subsytem.
+ */
+public class JaxpXPath10ExpressionRuntime implements ExpressionLanguageRuntime {
+    /** Class-level logger. */
+    private static final Log __log = LogFactory.getLog(JaxpXPath10ExpressionRuntime.class);
+
+    public void initialize(Map properties) throws ConfigurationException {
+        TransformerFactory trsf = TransformerFactory.newInstance();
+        __log.debug("JAXP runtime: TransformerFactory impl = " + trsf.getClass());
+        XslTransformHandler.getInstance().setTransformerFactory(trsf);
+    }
+
+    public String evaluateAsString(OExpression cexp, EvaluationContext ctx) throws FaultException {
+        return (String) evaluate(cexp, ctx, XPathConstants.STRING);
+    }
+
+    public boolean evaluateAsBoolean(OExpression cexp, EvaluationContext ctx) throws FaultException {
+        return (Boolean) evaluate(cexp, ctx, XPathConstants.BOOLEAN);
+    }
+
+    public Number evaluateAsNumber(OExpression cexp, EvaluationContext ctx) throws FaultException {
+        return (Number) evaluate(cexp, ctx, XPathConstants.NUMBER);
+    }
+
+    public List evaluate(OExpression cexp, EvaluationContext ctx) throws FaultException {
+        List result;
+        Object someRes = null;
+        try {
+            someRes = evaluate(cexp, ctx, XPathConstants.NODESET);
+        } catch (FaultException ex) {
+            try {
+                // JDK implementation of evaluation seems to be more strict about result types than Saxon:
+                // basic return types are not converted to lists automatically.
+                // this simulates Saxon behaviour: get a string result and put it in a list.
+                List resultList = new ArrayList(1);
+                resultList.add(evaluateAsString(cexp, ctx));
+                someRes = resultList;
+            } catch (Exception ex2) {
+                // re-throw original exception if workaround does not work.
+                throw ex;
+            }
+        }
+        if (someRes instanceof List) {
+            result = (List) someRes;
+            __log.debug("Returned list of size " + result.size());
+            if ((result.size() == 1) && !(result.get(0) instanceof Node)) {
+                // Dealing with a Java class
+                Object simpleType = result.get(0);
+                // Dates get a separate treatment as we don't want to call toString on them
+                String textVal;
+                if (simpleType instanceof Date)
+                    textVal = ISO8601DateParser.format((Date) simpleType);
+                else
+                    textVal = simpleType.toString();
+
+                // Wrapping in a document
+                Document d = DOMUtils.newDocument();
+                // Giving our node a parent just in case it's an LValue expression
+                Element wrapper = d.createElement("wrapper");
+                Text text = d.createTextNode(textVal);
+                wrapper.appendChild(text);
+                d.appendChild(wrapper);
+                result = Collections.singletonList(text);
+            }
+        } else if (someRes instanceof NodeList) {
+            NodeList retVal = (NodeList) someRes;
+            __log.debug("Returned node list of size " + retVal.getLength());
+            result = new ArrayList(retVal.getLength());
+            for (int m = 0; m < retVal.getLength(); ++m) {
+                Node val = retVal.item(m);
+                if (val.getNodeType() == Node.DOCUMENT_NODE)
+                    val = ((Document) val).getDocumentElement();
+                result.add(val);
+            }
+        } else {
+            result = null;
+        }
+
+        return result;
+    }
+
+    public Node evaluateNode(OExpression cexp, EvaluationContext ctx) throws FaultException {
+        List retVal = evaluate(cexp, ctx);
+        if (retVal.size() == 0)
+            throw new FaultException(cexp.getOwner().constants.qnSelectionFailure, "No results for expression: "
+                + cexp);
+        if (retVal.size() > 1)
+            throw new FaultException(cexp.getOwner().constants.qnSelectionFailure,
+                "Multiple results for expression: " + cexp);
+        return (Node) retVal.get(0);
+    }
+
+    public Calendar evaluateAsDate(OExpression cexp, EvaluationContext context) throws FaultException {
+        List literal = DOMUtils.toList(evaluate(cexp, context, XPathConstants.NODESET));
+        if (literal.size() == 0)
+            throw new FaultException(cexp.getOwner().constants.qnSelectionFailure, "No results for expression: "
+                + cexp);
+        if (literal.size() > 1)
+            throw new FaultException(cexp.getOwner().constants.qnSelectionFailure,
+                "Multiple results for expression: " + cexp);
+
+        Object date = literal.get(0);
+        if (date instanceof Calendar)
+            return (Calendar) date;
+        if (date instanceof Date) {
+            Calendar cal = Calendar.getInstance();
+            cal.setTime((Date) date);
+            return cal;
+        }
+        if (date instanceof Element)
+            date = ((Element) date).getTextContent();
+
+        try {
+            return ISO8601DateParser.parseCal(date.toString());
+        } catch (Exception ex) {
+            String errmsg = "Invalid date format: " + literal;
+            __log.error(errmsg);
+            throw new FaultException(cexp.getOwner().constants.qnInvalidExpressionValue, errmsg);
+        }
+    }
+
+    public Duration evaluateAsDuration(OExpression cexp, EvaluationContext context) throws FaultException {
+        String literal = this.evaluateAsString(cexp, context);
+        try {
+            return new Duration(literal);
+        } catch (Exception ex) {
+            String errmsg = "Invalid duration: " + literal;
+            __log.error(errmsg, ex);
+            throw new FaultException(cexp.getOwner().constants.qnInvalidExpressionValue, errmsg);
+        }
+    }
+
+    private Object evaluate(OExpression cexp, EvaluationContext ctx, QName type) throws FaultException {
+        try {
+            OXPath10Expression oxpath = (OXPath10Expression) cexp;
+            __log.debug("JAXP runtime: evaluating " + oxpath.xpath);
+            // use default XPath implementation
+            XPathFactory xpf = XPathFactory.newInstance();
+            __log.debug("JAXP runtime: XPathFactory impl = " + xpf.getClass());
+            XPath xpe = xpf.newXPath();
+            xpe.setXPathFunctionResolver(new JaxpFunctionResolver(ctx, oxpath));
+            xpe.setXPathVariableResolver(new JaxpVariableResolver(ctx, oxpath));
+            xpe.setNamespaceContext(oxpath.namespaceCtx);
+            XPathExpression expr = xpe.compile(((OXPath10Expression) cexp).xpath);
+            Object evalResult =
+                expr.evaluate(ctx.getRootNode() == null ? DOMUtils.newDocument() : ctx.getRootNode(), type);
+            if (evalResult != null && __log.isDebugEnabled()) {
+                __log.debug("Expression " + cexp.toString() + " generated result " + evalResult + " - type="
+                    + evalResult.getClass().getName());
+                if (ctx.getRootNode() != null)
+                    __log.debug("Was using context node " + DOMUtils.domToString(ctx.getRootNode()));
+            }
+            return evalResult;
+        } catch (XPathExpressionException e) {
+            // Extracting the real cause from all this wrapping isn't a simple task
+            Throwable cause = e.getCause() != null ? e.getCause() : e;
+            throw new FaultException(cexp.getOwner().constants.qnSubLanguageExecutionFault, cause.getMessage(),
+                cause);
+        } catch (WrappedFaultException wre) {
+            __log.debug("Could not evaluate expression because of ", wre);
+            throw (FaultException) wre.getCause();
+        } catch (Throwable t) {
+            __log.debug("Could not evaluate expression because of ", t);
+            throw new FaultException(cexp.getOwner().constants.qnSubLanguageExecutionFault, t.getMessage(), t);
+        }
+
+    }
+}

Added: ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v2/xpath10/jaxp/WrappedFaultException.java
URL: http://svn.apache.org/viewvc/ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v2/xpath10/jaxp/WrappedFaultException.java?rev=727785&view=auto
==============================================================================
--- ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v2/xpath10/jaxp/WrappedFaultException.java (added)
+++ ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v2/xpath10/jaxp/WrappedFaultException.java Thu Dec 18 10:31:27 2008
@@ -0,0 +1,27 @@
+package org.apache.ode.bpel.rtrep.v2.xpath10.jaxp;
+
+import org.apache.ode.bpel.common.FaultException;
+
+/**
+ * wrapper for ODE exceptions thrown during XPath evaluation.
+ */
+public class WrappedFaultException extends RuntimeException {
+    private static final long serialVersionUID = -3575585514576583418L;
+
+    public FaultException _fault;
+
+    public WrappedFaultException(String message) {
+        super(message);
+    }
+
+    public WrappedFaultException(FaultException message) {
+        super(message);
+        _fault = message;
+    }
+
+    public WrappedFaultException(String message, FaultException cause) {
+        super(message, cause);
+        _fault = cause;
+    }
+
+}

Modified: ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v2/xpath20/XPath20ExpressionRuntime.java
URL: http://svn.apache.org/viewvc/ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v2/xpath20/XPath20ExpressionRuntime.java?rev=727785&r1=727784&r2=727785&view=diff
==============================================================================
--- ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v2/xpath20/XPath20ExpressionRuntime.java (original)
+++ ode/trunk/runtimes/src/main/java/org/apache/ode/bpel/rtrep/v2/xpath20/XPath20ExpressionRuntime.java Thu Dec 18 10:31:27 2008
@@ -207,8 +207,9 @@
             OXPath20ExpressionBPEL20 oxpath20 = ((OXPath20ExpressionBPEL20) cexp);
             System.setProperty("javax.xml.xpath.XPathFactory:"+NamespaceConstant.OBJECT_MODEL_SAXON,
 		            "net.sf.saxon.xpath.XPathFactoryImpl");
-		    System.setProperty("javax.xml.xpath.XPathFactory:"+XPathConstants.DOM_OBJECT_MODEL,
-		            "net.sf.saxon.xpath.XPathFactoryImpl");
+            // JAXP based XPath 1.0 runtime does not work anymore after a XPath 2.0 has been evaluated if this is set.
+		    // System.setProperty("javax.xml.xpath.XPathFactory:"+XPathConstants.DOM_OBJECT_MODEL,
+		    //        "net.sf.saxon.xpath.XPathFactoryImpl");
 		    System.setProperty("javax.xml.xpath.XPathFactory:"+NamespaceConstant.OBJECT_MODEL_JDOM,
 		            "net.sf.saxon.xpath.XPathFactoryImpl");
 		    System.setProperty("javax.xml.xpath.XPathFactory:"+NamespaceConstant.OBJECT_MODEL_XOM,