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 java.util.Optional;
24 import javax.xml.XMLConstants;
25 import javax.xml.namespace.NamespaceContext;
26 import org.eclipse.jdt.annotation.NonNull;
27 import org.opendaylight.yangtools.yang.common.QName;
28 import org.opendaylight.yangtools.yang.common.QNameModule;
29 import org.opendaylight.yangtools.yang.common.YangConstants;
30 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement;
31 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement.PrefixToEffectiveModuleNamespace;
32 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement.QNameModuleToPrefixNamespace;
34 final class ModuleNamespaceContext implements NamespaceContext {
35 private static final Entry<String, String> YIN_PREFIX_AND_NAMESPACE =
36 new SimpleImmutableEntry<>(XMLConstants.DEFAULT_NS_PREFIX, YangConstants.RFC6020_YIN_NAMESPACE_STRING);
38 private final ListMultimap<@NonNull String, @NonNull String> namespaceToPrefix;
39 private final Map<String, @NonNull ModuleEffectiveStatement> prefixToModule;
40 private final Map<QNameModule, @NonNull String> moduleToPrefix;
42 ModuleNamespaceContext(final ModuleEffectiveStatement module) {
43 this.prefixToModule = requireNonNull(module.getAll(PrefixToEffectiveModuleNamespace.class));
44 this.moduleToPrefix = requireNonNull(module.getAll(QNameModuleToPrefixNamespace.class));
46 final Builder<String, String> namespaces = ImmutableListMultimap.builder();
47 for (Entry<QNameModule, @NonNull String> e : moduleToPrefix.entrySet()) {
48 namespaces.put(e.getKey().getNamespace().toString(), e.getValue());
50 namespaceToPrefix = namespaces.build();
54 public String getNamespaceURI(final String prefix) {
55 checkArgument(prefix != null);
58 case XMLConstants.DEFAULT_NS_PREFIX:
59 return YangConstants.RFC6020_YIN_NAMESPACE_STRING;
60 case XMLConstants.XML_NS_PREFIX:
61 return XMLConstants.XML_NS_URI;
62 case XMLConstants.XMLNS_ATTRIBUTE:
63 return XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
65 final ModuleEffectiveStatement module = prefixToModule.get(prefix);
66 return module != null ? module.localQNameModule().getNamespace().toString()
67 : XMLConstants.NULL_NS_URI;
72 public String getPrefix(final String namespaceURI) {
73 checkArgument(namespaceURI != null);
75 switch (namespaceURI) {
76 case YangConstants.RFC6020_YIN_NAMESPACE_STRING:
77 return XMLConstants.DEFAULT_NS_PREFIX;
78 case XMLConstants.XML_NS_URI:
79 return XMLConstants.XML_NS_PREFIX;
80 case XMLConstants.XMLNS_ATTRIBUTE_NS_URI:
81 return XMLConstants.XMLNS_ATTRIBUTE;
83 final List<@NonNull String> prefixes = namespaceToPrefix.get(namespaceURI);
84 return prefixes.isEmpty() ? null : prefixes.get(0);
89 public Iterator<String> getPrefixes(final String namespaceURI) {
90 checkArgument(namespaceURI != null);
92 switch (namespaceURI) {
93 case YangConstants.RFC6020_YIN_NAMESPACE_STRING:
94 return Iterators.singletonIterator(XMLConstants.DEFAULT_NS_PREFIX);
95 case XMLConstants.XML_NS_URI:
96 return Iterators.singletonIterator(XMLConstants.XML_NS_PREFIX);
97 case XMLConstants.XMLNS_ATTRIBUTE_NS_URI:
98 return Iterators.singletonIterator(XMLConstants.XMLNS_ATTRIBUTE);
100 return namespaceToPrefix.get(namespaceURI).iterator();
104 Entry<String, String> prefixAndNamespaceFor(final QNameModule module) {
105 if (YangConstants.RFC6020_YIN_MODULE.equals(module)) {
106 return YIN_PREFIX_AND_NAMESPACE;
109 final String prefix = moduleToPrefix.get(module);
110 checkArgument(prefix != null, "Module %s does not map to a prefix", module);
111 return new SimpleImmutableEntry<>(prefix, module.getNamespace().toString());
114 Entry<String, String> prefixAndNamespaceForStatement(final QName stmtName) {
115 final Optional<String> prefix = ExportUtils.statementPrefix(moduleToPrefix, stmtName);
116 if (!prefix.isPresent()) {
117 return YIN_PREFIX_AND_NAMESPACE;
120 return new SimpleImmutableEntry<>(prefix.get(), stmtName.getNamespace().toString());
123 Map<String, String> prefixesAndNamespaces() {
124 return Maps.transformValues(prefixToModule, module -> module.localQNameModule().getNamespace().toString());