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,