Add a few more utilities to EffectiveModelContext
[yangtools.git] / model / yang-model-api / src / main / java / org / opendaylight / yangtools / yang / model / api / EffectiveModelContext.java
1 /*
2  * Copyright (c) 2019 PANTHEON.tech, 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.api;
9
10 import static com.google.common.base.Verify.verifyNotNull;
11 import static java.util.Objects.requireNonNull;
12
13 import com.google.common.annotations.Beta;
14 import com.google.common.collect.Collections2;
15 import java.util.Collection;
16 import java.util.Map;
17 import java.util.Optional;
18 import org.eclipse.jdt.annotation.NonNull;
19 import org.opendaylight.yangtools.yang.common.QName;
20 import org.opendaylight.yangtools.yang.common.QNameModule;
21 import org.opendaylight.yangtools.yang.common.XMLNamespace;
22 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
23 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement;
24 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier;
25 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement;
26 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeRoot;
27
28 /**
29  * {@link EffectiveStatement}-based result of YANG parser compilation. Unlike a SchemaContext, which it extends,
30  * it gives access to individual {@link ModuleEffectiveStatement}s that comprise it. It also supports resolution of
31  * schema node identifiers via {@link #findSchemaTreeNode(SchemaNodeIdentifier)}.
32  *
33  * @author Robert Varga
34  */
35 @Beta
36 // FIXME: 8.0.0: evaluate if we still need to extend SchemaContext here
37 public interface EffectiveModelContext extends SchemaContext, SchemaTreeRoot {
38
39     @NonNull Map<QNameModule, ModuleEffectiveStatement> getModuleStatements();
40
41     default @NonNull Optional<ModuleEffectiveStatement> findModuleStatement(final QNameModule moduleName) {
42         return Optional.ofNullable(getModuleStatements().get(requireNonNull(moduleName)));
43     }
44
45     default @NonNull Optional<ModuleEffectiveStatement> findModuleStatement(final QName moduleName) {
46         return findModuleStatement(moduleName.getModule());
47     }
48
49     /**
50      * Returns module instances (from the context) with a concrete name. Returned collection is required to have its
51      * iteration order guarantee that the latest revision is encountered first.
52      *
53      * @param name string with the module name
54      * @return set of module instances with specified name.
55      */
56     default @NonNull Collection<@NonNull ModuleEffectiveStatement> findModuleStatements(final String name) {
57         return Collections2.transform(findModules(name), Module::asEffectiveStatement);
58     }
59
60     /**
61      * Returns module instance (from the context) with concrete namespace. Returned collection is required to have its
62      * iteration order guarantee that the latest revision is encountered first.
63      *
64      * @param namespace XMLNamespace instance with specified namespace
65      * @return module instance which has namespace equal to the {@code namespace} or {@code null} in other cases
66      */
67     default @NonNull Collection<@NonNull ModuleEffectiveStatement> findModuleStatements(
68             final XMLNamespace namespace) {
69         return Collections2.transform(findModules(namespace), Module::asEffectiveStatement);
70     }
71
72     default @NonNull ModuleEffectiveStatement getModuleStatement(final QNameModule moduleName) {
73         return verifyNotNull(getModuleStatements().get(requireNonNull(moduleName)));
74     }
75
76     default @NonNull ModuleEffectiveStatement getModuleStatement(final QName moduleName) {
77         return getModuleStatement(moduleName.getModule());
78     }
79
80     /**
81      * {@inheritDoc}
82      *
83      * @implSpec
84      *     Default implementation defers locates the module corresponding to the first element of path and then defers
85      *     to {@link ModuleEffectiveStatement#findSchemaTreeNode(SchemaNodeIdentifier)}.
86      */
87     @Override
88     default Optional<SchemaTreeEffectiveStatement<?>> findSchemaTreeNode(final SchemaNodeIdentifier path) {
89         return findModuleStatement(path.firstNodeIdentifier().getModule())
90             .flatMap(module -> module.findSchemaTreeNode(path));
91     }
92 }