2 * Copyright (c) 2018 Pantheon Technologies, s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.yang.model.export;
10 import static com.google.common.base.Preconditions.checkArgument;
11 import static java.util.Objects.requireNonNull;
13 import com.google.common.collect.ImmutableListMultimap;
14 import com.google.common.collect.ImmutableListMultimap.Builder;
15 import com.google.common.collect.Iterators;
16 import com.google.common.collect.ListMultimap;
17 import com.google.common.collect.Maps;
18 import java.util.AbstractMap.SimpleImmutableEntry;
19 import java.util.Iterator;
20 import java.util.List;
22 import java.util.Map.Entry;
23 import javax.xml.XMLConstants;
24 import javax.xml.namespace.NamespaceContext;
25 import org.eclipse.jdt.annotation.NonNull;
26 import org.opendaylight.yangtools.yang.common.QNameModule;
27 import org.opendaylight.yangtools.yang.common.YangConstants;
28 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement;
29 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement.PrefixToEffectiveModuleNamespace;
30 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement.QNameModuleToPrefixNamespace;
32 final class ModuleNamespaceContext implements NamespaceContext {
33 private static final Entry<String, String> YIN_PREFIX_AND_NAMESPACE =
34 new SimpleImmutableEntry<>(XMLConstants.DEFAULT_NS_PREFIX, YangConstants.RFC6020_YIN_NAMESPACE_STRING);
36 private final ListMultimap<@NonNull String, @NonNull String> namespaceToPrefix;
37 private final Map<String, @NonNull ModuleEffectiveStatement> prefixToModule;
38 private final Map<QNameModule, @NonNull String> moduleToPrefix;
40 ModuleNamespaceContext(final ModuleEffectiveStatement module) {
41 this.prefixToModule = requireNonNull(module.getAll(PrefixToEffectiveModuleNamespace.class));
42 this.moduleToPrefix = requireNonNull(module.getAll(QNameModuleToPrefixNamespace.class));
44 final Builder<String, String> namespaces = ImmutableListMultimap.builder();
45 for (Entry<QNameModule, @NonNull String> e : moduleToPrefix.entrySet()) {
46 namespaces.put(e.getKey().getNamespace().toString(), e.getValue());
48 namespaceToPrefix = namespaces.build();
52 public String getNamespaceURI(final String prefix) {
53 checkArgument(prefix != null);
56 case XMLConstants.DEFAULT_NS_PREFIX:
57 return YangConstants.RFC6020_YIN_NAMESPACE_STRING;
58 case XMLConstants.XML_NS_PREFIX:
59 return XMLConstants.XML_NS_URI;
60 case XMLConstants.XMLNS_ATTRIBUTE:
61 return XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
63 final ModuleEffectiveStatement module = prefixToModule.get(prefix);
64 return module != null ? module.localQNameModule().getNamespace().toString()
65 : XMLConstants.NULL_NS_URI;
70 public String getPrefix(final String namespaceURI) {
71 checkArgument(namespaceURI != null);
73 switch (namespaceURI) {
74 case YangConstants.RFC6020_YIN_NAMESPACE_STRING:
75 return XMLConstants.DEFAULT_NS_PREFIX;
76 case XMLConstants.XML_NS_URI:
77 return XMLConstants.XML_NS_PREFIX;
78 case XMLConstants.XMLNS_ATTRIBUTE_NS_URI:
79 return XMLConstants.XMLNS_ATTRIBUTE;
81 final List<@NonNull String> prefixes = namespaceToPrefix.get(namespaceURI);
82 return prefixes.isEmpty() ? null : prefixes.get(0);
87 public Iterator<String> getPrefixes(final String namespaceURI) {
88 checkArgument(namespaceURI != null);
90 switch (namespaceURI) {
91 case YangConstants.RFC6020_YIN_NAMESPACE_STRING:
92 return Iterators.singletonIterator(XMLConstants.DEFAULT_NS_PREFIX);
93 case XMLConstants.XML_NS_URI:
94 return Iterators.singletonIterator(XMLConstants.XML_NS_PREFIX);
95 case XMLConstants.XMLNS_ATTRIBUTE_NS_URI:
96 return Iterators.singletonIterator(XMLConstants.XMLNS_ATTRIBUTE);
98 return namespaceToPrefix.get(namespaceURI).iterator();
102 Entry<String, String> prefixAndNamespaceFor(final QNameModule module) {
103 if (YangConstants.RFC6020_YIN_MODULE.equals(module)) {
104 return YIN_PREFIX_AND_NAMESPACE;
107 final String prefix = moduleToPrefix.get(module);
108 checkArgument(prefix != null, "Module %s does not map to a prefix", module);
109 return new SimpleImmutableEntry<>(prefix, module.getNamespace().toString());
112 Map<String, String> prefixesAndNamespaces() {
113 return Maps.transformValues(prefixToModule, module -> module.localQNameModule().getNamespace().toString());