Clarify ACR API
[lgpl/argeo-commons.git] / org.argeo.api.acr / src / org / argeo / api / acr / RuntimeNamespaceContext.java
index 0941597d749b7887f7dc4227e76e71acd211979c..871275a487c2f310139600720a8c3131ae608af2 100644 (file)
@@ -10,38 +10,50 @@ import javax.xml.XMLConstants;
 import javax.xml.namespace.NamespaceContext;
 
 /**
- * Programmatically defined {@link NamespaceContext}, code contributing
- * namespaces MUST register here with a single default prefix.
+ * Programmatically defined {@link NamespaceContext}, which is valid at runtime
+ * (when the software is running). Code contributing namespaces MUST register
+ * here with a single default prefix, and MUST make sure that stored data
+ * contains the fully qualified namespace URI.</br>
+ * </br>
+ * All environments sharing the classloader of this class MUST use strictly the
+ * same default prefix / namespace mappings, as a static reference to the
+ * mapping is kept.
  */
 public class RuntimeNamespaceContext implements NamespaceContext {
        public final static String XSD_DEFAULT_PREFIX = "xs";
        public final static String XSD_INSTANCE_DEFAULT_PREFIX = "xsi";
 
+       private final static RuntimeNamespaceContext INSTANCE = new RuntimeNamespaceContext();
+
        private NavigableMap<String, String> prefixes = new TreeMap<>();
        private NavigableMap<String, String> namespaces = new TreeMap<>();
 
+       /*
+        * NAMESPACE CONTEXT IMPLEMENTATION
+        */
+
        @Override
-       public String getPrefix(String namespaceURI) {
+       public String getPrefix(String namespaceURI) throws IllegalArgumentException {
                return NamespaceUtils.getPrefix((ns) -> {
                        String prefix = namespaces.get(ns);
                        if (prefix == null)
-                               throw new IllegalStateException("Namespace " + ns + " is not registered.");
+                               throw new IllegalArgumentException("Namespace " + ns + " is not registered.");
                        return prefix;
                }, namespaceURI);
        }
 
        @Override
-       public String getNamespaceURI(String prefix) {
+       public String getNamespaceURI(String prefix) throws IllegalArgumentException {
                return NamespaceUtils.getNamespaceURI((p) -> {
                        String ns = prefixes.get(p);
                        if (ns == null)
-                               throw new IllegalStateException("Prefix " + p + " is not registered.");
+                               throw new IllegalArgumentException("Prefix " + p + " is not registered.");
                        return ns;
                }, prefix);
        }
 
        @Override
-       public Iterator<String> getPrefixes(String namespaceURI) {
+       public Iterator<String> getPrefixes(String namespaceURI) throws IllegalArgumentException {
                return Collections.singleton(getPrefix(namespaceURI)).iterator();
        }
 
@@ -49,47 +61,50 @@ public class RuntimeNamespaceContext implements NamespaceContext {
         * STATIC
         */
 
-       private final static RuntimeNamespaceContext INSTANCE = new RuntimeNamespaceContext();
-
        static {
                // Standard
                register(XMLConstants.XML_NS_URI, XMLConstants.XML_NS_PREFIX);
                register(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, XMLConstants.XMLNS_ATTRIBUTE);
 
                // Common
+               // FIXME shouldn't it be registered externally?
                register(XMLConstants.W3C_XML_SCHEMA_NS_URI, XSD_DEFAULT_PREFIX);
                register(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, XSD_INSTANCE_DEFAULT_PREFIX);
 
                // Argeo specific
-               register(CrName.CR_NAMESPACE_URI, CrName.CR_DEFAULT_PREFIX);
-               register(CrName.LDAP_NAMESPACE_URI, CrName.LDAP_DEFAULT_PREFIX);
-               register(CrName.ROLE_NAMESPACE_URI, CrName.ROLE_DEFAULT_PREFIX);
+               register(ArgeoNamespace.CR_NAMESPACE_URI, ArgeoNamespace.CR_DEFAULT_PREFIX);
+               register(ArgeoNamespace.LDAP_NAMESPACE_URI, ArgeoNamespace.LDAP_DEFAULT_PREFIX);
+               register(ArgeoNamespace.ROLE_NAMESPACE_URI, ArgeoNamespace.ROLE_DEFAULT_PREFIX);
        }
 
+       /** The runtime namespace context instance. */
        public static NamespaceContext getNamespaceContext() {
                return INSTANCE;
        }
 
+       /** The registered prefixes. */
        public static Map<String, String> getPrefixes() {
                return Collections.unmodifiableNavigableMap(INSTANCE.prefixes);
        }
 
-       public synchronized static void register(String namespaceURI, String prefix) {
+       /** Registers a namespace URI / default prefix mapping. */
+       public synchronized static void register(String namespaceURI, String defaultPrefix) {
                NavigableMap<String, String> prefixes = INSTANCE.prefixes;
                NavigableMap<String, String> namespaces = INSTANCE.namespaces;
-               if (prefixes.containsKey(prefix)) {
-                       String ns = prefixes.get(prefix);
+               if (prefixes.containsKey(defaultPrefix)) {
+                       String ns = prefixes.get(defaultPrefix);
                        if (ns.equals(namespaceURI))
                                return; // ignore silently
-                       throw new IllegalStateException("Prefix " + prefix + " is already registered with namespace URI " + ns);
+                       throw new IllegalStateException(
+                                       "Prefix " + defaultPrefix + " is already registered with namespace URI " + ns);
                }
                if (namespaces.containsKey(namespaceURI)) {
                        String p = namespaces.get(namespaceURI);
-                       if (p.equals(prefix))
+                       if (p.equals(defaultPrefix))
                                return; // ignore silently
                        throw new IllegalStateException("Namespace " + namespaceURI + " is already registered with prefix " + p);
                }
-               prefixes.put(prefix, namespaceURI);
-               namespaces.put(namespaceURI, prefix);
+               prefixes.put(defaultPrefix, namespaceURI);
+               namespaces.put(namespaceURI, defaultPrefix);
        }
 }