package org.basex.query.expr; import static org.basex.query.util.Err.*; import java.io.IOException; import org.basex.io.serial.Serializer; import org.basex.query.QueryContext; import org.basex.query.QueryException; import org.basex.query.item.AtomType; import org.basex.query.item.Item; import org.basex.query.item.QNm; import org.basex.query.item.Type; import org.basex.query.iter.Iter; import org.basex.query.util.Var; import org.basex.util.InputInfo; import org.basex.util.TokenBuilder; import org.basex.util.XMLToken; /** * Abstract fragment constructor with a QName argument. * * @author BaseX Team 2005-12, BSD License * @author Christian Gruen */ public abstract class CName extends CFrag { /** Description. */ private final String desc; /** QName. */ Expr name; /** * Constructor. * @param d description * @param ii input info * @param n name * @param v attribute values */ CName(final String d, final InputInfo ii, final Expr n, final Expr... v) { super(ii, v); name = n; desc = d; } @Override public CName comp(final QueryContext ctx) throws QueryException { super.comp(ctx); name = checkUp(name, ctx).comp(ctx); return this; } /** * Returns the atomized value of the constructor. * @param ctx query context * @param ii input info * @return resulting value * @throws QueryException query exception */ final byte[] value(final QueryContext ctx, final InputInfo ii) throws QueryException { final TokenBuilder tb = new TokenBuilder(); for(final Expr e : expr) { final Iter ir = ctx.iter(e); boolean m = false; for(Item it; (it = ir.next()) != null;) { if(m) tb.add(' '); tb.add(it.string(ii)); m = true; } } return tb.finish(); } /** * Returns an updated name expression. * @param ctx query context * @param ii input info * @return result * @throws QueryException query exception */ final QNm qname(final QueryContext ctx, final InputInfo ii) throws QueryException { final Item it = checkItem(name, ctx); final Type ip = it.type; if(ip == AtomType.QNM) return (QNm) it; final byte[] str = it.string(ii); if(!XMLToken.isQName(str)) { (ip.isString() || ip.isUntyped() ? INVNAME : INVQNAME).thrw(input, str); } // create and update namespace final QNm nm = new QNm(str, ctx); if(!nm.hasURI() && nm.hasPrefix()) INVPREF.thrw(input, nm); return nm; } @Override public final Expr remove(final Var v) { name = name.remove(v); return super.remove(v); } @Override public final boolean uses(final Use u) { return name.uses(u) || super.uses(u); } @Override public final int count(final Var v) { return name.count(v) + super.count(v); } @Override public final void plan(final Serializer ser) throws IOException { ser.openElement(this); name.plan(ser); for(final Expr e : expr) e.plan(ser); ser.closeElement(); } @Override public final String description() { return info(desc); } @Override public final String toString() { return toString(desc + " { " + name + " }"); } }