]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.api.acr/src/org/argeo/api/acr/RuntimeNamespaceContext.java
Releasing
[lgpl/argeo-commons.git] / org.argeo.api.acr / src / org / argeo / api / acr / RuntimeNamespaceContext.java
1 package org.argeo.api.acr;
2
3 import java.util.Collections;
4 import java.util.Iterator;
5 import java.util.Map;
6 import java.util.NavigableMap;
7 import java.util.TreeMap;
8
9 import javax.xml.XMLConstants;
10 import javax.xml.namespace.NamespaceContext;
11
12 /**
13 * Programmatically defined {@link NamespaceContext}, which is valid at runtime
14 * (when the software is running). Code contributing namespaces MUST register
15 * here with a single default prefix, and MUST make sure that stored data
16 * contains the fully qualified namespace URI.</br>
17 * </br>
18 * All environments sharing the classloader of this class MUST use strictly the
19 * same default prefix / namespace mappings, as a static reference to the
20 * mapping is kept.
21 */
22 public class RuntimeNamespaceContext implements NamespaceContext {
23 public final static String XSD_DEFAULT_PREFIX = "xs";
24 public final static String XSD_INSTANCE_DEFAULT_PREFIX = "xsi";
25
26 private final static RuntimeNamespaceContext INSTANCE = new RuntimeNamespaceContext();
27
28 private NavigableMap<String, String> prefixes = new TreeMap<>();
29 private NavigableMap<String, String> namespaces = new TreeMap<>();
30
31 /*
32 * NAMESPACE CONTEXT IMPLEMENTATION
33 */
34
35 @Override
36 public String getPrefix(String namespaceURI) throws IllegalArgumentException {
37 return NamespaceUtils.getPrefix((ns) -> {
38 String prefix = namespaces.get(ns);
39 if (prefix == null)
40 throw new IllegalArgumentException("Namespace " + ns + " is not registered.");
41 return prefix;
42 }, namespaceURI);
43 }
44
45 @Override
46 public String getNamespaceURI(String prefix) throws IllegalArgumentException {
47 return NamespaceUtils.getNamespaceURI((p) -> {
48 String ns = prefixes.get(p);
49 if (ns == null)
50 throw new IllegalArgumentException("Prefix " + p + " is not registered.");
51 return ns;
52 }, prefix);
53 }
54
55 @Override
56 public Iterator<String> getPrefixes(String namespaceURI) throws IllegalArgumentException {
57 return Collections.singleton(getPrefix(namespaceURI)).iterator();
58 }
59
60 /*
61 * STATIC
62 */
63
64 static {
65 // Standard
66 register(XMLConstants.XML_NS_URI, XMLConstants.XML_NS_PREFIX);
67 register(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, XMLConstants.XMLNS_ATTRIBUTE);
68
69 // Common
70 // FIXME shouldn't it be registered externally?
71 register(XMLConstants.W3C_XML_SCHEMA_NS_URI, XSD_DEFAULT_PREFIX);
72 register(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, XSD_INSTANCE_DEFAULT_PREFIX);
73
74 // Argeo specific
75 register(ArgeoNamespace.CR_NAMESPACE_URI, ArgeoNamespace.CR_DEFAULT_PREFIX);
76 register(ArgeoNamespace.LDAP_NAMESPACE_URI, ArgeoNamespace.LDAP_DEFAULT_PREFIX);
77 register(ArgeoNamespace.ROLE_NAMESPACE_URI, ArgeoNamespace.ROLE_DEFAULT_PREFIX);
78 }
79
80 /** The runtime namespace context instance. */
81 public static NamespaceContext getNamespaceContext() {
82 return INSTANCE;
83 }
84
85 /** The registered prefixes. */
86 public static Map<String, String> getPrefixes() {
87 return Collections.unmodifiableNavigableMap(INSTANCE.prefixes);
88 }
89
90 /** Registers a namespace URI / default prefix mapping. */
91 public synchronized static void register(String namespaceURI, String defaultPrefix) {
92 NavigableMap<String, String> prefixes = INSTANCE.prefixes;
93 NavigableMap<String, String> namespaces = INSTANCE.namespaces;
94 if (prefixes.containsKey(defaultPrefix)) {
95 String ns = prefixes.get(defaultPrefix);
96 if (ns.equals(namespaceURI))
97 return; // ignore silently
98 throw new IllegalStateException(
99 "Prefix " + defaultPrefix + " is already registered with namespace URI " + ns);
100 }
101 if (namespaces.containsKey(namespaceURI)) {
102 String p = namespaces.get(namespaceURI);
103 if (p.equals(defaultPrefix))
104 return; // ignore silently
105 throw new IllegalStateException("Namespace " + namespaceURI + " is already registered with prefix " + p);
106 }
107 prefixes.put(defaultPrefix, namespaceURI);
108 namespaces.put(namespaceURI, defaultPrefix);
109 }
110 }