
net.pincette.xml.NamespacePrefixMap Maven / Gradle / Ivy
package net.pincette.xml;
import static java.util.Collections.singletonList;
import static java.util.stream.Collectors.toMap;
import static javax.xml.XMLConstants.XMLNS_ATTRIBUTE;
import static javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
import static javax.xml.XMLConstants.XML_NS_PREFIX;
import static javax.xml.XMLConstants.XML_NS_URI;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Deque;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Optional;
import java.util.function.Supplier;
import javax.xml.namespace.NamespaceContext;
/**
* This class copes with the fact that the same namespace declarations can be nested and that
* prefixes can be redeclared for other URIs.
*
* @author Werner Donn\u00e9
*/
public class NamespacePrefixMap implements NamespaceContext {
private final Map> namespaceMap = new HashMap<>();
private final Map> prefixMap = new HashMap<>();
private static void map(
final Map> mapping, final String from, final String to) {
mapping.computeIfAbsent(from, k -> new ArrayDeque<>()).push(to);
}
private static void unmap(final Map> mapping, final String from) {
Optional.ofNullable(mapping.get(from))
.ifPresent(
stack -> {
stack.pop();
if (stack.isEmpty()) {
mapping.remove(from);
}
});
}
public void endPrefixMapping(final String prefix) {
Optional.ofNullable(prefixMap.get(prefix))
.ifPresent(
stack -> {
unmap(namespaceMap, stack.peek());
unmap(prefixMap, prefix);
});
}
public Map getCurrentPrefixMap() {
return prefixMap.entrySet().stream()
.collect(
toMap(
Map.Entry::getKey,
e -> Optional.ofNullable(e.getValue()).map(Deque::peek).orElse("")));
}
/**
* Returns the most recent namespace prefix which is associated with uri
or
* null
if there isn't any.
*
* @param uri the given URI.
* @return The prefix.
*/
public String getNamespacePrefix(final String uri) {
if (uri == null || "".equals(uri)) {
throw new IllegalArgumentException();
}
final Supplier attrNsOr =
() ->
XMLNS_ATTRIBUTE_NS_URI.equals(uri)
? XMLNS_ATTRIBUTE
: Optional.ofNullable(namespaceMap.get(uri)).map(Deque::peek).orElse(null);
return XML_NS_URI.equals(uri) ? XML_NS_PREFIX : attrNsOr.get();
}
/** Returns null
if there is no mapping. */
public String getNamespaceURI(final String prefix) {
if (prefix == null) {
throw new IllegalArgumentException();
}
final Supplier attrNsOr =
() ->
XMLNS_ATTRIBUTE.equals(prefix)
? XMLNS_ATTRIBUTE_NS_URI
: Optional.ofNullable(prefixMap.get(prefix)).map(Deque::peek).orElse(null);
return XML_NS_PREFIX.equals(prefix) ? XML_NS_URI : attrNsOr.get();
}
public String getPrefix(final String namespaceURI) {
return getNamespacePrefix(namespaceURI);
}
public Iterator getPrefixes(final String namespaceURI) {
if (namespaceURI == null || "".equals(namespaceURI)) {
throw new IllegalArgumentException();
}
final Supplier> mapOr =
() ->
namespaceMap.get(namespaceURI) != null
? namespaceMap.get(namespaceURI)
: new ArrayList<>();
final Supplier> attrNsOr =
() ->
XMLNS_ATTRIBUTE_NS_URI.equals(namespaceURI)
? singletonList(XMLNS_ATTRIBUTE)
: mapOr.get();
return (XML_NS_URI.equals(namespaceURI) ? singletonList(XML_NS_PREFIX) : attrNsOr.get())
.iterator();
}
public void startPrefixMapping(final String prefix, final String uri) {
map(prefixMap, prefix, uri);
map(namespaceMap, uri, prefix);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy