584e9ecc70e39ee5f1fec0bb937a8e7f3710087a
[yangtools.git] / yang / yang-common / src / main / java / org / opendaylight / yangtools / yang / common / YangNamespaceContext.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.common;
9
10 import static com.google.common.base.Preconditions.checkArgument;
11 import static com.google.common.base.Preconditions.checkState;
12 import static java.util.Objects.requireNonNull;
13
14 import com.google.common.annotations.Beta;
15 import java.io.Serializable;
16 import java.util.Optional;
17 import org.eclipse.jdt.annotation.NonNull;
18 import org.opendaylight.yangtools.concepts.Immutable;
19
20 /**
21  * Interface for mapping between {@link String} prefixes and {@link QNameModule} namespaces. The conceptual model
22  * matches prefix mapping inside a YANG {@code module} as defined through the use of {@code prefix} and {@code import}
23  * statements and detailed in <a href="https://tools.ietf.org/html/rfc7950#section-7.1.4">RFC7950 Section 7.1.4</a>.
24  *
25  * <p>
26  * Each namespace context can have a default namespace and a set of prefix/namespace mappings. A namespace can be bound
27  * to multiple prefixes at the same time. The default namespace must also have a prefix assigned.
28  *
29  * @author Robert Varga
30  */
31 @Beta
32 public interface YangNamespaceContext extends Immutable, Serializable {
33
34
35
36     /**
37      * Return the default namespace in this context.
38      *
39      * @return Default namespace, if supported.
40      */
41     @NonNull Optional<QNameModule> getDefaultNamespace();
42
43     /**
44      * Return QNameModule to which a particular prefix is bound.
45      *
46      * @param prefix Prefix to look up
47      * @return QNameModule bound to specified prefix
48      * @throws NullPointerException if {@code prefix} is null
49      */
50     @NonNull Optional<QNameModule> findNamespaceForPrefix(String prefix);
51
52     /**
53      * Return a prefix to which a particular QNameModule is bound. If a namespace is bound to multiple prefixes, it is
54      * left unspecified which of those prefixes is returned.
55      *
56      * @param namespace QNameModule to look up
57      * @return Prefix to which the QNameModule is bound
58      * @throws NullPointerException if {@code module} is null
59      */
60     @NonNull Optional<String> findPrefixForNamespace(QNameModule namespace);
61
62     /**
63      * Create a {@link QName} in the default namespace.
64      *
65      * @param localName QName local name
66      * @return A QName.
67      * @throws NullPointerException if {@code localName} is null
68      * @throws IllegalArgumentException if {@code localName} does not conform to local name requirements
69      * @throws IllegalStateException if this context does not have default namespace
70      */
71     default @NonNull QName createQName(final String localName) {
72         final Optional<QNameModule> namespace = getDefaultNamespace();
73         checkState(namespace.isPresent(), "%s does not have a default namespace", this);
74         return QName.create(namespace.get(), requireNonNull(localName));
75     }
76
77     /**
78      * Create a {@link QName} by resolving a prefix against currently-bound prefixes and combining it with specified
79      * local name.
80      *
81      * @param prefix Namespace prefix
82      * @param localName QName local name
83      * @return A QName.
84      * @throws NullPointerException if any argument is null
85      * @throws IllegalArgumentException if {@code localName} does not conform to local name requirements or if the
86      *                                  prefix is not bound in this context.
87      */
88     default @NonNull QName createQName(final String prefix, final String localName) {
89         final Optional<QNameModule> namespace = findNamespaceForPrefix(prefix);
90         checkArgument(namespace.isPresent(), "Prefix %s is not bound", prefix);
91         return QName.create(namespace.get(), localName);
92     }
93 }