blob: 3ed44d095daa9b3d5e6c20cc9001b67bed4e98c8 [file] [log] [blame]
/*
* 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(_cctx.getBaseResourceURI(), xslSheet.uri, xslSheet.sheetBody,
new XslCompileUriResolver(_cctx, _out));
} catch (Exception e) {
throw new CompilationException(
__msgs.errInvalidNumberOfArguments(xslUri));
}
_out.setXslSheet(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()));
}
}