package org.exist.xquery.functions.inspect; import org.exist.dom.QName; import org.exist.xquery.*; import org.exist.xquery.functions.fn.FunOnFunctions; import org.exist.xquery.functions.fn.LoadXQueryModule; import org.exist.xquery.parser.XQueryAST; import org.exist.xquery.value.*; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class ModuleFunctions extends BasicFunction { public final static FunctionSignature FNS_MODULE_FUNCTIONS_CURRENT = new FunctionSignature( new QName("module-functions", InspectionModule.NAMESPACE_URI, InspectionModule.PREFIX), "Returns a sequence of function items pointing to each public function in the current module.", new SequenceType[] {}, new FunctionReturnSequenceType( Type.FUNCTION_REFERENCE, Cardinality.ZERO_OR_MORE, "Sequence of function items containing all public functions in the current module or the empty sequence " + "if the module is not known in the current context.") ); public final static FunctionSignature FNS_MODULE_FUNCTIONS_OTHER = new FunctionSignature( new QName("module-functions", InspectionModule.NAMESPACE_URI, InspectionModule.PREFIX), "Returns a sequence of function items pointing to each public function in the specified module.", new SequenceType[] { new FunctionParameterSequenceType("location", Type.ANY_URI, Cardinality.EXACTLY_ONE, "The location URI of the module to be loaded.") }, new FunctionReturnSequenceType( Type.FUNCTION_REFERENCE, Cardinality.ZERO_OR_MORE, "Sequence of function items containing all public functions in the module or the empty sequence " + "if the module is not known in the current context.") ); public final static FunctionSignature FNS_MODULE_FUNCTIONS_OTHER_URI = new FunctionSignature( new QName("module-functions-by-uri", InspectionModule.NAMESPACE_URI, InspectionModule.PREFIX), "Returns a sequence of function items pointing to each public function in the specified module.", new SequenceType[] { new FunctionParameterSequenceType("uri", Type.ANY_URI, Cardinality.EXACTLY_ONE, "The URI of the module to be loaded.") }, new FunctionReturnSequenceType( Type.FUNCTION_REFERENCE, Cardinality.ZERO_OR_MORE, "Sequence of function items containing all public functions in the module or the empty sequence " + "if the module is not known in the current context.") ); public ModuleFunctions(XQueryContext context, FunctionSignature signature) { super(context, signature); } @Override public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException { final ValueSequence list = new ValueSequence(); if (getArgumentCount() == 1) { final XQueryContext tempContext = new XQueryContext(context.getBroker().getBrokerPool()); tempContext.setModuleLoadPath(context.getModuleLoadPath()); Module module = null; try { if (isCalledAs("module-functions-by-uri")) { module = tempContext.importModule(args[0].getStringValue(), null, null); } else { module = tempContext.importModule(null, null, args[0].getStringValue()); } } catch (final XPathException e) { LOG.debug("Failed to import module: " + args[0].getStringValue() + ": " + e.getMessage(), e); if (e.getErrorCode().equals(ErrorCodes.XPST0003)) { throw new XPathException(this, e.getMessage()); } } catch (final Exception e) { LOG.debug("Failed to import module: " + args[0].getStringValue() + ": " + e.getMessage(), e); } if (module == null) { return Sequence.EMPTY_SEQUENCE; } LoadXQueryModule.addFunctionRefsFromModule(this, tempContext, list, module); } else { addFunctionRefsFromContext(list); } return list; } private void addFunctionRefsFromContext(ValueSequence resultSeq) throws XPathException { for (final Iterator<UserDefinedFunction> i = context.localFunctions(); i.hasNext(); ) { final UserDefinedFunction f = i.next(); final FunctionCall call = FunOnFunctions.lookupFunction(this, f.getSignature().getName(), f.getSignature().getArgumentCount()); if (call != null) { resultSeq.add(new FunctionReference(call)); } } } }