use of org.exist.dom.QName in project exist by eXist-db.
the class FunctionFactory method wrap.
/**
* Wrap a function call into a user defined function.
* This is used to handle dynamic function calls or partial
* function applications on built in functions.
*
* @param context current context
* @param call the function call to be wrapped
* @return a new function call referencing an inline function
* @throws XPathException in case of a static error
*/
public static FunctionCall wrap(XQueryContext context, Function call) throws XPathException {
final int argCount = call.getArgumentCount();
final QName[] variables = new QName[argCount];
final List<Expression> innerArgs = new ArrayList<>(argCount);
final List<Expression> wrapperArgs = new ArrayList<>(argCount);
final FunctionSignature signature = call.getSignature();
// the parameters of the newly created inline function:
final List<SequenceType> newParamTypes = new ArrayList<>();
final SequenceType[] paramTypes = signature.getArgumentTypes();
for (int i = 0; i < argCount; i++) {
final Expression param = call.getArgument(i);
wrapperArgs.add(param);
QName varName = new QName("vp" + i, XMLConstants.NULL_NS_URI);
variables[i] = varName;
final VariableReference ref = new VariableReference(context, varName);
innerArgs.add(ref);
// overloaded functions like concat may have an arbitrary number of arguments
if (i < paramTypes.length) {
newParamTypes.add(paramTypes[i]);
} else // overloaded function: add last sequence type
{
newParamTypes.add(paramTypes[paramTypes.length - 1]);
}
}
final SequenceType[] newParamArray = newParamTypes.toArray(new SequenceType[0]);
final FunctionSignature newSignature = new FunctionSignature(signature);
newSignature.setArgumentTypes(newParamArray);
final UserDefinedFunction func = new UserDefinedFunction(context, newSignature);
for (final QName varName : variables) {
func.addVariable(varName);
}
call.setArguments(innerArgs);
func.setFunctionBody(call);
final FunctionCall wrappedCall = new FunctionCall(context, func);
wrappedCall.setArguments(wrapperArgs);
return wrappedCall;
}
use of org.exist.dom.QName in project exist by eXist-db.
the class CastExpression method toFunction.
public Function toFunction() throws XPathException {
final String typeName = Type.getTypeName(CastExpression.this.requiredType);
try {
final QName qname = QName.parse(context, typeName);
final FunctionSignature signature = new FunctionSignature(qname);
final SequenceType argType = new SequenceType(Type.ITEM, Cardinality.EXACTLY_ONE);
signature.setArgumentTypes(new SequenceType[] { argType });
signature.setReturnType(new SequenceType(CastExpression.this.requiredType, CastExpression.this.cardinality));
return new FunctionWrapper(this, signature);
} catch (final QName.IllegalQNameException e) {
throw new XPathException(ErrorCodes.XPST0081, "No namespace defined for prefix " + typeName);
}
}
use of org.exist.dom.QName in project exist by eXist-db.
the class ElementConstructor method addNamespaceDecl.
private void addNamespaceDecl(final QName qn) throws XPathException {
if (namespaceDecls == null) {
namespaceDecls = new QName[1];
namespaceDecls[0] = qn;
} else {
for (QName namespaceDecl : namespaceDecls) {
if (qn.equals(namespaceDecl)) {
throw new XPathException(this, ErrorCodes.XQST0071, "duplicate definition for '" + qn + "'");
}
}
final QName[] decls = new QName[namespaceDecls.length + 1];
System.arraycopy(namespaceDecls, 0, decls, 0, namespaceDecls.length);
decls[namespaceDecls.length] = qn;
namespaceDecls = decls;
}
// context.inScopeNamespaces.put(qn.getLocalPart(), qn.getNamespaceURI());
}
use of org.exist.dom.QName in project exist by eXist-db.
the class FunAnalyzeString method eval.
@Override
public Sequence eval(final Sequence[] args, final Sequence contextSequence) throws XPathException {
context.pushDocumentContext();
try {
final MemTreeBuilder builder = context.getDocumentBuilder();
builder.startDocument();
builder.startElement(new QName("analyze-string-result", Function.BUILTIN_FUNCTION_NS), null);
String input = "";
if (!args[0].isEmpty()) {
input = args[0].itemAt(0).getStringValue();
}
if (input != null && !input.isEmpty()) {
final String pattern = args[1].itemAt(0).getStringValue();
String flags = "";
if (args.length == 3) {
flags = args[2].itemAt(0).getStringValue();
}
analyzeString(builder, input, pattern, flags);
}
builder.endElement();
builder.endDocument();
return (NodeValue) builder.getDocument().getDocumentElement();
} finally {
context.popDocumentContext();
}
}
use of org.exist.dom.QName in project exist by eXist-db.
the class XQueryContext method declareFunction.
@Override
public void declareFunction(final UserDefinedFunction function) throws XPathException {
// TODO: redeclaring functions should be forbidden. however, throwing an
// exception will currently break util:eval.
final QName name = function.getSignature().getName();
if (XML_NS.equals(name.getNamespaceURI())) {
throw new XPathException(function, ErrorCodes.XQST0045, "Function '" + name + "' is in the forbidden namespace '" + XML_NS + "'");
}
if (Namespaces.SCHEMA_NS.equals(name.getNamespaceURI())) {
throw new XPathException(function, ErrorCodes.XQST0045, "Function '" + name + "' is in the forbidden namespace '" + Namespaces.SCHEMA_NS + "'");
}
if (Namespaces.SCHEMA_INSTANCE_NS.equals(name.getNamespaceURI())) {
throw new XPathException(function, ErrorCodes.XQST0045, "Function '" + name + "' is in the forbidden namespace '" + Namespaces.SCHEMA_INSTANCE_NS + "'");
}
if (Namespaces.XPATH_FUNCTIONS_NS.equals(name.getNamespaceURI())) {
throw new XPathException(function, ErrorCodes.XQST0045, "Function '" + name + "' is in the forbidden namespace '" + Namespaces.XPATH_FUNCTIONS_NS + "'");
}
if (name.getNamespaceURI().isEmpty()) {
throw new XPathException(function, ErrorCodes.XQST0060, "Every declared function name must have a non-null namespace URI, but function '" + name + "' does not meet this requirement.");
}
final FunctionSignature signature = function.getSignature();
final FunctionId functionKey = signature.getFunctionId();
if (declaredFunctions.containsKey(functionKey)) {
throw new XPathException(ErrorCodes.XQST0034, "Function " + signature.getName().toURIQualifiedName() + '#' + signature.getArgumentCount() + " is already defined.");
} else {
declaredFunctions.put(functionKey, function);
}
}
Aggregations