package org.basex.query.func; import static org.basex.core.Text.*; import static org.basex.query.util.Err.*; import org.basex.core.Prop; import org.basex.core.User; import org.basex.query.QueryContext; import org.basex.query.QueryException; import org.basex.query.expr.Expr; import org.basex.query.item.Item; import org.basex.query.item.QNm; import org.basex.query.item.AtomType; import org.basex.query.item.Str; import org.basex.query.item.Value; import org.basex.query.iter.Iter; import org.basex.query.iter.ItemCache; import org.basex.util.InputInfo; import org.basex.util.Token; import org.basex.util.TokenBuilder; import org.basex.util.Util; /** * Info functions. * * @author BaseX Team 2005-12, BSD License * @author Christian Gruen */ public final class FNInfo extends StandardFunc { /** * Constructor. * @param ii input info * @param f function definition * @param e arguments */ public FNInfo(final InputInfo ii, final Function f, final Expr... e) { super(ii, f, e); } @Override public Iter iter(final QueryContext ctx) throws QueryException { switch(sig) { case ERROR: final int al = expr.length; if(al == 0) FUNERR1.thrw(input); QNm name = FUNERR1.qname(); String msg = FUNERR1.desc; final Item it = expr[0].item(ctx, input); if(it == null) { if(al == 1) XPEMPTY.thrw(input, description()); } else { name = (QNm) checkType(it, AtomType.QNM); } if(al > 1) msg = Token.string(checkEStr(expr[1], ctx)); final Value val = al > 2 ? ctx.value(expr[2]) : null; throw new QueryException(input, name, msg).value(val); case TRACE: return new Iter() { final Iter ir = expr[0].iter(ctx); final byte[] s = checkEStr(expr[1], ctx); @Override public Item next() throws QueryException { final Item i = ir.next(); if(i != null) { final TokenBuilder tb = new TokenBuilder(s); if(s.length != 0) tb.add(COLS); dump(tb.add(i.toString()).toString(), ctx); } return i; } }; case AVAILABLE_ENVIRONMENT_VARIABLES: final ItemCache ic = new ItemCache(); for(final Object k : System.getenv().keySet().toArray()) { ic.add(Str.get(k)); } return ic; default: return super.iter(ctx); } } @Override public Item item(final QueryContext ctx, final InputInfo ii) throws QueryException { switch(sig) { case ENVIRONMENT_VARIABLE: final String e = System.getenv(Token.string(checkEStr(expr[0], ctx))); return e != null ? Str.get(e) : null; default: return super.item(ctx, ii); } } @Override public Expr cmp(final QueryContext ctx) { if(sig == Function.TRACE) type = expr[0].type(); return this; } @Override public boolean isVacuous() { return sig == Function.ERROR; } @Override public boolean uses(final Use u) { return u == Use.X30 && (sig == Function.ENVIRONMENT_VARIABLE || sig == Function.AVAILABLE_ENVIRONMENT_VARIABLES) || u == Use.NDT && (sig == Function.ERROR || sig == Function.TRACE) || super.uses(u); } /** * Dumps the specified info to standard error or the info view of the GUI. * @param info info * @param ctx query context */ static void dump(final String info, final QueryContext ctx) { // if GUI is used, or if user is no admin, trace info is cached if(Prop.gui || !ctx.context.user.perm(User.ADMIN)) { ctx.evalInfo(Token.token(info)); } else { Util.errln(info); } } }