package net.jhorstmann.i18n.tools.xml; import java.util.Collections; import java.util.Iterator; import java.util.LinkedList; import javax.xml.XMLConstants; import javax.xml.namespace.NamespaceContext; import javax.xml.namespace.QName; import org.xml.sax.SAXException; public final class NamespaceContextImpl implements NamespaceContext { static class PrefixMapping { String prefix; String uri; PrefixMapping(String prefix, String uri) { this.prefix = prefix; this.uri = uri; } } private final LinkedList<PrefixMapping> namespaces = new LinkedList<PrefixMapping>(); public final void startPrefixMapping(String prefix, String uri) throws SAXException { namespaces.addFirst(new PrefixMapping(prefix, uri)); } public final void endPrefixMapping(String prefix) throws SAXException { for (Iterator<PrefixMapping> it=namespaces.iterator(); it.hasNext(); ) { PrefixMapping mapping = it.next(); if (prefix.equals(mapping.prefix)) { it.remove(); return; } } throw new SAXException("End prefix mapping for unknown prefix '" + prefix + "'"); } @Override public final String getNamespaceURI(String prefix) { if (prefix == null) { throw new IllegalArgumentException("Prefix must not be null"); } else if (prefix.equals(XMLConstants.XML_NS_PREFIX)) { return XMLConstants.XML_NS_URI; } else if (prefix.equals(XMLConstants.XMLNS_ATTRIBUTE)) { return XMLConstants.XMLNS_ATTRIBUTE_NS_URI; } else { for (PrefixMapping mapping : namespaces) { if (prefix.equals(mapping.prefix)) { return mapping.uri; } } return XMLConstants.NULL_NS_URI; } } @Override public final String getPrefix(String uri) { if (uri == null) { throw new IllegalArgumentException("URI must not be null"); } else if (uri.equals(XMLConstants.XML_NS_URI)) { return XMLConstants.XML_NS_PREFIX; } else if (uri.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) { return XMLConstants.XMLNS_ATTRIBUTE; } else { for (PrefixMapping mapping : namespaces) { if (uri.equals(mapping.uri)) { return mapping.prefix; } } return null; } } @Override public final Iterator getPrefixes(String uri) { if (uri == null) { throw new IllegalArgumentException("URI must not be null"); } else if (uri.equals(XMLConstants.XML_NS_URI)) { return Collections.singleton(XMLConstants.XML_NS_PREFIX).iterator(); } else if (uri.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) { return Collections.singleton(XMLConstants.XMLNS_ATTRIBUTE).iterator(); } else { LinkedList<String> res = new LinkedList<String>(); for (PrefixMapping mapping : namespaces) { if (uri.equals(mapping.uri)) { res.add(mapping.prefix); } } return Collections.unmodifiableCollection(res).iterator(); } } public final QName resolveQName(String name) { int idx = name.indexOf(':'); if (idx == 0) { throw new IllegalArgumentException("Name must not start with a colon"); } else if (idx < 0) { return new QName(XMLConstants.NULL_NS_URI, name); } else { String prefix = name.substring(0, idx); String localName = name.substring(idx+1); String uri = getNamespaceURI(prefix); return new QName(uri, localName, prefix); } } }