package org.basex.query.util; import static org.basex.query.QueryText.*; import static org.basex.query.util.Err.*; import static org.basex.util.Token.*; import org.basex.query.QueryException; import org.basex.util.Atts; import org.basex.util.InputInfo; /** * This class references all statically known namespaces. * * @author BaseX Team 2005-12, BSD License * @author Christian Gruen */ public final class NSContext { /** Static namespaces, containing prefixes and URIs. */ private final Atts ns = new Atts(); /** Dynamically added namespaces. */ private Atts stack; /** * Validates and adds the specified namespace at parsing time. * @param pref namespace prefix * @param uri namespace URI * @param ii input info * @throws QueryException query exception */ public void add(final byte[] pref, final byte[] uri, final InputInfo ii) throws QueryException { if(eq(pref, XML) || eq(pref, XMLNS)) BINDXML.thrw(ii, pref); if(eq(XMLURI, uri)) BINDXMLURI.thrw(ii, uri, XML); if(eq(XMLNSURI, uri)) BINDXMLURI.thrw(ii, uri, XMLNS); ns.add(pref, uri); } /** * Deletes the specified namespace at parsing time. * @param pref namespace prefix */ public void delete(final byte[] pref) { for(int s = ns.size() - 1; s >= 0; s--) { if(eq(pref, ns.name(s))) ns.delete(s); } } /** * Finds the namespace URI for the specified prefix, if it is found * in statically declared namespaces. * @param pref prefix of the namespace * @return uri or {@code null} */ public byte[] staticURI(final byte[] pref) { for(int s = ns.size() - 1; s >= 0; s--) { if(eq(ns.name(s), pref)) return ns.string(s); } return null; } /** * Returns the namespace URI for the specified prefix, if it is either * found in the dynamic, static or predefined namespaces. * @param pref prefix of the namespace * @return namespace URI or {@code null} */ public byte[] uri(final byte[] pref) { if(stack != null) { for(int s = stack.size() - 1; s >= 0; s--) { if(eq(stack.name(s), pref)) return stack.string(s); } } final byte[] uri = staticURI(pref); return uri == null ? NSGlobal.uri(pref) : uri.length == 0 ? null : uri; } /** * Returns the prefix for the specified namespace URI. * Required by the JAXP API. * @param uri namespace URI * @return prefix */ public byte[] prefix(final byte[] uri) { for(int s = ns.size() - 1; s >= 0; s--) { if(eq(ns.string(s), uri)) return ns.name(s); } return NSGlobal.prefix(uri); } /** * Returns all prefixes. Required by the XQJ API. * @return prefixes */ public byte[][] prefixes() { final byte[][] prefs = new byte[ns.size()][]; for(int p = 0; p < prefs.length; ++p) prefs[p] = ns.name(p); return prefs; } /** * Returns the number of dynamic namespaces. * @return namespaces */ public int size() { return stack().size(); } /** * Sets the number of dynamic namespaces. * @param s namespaces */ public void size(final int s) { stack().size(s); } /** * Adds a namespace to the namespace stack. * @param pref namespace prefix * @param uri namespace URI */ public void add(final byte[] pref, final byte[] uri) { stack().add(pref, uri); } /** * Sets the specified stack. * @param s stack to be set */ public void stack(final Atts s) { stack = s; } /** * Resets the stack and returns the old instance. * @return old instance */ public Atts reset() { final Atts s = stack; stack = null; return s; } /** * Returns the namespace stack. * @return stack */ public Atts stack() { if(stack == null) stack = new Atts(); return stack; } }