From 862bc29f99617a37daecb59f3c2fa72c40dfa975 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Thu, 4 Apr 2019 21:42:43 +0200 Subject: [PATCH] Introduce EffectiveModelContext 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 --- .../yang/model/api/EffectiveModelContext.java | 27 +++++++++++ .../api/EffectiveModelContextProvider.java | 31 +++++++++++++ .../yang/model/api/SchemaContext.java | 1 + .../yang/model/parser/api/YangParser.java | 31 ++++++------- .../yang/parser/impl/YangParserImpl.java | 45 ++++++------------- .../stmt/reactor/EffectiveSchemaContext.java | 15 +++++-- .../yang/stmt/EffectiveSchemaContextTest.java | 2 +- 7 files changed, 101 insertions(+), 51 deletions(-) create mode 100644 yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/EffectiveModelContext.java create mode 100644 yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/EffectiveModelContextProvider.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 index 0000000000..92fe78c726 --- /dev/null +++ b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/EffectiveModelContext.java @@ -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 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 index 0000000000..15e6b4b933 --- /dev/null +++ b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/EffectiveModelContextProvider.java @@ -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(); + } +} diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/SchemaContext.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/SchemaContext.java index 2147d9bda5..4986eca713 100644 --- a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/SchemaContext.java +++ b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/SchemaContext.java @@ -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. diff --git a/yang/yang-parser-api/src/main/java/org/opendaylight/yangtools/yang/model/parser/api/YangParser.java b/yang/yang-parser-api/src/main/java/org/opendaylight/yangtools/yang/model/parser/api/YangParser.java index d0e5dccd58..bbfb37e77f 100644 --- a/yang/yang-parser-api/src/main/java/org/opendaylight/yangtools/yang/model/parser/api/YangParser.java +++ b/yang/yang-parser-api/src/main/java/org/opendaylight/yangtools/yang/model/parser/api/YangParser.java @@ -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> supportedSourceRepresentations(); + @NonNull Collection> 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 supportedStatements(); + @NonNull Set 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 sources) throws IOException, - YangSyntaxErrorException { + default @NonNull YangParser addSources(final Collection 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 sources) throws IOException, + default @NonNull YangParser addLibSources(final Collection 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 supportedFeatures); + @NonNull YangParser setSupportedFeatures(@NonNull Set 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 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> buildDeclaredModel() throws YangParserException; + @NonNull List> 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 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(); + } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.java index 8a76c6f1af..6da2bdda43 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.java @@ -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> REPRESENTATIONS = ImmutableList.of( - ASTSchemaSource.class, YangTextSchemaSource.class, YinDomSchemaSource.class, YinXmlSchemaSource.class, - YinTextSchemaSource.class); + private static final @NonNull Collection> 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> supportedSourceRepresentations() { + public @NonNull Collection> supportedSourceRepresentations() { return REPRESENTATIONS; } @Override - public Set supportedStatements() { + public @NonNull Set 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 supportedFeatures) { + public @NonNull YangParser setSupportedFeatures(final Set supportedFeatures) { buildAction.setSupportedFeatures(supportedFeatures); return this; } @Override - public YangParser setModulesWithSupportedDeviations( + public @NonNull YangParser setModulesWithSupportedDeviations( final SetMultimap modulesDeviatedByModules) { buildAction.setModulesWithSupportedDeviations(modulesDeviatedByModules); return this; } @Override - public List> buildDeclaredModel() throws YangParserException { + public @NonNull List> buildDeclaredModel() throws YangParserException { try { return buildAction.build().getRootStatements(); } catch (ReactorException e) { @@ -100,21 +97,7 @@ final class YangParserImpl implements YangParser { } @Override - public Map buildEffectiveModel() throws YangParserException { - final List> 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) { diff --git a/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/EffectiveSchemaContext.java b/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/EffectiveSchemaContext.java index 3276981af2..79e81fc6f7 100644 --- a/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/EffectiveSchemaContext.java +++ b/yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/EffectiveSchemaContext.java @@ -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> rootDeclaredStatements; - private final ImmutableList> rootEffectiveStatements; + private final ImmutableMap rootEffectiveStatements; private EffectiveSchemaContext(final Set modules, final List> rootDeclaredStatements, final List> 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> rootDeclaredStatements, @@ -51,7 +58,7 @@ public final class EffectiveSchemaContext extends SimpleSchemaContext { } @Beta - public List> getRootEffectiveStatements() { + public ImmutableMap getModuleStatements() { return rootEffectiveStatements; } } diff --git a/yang/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/EffectiveSchemaContextTest.java b/yang/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/EffectiveSchemaContextTest.java index 70766bf24b..70fb76b8e8 100644 --- a/yang/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/EffectiveSchemaContextTest.java +++ b/yang/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/EffectiveSchemaContextTest.java @@ -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 modules = schemaContext.getModules(); final SchemaContext copiedSchemaContext = SimpleSchemaContext.forModules(modules); -- 2.36.6