1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.opencastproject.util;
23
24 import static org.opencastproject.util.EqualsUtil.eq;
25
26 import java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.Collections;
29 import java.util.HashMap;
30 import java.util.Iterator;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.Optional;
34
35 import javax.xml.XMLConstants;
36 import javax.xml.namespace.NamespaceContext;
37
38 public final class XmlNamespaceContext implements NamespaceContext {
39
40 private static final int DEFAULT_BINDINGS = 2;
41
42
43 private final Map<String, String> prefixToUri = new HashMap<String, String>();
44
45
46
47
48
49 public XmlNamespaceContext(Map<String, String> prefixToUri) {
50 this.prefixToUri.putAll(prefixToUri);
51 this.prefixToUri.put(XMLConstants.XML_NS_PREFIX, XMLConstants.XML_NS_URI);
52 this.prefixToUri.put(XMLConstants.XMLNS_ATTRIBUTE, XMLConstants.XMLNS_ATTRIBUTE_NS_URI);
53 }
54
55 public static XmlNamespaceContext mk(Map<String, String> prefixToUri) {
56 return new XmlNamespaceContext(prefixToUri);
57 }
58
59 public static XmlNamespaceContext mk(XmlNamespaceBinding... bindings) {
60 return mk(Arrays.asList(bindings));
61 }
62
63 public static XmlNamespaceContext mk(String prefix, String namespaceUri) {
64 return new XmlNamespaceContext(Collections.singletonMap(prefix, namespaceUri));
65 }
66
67 public static XmlNamespaceContext mk(List<XmlNamespaceBinding> bindings) {
68 Map<String, String> prefixToUri = new HashMap<>();
69 for (XmlNamespaceBinding binding : bindings) {
70 prefixToUri.put(binding.getPrefix(), binding.getNamespaceURI());
71 }
72 return new XmlNamespaceContext(prefixToUri);
73 }
74
75
76 @Override
77 public String getNamespaceURI(String prefix) {
78 return Optional.ofNullable(prefixToUri.get(prefix)).orElse(XMLConstants.NULL_NS_URI);
79 }
80
81 @Override
82 public String getPrefix(String uri) {
83 RequireUtil.notNull(uri, "uri");
84 for (Map.Entry<String, String> entry : prefixToUri.entrySet()) {
85 if (uri.equals(entry.getValue())) {
86 return entry.getKey();
87 }
88 }
89 return null;
90 }
91
92 @Override
93 public Iterator<String> getPrefixes(String uri) {
94 RequireUtil.notNull(uri, "uri");
95 List<String> matchingPrefixes = new ArrayList<>();
96 for (Map.Entry<String, String> entry : prefixToUri.entrySet()) {
97 if (uri.equals(entry.getValue())) {
98 matchingPrefixes.add(entry.getKey());
99 }
100 }
101 return matchingPrefixes.iterator();
102 }
103
104
105 public List<XmlNamespaceBinding> getBindings() {
106 List<XmlNamespaceBinding> bindings = new ArrayList<>();
107 for (Map.Entry<String, String> entry : prefixToUri.entrySet()) {
108 bindings.add(new XmlNamespaceBinding(entry.getKey(), entry.getValue()));
109 }
110 return bindings;
111 }
112
113
114 public XmlNamespaceContext add(XmlNamespaceBinding... bindings) {
115 return add(Arrays.asList(bindings));
116 }
117
118
119 public XmlNamespaceContext add(XmlNamespaceContext binding) {
120 if (binding.prefixToUri.size() == DEFAULT_BINDINGS) {
121 return this;
122 } else {
123 return add(binding.getBindings());
124 }
125 }
126
127 private XmlNamespaceContext add(List<XmlNamespaceBinding> newBindings) {
128 Map<String, String> existingMap = new HashMap<>();
129 for (XmlNamespaceBinding b : getBindings()) {
130 existingMap.put(b.getPrefix(), b.getNamespaceURI());
131 }
132 for (XmlNamespaceBinding b : newBindings) {
133 if (!existingMap.containsKey(b.getPrefix())) {
134 existingMap.put(b.getPrefix(), b.getNamespaceURI());
135 }
136 }
137 return mk(existingMap);
138 }
139
140 public NamespaceContext merge(final NamespaceContext precedence) {
141 return merge(this, precedence);
142 }
143
144
145 public static NamespaceContext merge(final NamespaceContext a, final NamespaceContext b) {
146 return new NamespaceContext() {
147 @Override public String getNamespaceURI(String prefix) {
148 final String uri = b.getNamespaceURI(prefix);
149 if (eq(XMLConstants.DEFAULT_NS_PREFIX, prefix) && eq(XMLConstants.NULL_NS_URI, uri)) {
150 return a.getNamespaceURI(prefix);
151 } else {
152 return uri;
153 }
154 }
155
156 @Override public String getPrefix(final String uri) {
157 return Optional.ofNullable(b.getPrefix(uri))
158 .orElseGet(() -> a.getPrefix(uri));
159 }
160
161 @Override public Iterator getPrefixes(String uri) {
162 final Iterator prefixes = b.getPrefixes(uri);
163 if (prefixes.hasNext()) {
164 return prefixes;
165 } else {
166 return a.getPrefixes(uri);
167 }
168 }
169 };
170 }
171 }