@Override public final Expr compile(final QueryContext qc, final VarScope scp) throws QueryException { if (root != null) root = root.compile(qc, scp); // no steps if (steps.length == 0) return root == null ? new Context(info) : root; final Value init = qc.value, cv = initial(qc); final boolean doc = cv != null && cv.type == NodeType.DOC; qc.value = cv; try { final int sl = steps.length; for (int s = 0; s < sl; s++) { Expr e = steps[s]; // axis step: if input is a document, its type is temporarily generalized final boolean as = e instanceof Step; if (as && s == 0 && doc) cv.type = NodeType.NOD; e = e.compile(qc, scp); if (e.isEmpty()) return optPre(qc); steps[s] = e; // no axis step: invalidate context value if (!as) qc.value = null; } } finally { if (doc) cv.type = NodeType.DOC; qc.value = init; } // optimize path return optimize(qc, scp); }
/** * Checks if the predicates are successful for the specified item. * * @param it item to be checked * @param qc query context * @return result of check * @throws QueryException query exception */ protected final boolean preds(final Item it, final QueryContext qc) throws QueryException { if (preds.length == 0) return true; // set context value and position final Value cv = qc.value; try { if (qc.scoring) { double s = 0; for (final Expr p : preds) { qc.value = it; final Item i = p.test(qc, info); if (i == null) return false; s += i.score(); } it.score(Scoring.avg(s, preds.length)); } else { for (final Expr p : preds) { qc.value = it; if (p.test(qc, info) == null) return false; } } return true; } finally { qc.value = cv; } }
@Override public final Expr inline(final QueryContext ctx, final VarScope scp, final Var v, final Expr e) throws QueryException { final Value oldVal = ctx.value; try { ctx.value = root(ctx); final Expr rt = root == null ? null : root.inline(ctx, scp, v, e); if (rt != null) { setRoot(ctx, rt); ctx.value = oldVal; ctx.value = root(ctx); } boolean change = rt != null; for (int i = 0; i < steps.length; i++) { final Expr nw = steps[i].inline(ctx, scp, v, e); if (nw != null) { steps[i] = nw; change = true; } } return change ? optimize(ctx, scp) : null; } finally { ctx.value = oldVal; } }
@Override public final Expr compile(final QueryContext ctx, final VarScope scp) throws QueryException { if (root != null) setRoot(ctx, root.compile(ctx, scp)); final Value v = ctx.value; try { ctx.value = root(ctx); return compilePath(ctx, scp); } finally { ctx.value = v; } }
@Override public Expr compile(final QueryContext qc, final VarScope scp) throws QueryException { final Value init = qc.value; // never compile predicates with empty sequence as context value (#1016) if (init != null && init.isEmpty()) qc.value = null; try { final int pl = preds.length; for (int p = 0; p < pl; ++p) preds[p] = preds[p].compile(qc, scp).optimizeEbv(qc, scp); return this; } finally { qc.value = init; } }
@Override Value[] evalArgs(final QueryContext ctx) throws QueryException { final int al = expr.length - 1; final Value[] args = new Value[al]; for (int a = 0; a < al; ++a) args[a] = ctx.value(expr[a]); return args; }
@Override public final Value value(final QueryContext qc) throws QueryException { final int es = exprs.length; final Value[] args = new Value[es]; for (int e = 0; e < es; ++e) args[e] = qc.value(exprs[e]); return toValue(eval(args, qc), qc, sc); }
@Override public Item item(final QueryContext ctx, final InputInfo ii) throws QueryException { Map map = Map.EMPTY; for (int i = 0; i < expr.length; i++) { map = map.insert(checkItem(expr[i], ctx), ctx.value(expr[++i]), ii); } return map; }
@Override public final Expr compile(final QueryContext ctx, final VarScope scp) throws QueryException { // invalidate current context value (will be overwritten by filter) final Value cv = ctx.value; try { root = root.compile(ctx, scp); // return empty root if (root.isEmpty()) return optPre(null, ctx); // convert filters without numeric predicates to axis paths if (root instanceof AxisPath && !super.has(Flag.FCS)) return ((AxisPath) root.copy(ctx, scp)).addPreds(ctx, scp, preds).compile(ctx, scp); // optimize filter expressions ctx.value = null; final Expr e = super.compile(ctx, scp); if (e != this) return e; // no predicates.. return root; otherwise, do some advanced compilations return preds.length == 0 ? root : opt(ctx); } finally { ctx.value = cv; } }
@Override public Value value(final QueryContext ctx) throws QueryException { final ValueBuilder vb = new ValueBuilder(); for (final Expr e : expr) vb.add(ctx.value(e)); return vb.value(); }
@Override public Value value(final QueryContext qc) throws QueryException { final Value val = qc.value(exprs[0]); if (val.isEmpty()) throw ONEORMORE.get(info); return val; }