From: Robert Varga Date: Sat, 22 Feb 2020 08:21:14 +0000 (+0100) Subject: Inject YangParserFactory into SharedSchemaRepository X-Git-Tag: v5.0.0~68 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=refs%2Fchanges%2F01%2F88001%2F2;p=yangtools.git Inject YangParserFactory into SharedSchemaRepository Attempting to access defaultReactor() in OSGi environment trips up the inability to load XPath parser -- as that only works in single classloader. Force users to add parser reference, so that we can go through the proper API. JIRA: YANGTOOLS-1085 Change-Id: I9c1632f07c782234fd00b6f12a9a497d514557cf Signed-off-by: Robert Varga --- diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/SharedSchemaContextFactory.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/SharedSchemaContextFactory.java index 396bd754b6..b5ee5fd53e 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/SharedSchemaContextFactory.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/SharedSchemaContextFactory.java @@ -25,6 +25,7 @@ import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; import com.google.common.util.concurrent.SettableFuture; +import java.io.IOException; import java.util.Collection; import java.util.LinkedHashMap; import java.util.LinkedHashSet; @@ -37,19 +38,19 @@ import org.antlr.v4.runtime.ParserRuleContext; import org.eclipse.jdt.annotation.NonNull; import org.gaul.modernizer_maven_annotations.SuppressModernizer; import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; +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.YangParserFactory; +import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException; import org.opendaylight.yangtools.yang.model.repo.api.EffectiveModelContextFactory; import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactoryConfiguration; -import org.opendaylight.yangtools.yang.model.repo.api.SchemaRepository; import org.opendaylight.yangtools.yang.model.repo.api.SchemaResolutionException; import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier; import org.opendaylight.yangtools.yang.model.repo.api.StatementParserMode; import org.opendaylight.yangtools.yang.parser.antlr.YangStatementParser.StatementContext; -import org.opendaylight.yangtools.yang.parser.impl.DefaultReactors; import org.opendaylight.yangtools.yang.parser.rfc7950.repo.ASTSchemaSource; import org.opendaylight.yangtools.yang.parser.rfc7950.repo.YangModelDependencyInfo; -import org.opendaylight.yangtools.yang.parser.rfc7950.repo.YangStatementStreamSource; import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; -import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor.BuildAction; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -60,11 +61,11 @@ final class SharedSchemaContextFactory implements EffectiveModelContextFactory { .weakValues().build(); private final Cache, EffectiveModelContext> semVerCache = CacheBuilder.newBuilder() .weakValues().build(); - private final @NonNull SchemaRepository repository; + private final @NonNull SharedSchemaRepository repository; private final @NonNull SchemaContextFactoryConfiguration config; - SharedSchemaContextFactory(final @NonNull SchemaRepository repository, - final @NonNull SchemaContextFactoryConfiguration config) { + SharedSchemaContextFactory(final @NonNull SharedSchemaRepository repository, + final @NonNull SchemaContextFactoryConfiguration config) { this.repository = requireNonNull(repository); this.config = requireNonNull(config); } @@ -74,7 +75,7 @@ final class SharedSchemaContextFactory implements EffectiveModelContextFactory { final @NonNull Collection requiredSources) { return createSchemaContext(requiredSources, config.getStatementParserMode() == StatementParserMode.SEMVER_MODE ? semVerCache : revisionCache, - new AssembleSources(config)); + new AssembleSources(repository.factory(), config)); } private @NonNull ListenableFuture createSchemaContext( @@ -188,10 +189,13 @@ final class SharedSchemaContextFactory implements EffectiveModelContextFactory { } private static final class AssembleSources implements AsyncFunction, EffectiveModelContext> { + private final @NonNull YangParserFactory parserFactory; private final @NonNull SchemaContextFactoryConfiguration config; private final @NonNull Function getIdentifier; - private AssembleSources(final @NonNull SchemaContextFactoryConfiguration config) { + private AssembleSources(final @NonNull YangParserFactory parserFactory, + final @NonNull SchemaContextFactoryConfiguration config) { + this.parserFactory = parserFactory; this.config = config; switch (config.getStatementParserMode()) { case SEMVER_MODE: @@ -221,25 +225,28 @@ final class SharedSchemaContextFactory implements EffectiveModelContextFactory { res.getResolvedSources(), res.getUnsatisfiedImports()); } - final BuildAction reactor = DefaultReactors.defaultReactor().newBuild(statementParserMode); - config.getSupportedFeatures().ifPresent(reactor::setSupportedFeatures); - config.getModulesDeviatedByModules().ifPresent(reactor::setModulesWithSupportedDeviations); + final YangParser parser = parserFactory.createParser(statementParserMode); + config.getSupportedFeatures().ifPresent(parser::setSupportedFeatures); + config.getModulesDeviatedByModules().ifPresent(parser::setModulesWithSupportedDeviations); - for (final Entry e : srcs.entrySet()) { - final ASTSchemaSource ast = e.getValue(); + for (final Entry entry : srcs.entrySet()) { + final ASTSchemaSource ast = entry.getValue(); final ParserRuleContext parserRuleCtx = ast.getAST(); checkArgument(parserRuleCtx instanceof StatementContext, "Unsupported context class %s for source %s", - parserRuleCtx.getClass(), e.getKey()); + parserRuleCtx.getClass(), entry.getKey()); - reactor.addSource(YangStatementStreamSource.create(e.getKey(), (StatementContext) parserRuleCtx, - ast.getSymbolicName().orElse(null))); + try { + parser.addSource(entry.getValue()); + } catch (YangSyntaxErrorException | IOException e) { + throw new SchemaResolutionException("Failed to add source " + entry.getKey(), e); + } } final EffectiveModelContext schemaContext; try { - schemaContext = reactor.buildEffective(); - } catch (final ReactorException ex) { - throw new SchemaResolutionException("Failed to resolve required models", ex.getSourceIdentifier(), ex); + schemaContext = parser.buildEffectiveModel(); + } catch (final YangParserException e) { + throw new SchemaResolutionException("Failed to resolve required models", e); } return immediateFluentFuture(schemaContext); diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/SharedSchemaRepository.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/SharedSchemaRepository.java index b25cbeed88..de2d89d1b5 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/SharedSchemaRepository.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/SharedSchemaRepository.java @@ -17,11 +17,13 @@ import org.eclipse.jdt.annotation.NonNull; import org.kohsuke.MetaInfServices; import org.opendaylight.yangtools.concepts.Identifiable; import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.parser.api.YangParserFactory; import org.opendaylight.yangtools.yang.model.repo.api.EffectiveModelContextFactory; import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactoryConfiguration; import org.opendaylight.yangtools.yang.model.repo.api.SchemaRepository; import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier; import org.opendaylight.yangtools.yang.model.repo.util.AbstractSchemaRepository; +import org.opendaylight.yangtools.yang.parser.impl.YangParserFactoryImpl; /** * A {@link SchemaRepository} which allows sharing of {@link SchemaContext} as long as their specification is the same. @@ -42,9 +44,19 @@ public final class SharedSchemaRepository extends AbstractSchemaRepository imple }); private final @NonNull String id; + private final @NonNull YangParserFactory factory; + + public SharedSchemaRepository() { + this("unnamed"); + } public SharedSchemaRepository(final String id) { + this(id, new YangParserFactoryImpl()); + } + + public SharedSchemaRepository(final String id, final YangParserFactory factory) { this.id = requireNonNull(id); + this.factory = requireNonNull(factory); } @Override @@ -58,6 +70,10 @@ public final class SharedSchemaRepository extends AbstractSchemaRepository imple return cacheByConfig.getUnchecked(config); } + @NonNull YangParserFactory factory() { + return factory; + } + @Override public String toString() { return "SchemaRepository: " + id; diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/repo/SchemaContextFactoryDeviationsTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/repo/SchemaContextFactoryDeviationsTest.java index 36ed59ae91..be8ca50946 100644 --- a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/repo/SchemaContextFactoryDeviationsTest.java +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/repo/SchemaContextFactoryDeviationsTest.java @@ -7,11 +7,15 @@ */ package org.opendaylight.yangtools.yang.parser.repo; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.startsWith; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; +import com.google.common.base.Throwables; import com.google.common.collect.ImmutableSetMultimap; import com.google.common.collect.SetMultimap; import com.google.common.util.concurrent.ListenableFuture; @@ -109,15 +113,12 @@ public class SchemaContextFactoryDeviationsTest { public void shouldFailOnAttemptToDeviateTheSameModule2() throws Exception { final ListenableFuture lf = createSchemaContext(null, BAR_INVALID, BAZ_INVALID); assertTrue(lf.isDone()); - try { - lf.get(); - fail("Deviation that targets the same module as the one it is defined is forbidden."); - } catch (final ExecutionException ex) { - final Throwable cause = ex.getCause().getCause().getCause(); - assertTrue(cause instanceof InferenceException); - assertTrue(cause.getMessage() - .startsWith("Deviation must not target the same module as the one it is defined in")); - } + + final ExecutionException ex = assertThrows(ExecutionException.class, lf::get); + final Throwable cause = Throwables.getRootCause(ex); + assertThat(cause, instanceOf(InferenceException.class)); + assertThat(cause.getMessage(), + startsWith("Deviation must not target the same module as the one it is defined in")); } private static SettableSchemaProvider getImmediateYangSourceProviderFromResource(