X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;ds=sidebyside;f=org.argeo.api.acr%2Fsrc%2Forg%2Fargeo%2Fapi%2Facr%2FNamespaceUtils.java;h=e845560b032cc261fb4485e0fdc19b32d3a8456d;hb=9e6715d360fb29bb817ecaf6d49f0c8a3cc014f5;hp=9b5034b559c5692b3ec119f13e2b3ae5eed9c7ef;hpb=4c7e1885b8bf3c93fa0919ace122e3f289a925ea;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 9b5034b55..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 @@ -11,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) == '{') { @@ -27,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(); @@ -40,25 +87,56 @@ public class NamespaceUtils { return prefix + ":" + name.getLocalPart(); } - 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()); - } + /** + * 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(); } - - }; - /** singleton */ - private NamespaceUtils() { } /* - * 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) @@ -70,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) @@ -77,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"); @@ -87,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) @@ -99,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) @@ -108,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) @@ -119,4 +232,8 @@ public class NamespaceUtils { return prefixes.iterator(); } + /** singleton */ + private NamespaceUtils() { + } + }