Package org.exist.xquery.functions.inspect

Source Code of org.exist.xquery.functions.inspect.ModuleFunctions

package org.exist.xquery.functions.inspect;

import org.exist.dom.QName;
import org.exist.security.xacml.AccessContext;
import org.exist.xquery.*;
import org.exist.xquery.functions.fn.FunOnFunctions;
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(), AccessContext.XMLDB);
            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 Exception e) {
                LOG.debug("Failed to import module: " + args[0].getStringValue() + ": " + e.getMessage(), e);
            }
            if (module == null)
                {return Sequence.EMPTY_SEQUENCE;}
            addFunctionRefsFromModule(tempContext, list, module);
        } else {
            addFunctionRefsFromContext(list);
        }
        return list;
    }

    private void addFunctionRefsFromModule(XQueryContext tempContext, ValueSequence resultSeq, Module module) throws XPathException {
        final FunctionSignature signatures[] = module.listFunctions();
        for (final FunctionSignature signature : signatures) {
            if (!signature.isPrivate()) {
                if (module.isInternalModule()) {
                    int arity;
                    if (signature.isOverloaded())
                        {arity = signature.getArgumentTypes().length;}
                    else
                        {arity = signature.getArgumentCount();}
                    final FunctionDef def = ((InternalModule)module).getFunctionDef(signature.getName(), arity);
                    final XQueryAST ast = new XQueryAST();
                    ast.setLine(getLine());
                    ast.setColumn(getColumn());
                    final List<Expression> args = new ArrayList<Expression>(arity);
                    for (int i = 0; i < arity; i++) {
                        args.add(new Function.Placeholder(context));
                    }
                    final Function fn = Function.createFunction(tempContext, ast, def);
                    fn.setArguments(args);
                    final InternalFunctionCall call = new InternalFunctionCall(fn);
                    final FunctionCall ref = FunctionFactory.wrap(tempContext, call);
                    resultSeq.addAll(new FunctionReference(ref));
                } else {
                    final UserDefinedFunction func = ((ExternalModule) module).getFunction(signature.getName(), signature.getArgumentCount(), tempContext);
                    // could be null if private function
                    if (func != null) {
                        // create function reference
                        final FunctionCall funcCall = new FunctionCall(tempContext, func);
                        funcCall.setLocation(getLine(), getColumn());
                        resultSeq.add(new FunctionReference(funcCall));
                    }
                }
            }
        }
    }

    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));
            }
        }
    }
}
TOP

Related Classes of org.exist.xquery.functions.inspect.ModuleFunctions

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.