X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=org.argeo.api.acr%2Fsrc%2Forg%2Fargeo%2Fapi%2Facr%2FNamespaceUtils.java;h=e845560b032cc261fb4485e0fdc19b32d3a8456d;hb=369abbec35158f11bcca3651c1c3f2f7d6652226;hp=a1b4062aa3e4277e5b47606d81a2d992a1766b7f;hpb=c615307d7b87bcb260d8a9f402c6e0a880862f38;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.api.acr/src/org/argeo/api/acr/NamespaceUtils.java b/org.argeo.api.acr/src/org/argeo/api/acr/NamespaceUtils.java index a1b4062aa..e845560b0 100644 --- a/org.argeo.api.acr/src/org/argeo/api/acr/NamespaceUtils.java +++ b/org.argeo.api.acr/src/org/argeo/api/acr/NamespaceUtils.java @@ -1,6 +1,7 @@ package org.argeo.api.acr; import java.util.Collections; +import java.util.Comparator; import java.util.Iterator; import java.util.Objects; import java.util.Set; @@ -10,8 +11,41 @@ import javax.xml.XMLConstants; import javax.xml.namespace.NamespaceContext; import javax.xml.namespace.QName; +/** Static utilities around namespaces and prefixes. */ public class NamespaceUtils { + /** + * A {@link Comparator} ordering by namespace (full URI) and then local part. + */ + public final static Comparator QNAME_COMPARATOR = new Comparator() { + + @Override + public int compare(QName qn1, QName qn2) { + if (Objects.equals(qn1.getNamespaceURI(), qn2.getNamespaceURI())) {// same namespace + return qn1.getLocalPart().compareTo(qn2.getLocalPart()); + } else { + return qn1.getNamespaceURI().compareTo(qn2.getNamespaceURI()); + } + } + + }; + + /** + * Return a {@link ContentName} from a prefixed name, using the default runtime + * {@link NamespaceContext}. + * + * @see RuntimeNamespaceContext#getNamespaceContext() + */ + public static ContentName parsePrefixedName(String nameWithPrefix) { + return parsePrefixedName(RuntimeNamespaceContext.getNamespaceContext(), nameWithPrefix); + } + /** + * Return a {@link ContentName} from a prefixed name, using the provided + * {@link NamespaceContext}. Since {@link QName#QName(String, String)} does not + * validate, it can conceptually parse a CURIE. + * + * @see https://en.wikipedia.org/wiki/CURIE + */ public static ContentName parsePrefixedName(NamespaceContext nameSpaceContext, String nameWithPrefix) { Objects.requireNonNull(nameWithPrefix, "Name cannot be null"); if (nameWithPrefix.charAt(0) == '{') { @@ -26,10 +60,24 @@ public class NamespaceUtils { String localName = nameWithPrefix.substring(index + 1); String namespaceURI = nameSpaceContext.getNamespaceURI(prefix); if (XMLConstants.NULL_NS_URI.equals(namespaceURI)) - throw new IllegalStateException("Prefix " + prefix + " is unbound."); + throw new IllegalArgumentException("Prefix " + prefix + " is unbound."); return new ContentName(namespaceURI, localName, prefix); } + /** + * The prefixed name of this {@link QName}, using the default runtime + * {@link NamespaceContext}. + * + * @see RuntimeNamespaceContext#getNamespaceContext() + */ + public static String toPrefixedName(QName name) { + return toPrefixedName(RuntimeNamespaceContext.getNamespaceContext(), name); + } + + /** + * The prefixed name of this {@link QName}, using the provided + * {@link NamespaceContext}. + */ public static String toPrefixedName(NamespaceContext nameSpaceContext, QName name) { if (XMLConstants.NULL_NS_URI.equals(name.getNamespaceURI())) return name.getLocalPart(); @@ -39,12 +87,56 @@ public class NamespaceUtils { return prefix + ":" + name.getLocalPart(); } - /** singleton */ - private NamespaceUtils() { + /** + * Whether thei {@link QName} has a namespace, that is its namespace is not + * {@link XMLConstants#NULL_NS_URI}. + */ + public static boolean hasNamespace(QName qName) { + return !qName.getNamespaceURI().equals(XMLConstants.NULL_NS_URI); + } + + /** Throws an exception if the provided string has a prefix. */ + public static void checkNoPrefix(String unqualified) throws IllegalArgumentException { + if (unqualified.indexOf(':') >= 0) + throw new IllegalArgumentException("Name " + unqualified + " has a prefix"); + } + + /** + * Create an unqualified {@link QName}, checking that the argument does not + * contain a prefix. + */ + public static QName unqualified(String name) { + checkNoPrefix(name); + return new ContentName(XMLConstants.NULL_NS_URI, name, XMLConstants.DEFAULT_NS_PREFIX); + + } + + /** + * The common (fully qualified) representation of this name, as defined in + * {@link QName#toString()}. This should be used when a fully qualified + * representation is required, as subclasses of {@link QName} may override the + * {@link QName#toString()} method. + * + * @see ContentName#toString() + */ + public static String toFullyQualified(QName name) { + if (name.getNamespaceURI().equals(XMLConstants.NULL_NS_URI)) { + return name.getLocalPart(); + } else { + return "{" + name.getNamespaceURI() + "}" + name.getLocalPart(); + } + } /* - * DEFAULT NAMESPACE CONTEXT OPERATIONS as specified in NamespaceContext + * STANDARD NAMESPACE CONTEXT OPERATIONS as specified in NamespaceContext + */ + /** + * The standard prefix for well known namespaces as defined in + * {@link NamespaceContext}, or null if the namespace is not well-known. Helper + * method simplifying the implementation of a {@link NamespaceContext}. + * + * @see NamespaceContext#getPrefix(String) */ public static String getStandardPrefix(String namespaceURI) { if (namespaceURI == null) @@ -56,6 +148,13 @@ public class NamespaceUtils { return null; } + /** + * The standard prefixes for well known namespaces as defined in + * {@link NamespaceContext}, or null if the namespace is not well-known. Helper + * method simplifying the implementation of a {@link NamespaceContext}. + * + * @see NamespaceContext#getPrefixes(String) + */ public static Iterator getStandardPrefixes(String namespaceURI) { String prefix = getStandardPrefix(namespaceURI); if (prefix == null) @@ -63,6 +162,13 @@ public class NamespaceUtils { return Collections.singleton(prefix).iterator(); } + /** + * The standard URI for well known prefixes as defined in + * {@link NamespaceContext}, or null if the prefix is not well-known. Helper + * method simplifying the implementation of a {@link NamespaceContext}. + * + * @see NamespaceContext#getNamespaceURI(String) + */ public static String getStandardNamespaceURI(String prefix) { if (prefix == null) throw new IllegalArgumentException("Prefix cannot be null"); @@ -73,6 +179,13 @@ public class NamespaceUtils { return null; } + /** + * The namespace URI for a given prefix, based on the provided mapping and the + * standard prefixes/URIs. + * + * @return the namespace URI for this prefix, or + * {@link XMLConstants#NULL_NS_URI} if unknown. + */ public static String getNamespaceURI(Function mapping, String prefix) { String namespaceURI = NamespaceUtils.getStandardNamespaceURI(prefix); if (namespaceURI != null) @@ -85,6 +198,13 @@ public class NamespaceUtils { return XMLConstants.NULL_NS_URI; } + /** + * The prefix for a given namespace URI, based on the provided mapping and the + * standard prefixes/URIs. + * + * @return the prefix for this namespace URI. What is returned or throws as + * exception if the prefix is not found depdnds on the mapping function. + */ public static String getPrefix(Function mapping, String namespaceURI) { String prefix = NamespaceUtils.getStandardPrefix(namespaceURI); if (prefix != null) @@ -94,6 +214,13 @@ public class NamespaceUtils { return mapping.apply(namespaceURI); } + /** + * The prefixes for a given namespace URI, based on the provided mapping and the + * standard prefixes/URIs. + * + * @return the prefixes for this namespace URI. What is returned or throws as + * exception if the prefix is not found depdnds on the mapping function. + */ public static Iterator getPrefixes(Function> mapping, String namespaceURI) { Iterator standard = NamespaceUtils.getStandardPrefixes(namespaceURI); if (standard != null) @@ -105,4 +232,8 @@ public class NamespaceUtils { return prefixes.iterator(); } + /** singleton */ + private NamespaceUtils() { + } + }