/** * This method creates a copy of a FunctionLibrary: if the original FunctionLibrary allows * new functions to be added, then additions to this copy will not affect the original, or * vice versa. * * @return a copy of this function library. This must be an instance of the original class. */ public FunctionLibrary copy() { XQueryFunctionLibrary qfl = new XQueryFunctionLibrary(config); qfl.functions = new HashMap(functions); return qfl; }
/** * Declare an imported XQuery function * @param function the imported function */ protected void declareXQueryFunction(XQueryFunction function) throws XPathException { queryFunctions.declareFunction(function); }
/** * Output "explain" information about each declared function. * <p/> * This method is intended primarily for internal use. * @param out the expression presenter used to display the output */ public void explainGlobalFunctions(ExpressionPresenter out) { globalFunctionLibrary.explainGlobalFunctions(out); }
private <R> List<R> lookupFunctions(FunctionLibraryList fll, FunctionExtractor<R> ext) { List<R> fl = new ArrayList<>(); for (FunctionLibrary lib: fll.getLibraryList()) { logger.trace("lookupFunctions; function library: {}; class: {}", lib.toString(), lib.getClass().getName()); if (lib instanceof FunctionLibraryList) { fl.addAll(lookupFunctions((FunctionLibraryList) lib, ext)); //} else if (lib instanceof ExecutableFunctionLibrary) { // ExecutableFunctionLibrary efl = (ExecutableFunctionLibrary) lib; // Iterator<UserFunction> itr = efl.iterateFunctions(); // while (itr.hasNext()) { // fl.add(getFunctionDeclaration(itr.next())); // } } else if (lib instanceof XQueryFunctionLibrary) { XQueryFunctionLibrary xqfl = (XQueryFunctionLibrary) lib; Iterator<XQueryFunction> itr = xqfl.getFunctionDefinitions(); while (itr.hasNext()) { XQueryFunction fn = itr.next(); logger.trace("lookupFunctions; fn: {}", fn.getDisplayName()); R result = ext.extractFunction(fn.getUserFunction()); if (result != null) { fl.add(result); } } } } return fl; }
/** * Look for cyclic variable references that go via one or more function calls * @param f a used-defined function * @param referees a list of variables and functions that refer directly or indirectly to this variable * @param globalFunctionLibrary the library containing all global functions */ private static void lookForFunctionCycles( XQueryFunction f, Stack referees, XQueryFunctionLibrary globalFunctionLibrary) throws XPathException { Expression body = f.getBody(); referees.push(f); List list = new ArrayList(10); ExpressionTool.gatherReferencedVariables(body, list); for (int i=0; i<list.size(); i++) { Binding b = (Binding)list.get(i); if (b instanceof GlobalVariable) { ((GlobalVariable)b).lookForCycles(referees, globalFunctionLibrary); } } list.clear(); ExpressionTool.gatherCalledFunctionNames(body, list); for (int i=0; i<list.size(); i++) { XQueryFunction qf = globalFunctionLibrary.getDeclarationByKey((String)list.get(i)); if (!referees.contains(qf)) { // recursive function calls are allowed lookForFunctionCycles(qf, referees, globalFunctionLibrary); } } referees.pop(); }
final String uri = functionName.getNamespaceURI(); if (namespaces.contains(uri)) { Expression call = baseLibrary.bind(functionName, staticArgs, env); if (call != null) { XQueryFunction def = baseLibrary.getDeclaration(functionName, staticArgs); importingModule.checkImportedFunctionSignature(def);
/** * Test whether an extension function with a given name and arity is available. This supports * the function-available() function in XSLT. This method may be called either at compile time * or at run time. If the function library is to be used only in an XQuery or free-standing XPath * environment, this method may throw an UnsupportedOperationException. * * @param functionName the name of the function in question * @param arity The number of arguments. This is set to -1 in the case of the single-argument * function-available() function; in this case the method should return true if there is some */ public boolean isAvailable(StructuredQName functionName, int arity) { return namespaces.contains(functionName.getNamespaceURI()) && baseLibrary.isAvailable(functionName, arity); } }
/** * Fixup all references to global functions. This method is called * on completion of query parsing. Each XQueryFunction is required to * bind all references to that function to the object representing the run-time * executable code of the function. * <p/> * This method is for internal use only. It is called only on the StaticQueryContext for the main * query body (not for library modules). */ public void fixupGlobalFunctions() throws XPathException { globalFunctionLibrary.fixupGlobalFunctions(this); }
/** * Get the function declaration corresponding to a given function name and arity * @return the XQueryFunction if there is one, or null if not. */ public XQueryFunction getDeclaration(StructuredQName functionName, Expression[] staticArgs) { if (namespaces.contains(functionName.getNamespaceURI())) { return baseLibrary.getDeclaration(functionName, staticArgs); } else { return null; } }
/** * Get the function with a given name and arity. This method is provided so that XQuery functions * can be called directly from a Java application. Note that there is no type checking or conversion * of arguments when this is done: the arguments must be provided in exactly the form that the function * signature declares them. * * @param uri the uri of the function name * @param localName the local part of the function name * @param arity the number of arguments. * @return the user-defined function, or null if no function with the given name and arity can be located * @since 8.4 */ public UserFunction getUserDefinedFunction(String uri, String localName, int arity) { return globalFunctionLibrary.getUserDefinedFunction(uri, localName, arity); }
return baseLibrary.bind(symbolicName, staticArgs, env, reasons); } else { return null;
private void loadLibraryModule() throws XPathException { if (href==null && moduleURI==null) { // error already reported return; } try { XSLStylesheet top = getPrincipalStylesheet(); QueryModule importedModule = loadModule(); // Do the importing Iterator it = importedModule.getGlobalFunctionLibrary().getFunctionDefinitions(); while (it.hasNext()) { XQueryFunction def = (XQueryFunction)it.next(); // don't import functions transitively if (def.getFunctionName().getNamespaceURI().equals(moduleURI)) { top.declareXQueryFunction(def); } // Note, we are not importing global variables at present } } catch (XPathException err) { compileError(err); } }
/** * Look for cyclic variable references that go via one or more function calls * @param f a used-defined function * @param referees a list of variables and functions that refer directly or indirectly to this variable * @param globalFunctionLibrary the library containing all global functions */ private static void lookForFunctionCycles( XQueryFunction f, Stack referees, XQueryFunctionLibrary globalFunctionLibrary) throws XPathException { Expression body = f.getBody(); referees.push(f); List list = new ArrayList(10); ExpressionTool.gatherReferencedVariables(body, list); for (int i=0; i<list.size(); i++) { Binding b = (Binding)list.get(i); if (b instanceof GlobalVariable) { ((GlobalVariable)b).lookForCycles(referees, globalFunctionLibrary); } } list.clear(); ExpressionTool.gatherCalledFunctionNames(body, list); for (int i=0; i<list.size(); i++) { XQueryFunction qf = globalFunctionLibrary.getDeclarationByKey((String)list.get(i)); if (!referees.contains(qf)) { // recursive function calls are allowed lookForFunctionCycles(qf, referees, globalFunctionLibrary); } } referees.pop(); }
final String uri = functionName.getNamespaceURI(); if (namespaces.contains(uri)) { Expression call = baseLibrary.bind(functionName, staticArgs, env); if (call != null) { XQueryFunction def = baseLibrary.getDeclaration(functionName, staticArgs); importingModule.checkImportedFunctionSignature(def);
/** * Test whether an extension function with a given name and arity is available. This supports * the function-available() function in XSLT. This method may be called either at compile time * or at run time. If the function library is to be used only in an XQuery or free-standing XPath * environment, this method may throw an UnsupportedOperationException. * * @param functionName the name of the function in question * @param arity The number of arguments. This is set to -1 in the case of the single-argument * function-available() function; in this case the method should return true if there is some */ public boolean isAvailable(StructuredQName functionName, int arity) { return namespaces.contains(functionName.getNamespaceURI()) && baseLibrary.isAvailable(functionName, arity); } }
/** * Fixup all references to global functions. This method is called * on completion of query parsing. Each XQueryFunction is required to * bind all references to that function to the object representing the run-time * executable code of the function. * <p/> * This method is for internal use only. It is called only on the StaticQueryContext for the main * query body (not for library modules). */ public void fixupGlobalFunctions() throws XPathException { globalFunctionLibrary.fixupGlobalFunctions(this); }
/** * Get the function declaration corresponding to a given function name and arity * @return the XQueryFunction if there is one, or null if not. */ public XQueryFunction getDeclaration(StructuredQName functionName, Expression[] staticArgs) { if (namespaces.contains(functionName.getNamespaceURI())) { return baseLibrary.getDeclaration(functionName, staticArgs); } else { return null; } }
/** * Get the function with a given name and arity. This method is provided so that XQuery functions * can be called directly from a Java application. Note that there is no type checking or conversion * of arguments when this is done: the arguments must be provided in exactly the form that the function * signature declares them. * * @param uri the uri of the function name * @param localName the local part of the function name * @param arity the number of arguments. * @return the user-defined function * @since 8.4 */ public UserFunction getUserDefinedFunction(String uri, String localName, int arity) { return globalFunctionLibrary.getUserDefinedFunction(uri, localName, arity); }
return baseLibrary.bind(symbolicName, staticArgs, env, reasons); } else { return null;
private void loadLibraryModule() throws XPathException { if (href==null && moduleURI==null) { // error already reported return; } try { XSLStylesheet top = getPrincipalStylesheet(); QueryModule importedModule = loadModule(); // Do the importing Iterator it = importedModule.getGlobalFunctionLibrary().getFunctionDefinitions(); while (it.hasNext()) { XQueryFunction def = (XQueryFunction)it.next(); // don't import functions transitively if (def.getFunctionName().getNamespaceURI().equals(moduleURI)) { top.declareXQueryFunction(def); } // Note, we are not importing global variables at present } } catch (XPathException err) { compileError(err); } }