From a68e74852e09f1af6d93a755088d3c2c0c885a36 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Thu, 20 Feb 2020 14:52:28 +0100 Subject: [PATCH] Require XPath parser implementation in RFC7950 reactors XPath parser is now considered full production ready and our system needs to process XPaths at compile-time. Flip to requiring a parser instance for all RFC7950-based reactors, supplied by ServiceLoader when used in static contexts. JIRA: YANGTOOLS-1085 Change-Id: I32f12d7285bc25c522606cd51f04312ac41a287f Signed-off-by: Robert Varga --- docs/pom.xml | 5 + .../src/main/feature/feature.xml | 1 + .../src/main/feature/feature.xml | 6 + yang/odlext-parser-support/pom.xml | 6 + yang/rfc6241-parser-support/pom.xml | 8 +- yang/rfc6536-parser-support/pom.xml | 8 +- yang/rfc7952-parser-support/pom.xml | 8 +- yang/rfc8040-parser-support/pom.xml | 8 +- yang/rfc8528-parser-support/pom.xml | 8 +- yang/yang-parser-impl/pom.xml | 13 +- .../yang/parser/impl/DefaultReactors.java | 28 ++- .../parser/impl/OSGiYangParserFactory.java | 56 ++++++ .../parser/impl/YangParserFactoryImpl.java | 11 +- .../yang/parser/impl/osgi/Activator.java | 37 ---- .../yang/parser/impl/osgi/package-info.java | 11 -- ...tomCrossSourceStatementReactorBuilder.java | 21 +-- .../rfc7950/reactor/RFC7950Reactors.java | 167 +++++++++--------- .../rfc7950/reactor/ServiceLoaderState.java | 34 ++++ .../parser/rfc7950/stmt/ArgumentUtils.java | 5 - .../parser/rfc7950/stmt/XPathSupport.java | 75 +++----- .../stmt/must/MustStatementSupport.java | 17 +- .../stmt/when/WhenStatementSupport.java | 17 +- yang/yang-xpath-impl/pom.xml | 3 +- .../yangtools/yang/xpath/impl/Activator.java | 30 ---- .../xpath/impl/AntlrXPathParserFactory.java | 20 +++ 25 files changed, 345 insertions(+), 258 deletions(-) create mode 100644 features/odl-yangtools-xpath/src/main/feature/feature.xml create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/OSGiYangParserFactory.java delete mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/osgi/Activator.java delete mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/osgi/package-info.java create mode 100644 yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/reactor/ServiceLoaderState.java delete mode 100644 yang/yang-xpath-impl/src/main/java/org/opendaylight/yangtools/yang/xpath/impl/Activator.java diff --git a/docs/pom.xml b/docs/pom.xml index a56e7acd98..313fa181d2 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -203,6 +203,11 @@ metainf-services provided + + org.osgi + osgi.cmpn + provided + org.osgi org.osgi.core diff --git a/features/odl-yangtools-parser/src/main/feature/feature.xml b/features/odl-yangtools-parser/src/main/feature/feature.xml index 760cd874f5..8f4b841215 100644 --- a/features/odl-yangtools-parser/src/main/feature/feature.xml +++ b/features/odl-yangtools-parser/src/main/feature/feature.xml @@ -2,5 +2,6 @@ odl-antlr4 + scr diff --git a/features/odl-yangtools-xpath/src/main/feature/feature.xml b/features/odl-yangtools-xpath/src/main/feature/feature.xml new file mode 100644 index 0000000000..291ab204d2 --- /dev/null +++ b/features/odl-yangtools-xpath/src/main/feature/feature.xml @@ -0,0 +1,6 @@ + + + + scr + + diff --git a/yang/odlext-parser-support/pom.xml b/yang/odlext-parser-support/pom.xml index f0df632aa1..55be87d852 100644 --- a/yang/odlext-parser-support/pom.xml +++ b/yang/odlext-parser-support/pom.xml @@ -38,6 +38,12 @@ org.opendaylight.yangtools yang-parser-rfc7950 + + + org.opendaylight.yangtools + yang-xpath-impl + test + diff --git a/yang/rfc6241-parser-support/pom.xml b/yang/rfc6241-parser-support/pom.xml index a191ffce26..3986cd563e 100644 --- a/yang/rfc6241-parser-support/pom.xml +++ b/yang/rfc6241-parser-support/pom.xml @@ -31,16 +31,20 @@ org.opendaylight.yangtools yang-common - org.opendaylight.yangtools rfc6241-model-api - org.opendaylight.yangtools yang-parser-rfc7950 + + + org.opendaylight.yangtools + yang-xpath-impl + test + diff --git a/yang/rfc6536-parser-support/pom.xml b/yang/rfc6536-parser-support/pom.xml index cfd2c17116..a63ad7851f 100644 --- a/yang/rfc6536-parser-support/pom.xml +++ b/yang/rfc6536-parser-support/pom.xml @@ -30,16 +30,20 @@ org.opendaylight.yangtools yang-common - org.opendaylight.yangtools rfc6536-model-api - org.opendaylight.yangtools yang-parser-rfc7950 + + + org.opendaylight.yangtools + yang-xpath-impl + test + diff --git a/yang/rfc7952-parser-support/pom.xml b/yang/rfc7952-parser-support/pom.xml index 05872cb297..8367def024 100644 --- a/yang/rfc7952-parser-support/pom.xml +++ b/yang/rfc7952-parser-support/pom.xml @@ -30,16 +30,20 @@ org.opendaylight.yangtools yang-common - org.opendaylight.yangtools rfc7952-model-api - org.opendaylight.yangtools yang-parser-rfc7950 + + + org.opendaylight.yangtools + yang-xpath-impl + test + diff --git a/yang/rfc8040-parser-support/pom.xml b/yang/rfc8040-parser-support/pom.xml index d6619abcbf..912bc345a5 100644 --- a/yang/rfc8040-parser-support/pom.xml +++ b/yang/rfc8040-parser-support/pom.xml @@ -30,16 +30,20 @@ org.opendaylight.yangtools yang-common - org.opendaylight.yangtools rfc8040-model-api - org.opendaylight.yangtools yang-parser-rfc7950 + + + org.opendaylight.yangtools + yang-xpath-impl + test + diff --git a/yang/rfc8528-parser-support/pom.xml b/yang/rfc8528-parser-support/pom.xml index 60703c055b..40ee8fb560 100644 --- a/yang/rfc8528-parser-support/pom.xml +++ b/yang/rfc8528-parser-support/pom.xml @@ -30,16 +30,20 @@ org.opendaylight.yangtools yang-common - org.opendaylight.yangtools rfc8528-model-api - org.opendaylight.yangtools yang-parser-rfc7950 + + + org.opendaylight.yangtools + yang-xpath-impl + test + diff --git a/yang/yang-parser-impl/pom.xml b/yang/yang-parser-impl/pom.xml index 0f830bd923..aea76021c6 100644 --- a/yang/yang-parser-impl/pom.xml +++ b/yang/yang-parser-impl/pom.xml @@ -121,17 +121,19 @@ yang-xpath-impl - - com.google.guava - guava - org.kohsuke.metainf-services metainf-services org.osgi - org.osgi.core + osgi.cmpn + + + javax.inject + javax.inject + provided + true @@ -144,7 +146,6 @@ org.opendaylight.yangtools.yang.parser.impl - org.opendaylight.yangtools.yang.parser.impl.osgi.Activator diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/DefaultReactors.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/DefaultReactors.java index 3bcd1c6107..35249717d0 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/DefaultReactors.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/DefaultReactors.java @@ -25,6 +25,7 @@ import org.opendaylight.yangtools.yang.parser.rfc7950.reactor.RFC7950Reactors; import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase; import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor; import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor.Builder; +import org.opendaylight.yangtools.yang.xpath.api.YangXPathParserFactory; /** * Utility class for instantiating default-configured {@link CrossSourceStatementReactor}s. @@ -33,7 +34,10 @@ import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementR */ @Beta public final class DefaultReactors { - private static final @NonNull CrossSourceStatementReactor DEFAULT_REACTOR = defaultReactorBuilder().build(); + private static final class DefaultReactor { + // Thread-safe lazy init + static final @NonNull CrossSourceStatementReactor INSTANCE = defaultReactorBuilder().build(); + } private DefaultReactors() { // Hidden on purpose @@ -53,7 +57,7 @@ public final class DefaultReactors { * @return a shared default-configured reactor instance. */ public static @NonNull CrossSourceStatementReactor defaultReactor() { - return DEFAULT_REACTOR; + return DefaultReactor.INSTANCE; } /** @@ -62,8 +66,24 @@ public final class DefaultReactors { * * @return A populated CrossSourceStatementReactor builder. */ - public static CustomCrossSourceStatementReactorBuilder defaultReactorBuilder() { - return RFC7950Reactors.defaultReactorBuilder() + public static @NonNull CustomCrossSourceStatementReactorBuilder defaultReactorBuilder() { + return addExtensions(RFC7950Reactors.defaultReactorBuilder()); + } + + /** + * Return a baseline CrossSourceStatementReactor {@link Builder}. The builder is initialized to the equivalent + * of the reactor returned via {@link #defaultReactor()}, but can be further customized before use. + * + * @return A populated CrossSourceStatementReactor builder. + */ + public static @NonNull CustomCrossSourceStatementReactorBuilder defaultReactorBuilder( + final YangXPathParserFactory xpathFactory) { + return addExtensions(RFC7950Reactors.defaultReactorBuilder(xpathFactory)); + } + + private static @NonNull CustomCrossSourceStatementReactorBuilder addExtensions( + final @NonNull CustomCrossSourceStatementReactorBuilder builder) { + return builder // AnyxmlSchemaLocation support .addStatementSupport(ModelProcessingPhase.FULL_DECLARATION, AnyxmlSchemaLocationStatementSupport.getInstance()) diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/OSGiYangParserFactory.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/OSGiYangParserFactory.java new file mode 100644 index 0000000000..3dcb2eb0bb --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/OSGiYangParserFactory.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2020 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.parser.impl; + +import com.google.common.annotations.Beta; +import java.util.Collection; +import org.opendaylight.yangtools.yang.model.parser.api.YangParser; +import org.opendaylight.yangtools.yang.model.parser.api.YangParserFactory; +import org.opendaylight.yangtools.yang.model.repo.api.StatementParserMode; +import org.opendaylight.yangtools.yang.xpath.api.YangXPathParserFactory; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Deactivate; +import org.osgi.service.component.annotations.Reference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Beta +@Component(immediate = true) +// FIXME: merge this with YangParserFactoryImpl once we have OSGi R7, which we really want because field injection is +// a static analysis pain. It also results in not-obvious classes like this one. +public final class OSGiYangParserFactory implements YangParserFactory { + private static final Logger LOG = LoggerFactory.getLogger(OSGiYangParserFactory.class); + + @Reference + YangXPathParserFactory xpathFactory = null; + + private YangParserFactory delegate = null; + + @Activate + void activate() { + delegate = new YangParserFactoryImpl(xpathFactory); + LOG.info("YANG Parser activated"); + } + + @Deactivate + void deactivate() { + LOG.info("YANG Parser deactivated"); + delegate = null; + } + + @Override + public Collection supportedParserModes() { + return delegate.supportedParserModes(); + } + + @Override + public YangParser createParser(final StatementParserMode parserMode) { + return delegate.createParser(parserMode); + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserFactoryImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserFactoryImpl.java index f64fb23d64..7bc003d4e0 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserFactoryImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserFactoryImpl.java @@ -12,12 +12,15 @@ import static java.util.Objects.requireNonNull; import com.google.common.annotations.Beta; import com.google.common.collect.ImmutableList; import java.util.Collection; +import javax.inject.Inject; +import javax.inject.Singleton; import org.eclipse.jdt.annotation.NonNull; import org.kohsuke.MetaInfServices; import org.opendaylight.yangtools.yang.model.parser.api.YangParser; import org.opendaylight.yangtools.yang.model.parser.api.YangParserFactory; import org.opendaylight.yangtools.yang.model.repo.api.StatementParserMode; import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor; +import org.opendaylight.yangtools.yang.xpath.api.YangXPathParserFactory; /** * Reference {@link YangParserFactory} implementation. @@ -26,6 +29,7 @@ import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementR */ @Beta @MetaInfServices +@Singleton public final class YangParserFactoryImpl implements YangParserFactory { private static final ImmutableList SUPPORTED_MODES = ImmutableList.of( StatementParserMode.DEFAULT_MODE, StatementParserMode.SEMVER_MODE); @@ -39,12 +43,17 @@ public final class YangParserFactoryImpl implements YangParserFactory { this(DefaultReactors.defaultReactor()); } + @Inject + public YangParserFactoryImpl(final YangXPathParserFactory xpathFactory) { + this(DefaultReactors.defaultReactorBuilder(xpathFactory).build()); + } + /** * Construct a new {@link YangParserFactory} backed by specified reactor. * * @param reactor Backing reactor */ - public YangParserFactoryImpl(@NonNull final CrossSourceStatementReactor reactor) { + public YangParserFactoryImpl(final @NonNull CrossSourceStatementReactor reactor) { this.reactor = requireNonNull(reactor); } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/osgi/Activator.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/osgi/Activator.java deleted file mode 100644 index c42d0b3b87..0000000000 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/osgi/Activator.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2017 Pantheon Technologies, 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.parser.impl.osgi; - -import org.eclipse.jdt.annotation.NonNull; -import org.opendaylight.yangtools.yang.model.parser.api.YangParserFactory; -import org.opendaylight.yangtools.yang.parser.impl.YangParserFactoryImpl; -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceRegistration; - -/** - * YANG parser implementation activator. Publishes a {@link YangParserFactory} implementation on bundle start. - * - * @author Robert Varga - */ -public final class Activator implements BundleActivator { - private ServiceRegistration<@NonNull YangParserFactory> registration; - - @Override - public void start(final BundleContext context) throws Exception { - registration = context.registerService(YangParserFactory.class, new YangParserFactoryImpl(), null); - } - - @Override - public void stop(final BundleContext context) throws Exception { - if (registration != null) { - registration.unregister(); - registration = null; - } - } -} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/osgi/package-info.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/osgi/package-info.java deleted file mode 100644 index f052302e2b..0000000000 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/osgi/package-info.java +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright (c) 2017 Pantheon Technologies, 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 - */ -/** - * OSGi-specific YANG parser code. Contains activators and similar. - */ -package org.opendaylight.yangtools.yang.parser.impl.osgi; \ No newline at end of file diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/reactor/CustomCrossSourceStatementReactorBuilder.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/reactor/CustomCrossSourceStatementReactorBuilder.java index 44884a2c6d..d9ebbfe8b3 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/reactor/CustomCrossSourceStatementReactorBuilder.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/reactor/CustomCrossSourceStatementReactorBuilder.java @@ -50,31 +50,31 @@ public class CustomCrossSourceStatementReactorBuilder implements Builder stmtSupport) { reactorSupportBundles.get(phase).addSupport(stmtSupport); return this; } - public CustomCrossSourceStatementReactorBuilder overrideStatementSupport(final ModelProcessingPhase phase, + public @NonNull CustomCrossSourceStatementReactorBuilder overrideStatementSupport(final ModelProcessingPhase phase, final StatementSupport stmtSupport) { reactorSupportBundles.get(phase).overrideSupport(stmtSupport); return this; } - public CustomCrossSourceStatementReactorBuilder addNamespaceSupport(final ModelProcessingPhase phase, + public @NonNull CustomCrossSourceStatementReactorBuilder addNamespaceSupport(final ModelProcessingPhase phase, final NamespaceBehaviour namespaceSupport) { reactorSupportBundles.get(phase).addSupport(namespaceSupport); return this; } - public CustomCrossSourceStatementReactorBuilder addValidationBundle(final ValidationBundleType validationBundleType, - final Collection validationBundle) { + public @NonNull CustomCrossSourceStatementReactorBuilder addValidationBundle( + final ValidationBundleType validationBundleType, final Collection validationBundle) { reactorValidationBundles.put(validationBundleType, validationBundle); return this; } - public CustomCrossSourceStatementReactorBuilder addAllSupports(final ModelProcessingPhase phase, + public @NonNull CustomCrossSourceStatementReactorBuilder addAllSupports(final ModelProcessingPhase phase, final StatementSupportBundle stmtSupportBundle) { addAllCommonStatementSupports(phase, stmtSupportBundle.getCommonDefinitions().values()); addAllVersionSpecificSupports(phase, stmtSupportBundle.getAllVersionSpecificDefinitions()); @@ -82,7 +82,7 @@ public class CustomCrossSourceStatementReactorBuilder implements Builder> namespaceSupports) { final StatementSupportBundle.Builder stmtBundleBuilder = reactorSupportBundles.get(phase); for (final NamespaceBehaviour namespaceSupport : namespaceSupports) { @@ -91,8 +91,8 @@ public class CustomCrossSourceStatementReactorBuilder implements Builder> statementSupports) { + public @NonNull CustomCrossSourceStatementReactorBuilder addAllCommonStatementSupports( + final ModelProcessingPhase phase, final Collection> statementSupports) { final StatementSupportBundle.Builder stmtBundleBuilder = reactorSupportBundles.get(phase); for (final StatementSupport statementSupport : statementSupports) { stmtBundleBuilder.addSupport(statementSupport); @@ -100,7 +100,8 @@ public class CustomCrossSourceStatementReactorBuilder implements Builder> versionSpecificSupports) { final StatementSupportBundle.Builder stmtBundleBuilder = reactorSupportBundles.get(phase); for (final Cell> cell : versionSpecificSupports.cellSet()) { diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/reactor/RFC7950Reactors.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/reactor/RFC7950Reactors.java index 202bb16358..7c7cea8b7c 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/reactor/RFC7950Reactors.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/reactor/RFC7950Reactors.java @@ -11,17 +11,15 @@ import static org.opendaylight.yangtools.yang.common.YangVersion.VERSION_1; import static org.opendaylight.yangtools.yang.common.YangVersion.VERSION_1_1; import com.google.common.annotations.Beta; -import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; -import java.util.Collection; -import java.util.Map; +import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.yangtools.yang.common.YangVersion; -import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition; import org.opendaylight.yangtools.yang.parser.openconfig.stmt.OpenConfigVersionSupport; import org.opendaylight.yangtools.yang.parser.rfc7950.namespace.ChildSchemaNodeNamespace; import org.opendaylight.yangtools.yang.parser.rfc7950.namespace.ModuleQNameToPrefix; import org.opendaylight.yangtools.yang.parser.rfc7950.namespace.URIStringToImportPrefix; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.XPathSupport; import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.action.ActionStatementSupport; import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.anydata.AnydataStatementSupport; import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.anyxml.AnyxmlStatementSupport; @@ -149,6 +147,7 @@ import org.opendaylight.yangtools.yang.parser.spi.source.SupportedFeaturesNamesp import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace; import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace.ValidationBundleType; import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor; +import org.opendaylight.yangtools.yang.xpath.api.YangXPathParserFactory; /** * Utility class holding entrypoints for assembling RFC6020/RFC7950 statement {@link CrossSourceStatementReactor}s. @@ -262,68 +261,6 @@ public final class RFC7950Reactors { .addSupport(StatementDefinitionNamespace.BEHAVIOUR) .build(); - private static final StatementSupportBundle FULL_DECL_BUNDLE = StatementSupportBundle - .derivedFrom(STMT_DEF_BUNDLE) - .addSupport(LeafStatementSupport.getInstance()) - .addSupport(ConfigStatementSupport.getInstance()) - .addSupport(DeviationStatementSupport.getInstance()) - .addVersionSpecificSupport(VERSION_1, DeviateStatementRFC6020Support.getInstance()) - .addVersionSpecificSupport(VERSION_1_1, DeviateStatementRFC7950Support.getInstance()) - .addVersionSpecificSupport(VERSION_1, ChoiceStatementRFC6020Support.getInstance()) - .addVersionSpecificSupport(VERSION_1_1, ChoiceStatementRFC7950Support.getInstance()) - .addVersionSpecificSupport(VERSION_1, CaseStatementRFC6020Support.getInstance()) - .addVersionSpecificSupport(VERSION_1_1, CaseStatementRFC7950Support.getInstance()) - .addSupport(MustStatementSupport.getInstance()) - .addSupport(MandatoryStatementSupport.getInstance()) - .addSupport(AnyxmlStatementSupport.getInstance()) - .addVersionSpecificSupport(VERSION_1_1, AnydataStatementSupport.getInstance()) - .addSupport(FeatureNamespace.BEHAVIOUR) - .addSupport(IfFeatureStatementSupport.getInstance()) - .addSupport(UsesStatementSupport.getInstance()) - .addSupport(GroupingNamespace.BEHAVIOUR) - .addSupport(ErrorMessageStatementSupport.getInstance()) - .addSupport(ErrorAppTagStatementSupport.getInstance()) - .addVersionSpecificSupport(VERSION_1, LeafListStatementRFC6020Support.getInstance()) - .addVersionSpecificSupport(VERSION_1_1, LeafListStatementRFC7950Support.getInstance()) - .addSupport(PresenceStatementSupport.getInstance()) - .addSupport(MaxElementsStatementSupport.getInstance()) - .addSupport(MinElementsStatementSupport.getInstance()) - .addSupport(OrderedByStatementSupport.getInstance()) - .addSupport(WhenStatementSupport.getInstance()) - .addSupport(AugmentImplicitHandlingNamespace.BEHAVIOUR) - .addVersionSpecificSupport(VERSION_1, AugmentStatementRFC6020Support.getInstance()) - .addVersionSpecificSupport(VERSION_1_1, AugmentStatementRFC7950Support.getInstance()) - .addVersionSpecificSupport(VERSION_1, RefineStatementRFC6020Support.getInstance()) - .addVersionSpecificSupport(VERSION_1_1, RefineStatementRFC7950Support.getInstance()) - .addSupport(FeatureStatementSupport.getInstance()) - .addSupport(PositionStatementSupport.getInstance()) - .addSupport(ValueStatementSupport.getInstance()) - .build(); - - private static final Map RFC7950_BUNDLES = - ImmutableMap.builder() - .put(ModelProcessingPhase.INIT, INIT_BUNDLE) - .put(ModelProcessingPhase.SOURCE_PRE_LINKAGE, PRE_LINKAGE_BUNDLE) - .put(ModelProcessingPhase.SOURCE_LINKAGE, LINKAGE_BUNDLE) - .put(ModelProcessingPhase.STATEMENT_DEFINITION, STMT_DEF_BUNDLE) - .put(ModelProcessingPhase.FULL_DECLARATION, FULL_DECL_BUNDLE) - .put(ModelProcessingPhase.EFFECTIVE_MODEL, FULL_DECL_BUNDLE) - .build(); - - private static final Map> RFC6020_VALIDATION_BUNDLE = - ImmutableMap.>builder() - .put(ValidationBundleType.SUPPORTED_REFINE_SUBSTATEMENTS, - YangValidationBundles.SUPPORTED_REFINE_SUBSTATEMENTS) - .put(ValidationBundleType.SUPPORTED_AUGMENT_TARGETS, YangValidationBundles.SUPPORTED_AUGMENT_TARGETS) - - // FIXME: 5.0.0: we do not seem to need this validation bundle - .put(ValidationBundleType.SUPPORTED_CASE_SHORTHANDS, YangValidationBundles.SUPPORTED_CASE_SHORTHANDS) - - .put(ValidationBundleType.SUPPORTED_DATA_NODES, YangValidationBundles.SUPPORTED_DATA_NODES) - .build(); - - private static final CrossSourceStatementReactor DEFAULT_RFC6020_RFC7950_REACTOR = defaultReactorBuilder().build(); - private static final CrossSourceStatementReactor VANILLA_RFC6020_RFC7950_REACTOR = vanillaReactorBuilder().build(); private RFC7950Reactors() { // Hidden on purpose @@ -336,8 +273,8 @@ public final class RFC7950Reactors { * * @return A shared reactor instance. */ - public static CrossSourceStatementReactor defaultReactor() { - return DEFAULT_RFC6020_RFC7950_REACTOR; + public static @NonNull CrossSourceStatementReactor defaultReactor() { + return ServiceLoaderState.DefaultReactor.INSTANCE; } /** @@ -346,8 +283,18 @@ public final class RFC7950Reactors { * * @return A new {@link CustomCrossSourceStatementReactorBuilder}. */ - public static CustomCrossSourceStatementReactorBuilder defaultReactorBuilder() { - return vanillaReactorBuilder() + public static @NonNull CustomCrossSourceStatementReactorBuilder defaultReactorBuilder() { + return addExtensions(vanillaReactorBuilder()); + } + + public static @NonNull CustomCrossSourceStatementReactorBuilder defaultReactorBuilder( + final YangXPathParserFactory xpathFactory) { + return addExtensions(vanillaReactorBuilder(xpathFactory)); + } + + private static @NonNull CustomCrossSourceStatementReactorBuilder addExtensions( + final @NonNull CustomCrossSourceStatementReactorBuilder builder) { + return builder // Semantic version support .addStatementSupport(ModelProcessingPhase.SOURCE_LINKAGE, OpenConfigVersionSupport.getInstance()) .addNamespaceSupport(ModelProcessingPhase.SOURCE_LINKAGE, SemanticVersionNamespace.BEHAVIOUR) @@ -363,8 +310,8 @@ public final class RFC7950Reactors { * * @return A shared reactor instance. */ - public static CrossSourceStatementReactor vanillaReactor() { - return VANILLA_RFC6020_RFC7950_REACTOR; + public static @NonNull CrossSourceStatementReactor vanillaReactor() { + return ServiceLoaderState.VanillaReactor.INSTANCE; } /** @@ -373,15 +320,75 @@ public final class RFC7950Reactors { * * @return A new {@link CustomCrossSourceStatementReactorBuilder}. */ - public static CustomCrossSourceStatementReactorBuilder vanillaReactorBuilder() { - return addDefaultRFC7950Bundles(new CustomCrossSourceStatementReactorBuilder(SUPPORTED_VERSIONS)); + public static @NonNull CustomCrossSourceStatementReactorBuilder vanillaReactorBuilder() { + return vanillaReactorBuilder(ServiceLoaderState.XPath.INSTANCE); + } + + public static @NonNull CustomCrossSourceStatementReactorBuilder vanillaReactorBuilder( + final @NonNull YangXPathParserFactory xpathFactory) { + return vanillaReactorBuilder(new XPathSupport(xpathFactory)); } - private static CustomCrossSourceStatementReactorBuilder addDefaultRFC7950Bundles( - final CustomCrossSourceStatementReactorBuilder builder) { - RFC7950_BUNDLES.entrySet().forEach(entry -> builder.addAllSupports(entry.getKey(), entry.getValue())); - RFC6020_VALIDATION_BUNDLE.entrySet().forEach( - entry -> builder.addValidationBundle(entry.getKey(), entry.getValue())); - return builder; + private static @NonNull CustomCrossSourceStatementReactorBuilder vanillaReactorBuilder( + final @NonNull XPathSupport xpathSupport) { + final StatementSupportBundle fullDeclarationBundle = fullDeclarationBundle(xpathSupport); + return new CustomCrossSourceStatementReactorBuilder(SUPPORTED_VERSIONS) + .addAllSupports(ModelProcessingPhase.INIT, INIT_BUNDLE) + .addAllSupports(ModelProcessingPhase.SOURCE_PRE_LINKAGE, PRE_LINKAGE_BUNDLE) + .addAllSupports(ModelProcessingPhase.SOURCE_LINKAGE, LINKAGE_BUNDLE) + .addAllSupports(ModelProcessingPhase.STATEMENT_DEFINITION, STMT_DEF_BUNDLE) + .addAllSupports(ModelProcessingPhase.FULL_DECLARATION, fullDeclarationBundle) + .addAllSupports(ModelProcessingPhase.EFFECTIVE_MODEL, fullDeclarationBundle) + .addValidationBundle(ValidationBundleType.SUPPORTED_REFINE_SUBSTATEMENTS, + YangValidationBundles.SUPPORTED_REFINE_SUBSTATEMENTS) + .addValidationBundle(ValidationBundleType.SUPPORTED_AUGMENT_TARGETS, + YangValidationBundles.SUPPORTED_AUGMENT_TARGETS) + + // FIXME: 5.0.0: we do not seem to need this validation bundle + .addValidationBundle(ValidationBundleType.SUPPORTED_CASE_SHORTHANDS, + YangValidationBundles.SUPPORTED_CASE_SHORTHANDS) + + .addValidationBundle(ValidationBundleType.SUPPORTED_DATA_NODES, + YangValidationBundles.SUPPORTED_DATA_NODES); + } + + private static @NonNull StatementSupportBundle fullDeclarationBundle(final XPathSupport xpathSupport) { + return StatementSupportBundle + .derivedFrom(STMT_DEF_BUNDLE) + .addSupport(LeafStatementSupport.getInstance()) + .addSupport(ConfigStatementSupport.getInstance()) + .addSupport(DeviationStatementSupport.getInstance()) + .addVersionSpecificSupport(VERSION_1, DeviateStatementRFC6020Support.getInstance()) + .addVersionSpecificSupport(VERSION_1_1, DeviateStatementRFC7950Support.getInstance()) + .addVersionSpecificSupport(VERSION_1, ChoiceStatementRFC6020Support.getInstance()) + .addVersionSpecificSupport(VERSION_1_1, ChoiceStatementRFC7950Support.getInstance()) + .addVersionSpecificSupport(VERSION_1, CaseStatementRFC6020Support.getInstance()) + .addVersionSpecificSupport(VERSION_1_1, CaseStatementRFC7950Support.getInstance()) + .addSupport(MustStatementSupport.createInstance(xpathSupport)) + .addSupport(MandatoryStatementSupport.getInstance()) + .addSupport(AnyxmlStatementSupport.getInstance()) + .addVersionSpecificSupport(VERSION_1_1, AnydataStatementSupport.getInstance()) + .addSupport(FeatureNamespace.BEHAVIOUR) + .addSupport(IfFeatureStatementSupport.getInstance()) + .addSupport(UsesStatementSupport.getInstance()) + .addSupport(GroupingNamespace.BEHAVIOUR) + .addSupport(ErrorMessageStatementSupport.getInstance()) + .addSupport(ErrorAppTagStatementSupport.getInstance()) + .addVersionSpecificSupport(VERSION_1, LeafListStatementRFC6020Support.getInstance()) + .addVersionSpecificSupport(VERSION_1_1, LeafListStatementRFC7950Support.getInstance()) + .addSupport(PresenceStatementSupport.getInstance()) + .addSupport(MaxElementsStatementSupport.getInstance()) + .addSupport(MinElementsStatementSupport.getInstance()) + .addSupport(OrderedByStatementSupport.getInstance()) + .addSupport(WhenStatementSupport.createInstance(xpathSupport)) + .addSupport(AugmentImplicitHandlingNamespace.BEHAVIOUR) + .addVersionSpecificSupport(VERSION_1, AugmentStatementRFC6020Support.getInstance()) + .addVersionSpecificSupport(VERSION_1_1, AugmentStatementRFC7950Support.getInstance()) + .addVersionSpecificSupport(VERSION_1, RefineStatementRFC6020Support.getInstance()) + .addVersionSpecificSupport(VERSION_1_1, RefineStatementRFC7950Support.getInstance()) + .addSupport(FeatureStatementSupport.getInstance()) + .addSupport(PositionStatementSupport.getInstance()) + .addSupport(ValueStatementSupport.getInstance()) + .build(); } } diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/reactor/ServiceLoaderState.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/reactor/ServiceLoaderState.java new file mode 100644 index 0000000000..c62b316124 --- /dev/null +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/reactor/ServiceLoaderState.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2020 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.parser.rfc7950.reactor; + +import java.util.ServiceLoader; +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.XPathSupport; +import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor; +import org.opendaylight.yangtools.yang.xpath.api.YangXPathParserFactory; + +/** + * State derived from ServiceLoader. We statically bind to this state. If you need more dynamics, you should not be + * showing up here at all. + */ +@NonNullByDefault +final class ServiceLoaderState { + static final class DefaultReactor { + static final CrossSourceStatementReactor INSTANCE = RFC7950Reactors.defaultReactorBuilder().build(); + } + + static final class VanillaReactor { + static final CrossSourceStatementReactor INSTANCE = RFC7950Reactors.vanillaReactorBuilder().build(); + } + + static final class XPath { + static final XPathSupport INSTANCE = new XPathSupport(ServiceLoader.load(YangXPathParserFactory.class) + .findFirst().orElseThrow(() -> new ExceptionInInitializerError("No YangXPathParserFactory found"))); + } +} diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/ArgumentUtils.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/ArgumentUtils.java index 942650519f..5ed39e3975 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/ArgumentUtils.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/ArgumentUtils.java @@ -16,7 +16,6 @@ import java.util.regex.Pattern; import org.checkerframework.checker.regex.qual.Regex; import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath; import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition; import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier; import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute; @@ -77,10 +76,6 @@ public final class ArgumentUtils { } } - public static RevisionAwareXPath parseXPath(final StmtContext ctx, final String path) { - return XPathSupport.parseXPath(ctx, path); - } - public static boolean isAbsoluteXPath(final String path) { return PATH_ABS.matcher(path).matches(); } diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/XPathSupport.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/XPathSupport.java index c9f60274ce..a5bc3f462e 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/XPathSupport.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/XPathSupport.java @@ -7,8 +7,9 @@ */ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt; -import java.util.Iterator; -import java.util.ServiceLoader; +import static java.util.Objects.requireNonNull; + +import com.google.common.annotations.Beta; import javax.xml.xpath.XPathExpressionException; import org.eclipse.jdt.annotation.NonNullByDefault; import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath; @@ -18,62 +19,36 @@ import org.opendaylight.yangtools.yang.xpath.api.YangXPathExpression.QualifiedBo import org.opendaylight.yangtools.yang.xpath.api.YangXPathParser; import org.opendaylight.yangtools.yang.xpath.api.YangXPathParserFactory; import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +@Beta @NonNullByDefault -abstract class XPathSupport { - private static final Logger LOG = org.slf4j.LoggerFactory.getLogger(XPathSupport.class); - - private static final XPathSupport INSTANCE; - - static { - final Iterator it = ServiceLoader.load(YangXPathParserFactory.class).iterator(); - if (!it.hasNext()) { - LOG.warn("Failed to find XPath parser factory, no XPath validation will be performed"); - INSTANCE = new Noop(); - } else { - INSTANCE = new XPathImpl(it.next()); - } - } +public final class XPathSupport { + private static final Logger LOG = LoggerFactory.getLogger(XPathSupport.class); - static RevisionAwareXPath parseXPath(final StmtContext ctx, final String xpath) { - return INSTANCE.parseXPath(xpath, ctx); - } - - abstract RevisionAwareXPath parseXPath(String xpath, StmtContext ctx); + private final YangXPathParserFactory factory; - private static final class Noop extends XPathSupport { - @Override - RevisionAwareXPath parseXPath(final String xpath, final StmtContext ctx) { - return new RevisionAwareXPathImpl(xpath, ArgumentUtils.isAbsoluteXPath(xpath)); - } + public XPathSupport(final YangXPathParserFactory factory) { + this.factory = requireNonNull(factory); } - private static final class XPathImpl extends XPathSupport { - private final YangXPathParserFactory factory; - - XPathImpl(final YangXPathParserFactory factory) { - this.factory = factory; + public RevisionAwareXPath parseXPath(final StmtContext ctx, final String xpath) { + final boolean isAbsolute = ArgumentUtils.isAbsoluteXPath(xpath); + final YangXPathParser.QualifiedBound parser = factory.newParser(new StmtNamespaceContext(ctx)); + final QualifiedBound parsed; + try { + parsed = parser.parseExpression(xpath); + } catch (XPathExpressionException e) { + LOG.warn("Argument \"{}\" is not valid XPath string at \"{}\"", xpath, + ctx.getStatementSourceReference(), e); + return new RevisionAwareXPathImpl(xpath, isAbsolute); } - @Override - RevisionAwareXPath parseXPath(final String xpath, final StmtContext ctx) { - final boolean isAbsolute = ArgumentUtils.isAbsoluteXPath(xpath); - final YangXPathParser.QualifiedBound parser = factory.newParser(new StmtNamespaceContext(ctx)); - final QualifiedBound parsed; - try { - parsed = parser.parseExpression(xpath); - } catch (XPathExpressionException e) { - LOG.warn("Argument \"{}\" is not valid XPath string at \"{}\"", xpath, - ctx.getStatementSourceReference(), e); - return new RevisionAwareXPathImpl(xpath, isAbsolute); - } - - if (ctx.getRootVersion().compareTo(parsed.getYangVersion()) < 0) { - LOG.warn("{} features required in {} context to parse expression '{}' [at {}]", - parsed.getYangVersion().getReference(), ctx.getRootVersion().getReference(), xpath, - ctx.getStatementSourceReference()); - } - return new WithExpressionImpl(xpath, isAbsolute, parsed); + if (ctx.getRootVersion().compareTo(parsed.getYangVersion()) < 0) { + LOG.warn("{} features required in {} context to parse expression '{}' [at {}]", + parsed.getYangVersion().getReference(), ctx.getRootVersion().getReference(), xpath, + ctx.getStatementSourceReference()); } + return new WithExpressionImpl(xpath, isAbsolute, parsed); } } diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/must/MustStatementSupport.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/must/MustStatementSupport.java index bdaf2fbbef..8ce4e2cd19 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/must/MustStatementSupport.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/must/MustStatementSupport.java @@ -7,11 +7,14 @@ */ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.must; +import static java.util.Objects.requireNonNull; + +import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath; import org.opendaylight.yangtools.yang.model.api.YangStmtMapping; import org.opendaylight.yangtools.yang.model.api.stmt.MustEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.MustStatement; -import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.ArgumentUtils; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.XPathSupport; import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; import org.opendaylight.yangtools.yang.parser.spi.meta.SubstatementValidator; @@ -25,19 +28,21 @@ public final class MustStatementSupport .addOptional(YangStmtMapping.ERROR_MESSAGE) .addOptional(YangStmtMapping.REFERENCE) .build(); - private static final MustStatementSupport INSTANCE = new MustStatementSupport(); - private MustStatementSupport() { + private final @NonNull XPathSupport xpathSupport; + + private MustStatementSupport(final XPathSupport xpathSupport) { super(YangStmtMapping.MUST); + this.xpathSupport = requireNonNull(xpathSupport); } - public static MustStatementSupport getInstance() { - return INSTANCE; + public static MustStatementSupport createInstance(final XPathSupport xpathSupport) { + return new MustStatementSupport(xpathSupport); } @Override public RevisionAwareXPath parseArgumentValue(final StmtContext ctx, final String value) { - return ArgumentUtils.parseXPath(ctx, value); + return xpathSupport.parseXPath(ctx, value); } @Override diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/when/WhenStatementSupport.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/when/WhenStatementSupport.java index 4f862d3d73..060a4665ca 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/when/WhenStatementSupport.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/when/WhenStatementSupport.java @@ -7,11 +7,14 @@ */ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.when; +import static java.util.Objects.requireNonNull; + +import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath; import org.opendaylight.yangtools.yang.model.api.YangStmtMapping; import org.opendaylight.yangtools.yang.model.api.stmt.WhenEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.WhenStatement; -import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.ArgumentUtils; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.XPathSupport; import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; import org.opendaylight.yangtools.yang.parser.spi.meta.SubstatementValidator; @@ -23,19 +26,21 @@ public final class WhenStatementSupport .addOptional(YangStmtMapping.DESCRIPTION) .addOptional(YangStmtMapping.REFERENCE) .build(); - private static final WhenStatementSupport INSTANCE = new WhenStatementSupport(); - private WhenStatementSupport() { + private final @NonNull XPathSupport xpathSupport; + + private WhenStatementSupport(final XPathSupport xpathSupport) { super(YangStmtMapping.WHEN); + this.xpathSupport = requireNonNull(xpathSupport); } - public static WhenStatementSupport getInstance() { - return INSTANCE; + public static WhenStatementSupport createInstance(final XPathSupport xpathSupport) { + return new WhenStatementSupport(xpathSupport); } @Override public RevisionAwareXPath parseArgumentValue(final StmtContext ctx, final String value) { - return ArgumentUtils.parseXPath(ctx, value); + return xpathSupport.parseXPath(ctx, value); } @Override diff --git a/yang/yang-xpath-impl/pom.xml b/yang/yang-xpath-impl/pom.xml index bc60526563..eccdd51fb0 100644 --- a/yang/yang-xpath-impl/pom.xml +++ b/yang/yang-xpath-impl/pom.xml @@ -55,7 +55,7 @@ org.osgi - org.osgi.core + osgi.cmpn @@ -68,7 +68,6 @@ org.opendaylight.yangtools.yang.xpath.impl - org.opendaylight.yangtools.yang.xpath.impl.Activator diff --git a/yang/yang-xpath-impl/src/main/java/org/opendaylight/yangtools/yang/xpath/impl/Activator.java b/yang/yang-xpath-impl/src/main/java/org/opendaylight/yangtools/yang/xpath/impl/Activator.java deleted file mode 100644 index 0ab894f08b..0000000000 --- a/yang/yang-xpath-impl/src/main/java/org/opendaylight/yangtools/yang/xpath/impl/Activator.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2017 Pantheon Technologies, 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.xpath.impl; - -import org.eclipse.jdt.annotation.Nullable; -import org.opendaylight.yangtools.yang.xpath.api.YangXPathParserFactory; -import org.osgi.framework.BundleActivator; -import org.osgi.framework.BundleContext; - -/** - * YANG XPath implementation activator. Publishes a {@link YangXPathParserFactory} implementation on bundle start. - * - * @author Robert Varga - */ -public final class Activator implements BundleActivator { - @Override - public void start(final @Nullable BundleContext context) throws Exception { - context.registerService(YangXPathParserFactory.class, new AntlrXPathParserFactory(), null); - } - - @Override - public void stop(final @Nullable BundleContext context) throws Exception { - // No-op, framework will unregister our services - } -} diff --git a/yang/yang-xpath-impl/src/main/java/org/opendaylight/yangtools/yang/xpath/impl/AntlrXPathParserFactory.java b/yang/yang-xpath-impl/src/main/java/org/opendaylight/yangtools/yang/xpath/impl/AntlrXPathParserFactory.java index 52f77cdab3..0569374538 100644 --- a/yang/yang-xpath-impl/src/main/java/org/opendaylight/yangtools/yang/xpath/impl/AntlrXPathParserFactory.java +++ b/yang/yang-xpath-impl/src/main/java/org/opendaylight/yangtools/yang/xpath/impl/AntlrXPathParserFactory.java @@ -16,10 +16,18 @@ import org.opendaylight.yangtools.yang.xpath.api.YangXPathParser; import org.opendaylight.yangtools.yang.xpath.api.YangXPathParser.QualifiedBound; import org.opendaylight.yangtools.yang.xpath.api.YangXPathParser.UnqualifiedBound; import org.opendaylight.yangtools.yang.xpath.api.YangXPathParserFactory; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Deactivate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @MetaInfServices @Singleton +@Component(immediate = true) public final class AntlrXPathParserFactory implements YangXPathParserFactory { + private static final Logger LOG = LoggerFactory.getLogger(AntlrXPathParserFactory.class); + @Override public YangXPathParser newParser(final YangXPathMathMode mathMode) { return new AntlrXPathParser.Base(mathMode); @@ -35,4 +43,16 @@ public final class AntlrXPathParserFactory implements YangXPathParserFactory { final QNameModule defaultNamespace) { return new AntlrXPathParser.Unqualified(mathMode, namespaceContext, defaultNamespace); } + + @Activate + @SuppressWarnings("static-method") + void activate() { + LOG.info("XPath Parser activated"); + } + + @Deactivate + @SuppressWarnings("static-method") + void deactivate() { + LOG.info("XPath Parser deactivated"); + } } -- 2.36.6