/** * Finds similar function names and throws an error message. * * @param name function name * @param ii input info * @throws QueryException query exception */ public void funError(final QNm name, final InputInfo ii) throws QueryException { // find global function Functions.get().error(name, ii); // find similar local function final Levenshtein ls = new Levenshtein(); final byte[] nm = lc(name.local()); for (final UserFunc f : funcs) { if (ls.similar(nm, lc(f.name.local()), 0)) { FUNSIMILAR.thrw(ii, name.string(), f.name.string()); } } }
@Override public Item item(final QueryContext qc, final InputInfo ii) throws QueryException { final QNm name = toQNm(exprs[0], qc, sc, false); final long arity = toLong(exprs[1], qc); if (arity < 0 || arity > Integer.MAX_VALUE) throw FUNCUNKNOWN_X.get(ii, name); try { final Expr lit = Functions.getLiteral(name, (int) arity, qc, sc, ii); return lit == null ? null : lit.item(qc, ii); } catch (final QueryException e) { // function not found (in most cases: XPST0017) return null; } }
/** * Returns an instance of a with the specified name and number of arguments, or {@code null}. * * @param name name of the function * @param args optional arguments * @param dyn compile-/run-time flag * @param ctx query context * @param ii input info * @return function instance * @throws QueryException query exception */ public static TypedFunc get( final QNm name, final Expr[] args, final boolean dyn, final QueryContext ctx, final InputInfo ii) throws QueryException { // get namespace and local name // parse data type constructors if (eq(name.uri(), XSURI)) { final byte[] ln = name.local(); final AtomType type = AtomType.find(name, false); if (type == null) { final Levenshtein ls = new Levenshtein(); for (final AtomType t : AtomType.values()) { if (t.par != null && t != AtomType.NOT && t != AtomType.AAT && t != AtomType.BIN && ls.similar(lc(ln), lc(t.string()), 0)) FUNSIMILAR.thrw(ii, name.string(), t.string()); } } // no constructor function found, or abstract type specified if (type == null || type == AtomType.NOT || type == AtomType.AAT) { FUNCUNKNOWN.thrw(ii, name.string()); } if (args.length != 1) FUNCTYPE.thrw(ii, name.string()); final SeqType to = SeqType.get(type, Occ.ZERO_ONE); return TypedFunc.constr(new Cast(ii, args[0], to), to); } // pre-defined functions final StandardFunc fun = Functions.get().get(name, args, ii); if (fun != null) { if (!ctx.sc.xquery3 && fun.xquery3()) FEATURE30.thrw(ii); for (final Function f : Function.UPDATING) { if (fun.sig == f) { ctx.updating(true); break; } } return new TypedFunc(fun, fun.sig.type(args.length)); } // user-defined function final TypedFunc tf = ctx.funcs.get(name, args, ii); if (tf != null) return tf; // Java function (only allowed with administrator permissions) final JavaMapping jf = JavaMapping.get(name, args, ctx, ii); if (jf != null) return TypedFunc.java(jf); // add user-defined function that has not been declared yet if (!dyn && FuncType.find(name) == null) return ctx.funcs.add(name, args, ii, ctx); // no function found return null; }
/** * Returns the specified function. * * @param name name of the function * @param args optional arguments * @param dyn compile-/run-time flag * @param ctx query context * @param ii input info * @return function instance * @throws QueryException query exception */ public TypedFunc get( final QNm name, final Expr[] args, final boolean dyn, final QueryContext ctx, final InputInfo ii) throws QueryException { // find function final byte[] uri = name.uri(); final byte[] ln = name.local(); // parse data type constructors if (eq(uri, XSURI)) { final Type type = AtomType.find(name, true); if (type == null || type == AtomType.NOT || type == AtomType.AAT) { final Levenshtein ls = new Levenshtein(); for (final AtomType t : AtomType.values()) { if (t.par != null && ls.similar(lc(ln), lc(t.string()), 0)) FUNSIMILAR.thrw(ii, name.string(), t.string()); } FUNCUNKNOWN.thrw(ii, name.string()); } if (args.length != 1) FUNCTYPE.thrw(ii, name.string()); final SeqType to = SeqType.get(type, SeqType.Occ.ZO); return TypedFunc.constr(new Cast(ii, args[0], to), to); } // check Java functions - only allowed with administrator permissions if (startsWith(uri, JAVAPRE) && ctx.context.user.perm(User.ADMIN)) { final String c = string(substring(uri, JAVAPRE.length)); // convert dashes to upper-case initials final TokenBuilder tb = new TokenBuilder().add(c).add('.'); boolean dash = false; for (int p = 0; p < ln.length; p += cl(ln, p)) { final int ch = cp(ln, p); if (dash) { tb.add(Character.toUpperCase(ch)); dash = false; } else { dash = ch == '-'; if (!dash) tb.add(ch); } } final String java = tb.toString(); final int i = java.lastIndexOf("."); final Class<?> cls = Reflect.find(java.substring(0, i)); if (cls == null) FUNCJAVA.thrw(ii, java); final String mth = java.substring(i + 1); return TypedFunc.java(new JavaFunc(ii, cls, mth, args)); } // check predefined functions final FuncCall fun = Functions.get().get(ln, uri, args, ctx, ii); if (fun != null) { for (final Function f : Function.UPDATING) { if (fun.def == f) { ctx.updating = true; break; } } return new TypedFunc(fun, fun.def.type(args.length)); } // find local function for (int l = 0; l < func.length; ++l) { final QNm qn = func[l].name; if (eq(ln, qn.local()) && eq(uri, qn.uri()) && args.length == func[l].args.length) return new TypedFunc(add(ii, qn, l, args), FuncType.get(func[l])); } // add function call for function that has not been defined yet if (!dyn && Types.find(name, false) == null) { return new TypedFunc( add(ii, name, add(new UserFunc(ii, name, new Var[args.length], null, false), ii), args), FuncType.arity(args.length)); } return null; }