Populate data/ hierarchy
[yangtools.git] / yang / yang-model-export / src / main / java / org / opendaylight / yangtools / yang / model / export / ModuleNamespaceContext.java
1 /*
2  * Copyright (c) 2018 Pantheon Technologies, s.r.o. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.yangtools.yang.model.export;
9
10 import static com.google.common.base.Preconditions.checkArgument;
11 import static java.util.Objects.requireNonNull;
12
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;
21 import java.util.Map;
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;
31
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);
35
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;
39
40     ModuleNamespaceContext(final ModuleEffectiveStatement module) {
41         this.prefixToModule = requireNonNull(module.getAll(PrefixToEffectiveModuleNamespace.class));
42         this.moduleToPrefix = requireNonNull(module.getAll(QNameModuleToPrefixNamespace.class));
43
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());
47         }
48         namespaceToPrefix = namespaces.build();
49     }
50
51     @Override
52     public String getNamespaceURI(final String prefix) {
53         checkArgument(prefix != null);
54
55         switch (prefix) {
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;
62             default:
63                 final ModuleEffectiveStatement module = prefixToModule.get(prefix);
64                 return module != null ? module.localQNameModule().getNamespace().toString()
65                         : XMLConstants.NULL_NS_URI;
66         }
67     }
68
69     @Override
70     public String getPrefix(final String namespaceURI) {
71         checkArgument(namespaceURI != null);
72
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;
80             default:
81                 final List<@NonNull String> prefixes = namespaceToPrefix.get(namespaceURI);
82                 return prefixes.isEmpty() ? null : prefixes.get(0);
83         }
84     }
85
86     @Override
87     public Iterator<String> getPrefixes(final String namespaceURI) {
88         checkArgument(namespaceURI != null);
89
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);
97             default:
98                 return namespaceToPrefix.get(namespaceURI).iterator();
99         }
100     }
101
102     Entry<String, String> prefixAndNamespaceFor(final QNameModule module) {
103         if (YangConstants.RFC6020_YIN_MODULE.equals(module)) {
104             return YIN_PREFIX_AND_NAMESPACE;
105         }
106
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());
110     }
111
112     Map<String, String> prefixesAndNamespaces() {
113         return Maps.transformValues(prefixToModule, module -> module.localQNameModule().getNamespace().toString());
114     }
115 }