/* * 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.elang.xpath10.compiler; import java.util.List; import javax.xml.namespace.QName; import org.apache.ode.bpel.compiler.api.CompilationException; import org.apache.ode.bpel.compiler.api.CompilerContext; import org.apache.ode.bpel.elang.xpath10.o.OXPath10Expression; import org.apache.ode.bpel.elang.xpath10.o.OXPath10ExpressionBPEL20; import org.apache.ode.bpel.o.OExpression; import org.apache.ode.bpel.o.OLink; import org.apache.ode.bpel.o.OMessageVarType; import org.apache.ode.bpel.o.OProcess; import org.apache.ode.bpel.o.OScope; import org.apache.ode.bpel.o.OXslSheet; import org.apache.ode.utils.NSContext; import org.apache.ode.utils.msg.MessageBundle; import org.apache.ode.utils.xsl.XslTransformHandler; import org.jaxen.JaxenException; import org.jaxen.JaxenHandler; import org.jaxen.expr.Expr; import org.jaxen.expr.FunctionCallExpr; import org.jaxen.expr.LiteralExpr; /** * Verifies validity of bpel extensions for xpath expressions */ class JaxenBpelHandler extends JaxenHandler { private static final XPathMessages __msgs = MessageBundle.getMessages(XPathMessages.class); private CompilerContext _cctx; private OXPath10Expression _out; private NSContext _nsContext; private String _bpelNsUril; JaxenBpelHandler(String bpelNsUri, OXPath10Expression out, NSContext nsContext, CompilerContext cctx) { _bpelNsUril = bpelNsUri; _cctx = cctx; _nsContext = nsContext; _out = out; assert nsContext != null; assert cctx != null; assert out != null; } public void variableReference(String prefix, String variableName) throws JaxenException { super.variableReference(prefix, variableName); // Custom variables if ("ode".equals(prefix)) { if ("pid".equals(variableName)) return; } if(_out instanceof OXPath10ExpressionBPEL20){ OXPath10ExpressionBPEL20 out = (OXPath10ExpressionBPEL20)_out; try{ if(out.isJoinExpression){ // these resolve to links OLink olink = _cctx.resolveLink(variableName); _out.links.put(variableName, olink); }else{ int dot = variableName.indexOf('.'); if (dot != -1) variableName = variableName.substring(0,dot); OScope.Variable var = _cctx.resolveVariable(variableName); _out.vars.put(variableName, var); } }catch(CompilationException ce){ throw new CompilationExceptionWrapper(ce); } } } public void endXPath() throws JaxenException { super.endXPath(); } /** */ public void endFunction() { super.endFunction(); FunctionCallExpr c = (FunctionCallExpr)peekFrame() .getLast(); String prefix = c.getPrefix(); // empty string prefix should resolve to xpath namespace, NOT bpel if ((prefix == null) || "".equals(prefix)) { return; } String ns = _nsContext.getNamespaceURI(prefix); if (ns == null) { throw new CompilationException( __msgs.errUndeclaredFunctionPrefix(prefix,c.getFunctionName())); } else if (isBpelNamespace(ns)) { try { if (Constants.EXT_FUNCTION_GETVARIABLEDATA.equals(c.getFunctionName())) { compileGetVariableData(c); } else if (Constants.EXT_FUNCTION_GETVARIABLEPROPRTY.equals(c .getFunctionName())) { compileGetVariableProperty(c); } else if (Constants.EXT_FUNCTION_GETLINKSTATUS.equals(c.getFunctionName())) { compileGetLinkStatus(c); } else if (Constants.EXT_FUNCTION_DOXSLTRANSFORM.equals(c.getFunctionName())) { compileDoXslTransform(c); } else { throw new CompilationException(__msgs.errUnknownBpelFunction(c.getFunctionName())); } } catch (CompilationException ce) { throw new RuntimeException(ce); } } } private boolean isBpelNamespace(String ns) { return ns.equals(_bpelNsUril); } private void compileGetLinkStatus(FunctionCallExpr c) throws CompilationException { List params = c.getParameters(); if (params.size() != 1) { throw new CompilationException(__msgs.errInvalidNumberOfArguments(c.getFunctionName())); } String linkName = getLiteralFromExpression((Expr)params.get(0)); OLink olink = _cctx.resolveLink(linkName); _out.links.put(linkName, olink); } /** * Compile a <code>bpws:getVariableData(...)</em> function call. Note that all arguments * to this call <em>must</em> be literal values. Therefore, we are able to "pre-compile" * all possible invocations of this call, and save ourselves the problem of compiling * query expressions at runtime. * @param c {@link FunctionCallExpr} for this invocation * @throws CompilationException */ private void compileGetVariableData(FunctionCallExpr c) throws CompilationException { List params = c.getParameters(); if (params.size() < 1 || params.size() > 3) { throw new CompilationException( __msgs.errInvalidNumberOfArguments(c.getFunctionName())); } String varname = getLiteralFromExpression((Expr)params.get(0)); String partname = params.size() > 1 ? getLiteralFromExpression((Expr)params.get(1)) : null; String locationstr = params.size() > 2 ? getLiteralFromExpression((Expr)params.get(2)) : null; OScope.Variable var = _cctx.resolveVariable(varname); OMessageVarType.Part part = partname != null ? _cctx.resolvePart(var,partname) : null; OExpression location = null; if (locationstr != null) { location = _cctx.compileExpr(locationstr,_nsContext); } _out.addGetVariableDataSig(varname, partname, locationstr, new OXPath10Expression.OSigGetVariableData(_cctx.getOProcess(),var, part,location)); } private void compileGetVariableProperty(FunctionCallExpr c) throws CompilationException{ List params = c.getParameters(); if (params.size() != 2) { throw new CompilationException( __msgs.errInvalidNumberOfArguments(Constants.EXT_FUNCTION_GETVARIABLEPROPRTY)); } String varName = getLiteralFromExpression((Expr)params.get(0)); OScope.Variable v = _cctx.resolveVariable(varName); _out.vars.put(varName, v); String propName = getLiteralFromExpression((Expr)params.get(1)); QName qname = _nsContext.derefQName(propName); if (qname == null) throw new CompilationException( __msgs.errInvalidQName(propName)); OProcess.OProperty property = _cctx.resolveProperty(qname); // Make sure we can... _cctx.resolvePropertyAlias(v, qname); _out.properties.put(propName, property); _out.vars.put(varName, v); } private void compileDoXslTransform(FunctionCallExpr c) throws CompilationException { List params = c.getParameters(); if (params.size() < 2 || params.size() % 2 != 0) { throw new CompilationException( __msgs.errInvalidNumberOfArguments(Constants.EXT_FUNCTION_DOXSLTRANSFORM)); } String xslUri = getLiteralFromExpression((Expr)params.get(0)); OXslSheet xslSheet = _cctx.compileXslt(xslUri); try { XslTransformHandler.getInstance().parseXSLSheet(xslSheet.uri, xslSheet.sheetBody, new XslCompileUriResolver(_cctx, _out)); } catch (Exception e) { throw new CompilationException( __msgs.errInvalidNumberOfArguments(xslUri)); } _out.xslSheets.put(xslSheet.uri, xslSheet); } private String getLiteralFromExpression(Expr expr) throws CompilationException { expr = expr.simplify(); if (expr instanceof LiteralExpr) return ((LiteralExpr)expr).getLiteral(); throw new CompilationException(__msgs.errLiteralExpected(expr.getText())); } }