Merge branch 'master' of ../controller
[yangtools.git] / yang / yang-model-util / src / main / java / org / opendaylight / yangtools / yang / model / util / ModuleNameNamespaceContext.java
1 /*
2  * Copyright (c) 2019 Pantheon Technologies, s.r.o.  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.util;
9
10 import static java.util.Objects.requireNonNull;
11
12 import com.google.common.annotations.Beta;
13 import com.google.common.collect.ImmutableBiMap;
14 import com.google.common.collect.ImmutableBiMap.Builder;
15 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
16 import java.util.Optional;
17 import java.util.stream.Collectors;
18 import org.opendaylight.yangtools.yang.common.BiMapYangNamespaceContext;
19 import org.opendaylight.yangtools.yang.common.QNameModule;
20 import org.opendaylight.yangtools.yang.common.YangNamespaceContext;
21 import org.opendaylight.yangtools.yang.model.api.Module;
22 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
23 import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
24
25 /**
26  * Utility {@link YangNamespaceContext} backed by a SchemaContext, resolving namespaces to their module names. This
27  * is useful for implementing namespace resolution according to
28  * <a href="https://tools.ietf.org/html/rfc7951#section-4">RFC7951 Section 4</a>.
29  *
30  * <p>
31  * When multiple revisions of a particular namespace are present in the backing SchemaContext, this ambiguity is
32  * resolved by using the latest revision available.
33  *
34  * @author Robert Varga
35  */
36 @Beta
37 public final class ModuleNameNamespaceContext implements YangNamespaceContext, SchemaContextProvider {
38     private static final long serialVersionUID = 1L;
39
40     @SuppressFBWarnings(value = "SE_BAD_FIELD", justification = "Handled through writeReplace()")
41     private final SchemaContext schemaContext;
42
43     public ModuleNameNamespaceContext(final SchemaContext schemaContext) {
44         this.schemaContext = requireNonNull(schemaContext);
45     }
46
47     /**
48      * Convert this object to an equivalent {@link BiMapYangNamespaceContext}.
49      *
50      * @return A BiMapYangNamespaceContext.
51      */
52     public BiMapYangNamespaceContext toBiMap() {
53         final Builder<String, QNameModule> builder = ImmutableBiMap.builder();
54         for (String name : schemaContext.getModules().stream().map(Module::getName).collect(Collectors.toSet())) {
55             builder.put(name, findNamespaceForPrefix(name).get());
56         }
57         return new BiMapYangNamespaceContext(builder.build());
58     }
59
60     @Override
61     public SchemaContext getSchemaContext() {
62         return schemaContext;
63     }
64
65     @Override
66     public Optional<QNameModule> findNamespaceForPrefix(final String prefix) {
67         return schemaContext.findModules(prefix).stream().findFirst().map(Module::getQNameModule);
68     }
69
70     @Override
71     public Optional<String> findPrefixForNamespace(final QNameModule namespace) {
72         return schemaContext.findModule(namespace).map(Module::getName);
73     }
74
75     private Object writeReplace() {
76         return toBiMap();
77     }
78 }