Introduce EffectiveModelContext 81/81381/3
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 4 Apr 2019 19:42:43 +0000 (21:42 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 4 Apr 2019 20:01:59 +0000 (22:01 +0200)
EffectiveModelContext ties together SchemaNode world, as represented
by SchemaContext and EffectiveStatement world, which does not have
a representation, yet.

Change-Id: I1b1eba4c4030c597151662b2cafefdc841943701
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/EffectiveModelContext.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/EffectiveModelContextProvider.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/SchemaContext.java
yang/yang-parser-api/src/main/java/org/opendaylight/yangtools/yang/model/parser/api/YangParser.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.java
yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/EffectiveSchemaContext.java
yang/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/EffectiveSchemaContextTest.java

diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/EffectiveModelContext.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/EffectiveModelContext.java
new file mode 100644 (file)
index 0000000..92fe78c
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api;
+
+import com.google.common.annotations.Beta;
+import java.util.Map;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement;
+
+/**
+ * {@link EffectiveStatement}-based result of YANG parser compilation. Unlike a SchemaContext, which it extends,
+ * it gives access to individual {@link ModuleEffectiveStatement}s that comprise it.
+ *
+ * @author Robert Varga
+ */
+@Beta
+// FIXME: 4.0.0: evaluate if we still need to extend SchemaContext here
+public interface EffectiveModelContext extends SchemaContext {
+
+    Map<QNameModule, ModuleEffectiveStatement> getModuleStatements();
+}
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/EffectiveModelContextProvider.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/EffectiveModelContextProvider.java
new file mode 100644 (file)
index 0000000..15e6b4b
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api;
+
+import com.google.common.annotations.Beta;
+import org.eclipse.jdt.annotation.NonNull;
+
+/**
+ * A static provider of an {@link EffectiveModelContext}.
+ *
+ * @author Robert Varga
+ */
+@Beta
+public interface EffectiveModelContextProvider extends SchemaContextProvider {
+    /**
+     * Return the {@link EffectiveModelContext} attached to this object.
+     *
+     * @return An EffectiveModelContext instance.
+     */
+    @NonNull EffectiveModelContext getEffectiveModelContext();
+
+    @Override
+    default @NonNull SchemaContext getSchemaContext() {
+        return getEffectiveModelContext();
+    }
+}
index 2147d9bda5b8b9eae1570e0cc9b7078f7fc7038a..4986eca713ee46e1440c4e53511584b5e3242d16 100644 (file)
@@ -31,6 +31,7 @@ import org.opendaylight.yangtools.yang.common.Revision;
  */
 // FIXME: 3.0.0: ContainerSchemaNode is far too broad. A combination of DataNodeContainer, NotificationNodeContainer
 //               and possibly DataSchemaNode would reflect SchemaContext traits better.
+// FIXME: 4.0.0: consider deprecating this class in favor of EffectiveModelContext
 public interface SchemaContext extends ContainerSchemaNode, Immutable {
     /**
      * QName of NETCONF top-level data node.
index d0e5dccd58442be5c9c4f8802f45e631811a6649..bbfb37e77f1d62606a7aa2cae070df4aada1ce7a 100644 (file)
@@ -12,14 +12,13 @@ import com.google.common.collect.SetMultimap;
 import java.io.IOException;
 import java.util.Collection;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation;
 
 /**
@@ -37,14 +36,14 @@ public interface YangParser {
      *
      * @return Enumeration of supported schema source representations.
      */
-    Collection<Class<? extends SchemaSourceRepresentation>> supportedSourceRepresentations();
+    @NonNull Collection<Class<? extends SchemaSourceRepresentation>> supportedSourceRepresentations();
 
     /**
      * Return the set of all YANG statements semantically supported by this parser instance.
      *
      * @return Set of all YANG statements semantically supported by this parser instance.
      */
-    Set<QName> supportedStatements();
+    @NonNull Set<QName> supportedStatements();
 
     /**
      * Add main source. All main sources are present in resulting SchemaContext.
@@ -54,7 +53,7 @@ public interface YangParser {
      * @throws IOException when an IO error occurs
      * @throws IllegalArgumentException if the representation is not supported
      */
-    YangParser addSource(SchemaSourceRepresentation source) throws IOException, YangSyntaxErrorException;
+    @NonNull YangParser addSource(SchemaSourceRepresentation source) throws IOException, YangSyntaxErrorException;
 
     /**
      * Add main sources. All main sources are present in resulting SchemaContext.
@@ -64,7 +63,7 @@ public interface YangParser {
      * @throws IOException when an IO error occurs
      * @throws IllegalArgumentException if the representation is not supported
      */
-    default YangParser addSources(final SchemaSourceRepresentation... sources) throws IOException,
+    default @NonNull YangParser addSources(final SchemaSourceRepresentation... sources) throws IOException,
         YangSyntaxErrorException {
         for (SchemaSourceRepresentation source : sources) {
             addSource(source);
@@ -72,8 +71,8 @@ public interface YangParser {
         return this;
     }
 
-    default YangParser addSources(final Collection<? extends SchemaSourceRepresentation> sources) throws IOException,
-        YangSyntaxErrorException {
+    default @NonNull YangParser addSources(final Collection<? extends SchemaSourceRepresentation> sources)
+            throws IOException, YangSyntaxErrorException {
         for (SchemaSourceRepresentation source : sources) {
             addSource(source);
         }
@@ -94,7 +93,7 @@ public interface YangParser {
      * @throws IOException when an IO error occurs
      * @throws IllegalArgumentException if the representation is not supported
      */
-    default YangParser addLibSources(final SchemaSourceRepresentation... sources) throws IOException,
+    default @NonNull YangParser addLibSources(final SchemaSourceRepresentation... sources) throws IOException,
             YangSyntaxErrorException {
         for (SchemaSourceRepresentation source : sources) {
             addLibSource(source);
@@ -102,7 +101,7 @@ public interface YangParser {
         return this;
     }
 
-    default YangParser addLibSources(final Collection<SchemaSourceRepresentation> sources) throws IOException,
+    default @NonNull YangParser addLibSources(final Collection<SchemaSourceRepresentation> sources) throws IOException,
             YangSyntaxErrorException {
         for (SchemaSourceRepresentation source : sources) {
             addLibSource(source);
@@ -117,7 +116,7 @@ public interface YangParser {
      * @param supportedFeatures Set of supported features in the final SchemaContext. If the set is empty, no features
      *                          encountered will be supported.
      */
-    YangParser setSupportedFeatures(@NonNull Set<QName> supportedFeatures);
+    @NonNull YangParser setSupportedFeatures(@NonNull Set<QName> supportedFeatures);
 
     /**
      * Set YANG modules which can be deviated by specified modules during the parsing process. Map key (QNameModule)
@@ -127,7 +126,7 @@ public interface YangParser {
      *                                 value) in the final SchemaContext. If the map is empty, no deviations encountered
      *                                 will be supported.
      */
-    YangParser setModulesWithSupportedDeviations(
+    @NonNull YangParser setModulesWithSupportedDeviations(
             @NonNull SetMultimap<QNameModule, QNameModule> modulesDeviatedByModules);
 
     /**
@@ -136,7 +135,7 @@ public interface YangParser {
      * @return Ordered collection of declared statements from requested sources.
      * @throws YangSyntaxErrorException When a syntactic error is encountered.
      */
-    List<DeclaredStatement<?>> buildDeclaredModel() throws YangParserException;
+    @NonNull List<DeclaredStatement<?>> buildDeclaredModel() throws YangParserException;
 
     /**
      * Build the effective view of a combined view of effective statements. Note that this representation, unlike
@@ -146,7 +145,7 @@ public interface YangParser {
      * @return Effective module statements indexed by their QNameModule.
      * @throws YangSyntaxErrorException When a syntactic error is encountered.
      */
-    Map<QNameModule, ModuleEffectiveStatement> buildEffectiveModel() throws YangParserException;
+    @NonNull EffectiveModelContext buildEffectiveModel() throws YangParserException;
 
     /**
      * Build effective {@link SchemaContext}.
@@ -154,5 +153,7 @@ public interface YangParser {
      * @return An effective schema context comprised of configured models.
      * @throws YangSyntaxErrorException When a syntactic error is encountered.
      */
-    SchemaContext buildSchemaContext() throws YangParserException;
+    default @NonNull SchemaContext buildSchemaContext() throws YangParserException {
+        return buildEffectiveModel();
+    }
 }
index 8a76c6f1af0711081b2bba7f80a1890be54f29bc..6da2bdda4365e0de18068f3acd668e3e22688516 100644 (file)
@@ -7,24 +7,20 @@
  */
 package org.opendaylight.yangtools.yang.parser.impl;
 
-import static com.google.common.collect.ImmutableMap.toImmutableMap;
 import static java.util.Objects.requireNonNull;
-import static java.util.function.Function.identity;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.SetMultimap;
 import java.io.IOException;
 import java.util.Collection;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 import javax.xml.transform.TransformerException;
+import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.QNameModule;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
-import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.parser.api.YangParser;
 import org.opendaylight.yangtools.yang.model.parser.api.YangParserException;
 import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
@@ -43,9 +39,9 @@ import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementR
 import org.xml.sax.SAXException;
 
 final class YangParserImpl implements YangParser {
-    private static final Collection<Class<? extends SchemaSourceRepresentation>> REPRESENTATIONS = ImmutableList.of(
-        ASTSchemaSource.class, YangTextSchemaSource.class, YinDomSchemaSource.class, YinXmlSchemaSource.class,
-        YinTextSchemaSource.class);
+    private static final @NonNull Collection<Class<? extends SchemaSourceRepresentation>> REPRESENTATIONS =
+            ImmutableList.of(ASTSchemaSource.class, YangTextSchemaSource.class,
+                YinDomSchemaSource.class, YinXmlSchemaSource.class, YinTextSchemaSource.class);
 
     private final BuildAction buildAction;
 
@@ -54,44 +50,45 @@ final class YangParserImpl implements YangParser {
     }
 
     @Override
-    public Collection<Class<? extends SchemaSourceRepresentation>> supportedSourceRepresentations() {
+    public @NonNull Collection<Class<? extends SchemaSourceRepresentation>> supportedSourceRepresentations() {
         return REPRESENTATIONS;
     }
 
     @Override
-    public Set<QName> supportedStatements() {
+    public @NonNull Set<QName> supportedStatements() {
         // TODO Auto-generated method stub
         return null;
     }
 
     @Override
-    public YangParser addSource(final SchemaSourceRepresentation source) throws IOException, YangSyntaxErrorException {
+    public @NonNull YangParser addSource(final SchemaSourceRepresentation source) throws IOException,
+            YangSyntaxErrorException {
         buildAction.addSources(sourceToStatementStream(source));
         return this;
     }
 
     @Override
-    public YangParser addLibSource(final SchemaSourceRepresentation source) throws IOException,
+    public @NonNull YangParser addLibSource(final SchemaSourceRepresentation source) throws IOException,
             YangSyntaxErrorException {
         buildAction.addLibSources(sourceToStatementStream(source));
         return this;
     }
 
     @Override
-    public YangParser setSupportedFeatures(final Set<QName> supportedFeatures) {
+    public @NonNull YangParser setSupportedFeatures(final Set<QName> supportedFeatures) {
         buildAction.setSupportedFeatures(supportedFeatures);
         return this;
     }
 
     @Override
-    public YangParser setModulesWithSupportedDeviations(
+    public @NonNull YangParser setModulesWithSupportedDeviations(
             final SetMultimap<QNameModule, QNameModule> modulesDeviatedByModules) {
         buildAction.setModulesWithSupportedDeviations(modulesDeviatedByModules);
         return this;
     }
 
     @Override
-    public List<DeclaredStatement<?>> buildDeclaredModel() throws YangParserException {
+    public @NonNull List<DeclaredStatement<?>> buildDeclaredModel() throws YangParserException {
         try {
             return buildAction.build().getRootStatements();
         } catch (ReactorException e) {
@@ -100,21 +97,7 @@ final class YangParserImpl implements YangParser {
     }
 
     @Override
-    public Map<QNameModule, ModuleEffectiveStatement> buildEffectiveModel() throws YangParserException {
-        final List<EffectiveStatement<?, ?>> effectiveStatements;
-        try {
-            effectiveStatements = buildAction.buildEffective().getRootEffectiveStatements();
-        } catch (ReactorException e) {
-            throw decodeReactorException(e);
-        }
-
-        return effectiveStatements.stream()
-                .filter(ModuleEffectiveStatement.class::isInstance).map(ModuleEffectiveStatement.class::cast)
-                .collect(toImmutableMap(ModuleEffectiveStatement::localQNameModule, identity()));
-    }
-
-    @Override
-    public SchemaContext buildSchemaContext() throws YangParserException {
+    public @NonNull EffectiveModelContext buildEffectiveModel() throws YangParserException {
         try {
             return buildAction.buildEffective();
         } catch (ReactorException e) {
index 3276981af2c83e49576c22850e52bb4fcee26355..79e81fc6f717bab2cd56d0d254b2f0481922bb61 100644 (file)
@@ -11,25 +11,32 @@ import com.google.common.annotations.Beta;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Verify;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.function.Function;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleStatement;
 import org.opendaylight.yangtools.yang.model.util.SimpleSchemaContext;
 
 @VisibleForTesting
-public final class EffectiveSchemaContext extends SimpleSchemaContext {
+public final class EffectiveSchemaContext extends SimpleSchemaContext implements EffectiveModelContext {
     private final ImmutableList<DeclaredStatement<?>> rootDeclaredStatements;
-    private final ImmutableList<EffectiveStatement<?, ?>> rootEffectiveStatements;
+    private final ImmutableMap<QNameModule, ModuleEffectiveStatement> rootEffectiveStatements;
 
     private EffectiveSchemaContext(final Set<Module> modules, final List<DeclaredStatement<?>> rootDeclaredStatements,
             final List<EffectiveStatement<?, ?>> rootEffectiveStatements) {
         super(modules);
         this.rootDeclaredStatements = ImmutableList.copyOf(rootDeclaredStatements);
-        this.rootEffectiveStatements = ImmutableList.copyOf(rootEffectiveStatements);
+        this.rootEffectiveStatements = rootEffectiveStatements.stream()
+                .filter(ModuleEffectiveStatement.class::isInstance).map(ModuleEffectiveStatement.class::cast)
+                .collect(ImmutableMap.toImmutableMap(ModuleEffectiveStatement::localQNameModule, Function.identity()));
     }
 
     static EffectiveSchemaContext create(final List<DeclaredStatement<?>> rootDeclaredStatements,
@@ -51,7 +58,7 @@ public final class EffectiveSchemaContext extends SimpleSchemaContext {
     }
 
     @Beta
-    public List<EffectiveStatement<?, ?>> getRootEffectiveStatements() {
+    public ImmutableMap<QNameModule, ModuleEffectiveStatement> getModuleStatements() {
         return rootEffectiveStatements;
     }
 }
index 70766bf24b3e2388b3a39bb9e1a77b4946cbdd4f..70fb76b8e8268ef4682f2e58c55f4f1646d3231b 100644 (file)
@@ -98,7 +98,7 @@ public class EffectiveSchemaContextTest {
         Module fooModule = schemaContext.findModule("foo", Revision.of("2016-09-21")).get();
         assertEquals(3, schemaContext.getModules().size());
         assertEquals(3, schemaContext.getRootDeclaredStatements().size());
-        assertEquals(3, schemaContext.getRootEffectiveStatements().size());
+        assertEquals(3, schemaContext.getModuleStatements().size());
 
         final Set<Module> modules = schemaContext.getModules();
         final SchemaContext copiedSchemaContext =  SimpleSchemaContext.forModules(modules);