Merge branch 'master' of ../controller
[yangtools.git] / yang / yang-model-api / src / main / java / org / opendaylight / yangtools / yang / model / api / SchemaContext.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. 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.api;
9
10 import static java.util.Objects.requireNonNull;
11
12 import com.google.common.annotations.Beta;
13 import com.google.common.collect.ImmutableSet;
14 import com.google.common.collect.Sets;
15 import java.net.URI;
16 import java.util.Collection;
17 import java.util.Optional;
18 import java.util.Set;
19 import org.eclipse.jdt.annotation.NonNull;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.opendaylight.yangtools.concepts.Immutable;
22 import org.opendaylight.yangtools.yang.common.QName;
23 import org.opendaylight.yangtools.yang.common.QNameModule;
24 import org.opendaylight.yangtools.yang.common.Revision;
25
26 /**
27  * The interface represents static view of compiled yang files,
28  * contains the methods for obtaining all the top level context
29  * data (data from all modules) like YANG notifications, extensions,
30  * operations...
31  * Instances MUST be immutable and thus usage in multi threaded
32  * environment is safe.
33  */
34 // FIXME: 5.0.0: ContainerSchemaNode is far too broad. A combination of DataNodeContainer, NotificationNodeContainer
35 //               and possibly DataSchemaNode would reflect SchemaContext traits better.
36 // FIXME: 5.0.0: consider deprecating this class in favor of EffectiveModelContext
37 public interface SchemaContext extends ContainerSchemaNode, Immutable {
38     /**
39      * QName of NETCONF top-level data node.
40      */
41     @NonNull QName NAME = QName.create(URI.create("urn:ietf:params:xml:ns:netconf:base:1.0"), "data").intern();
42
43     /**
44      * Returns data schema node instances which represents direct subnodes (like
45      * leaf, leaf-list, list, container) in all YANG modules in the context.
46      *
47      * @return set of <code>DataSchemaNode</code> instances which represents
48      *         YANG data nodes at the module top level
49      */
50     Set<DataSchemaNode> getDataDefinitions();
51
52     /**
53      * Returns modules which are part of the schema context. Returned set is required to have its iteration ordered
54      * by module revision, so that if modules are filtered by {@link Module#getName()} or {@link Module#getNamespace()},
55      * modules having the same attribute are encountered newest revision first.
56      *
57      * @return set of the modules which belong to the schema context
58      */
59     Set<Module> getModules();
60
61     /**
62      * Returns rpc definition instances which are defined as the direct
63      * subelements in all YANG modules in the context.
64      *
65      * @return set of <code>RpcDefinition</code> instances which represents
66      *         nodes defined via <code>rpc</code> YANG keyword
67      */
68     Set<RpcDefinition> getOperations();
69
70     /**
71      * Returns extension definition instances which are defined as the direct
72      * subelements in all YANG modules in the context.
73      *
74      * @return set of <code>ExtensionDefinition</code> instances which
75      *         represents nodes defined via <code>extension</code> YANG keyword
76      */
77     Set<ExtensionDefinition> getExtensions();
78
79     /**
80      * Returns the module matching specified {@link QNameModule}, if present.
81      *
82      * @param qnameModule requested QNameModule
83      * @return Module, if present.
84      * @throws NullPointerException if qnameModule is null
85      */
86     Optional<Module> findModule(@NonNull QNameModule qnameModule);
87
88     /**
89      * Returns module instance (from the context) with specified namespace and no revision.
90      *
91      * @param namespace module namespace
92      * @return module instance which has name and revision the same as are the values specified in parameters
93      *         <code>namespace</code> and no revision.
94      */
95     default Optional<Module> findModule(final @NonNull URI namespace) {
96         return findModule(QNameModule.create(namespace));
97     }
98
99     /**
100      * Returns module instance (from the context) with specified namespace and revision.
101      *
102      * @param namespace module namespace
103      * @param revision module revision, may be null
104      * @return module instance which has name and revision the same as are the values specified in parameters
105      *         <code>namespace</code> and <code>revision</code>.
106      */
107     default Optional<Module> findModule(final @NonNull URI namespace, final @Nullable Revision revision) {
108         return findModule(QNameModule.create(namespace, revision));
109     }
110
111     /**
112      * Returns module instance (from the context) with specified namespace and revision.
113      *
114      * @param namespace module namespace
115      * @param revision module revision, may be null
116      * @return module instance which has name and revision the same as are the values specified in parameters
117      *         <code>namespace</code> and <code>revision</code>.
118      */
119     default Optional<Module> findModule(final @NonNull URI namespace, final @NonNull Optional<Revision> revision) {
120         return findModule(QNameModule.create(namespace, revision));
121     }
122
123     /**
124      * Returns module instance (from the context) with specified name and an optional revision.
125      *
126      * @param name
127      *            string with the module name
128      * @param revision
129      *            date of the module revision
130      * @return module instance which has name and revision the same as are the values specified in parameters
131      *                <code>name</code> and <code>revision</code>.
132      */
133     default Optional<Module> findModule(final String name, final Optional<Revision> revision) {
134         return findModules(name).stream().filter(module -> revision.equals(module.getRevision())).findAny();
135     }
136
137     /**
138      * Returns module instance (from the context) with specified name and revision.
139      *
140      * @param name
141      *            string with the module name
142      * @param revision
143      *            date of the module revision, may be null
144      * @return module instance which has name and revision the same as are the values specified in parameters
145      *         <code>name</code> and <code>revision</code>.
146      */
147     default Optional<Module> findModule(final String name, final @Nullable Revision revision) {
148         return findModule(name, Optional.ofNullable(revision));
149     }
150
151     /**
152      * Returns module instance (from the context) with specified name and no revision.
153      *
154      * @param name string with the module name
155      * @return module instance which has name and revision the same as are the values specified in <code>name</code>
156      *                and no revision.
157      * @throws NullPointerException if name is null
158      */
159     default Optional<Module> findModule(final String name) {
160         return findModule(name, Optional.empty());
161     }
162
163     /**
164      * Returns module instances (from the context) with a concrete name. Returned Set is required to have its iteration
165      * order guarantee that the latest revision is encountered first.
166      *
167      * @param name
168      *            string with the module name
169      * @return set of module instances with specified name.
170      */
171     default Set<Module> findModules(final String name) {
172         return Sets.filter(getModules(), m -> name.equals(m.getName()));
173     }
174
175     /**
176      * Returns module instance (from the context) with concrete namespace. Returned Set is required to have its
177      * iteration order guarantee that the latest revision is encountered first.
178      *
179      * @param namespace
180      *            URI instance with specified namespace
181      * @return module instance which has namespace equal to the
182      *         <code>namespace</code> or <code>null</code> in other cases
183      */
184     default Set<Module> findModules(final URI namespace) {
185         return Sets.filter(getModules(), m -> namespace.equals(m.getNamespace()));
186     }
187
188     @Override
189     default Set<ActionDefinition> getActions() {
190         return ImmutableSet.of();
191     }
192
193     @Override
194     default Optional<ActionDefinition> findAction(final QName qname) {
195         requireNonNull(qname);
196         return Optional.empty();
197     }
198
199     @Override
200     default Optional<NotificationDefinition> findNotification(final QName qname) {
201         final Optional<Set<NotificationDefinition>> defs = findModule(qname.getModule()).map(Module::getNotifications);
202         if (defs.isPresent()) {
203             for (NotificationDefinition def : defs.get()) {
204                 if (qname.equals(def.getQName())) {
205                     return Optional.of(def);
206                 }
207             }
208         }
209         return Optional.empty();
210     }
211
212     @Override
213     default Optional<String> getDescription() {
214         return Optional.empty();
215     }
216
217     @Override
218     default Optional<String> getReference() {
219         return Optional.empty();
220     }
221
222     @Override
223     default Collection<MustDefinition> getMustConstraints() {
224         return ImmutableSet.of();
225     }
226
227     @Override
228     default Optional<RevisionAwareXPath> getWhenCondition() {
229         return Optional.empty();
230     }
231
232     @Beta
233     @Override
234     default Optional<DataSchemaNode> findDataTreeChild(final QName name) {
235         return findModule(name.getModule()).flatMap(mod -> mod.findDataTreeChild(name));
236     }
237 }